关于STM32数据的大小端问题以及可能的解决办法

最近着手于开发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 
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项目)