在AVR單片機中,PORTC |= BIT(2) 和 PORTC &= ~BIT(2)均能正常運行,但是在C51單片機中後者會出錯。這主要是因為定義BIT宏的時候格式有問題。
在AVR單片機中,BIT(n)宏(ICCAVR)和_BV(n)宏(WinAVR)都是在頭文件中定義好了的,而C51單片機庫函數裡沒有這兩個宏,所以需要手動定義。如果在手動定義時寫的是下面的語句:
#define BIT(n) 1<<n
那麼,如果執行P2 &= ~BIT(2),編譯器在編譯時就會將其替換為P2 &= ~1<<2。那麼問題來了,因為~1 == 0xfe,且0xfe << 2 == 0xf8,因此執行後的結果是P2被賦上了0xf8的值,也就是11111000。而我們期望的P2值卻是0xfb (11111011)。
因此,錯誤的根源就是BIT宏替換後1<<2沒有加上括號。如果替換後的語句是P2 &= ~(1<<2),那麼我們就能得出正確的結果。
所以,在手動定義BIT宏的時候,一定要把1<<n用括號括起來:
#define BIT(n) (1<<n)