【问题标题】:C - 8051 Array outputC - 8051 阵列输出
【发布时间】:2017-09-24 06:36:47
【问题描述】:

我的代码中有一个非常微不足道但似乎很难修复的错误。长话短说,当我从芯片读取数据值时,我有一个数组,其中充满了信息。这个名为data_buffer 的数组然后以一种十六进制文件格式将每个字符发送到UART 以进行调试。

当我键入命令并将字符输出到终端时,数组会为我指定有数据的空格吐出空字符。

代码如下,我尽量按顺序排列:

void read_256_address(void)
{
    char SFRPAGE_SAVE=SFRPAGE;
    SFRPAGE=CONFIG_PAGE;

    RFLAG=0;

    address_sum=((unsigned long)address_byte3<<16)
                +((unsigned long)address_byte2<<8)
                +((unsigned long)address_byte1);

    if(chip_byte>=0 && chip_byte<=76)
    {
        Port4=chip_byte;
        read_address_loop();
    }

    while(RFLAG==0){if(RFLAG==1){break;}}

    SFRPAGE=SFRPAGE_SAVE;
}

void read_address_loop(void)
{
    unsigned long int i=14;

    char SFRPAGE_SAVE=SFRPAGE;
    SFRPAGE=CONFIG_PAGE;

    RFLAG=0;

    if(command_byte==0x82)
    {
        write_P4();
  for(next_address=address_sum;next_address<(address_sum+256);next_address++)
        {
            output_address();
            read_op();
            hex_data=data_read;
            HEXtoASC();
            data_buffer[i]=msb;i++;
            data_buffer[i]=lsb;i++;
            data_buffer[i]=' ';i++;
            if(next_address+=15){format_data_dump();}
        }
   }

void output_data(void)
{
    unsigned char i;

    for(i=0;i<65;i++)
    {
        send_byte(data_buffer[i]);
    }
}

对于for loop 上的缩进,我深表歉意,但这是由于格式问题。它应该与上面的write_P4(); 代码对齐。当上面的代码运行时,它会输出所需的格式而不是值,例如:

M82 1B 104560 FF ****null char for remaining indices**** 0x0D 0x0A
M82 1B 104560 FF FF ****null char for remaining indices**** 0x0D 0x0A
M82 1B 104560 FF FF FF ****null char for remaining indices**** 0x0D 0x0A

我期望看到的如下:

M82 1B 1040560 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 0x0D 0x0A
M82 1B 1040570 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 0x0D 0x0A
.
.
.
M82 1B 1040650 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 0x0D 0x0A

有人可以告诉我为什么会发生这种情况吗?似乎整个缓冲区的每次迭代后缓冲区的长度都在增加,而不是每次都相同。

【问题讨论】:

  • else if(command_byte==0x82) 没有找到if(你可能在某处犯了剪切和粘贴错误)
  • @wildplasser 我为那个声明道歉。在我之前的实际代码中有一个匹配的if 语句。我只是为了在问题中压缩我的代码而将其排除在外。我知道这会如何引起混乱。
  • 您对if (next_address+=15) 的意图是什么? next_address += 15 添加了 15,但它的计算结果始终为 true,当您在两个位置更改 for 循环变量时会令人困惑。你的意思是像next_address % 16 == 15这样的东西吗?我会说代码的功能相当复杂。你怎么样1)在一个函数中将数据读入一个特定长度的数组,然后2)在第二个函数中将数组的内容转储到一个十六进制字符串中?这比这更容易测试(和推理)。
  • @Groo 我的意图是让for 循环增加next_address 15 次,当第15 次到来时,这将填满data_buffer 并将其发送到终端。所以我应该看到 16 行数据来自 16 个地址。这就是我得到的,但我得到的是null char 而不是FF。我希望这是有道理的。我可能已经解释过,到处都有
  • @Groo 我还没有尝试过模运算。 Brb 与结果

标签: c arrays function loops 8051


【解决方案1】:

我可能找不到您的问题,但让我在您的代码中看到一些 cmets 供您思考。有问题的代码上方会出现注释:

void read_256_address(void)
{
    char SFRPAGE_SAVE=SFRPAGE;
    SFRPAGE=CONFIG_PAGE;

    RFLAG=0;

假设地址总和的大小至少为 32 位?

    address_sum=((unsigned long)address_byte3<<16)
                +((unsigned long)address_byte2<<8)
                +((unsigned long)address_byte1);

如果chip_bytes是无符号的,则不需要0校验

    if(chip_byte>=0 && chip_byte<=76)
    {
        Port4=chip_byte;
        read_address_loop();
    }

我祈祷RFLAG 在这里是volatile,否则会混乱。在线程系统上,在这里使用 yield 或类似的东西会很好,而不是旋转。

    while(RFLAG==0){if(RFLAG==1){break;}}

    SFRPAGE=SFRPAGE_SAVE;
}

void read_address_loop(void)
{

非常神奇的 14 和 i 作为非索引也不是一个好主意(哦,我明白了 - 稍后用于索引。)

    unsigned long int i=14;

    char SFRPAGE_SAVE=SFRPAGE;
    SFRPAGE=CONFIG_PAGE;

    RFLAG=0;

    if(command_byte==0x82)
    {
        write_P4();

如果 address_sum 接近其类型的大小,这可能会永远循环。

        for(next_address=address_sum;
            next_address<(address_sum+256);
            next_address++)
        {
            output_address();
            read_op();
            hex_data=data_read;
            HEXtoASC();

考虑将 ++ 放在索引中的 i 上

            data_buffer[i]=msb;i++;
            data_buffer[i]=lsb;i++;

第三个字节的空间?这很有趣 - 猜测这是您获取 NUL 值的部分。也许仔细检查您的转换器,看看它是否通过将空格转换为 0 来帮助您。

            data_buffer[i]=' ';i++;

考虑使用next_address &amp; 0x0f,如果你在低半字节检查0,加15很奇怪。您的意思是加 16 吗?

            if(next_address+=15){format_data_dump();}
        }
   }

void output_data(void)
{
    unsigned char i;

再次神奇的 65 大小 - 考虑 sizeof() 数组或通过另一种方法检查结束。

    for(i=0;i<65;i++)
    {
        send_byte(data_buffer[i]);
    }
}

在我上面提到的所有内容中,带有 +=15 的 if 检查似乎是最令人不安的区域。同样,我不知道我所掌握的任何内容是否能引起您的问题,但值得深入研究以确定。

【讨论】:

  • address_sum 不是 8 字节宽,而是 5 字节宽,我不知道 6 字节宽的数据类型。 chip_byte 没有签名,所以检查主要是为了我的理智。我不熟悉 volatile 类型,所以我会研究一下。地址总和永远不会超过 0x140000(防止这种情况发生的声明变量)。我会放置++ 来清理它。我假设如果我将字符硬连线到该索引中,我就不需要转换?我正在检查next_address 是否已增加 15 次,以便将其转储到终端中。比如检查NULL char?
  • 感谢您的所有建议!刚刚还有几个问题要问你
  • address_sum 那么是非标准类型吗?这意味着您的编译器必须做一些魔术才能使数学在您的系统上工作。 volatile 告诉你的编译器不要优化你的循环——总是读入这个值,即使它看起来永远不会改变。这在嵌入式编码中很常见。如果您正在检查 next_address 是否已增加 15 次,请考虑使用单独的计数器。每次循环递增,如果 == 15,重置为 0 并转储。像您现在所拥有的那样干净得多,根本不会真正做到这一点。
  • 我让它工作了!实际上最终为了清理和可读性而将几个重复的代码分成单独的子例程。它现在工作正常!感谢帮助
  • 很高兴听到这个消息!
猜你喜欢
  • 2012-11-24
  • 1970-01-01
  • 2015-02-13
  • 2012-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多