用STM32 的配置GPIO 來控制LED 顯示狀態,可用ODR,BSRR,BRR 直接來控制引腳輸出狀態。
ODR寄存器可讀可寫:既能控制管腳為高電平,也能控制管腳為低電平。
管腳對于位寫1 gpio 管腳為高電平,寫 0 為低電平
BSRR 只寫寄存器:[color=Red]既能控制管腳為高電平,也能控制管腳為低電平。
對寄存器高 16bit 寫1 對應管腳為低電平,對寄存器低16bit寫1對應管腳為高電平。寫 0 ,無動作
BRR 只寫寄存器:只能改變管腳狀態為低電平,對寄存器 管腳對于位寫 1 相應管腳會為低電平。寫 0 無動作。
剛開始或許你跟我一樣有以下疑惑:
1.既然ODR 能控制管腳高低電平為什么還需要BSRR和SRR寄存器?
2.既然BSRR能實現BRR的全部功能,為什么還需要SRR寄存器?
對于問題 1 ------ 意法半導體給的答案是---
“This way, there is no risk that an IRQ occurs between the read and the modify access.”
什么意思呢?就就是你用BSRR和BRR去改變管腳狀態的時候,沒有被中斷打斷的風險。也就不需要關閉中斷。
用ODR操作GPIO的偽代碼如下:
disable_irq()
save_gpio_pin_sate = read_gpio_pin_state();
save_gpio_pin_sate = xxxx;
chang_gpio_pin_state(save_gpio_pin_sate);
enable_irq();
關閉中斷明顯會延遲或丟失一事件的捕獲,所以控制GPIO的狀態最好還是用SBRR和BRR
對于問題 2 ------- 個人經驗判斷意法半導體僅僅是為了程序員操作方便估計做么做的。
因為BSRR的 低 16bsts 恰好是set操作,而高16bit是 reset 操作 而BRR 低 16bits 是reset 操作。
簡單地說GPIOx_BSRR的高16位稱作清除寄存器,而GPIOx_BSRR的低16位稱作設置寄存器。
另一個寄存器GPIOx_BRR只有低16位有效,與GPIOx_BSRR的高16位具有相同功能。
舉個例子說明如何使用這兩個寄存器和所體現的優勢。
例如GPIOE的16個IO都被設置成輸出,而每次操作僅需要
改變低8位的數據而保持高8位不變,假設新的8位數據在變量Newdata中,
這個要求可以通過操作這兩個寄存器實現,STM32的固件庫中有兩個函數
GPIO_SetBits()和GPIO_ResetBits()使用了這兩個寄存器操作端口。
上述要求可以這樣實現:
GPIO_SetBits(GPIOE, Newdata & 0xff);
GPIO_ResetBits(GPIOE, (~Newdata & 0xff));
也可以直接操作這兩個寄存器:
GPIOE-》BSRR = Newdata & 0xff;
GPIOE-》BRR = ~Newdata & 0xff;
當然還可以一次完成對8位的操作:
GPIOE-》BSRR = (Newdata & 0xff) | ( (~Newdata & 0xff)《《16 );
當然還可以一次完成對16位的操作:
GPIOE-》BSRR = (Newdata & 0xffff) | ( (~Newdata )《《16 );
從最后這個操作可以看出使用BSRR寄存器,可以實現8個端口位的同時修改操作。
有人問是否BSRR的高16位是多余的,請看下面這個例子:
假如你想在一個操作中對GPIOE的位7置‘1’,位6置‘0’,則使用BSRR非常方便:
GPIOE-》BSRR = 0x400080;
如果沒有BSRR的高16位,則要分2次操作,結果造成位7和位6的變化不同步!
GPIOE-》BSRR = 0x80;
GPIOE-》BRR = 0x40;
BSRR還有一個特點,就是Set比Reset的級別高,
就是說同一個bit又做Set又做Reset,最后結果是Set
要同步變化只要簡單的 GPIOx-》BSRR = 0xFFFF0000 | PATTEN;
即可,不用考慮哪些需要置1,哪些需要清零
從最后這個操作可以看出使用BSRR寄存器,可以實現8個端口位的同時修改操作。
評論
查看更多