關於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 <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問題解決完畢(大概?),下一步繼續完善項目的通信協議。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章