最近着手于开发RPIMouse的通信协议,第一次接触CRC校验,发现有很多问题。32本身是带有硬件CRC校验的,但是他的校验结果和PC算法计算出来的完全不同。在查找解决方法的过程中得知32数据和PC数据的大小端不同,数据计算结果当然不同。什么是大小端呢?
一、什么是大小端
大端模式:即高位字节排放在内存地址低地址端,低位字节排放在内存的高地址端。
小端模式:即低位字节排放在内存地址低地址端,高位字节排放在内存的高地址端。
比如:数字0x12 34 56 78 在内存中的表示形式为:
1)大端模式:
低地址------------------>高地址
0x12 | 0x34 | 0x56 | 0x78
2)小端模式:
低地址------------------>高地址
0x78 | 0x56 | 0x34 | 0x12
3)具体例子:
16bit宽的数0x1234在小端模式及大端模式CPU中存放的方式(假设从0x4000开始存放)为:
| 内存地址 | 小端模式存放内容 | 大端模式存放内容 |
| 0x4000 | 0x34 | 0x12 |
| 0x4001 | 0x12 | 0x34 |
32bit宽的数0x12345678在小端模式及大端模式CPU中存放的方式(假设地址从0x4000开始存放)为:
| 内存地址 | 小端模式存放内容 | 大端模式存放内容 |
| 0x4000 | 0x78 | 0x12 |
| 0x4001 | 0x56 | 0x34 |
| 0x4002 | 0x34 | 0x56 |
| 0x4003 | 0x12 | 0x78 |
二、数组在大小端下的存储
以unsigned int value = 0x12345678为例,分别看看两种字节序下其存储情况。我们可以用unsigned char buf[4] 来表示 value
大端模式:
高地址
|
| buf[3] (0x78) 低位
| buf[2] (0x56)
| buf[1] (0x34)
| buf[0] (0x12) 高位
|
低地址
小端模式:
高地址
|
| buf[0] (0x12) 低位
| buf[1] (0x34)
| buf[2] (0x56)
| buf[3] (0x78) 高位
|
低地址
三、判断机器字节序的方法
一般通过union类型来测试。以下代码可用来测试编译器大小端模式。
#include <stdio.h>
int main (void)
{
union
{
short i;
char a[2];
}u;
u.a[0] = 0x11;
u.a[1] = 0x22;
printf ("0x%x\n", u.i); //0x2211 为小端 0x1122 为大端
return 0;
}
输出结果:
0x2211
四、数据转换方法
对于单字数据(16bit)
#define BigtoLittle16(A) (( ((uint16)(A) & 0xff00) >> 8) | \
(( (uint16)(A) & 0x00ff) << 8))
对于双字数据(32bit)
#define BigtoLittle32(A) ((( (uint32)(A) & 0xff000000) >> 24) | \
(( (uint32)(A) & 0x00ff0000) >> 8) | \
(( (uint32)(A) & 0x0000ff00) << 8) | \
(( (uint32)(A) & 0x000000ff) << 24))
以上方法及内容来自CSDN:https://blog.csdn.net/ce123_zhouwei/article/details/6971544 ,程序未经测试。
所以,如果想使用32的硬件CRC,首先要将小端数据转为大端,得到CRC后与初值(0xFFFF FFFF)按位异或,即可得到主流CRC32-MPEG2的校验结果。
参考链接:
STM32的硬件CRC32使用 https://blog.csdn.net/lan120576664/article/details/47156067
STM32 大小端模式 与 堆栈及其增长方向分析 http://www.openedv.com/thread-24152-1-1.html
How to set STM32 to generate standard CRC32 https://stackoverflow.com/questions/39646441/how-to-set-stm32-to-generate-standard-crc32
STM32内置CRC模块的使用 http://bbs.21ic.com/icview-111321-1-1.html
至此,32CRC问题解决完毕(大概?),下一步继续完善项目的通信协议。
本文详细介绍了STM32中CRC校验的工作原理,包括大小端模式的区别、如何判断当前机器的字节序以及如何进行数据转换。此外,还提供了具体的代码实现,帮助读者更好地理解和应用CRC校验。
3277

被折叠的 条评论
为什么被折叠?



