在 Arduino 中添加以错误结果结尾的十六进制数字



我写了一个简单的代码,将十六进制值乘以0x1、0x100等相加。

uid = (nuidPICC[0] * 0x1000000);
uid = uid + (nuidPICC[1] * 0x10000);
uid = uid + (nuidPICC[2] * 0x100);
uid = uid + nuidPICC[3];

当我传递数字 D1,55,BF,2D 结果时D154BF2D但在某些数字组合上它运行良好,我使用的是 Arduino IDE 1.8.5,你能解释一下吗?

您拥有的代码运行良好,因此如果您假设它正在执行您想要它执行的操作,则无需解释。如果它没有做你想让它做的事情,那么我们可以猜测你想让它做什么,但可能是你想让它给你泡一杯好茶,在这种情况下,这不会有太大帮助。

由于您没有给出变量的定义,因此我假设您有类似以下内容:

int8_t nuidPICC[] = { 0xD1,0x55,0xBF,0x2D };
printf("nuidPICC = { %d, %d, %d, %d }n", nuidPICC[0], nuidPICC[1], nuidPICC[2], nuidPICC[3]);
int32_t     uid = (nuidPICC[0] * 0x1000000);
uid = uid + (nuidPICC[1] * 0x10000);
uid = uid + (nuidPICC[2] * 0x100);
uid = uid + nuidPICC[3];
printf("uid = %d * %d + %d * %d + %d * %d + %d  = %dn",
nuidPICC[0], 0x1000000,
nuidPICC[1], 0x10000,
nuidPICC[2], 0x100,
nuidPICC[3], uid);
printf("%d in hex is %08xn",uid,uid);

哪些输出

nuidPICC = { -47, 85, -65, 45 }
uid = -47 * 16777216 + 85 * 65536 + -65 * 256 + 45  = -782975187
-782975187 in hex is d154bf2d

您可以验证它是否完全按照您的要求执行。

但是,给定您要乘以的值,您似乎正在尝试从四个有符号字节制作掩码。

将int8_t乘以整数文本会导致它扩展到整数,因此

int32_t x = int8_t(0xbf) * 0x100;
printf("0xbf * 0x100 = %d or 0x%08xn",x,x);
0xbf * 0x100 = -16640 or 0xffffbf00

那些领先的0xffff被称为"符号扩展",并导致下一个更高的字节值与你只是移动和组合位时得到的字节值不同。

如果要合并有符号字节,则需要屏蔽符号扩展:

uid = (nuidPICC[0] << 24);
uid = uid | (nuidPICC[1] << 16) & 0xff0000;
uid = uid | (nuidPICC[2] << 8) & 0xff00;
uid = uid | nuidPICC[3] & 0xff;

uid = ( 0xffffffd1 << 24) 
| ( ( 0x00000055 << 16 )  & 0xff0000 )
| ( ( 0xffffffbf << 8 ) & 0xff00 ) 
| ( 0x0000002d & 0xff ) 
= 0xd155bf2d

但通常将无符号字节用于位掩码更容易,因为它们没有符号扩展名:

uint8_t nuidPICC[] = { 0xD1,0x55,0xBF,0x2D };
uint32_t uid = (nuidPICC[0] << 24);
uid = uid | (nuidPICC[1] << 16);
uid = uid | (nuidPICC[2] << 8);
uid = uid | nuidPICC[3];
printf("uid = ( 0x%x << %d) | ( 0x%x << %d ) | ( 0x%x << %d ) | 0x%x  = 0x%xn",
nuidPICC[0], 24,
nuidPICC[1], 16,
nuidPICC[2], 8,
nuidPICC[3], uid);
uid = ( 0x000000d1 << 24)
| ( 0x00000055 << 16 )
| ( 0x000000bf << 8 ) 
|   0x0000002d  
= 0xd155bf2d

最新更新