也許這個問題會有點愚蠢,但我想知道為什么如果我們想在暫存器的某個特定位置寫 0 我們必須這樣寫:
PORTB &= ~(1 << 2);
而不是這樣(因為它不起作用):
PORTB &= (0 << 2);
0 在這里是否意味著像 0b00000000(對于 8 位暫存器)?
uj5u.com熱心網友回復:
讓我們一步一步分解:
// PORTB &= ~(1 << 2);
int bit_position = 2;
int bit_mask = 1; // = 0000 0001
bit_mask <<= bit_position; // = 0000 0100
int inverted_mask = ~bit_mask; // = 1111 1011
int PORTB = 0x77; // 0111 0111
PORTB &= inverted_mask; // & 1111 1011
// = 0111 0011
而且,您建議的替代方案:
// PORTB &= (0 << 2);
int bit_position = 2;
int bit_mask = 0; // = 0000 0000
bit_mask <<= bit_position; // = 0000 0000
int PORTB = 0x77; // 0111 0111
PORTB &= bit_mask; // & 0000 0000
// = 0000 0000
關鍵是計算機只是對整個暫存器一個一個地執行操作。它不知道它應該關心該數字中所有零中的特定零。因此,您不是通過“位置 2 處的零”進行 AND 運算,而只是通過數字零進行 AND 運算。事實上,你不是在移動一個零或一,而是整個數字。
這就是為什么要將特定位設定為零的原因,我們必須與一個掩碼進行 AND,該掩碼在除我們希望為零的位置之外的每個位置都具有 1。(與 1 進行 AND 運算不會改變該位,而與 0 進行 AND 運算使其為零。)
uj5u.com熱心網友回復:
為簡單起見,使用位元組0 << 2等于零 - 0b00000000。因此,您與此 AND 的任何值也將產生零。
1 << 2 等于 0b00000100
~(1 << 2) 等于 0b11111011
現在您有一個 AND 掩碼,它只會將特定位設定為零。其余位將保持不變。
uj5u.com熱心網友回復:
當您反匯編代碼時,您可以理解為什么:
PORTB &= ~(1 << 2);
是這樣翻譯的:
PORTB = PORTB & (~(0b00000001 << 2));
到
PORTB = PORTB & (~(0b00000100));
到
PORTB = PORTB & ((0b11111011));
這意味著它將采用 PORTB 的舊值并將它的第 2 位寫入 0,同時將其余位保持為其原始值(無論它們是 0 還是 1)
這樣做是因為您只想更改 PORTB 的 PIN2 值而不更改任何其他引腳值。
而另一行:
PORTB &= (0 << 2);
評價為
PORTB = PORTB & ((0b00000000));
這反過來會將所有 PORTB 引腳重置為 0。
所以這真的取決于你到底想做什么。
另一個例子是如果你想將 PORTB 的 PIN2 設定為 1:
PORTB = PORTB | (0b00000100);
可以這樣寫:
PORTB |= (1 << 2);
這將確保僅將 PIN2 設定為 1,而不會將 PORTB 的其他引腳設定為 1。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/335268.html
