二进制字面量、字节序、串口发送、转16进制时符号扩展问题

int data = 0b11111111'00000000'00000000'00000001;
//int data=-16777215  //等效
char cBuff[4];
*(short*)cBuff = 1;
cBuff[2] = 0; 
cBuff[3] = 255;

二进制字面量data与cBuff等效,注意:二进制字面量的右侧是低字节

在大多数系统中,整数是以小端序(Little Endian)存储的。因此,-16777215 的字节序为:

 用命令行向串口发送数据,是以字节序发送的(低到高依次发送,16进制格式),所以发送data应该

printf '\x01\x00\x00\xFF' > /dev/ttyTHS1
或
echo -ne '\x01\x00\x00\xFF' > /dev/ttyTHS1

而不是

printf '-16777215' > /dev/ttyTHS1

 【转16进制时符号扩展问题】

cBuff是char类型,255其实是-1,-1 会被符号扩展为 int 类型的 -1(二进制表示为 0xFFFFFFFF),而不是认为的0xFF

//发送给串口(需转2位16进制)
char command[64];
sprintf(command, "printf '\\x%02X\\x%02X\\x%02X\\x%02X' > /dev/ttyTHS1",(unsigned char)cBuff[0], (unsigned char)cBuff[1],(unsigned char)cBuff[2], 
cBuff[3]); sendSSH(m_session, command);

注意 cBuff[3] 没有加 (unsigned char),那么发送给串口会出现异常(我的灯不确定的亮起)

所以,通过代码转16进制时,一定要留意溢出导致的符号扩展问题。推荐严谨的代码风格,0~255就用uchar(即 uchar cBuff[4],之后的就不再用unsigned char转了)

 ARM中,下述不会出错的原因是指定写入4字节数据,cBuff[3]是第4个字节,其8位是 11111111。而 %02X 会将其格式化为 FFFFFFFF,而不是期望的 FF。

ssize_t bytesWritten = write(fd, cBuff, 4);//写入4字节数据

 

posted @ 2025-03-17 13:42  夕西行  阅读(30)  评论(0)    收藏  举报