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