巧妙利用結構體解析協議資料

2021-10-25 13:26:28 字數 1948 閱讀 2260

例項一:根據電池bms協議解析電池資料(小端模式)

根據電池應答訊息格式定義電池資料結構

分析例項二:根據電池bms協議解析電池資料(大端模式)

stm32屬於小端模式

這裡的小端模式是指:對於超過乙個位元組的資料傳輸時,低位位元組在前高位位元組在後。

:這裡只是為了說明,對協議內容進行了簡化。

1. 電池狀態資訊

由3個位元組組成:

第2位元組:

第3位元組:

2. 電流值

3. 電芯串數

4. 電芯電壓

5. 迴圈次數

6. 剩餘電量

7. 總容量

8. 開關狀態

#define battery_cell_num 7 

//7串電芯

#pragma pack(push)

#pragma pack(1)

typedef

struct

bit;

uint8_t byte;

}status1;

union

bit;

uint8_t byte;

}status2;

// uint8_t status1;

// uint8_t status2;

uint8_t status3;

int16_t current;

uint8_t cell_num;

uint16_t cell_voltage[battery_cell_num]

; uint16_t cycles;

uint16_t remaining_capacity;

uint16_t total_capacity;

//uint8_t switch_status;

union

bit;

uint8_t byte;

}switch_status;

}batteryrawdata_t;

#pragma pack(pop)

通過接收到的電池報文資料,在符合包頭、長度、校驗等資訊後便可以將對應欄位的資料直接複製到batteryrawdata_t型別的結構體資料中,通過該結構體便可以直接獲取需要的變數資訊。這樣的處理方式極大的簡化了報文的解包處理。

當然這裡的應用還有乙個前提:超過1個位元組的變數傳輸的時候是按照小端模式(低位位元組先傳輸,高位位元組後傳輸)進行傳輸的。如果當前協議不符合該格式,是不能夠直接應用這種方式的。這裡的大端模式是指:對於超過乙個位元組的資料傳輸時,高位位元組在前低位位元組在後。

省略。。。

#define bigtolittle16(a)   ((((uint16)(a) & 0xff00) >> 8)    | \  ((

(uint16)

(a)&

0x00ff

)<<8)

)#define battery_ntc_num 2

#pragma pack(push)

#pragma pack(1)

typedef

struct

batteryrawdata_t;

#pragma pack(pop)

batteryrawdata_t battery_raw_data;

//假設電池資料已經儲存到了battery_raw_data中

//獲取原始的電壓資料

uint16_t voltage_raw =

bigtolittle16

(battery_raw_data.voltage_bigendian)

;

這裡同樣可以使用結構體的方式來直接將電池反饋的報文資料的對應位置複製到相應的結構體變數中,但需要注意的時,結構體中的變數並不能直接使用,必須進行大端模式轉換成小端模式才是正常的值。

巧妙獲取結構體大小

在 sys un.h中有這麼乙個巨集 define sun len ptr size t struct sockaddr un 0 sun path strlen ptr sun path 這個巨集的巧妙之處是在不需要分配記憶體的情況下可以獲取結構各個部分 除了最後乙個 的大小 如 struct a...

利用串列埠傳輸結構體資料

寫在前面 結構體是一種資料的歸類方式,相比陣列或變數更具有整體全面性,例如乙個陣列只可以放一些按照元素順序存放的單元變數,即 buffer i 有多大,陣列內元素就有多少。那麼我們這時候如果我們用這個陣列來接收串列埠接收資訊,資訊的格式是 資料頭 資料長度 資料區 資料校驗 資料尾 假設資料區為 姓...

struct stat結構體解析

在使用這個結構體和方法時,需要引入 struct stat這個結構體是用來描述乙個linux系統檔案系統中的檔案屬性的結構。可以有兩種方法來獲取乙個檔案的屬性 1 通過路徑 int stat const char path,struct stat struct stat int lstat cons...