常用處理差異辦法
關于差異的處理,前文提到的全部采用uint8_t類型進行設計,比較保險穩妥,但數據量大、項目需求復雜的時候,未必就能滿足,所以還是需要正面應對這些硬性問題。
這里整理出幾個簡單轉換的過程。
1. 多個uint8_t轉uint16_t/uint32_t
這個轉換很容易可以實現,信手拈來:
val_u16 = (val_u8_tmp1<<8) |val_u8_tmp2;
這里的轉基本都是把兩個uint8_t類型“組合”成uint16_t或者uint32_t,而實際項目工程中,多是對uint8_t類型的數據流進行轉換,并且是轉換部分數據,因此這里直接寫成宏定義,便于開發移植:
小端模式轉成uint16_t/uint32_t
大端模式轉成uint16_t/uint32_t
分析小端模式轉成uint16_t類型的數據,首先將這一長串的宏拆分然后逐步去理解:
實際是((uint16_t)*(volatile uint8_t*)((ptr)+1)<<8)和(uint16_t)*(volatile uint8_t*)(ptr)兩個數據進行位或的運算。
1.右半邊 (volatileuint8_t*)(ptr)是將ptr所指地址強轉為volatile uint8_t*類型;
2.然后是使用*(volatileuint8_t*)(ptr)根據地址從內存中取出該字節;
3.緊接著將取出的一字節數據使用(uint16_t)強制類型轉換成uint16_t類型。
同樣的原理,
1.左半邊(volatileuint8_t*)((ptr)+1)是將prt所指地址的下一個內存單元強轉為volatile uint8_t*類型;
2.然后是使用*(volatileuint8_t*)((ptr)+1) 根據地址從內存中取出該字節;
3.緊接著將取出的一字節數據使用(uint16_t)強制類型轉換成uint16_t類型,再左移8位處理。
最后將兩個結果做位或運算,即實現了“組合”,返回uint16_t類型結果。
以上過程分析的比較啰嗦,并且其中做的一些強轉和volatile修飾也是很有必要的,因為設計的宏要想可靠,還考慮到在有中斷、有事件處理的系統里,對數據操作還是需要謹慎些!
2.單個uint16_t/uint32_t轉uint8_t
單個字/雙字轉成字節,使用場景比較少,最簡單方式直接利用位與(&)和移位運算。
取低字節:
val_u8_tmp = val_u16&0xFF;
取高字節:
val_u8_tmp =(val_u16>>8)&0xFF;
3.對uint16_t/uint32_t類型進行字/雙字內自轉
其原理一樣是操作內存地址的方式,寫成宏定義,方便使用。
其轉換的結果是將原數據翻轉成相反的端模式。
總結,項目的開發細節問題弄清楚了,對后續的開發工作也是磨刀不誤砍柴工,并且在有通信需求時,尤其有必要做好通信協議的溝通協調,設計一套雙方通用的協議結構,對后續開發有著規范可循,對解決Bug也可以快速定位問題!