STM32CubeMX Lesson 1.1 ─ 位元運算

  在Lesson 1有提到GPIO操作的相關位元運算,在此可以更詳細的解說在ODR及IDR的操作為什麼需要Shift、AND、OR、NOT或是XOR。

  下文將使用的IDE為Keil uVision5(MDK-ARM),而STM32CubeMX的版本為6.2.1,因是使用底層暫存器控制,不限開發板及MCU型號。

首先Output High,以PA5為例。

GPIOA->ODR|=(1<<5);

因為ODR是直接控制整個Port A的16Bits輸出狀態,因此位元操作要正確,否則會影響到其他的位元。下方以表格的方式呈現,會較容易了解整個操作的流程與邏輯變化。

PIN76543210
GPIOA->ODR10010101

我們要將PA5設置為1,而保留其於PIN7~PIN6、PIN4~PIN0的狀態。可以了解到數位邏輯的OR運算,與0運算則是保留自己,與1運算則是固定為1。因此需與00100000做OR運算,達到PA5設定為1的目的。

PIN76543210
GPIOA->ODR10010101
OR00100000
GPIOA->ODR10110101

因此上述可以寫成 GPIOA->ODR=GPIOA->ODR | 32;

GPIOA->ODR=GPIOA->ODR | 32;

而我們可以瞭解到32是2的5次方,1每向左位移一個位元,就是乘2的運算,因此1位移5次則會是32,故可以將32替換為1<<5,又可以稱做PA0設定1,向左移5次,移到PA5,每左移一次,就推進一個0。

PIN76543210
1<<000000001
1<<100000010
1<<200000100
1<<300001000
1<<400010000
1<<500100000

所以Output High則可以寫為GPIOA->ODR|=(1<<5);


接著以PA5,Output Low為例。

GPIOA->ODR&=~(1<<5);

我們要將PA5設置為0,而保留其於PIN7~PIN6、PIN4~PIN0的狀態。可以了解到數位邏輯的AND運算,與1運算則是保留自己,與0運算則是固定為0。因此需與11011111做AND運算,達到PA5清除為0的目的。

PIN76543210
GPIOA->ODR10110101
AND11011111
GPIOA->ODR10010101

而在Output High的地方提到位移,在這邊AND的運算看起來就像是0位移5次,但補上的位元皆是補1,從中觀察可以發現其實就是1<<5的反向,因此可以寫為

GPIOA->ODR = GPIOA->ODR & ~(1<<5);

簡化後為GPIOA->ODR&=~(1<<5);

GPIOA->ODR&=~(1<<5);


最後是Toggle,反轉PA5的訊號。

GPIOA->ODR^=(1<<5);

許多人可能會直接的聯想到反向,但我們更仔細地來觀察,若PA5為0,則要輸出1,若PA5為1則要輸出0,但因為要使用ODR暫存器,因此不能直接賦值,不能直接反向。而可以做到反向的就是互斥或XOR,與1做XOR,皆會反向,與0做XOR,皆會與原狀態一樣。

PIN76543210
GPIOA->ODR10110101
XOR00100000
GPIOA->ODR10010101
PIN76543210
GPIOA->ODR10010101
XOR00100000
GPIOA->ODR10110101

因此可以寫成

GPIOA->ODR = GPIOA->ODR ^ (1<<5);

而「^」符號並不是次方的意思哦,在C語言當中是XOR的運算。簡化後可以寫成

GPIOA->ODR^=(1<<5);

以上是位元運算的詳細教學,希望可以幫助操作時更直覺的運用與有更好的理解。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *