個人使用單片機有些時間了,尤其是在這個快速變化的時代,數字編程已經是工科生必備的素養了。
雖然說單片機現在也支持C語言編程了,但是和計算機的C語言編程也存在一些差異,尤其是在進行數據乘除法計算的時候。
有些單片機不一定使用的標准C語言編譯器,請注意不同單片機的編程風格,具體請
單片機從以前的匯編,逐漸支持C語言編譯器,但是可能支持部分C語言,不一定是標准的C語言編譯器。
以dsPIC單片機為例,以下有兩種C語言除法編程風格:
uint16_t a; uint16_t temp; uint16_t b; //example 1: 標准C語言編譯器的除法 b = (a << 10)/1023; //example 2: dsPIC 單片機支持的乘法與除法
temp = __builtin_muluu(a,1024); b = __builtini_divud(temp,1023);
上面兩種寫法,第一種計算結果是正確的,只有第二種寫法在dsPIC單片機上才能得到正常的結果。
根本的原因在於編譯器對整形乘除數據,處理方式不一樣。
以下有兩種C語言乘法編程風格:
uint16_t a; uint16_t b; long c; long d;
a = 32676;
b = 32676;
//example 1: 標准C語言的無符號整數乘法 c = a * b; //example 2: dsPIC內部自帶的無符號整數乘法 d = __builtin_muluu(a,b);
uint16_t a; uint16_t b; long c; long d; a = 256; b = 256; //example 3: 標准C語言的無符號整數乘法 c = a * b; //example 4: dsPIC內部自帶的無符號整數乘法 d = __builtin_muluu(a,b);
上面兩種寫法,第一種計算的結果是錯誤的,第二種計算的結果是正確的。
原因是dsPIC單片機沒有合適的工作寄存器來存儲a*b的值。所以計算結果不同。
當a*b的值小於65535時,兩種計算方式的計算結果都是正確的。
uint16_t a; uint16_t b; long c; long d; a = 100; b = 100; //example 5: 標准C語言的無符號整數乘法 c = a * b; //example 6: dsPIC內部自帶的無符號整數乘法 d = __builtin_muluu(a,b);
uint16_t a; uint16_t b; long c; long d; a = 256; b = 255; //example 7: 標准C語言的無符號整數乘法 c = a * b; //example 8: dsPIC內部自帶的無符號整數乘法 d = __builtin_muluu(a,b);
C語言編譯器的不同,對於a*b結果的中間工作寄存器不同,導致標准C語言的寫法在單片機上不能正確的編譯。
為了以后的工作中少走彎路,學弟學妹們,
請優先學習該單片機的官方的參考文檔;
請優先使用內部自帶的函數;
請優先學習官方IDE的Help文檔;