stm32自設指令協議中,大小端問題的處理

大端模式,是指數據的高字節保存在內存的低地址中,而數據的低字節保存在內存的高地址中,這樣的存儲模式有點兒類似於把數據當作字符串順序處理:地址由小向大增加,而數據從高位往低位放;

小端模式,是指數據的高字節保存在內存的高地址中,而數據的低字節保存在內存的低地址中,這種存儲模式將地址的高低和數據位權有效地結合起來,高地址部分權值高,低地址部分權值低,和我們的邏輯方法一致。

data0

Data1

Data2

Data3

Data4

Data5

Data6

Data7

Data8

Data9

幀頭

指令

參數

CRC校驗碼

0xaabb

0x0001

0x01

0x02

0x1234

 

如上指令協議,我在解讀時會按照大端模式理解,

即數據發送的順序爲:aabb 0001 0102 1234 crc

爲了處理方便,構建如下結構體:

typedef struct
{
    u16 frame_head;
    u16 module_cmd;
    u8 cmd_data4;
    u8 cmd_data5;
    u16 cmd_data67;
    u16 crc_data;
}ProtocolType;

但我用的stm32f4系列爲小端模式,這麼構建結構體會帶來一些問題:

問題1: 不能使用memcpy函數向結構體中複製數據,如果直接複製,frame_head中存儲的數據爲0xbbaa,這是大小端模式導致的。

問題2:crc碼的計算,正如問題1所述,若要爲計算crc16建立一個u16的數組,需要將源數據按字節取出,按照小端模式組合,再賦值到數組中:    

for(;word_len < (len>>1) ;word_len++)
    {
        rec_cmd_buff[word_len] = ((u16)p_data[(word_len<<1)]<<8)+p_data[(word_len<<1)+1];

    }

問題3:按照問題2的處理方法,我們可以很容易計算數據的crc碼,並校驗,而且還可以直接把這個數組複製到問題1設想的結構體中,但又會出現新的問題:結構體中的cmd_data4並非是0x01,而是0x02,這是因爲單字節數據本身不受大小端存儲方式的影響,但在問題2中,我們強行把cmd_data4,cmd_data5合併爲了u16類型數據,導致兩個數據顛倒了位置,所以要想正常使用ProtocolType結構體,可以把cmd_data4,cmd_data5的定義顛倒一下,或者乾脆也定義成u16類型數據,高低字節分別取用就是了。

至於爲什麼非要定義成一個結構體呢,爲了維護方便,提高可讀性。。。

 

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