我在C中编写了PIC16F1947的代码。我使用以下内容:
部分代码处理来自PC的数据。我从PC发送的特定数据包是325字节。该数据包如下所示:
data: 0, 64, 1, 0, 255, 255, 255, ... (all 255) ..., 255, 1
index: 0 1 2 3 4 5 6 323 324
数据包的内容显示为8位十进制值(8位无符号整数)。微商店将其存储在unsigned char
:
unsigned char _command_mgr_buff[330];
unsigned char
是PIC16F的8位无符号整数。
数据包的最后一个字节,即索引324,是数据包的校验和。它是索引1到323的总和,包括1和323.计算此校验和的PC代码(在C#中)如下:
allCertPages[324] = 0;
for (int i = 1; i <= 323; i++)
{
allCertPages[324] += allCertPages[i];
}
allCertPages
是byte[]
。
微观必须验证校验和确实是从PC传递的值。这是我为PIC16F编写的验证码,包括一些调试信息:
param0 = _command_mgr_buff[324]; // param0 is unsigned int, 16 bit
param1 = _command_mgr_buff[324]; // param1 is unsigned int, 16 bit
// Checksum verification
for (var = 1; var <= 323; var++) // var is unsigned int, 16 bit
{
_command_mgr_buff[324] -= _command_mgr_buff[var];
param1 -= _command_mgr_buff[var];
}
if (!_command_mgr_buff[324])
{
send_status(CS_BAD_PARAM);
}
想法是从校验和中减去[1,323]范围内的所有值。如果最终值为0,则校验和是正确的。否则,如果在减法后发现_command_mgr_buff[324]
为非零,则校验和不正确。
在调试模式下(以及在发布模式下)执行代码后,我在_command_mgr_buff[324]
中获得非零值(因此send_status(CS_BAD_PARAM);
执行并且PC认为出错了),但param1
的低位字节为零!
这怎么可能?!
如果您感兴趣,这里是为非零检查生成的程序集:
8780 ;mgr_command.c: 1230: if (!_command_mgr_buff[324])
8781 0E89 30EA movlw low(8870+0144h)
8782 0E8A 00D3 movwf (??_command_mgr_run+0)^080h+0
8783 0E8B 3023 movlw high(8870+0144h)
8784 0E8C 00D4 movwf (??_command_mgr_run+0)^080h+0+1
8785 0E8D 0853 movf 0+(??_command_mgr_run+0)^080h+0,w
8786 0E8E 0086 movwf fsr1l
8787 0E8F 0854 movf 1+(??_command_mgr_run+0)^080h+0,w
8788 0E90 0087 movwf fsr1h
8789
8790 0E91 0881 movf indf1,f
8791 0E92 1D03 skipz
8792 0E93 2E95 goto u10101
8793 0E94 2E96 goto u10100
8794 0E95 u10101:
8795 0E95 2E9B goto l55070
8796 0E96 u10100:
8797 line 1232
8798
8799 0E96 l55068:
8800 ;mgr_command.c: 1231: {
8801 ;mgr_command.c: 1232: send_status(0x11);
8802 0E96 3011 movlw (011h)
8803 0E97 31B6 2693 3188 fcall _send_status
8804 line 1233
8805 ;mgr_command.c: 1233: }
8806 0E9A 2FE3 goto l45048
8807 line 1234
以下是调试期间的截图。请检查右侧的Watch窗口和第324个元素的工具提示。
param0
应为1 param1 & 0xFF
应为0 _command_mgr_buff[324]
应为0(工具提示显示0x0F ?? !!)
答案 0 :(得分:8)
如果您的代码与您说的一样,那么主要问题是您的测试本身:
if (!_command_mgr_buff[324])
{
send_status(CS_BAD_PARAM);
}
如果结果符合您的要求(即零),您就会发送信号......
这是我不喜欢非布尔值的布尔测试的原因之一。布尔变量通常具有一些名称,可以帮助您读取它们正确捕获的条件,例如if (isLoaded)
或if (!anyErrors)
......这对于数字而言并不适用。所以更容易确保你已经得到了你想要写出来的语义:
if (_command_mgr_buff[324] != 0)
{
send_status(CS_BAD_PARAM);
}
至于为什么你的调试器给你0x0F ...无法帮助你...我的观点只是你在零分支。您可以尝试一个干净的构建,看看它是否仍然这样说。 (程序的调试符号可能已过时或其他什么?)