编译器编译16bit单片机程序对数组data[0]=0x12,data[1]=0xBD,data[2]=0x00,data[3]=0x45转换成16进制整数12BD0045的报警
16bit單片機(jī)程序:
定義32bit一個(gè)變量,uint32_t ?decData = 0;
剛開始時(shí)在16bit和32bit單片機(jī)中都這樣寫:
decData = ( data[0]?<< 24) | (data[1] << 16) | (data[2] << 8 ) | data[3];
問題發(fā)現(xiàn):
編譯16bit單片機(jī)程序時(shí),編譯器一直報(bào)警,提示數(shù)據(jù)太大溢出;
編譯32bit單片機(jī)程序時(shí),編譯器不報(bào)警。
疑問猜測:
16bit單片機(jī)不支持這樣的寫法?
查看芯片技術(shù)手冊,發(fā)現(xiàn)芯片內(nèi)部有32bit硬件乘法器,
程序改良:
decData = ( data[0]?*2^24) | (data[1]?*2^16) | (data[2]*2^8) |?data[3];
不過這樣寫還得實(shí)現(xiàn)一個(gè)類似pow功能函數(shù)或者直接調(diào)用C語言庫函數(shù)pow,C語言庫函數(shù)的pow都是double參數(shù)和字節(jié)實(shí)現(xiàn)返回值,用著不習(xí)慣,自己實(shí)現(xiàn)一個(gè)pow功能函數(shù),
uint32_t powFunc(uint8_t x,uint8_t power)//n的幾次方
{
? ? if(power == 0)
? ? {
? ? ? ? return 1;
? ? }
? ? if(power == 1)
? ? {
? ? ? ? return x;
? ? }
? ? return x*powFunc(x,power-1);
}
decData = (data[0]*powFunc(2,24)) | (data[1]*powFunc(2,16)) | (data[2]*powFunc(2,8)) | data[3]?;
后來想了想,這樣寫一個(gè)函數(shù)占內(nèi)存空間,把上面的代碼再改良,如下:
decData = ( data[0]?*0x1000000UL) | (data[1]*0x10000UL) | (data[2] *0x100UL) | data[3];
或者宏定義:
#define ?SHIFT_LEFT_24BIT ??0x1000000UL
#define ?SHIFT_LEFT_16BIT ??0x10000UL
#define ?SHIFT_LEFT_8BIT ??0x100UL
decData = ( data[0] *?SHIFT_LEFT_24BIT) | (data[1]*SHIFT_LEFT_16BIT) ?| (data[2] *SHIFT_LEFT_8BITL) | data[3];
發(fā)現(xiàn)這樣也占內(nèi)存,不過看著能理解其中的意思,但是考慮到芯片內(nèi)存比較小,最后退回上一個(gè)寫法:
decData = ( data[0]?* 0x1000000UL) |?(data[1] * 0x10000UL) |?(data[2]?* 0x100UL) | data[3];
這樣順利解決了編譯器報(bào)警溢出問題,換算出來的數(shù)據(jù)正常沒有問題。
在32bit單片機(jī)程序中,用上面三種方式得到的結(jié)果都是一樣的,如下圖所示:
?
總結(jié)
以上是生活随笔為你收集整理的编译器编译16bit单片机程序对数组data[0]=0x12,data[1]=0xBD,data[2]=0x00,data[3]=0x45转换成16进制整数12BD0045的报警的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第三课--EFM32GG11系列--串口
- 下一篇: PKCS7填充标准代码--C语言实现