前段时间做了一个STM32上的Modbus通信,磕磕绊绊,总算是做的差不多了。
在实现的过程中出现一些问题,就是在调试的时候发现因为STM32的字节存储是小端模式的,通信的数据大多是16位的,这就造成如果我才用的内存复制函数把存储中数据复制到帧中时候自己顺序反了(因为Modbus里面的数据是大端模式的),本来实现着在复制的时候不用函数memcpy而是一个一个的取出之后调换字节序,放入帧中,但是很明显这样子太复杂了,一点都不好。
后来的想法是创建一个“寄存器”的结构体,这个存放所有的保持型数据或者是输入型数据,当向其中存入数据的时候,使用字节序的转换函数把字节序转换之后存入到这个“寄存器”中,这样子就可以在后续的读取时候直接使用memecpy了!
STM32没有专门的字节序转换的函数,所以我们自己定义一个
#define SWAP(A) ((((u16)(A)&0xff00) >> 8)|(((u16)(A)&0x00ff)<<8)) //字节序转换
这样读取数据就可以直接使用memecpy了
//读取数据
void read_data(u8 func, u16 start_addr, u16 num, u8*buff){
switch(func){
case MB_RD_HOLD:
//保持型寄存器 保持寄存器的值不需要更新,只需要直接读取即可
memcpy(buff, (u8*)(((u8*)&hold_data)+start_addr*2), num*2);
break;
case MB_RD_INPUT:
update_input(); //先更新一次输入寄存器的值
memcpy(buff, (u8*)(((u8*)&input_data)+start_addr*2), num*2);
break;
}
}
以前是很少关心到数据到底是怎么存储的,但是在做像网络编程这类应用的时候,字节序就很重要了。