STM32 GPIO 配置之ODR, BSRR, BRR 詳解

用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; 

  GPIOE->BRR = 0x40;



BSRR還有一個特點,就是Set比Reset的級別高,

就是說同一個bit又做Set又做Reset,最後結果是Set

要同步變化只要簡單的 GPIOx->BSRR = 0xFFFF0000 | PATTEN;

即可,不用考慮哪些需要置1,哪些需要清零

從最後這個操作可以看出使用BSRR寄存器,可以實現8個端口位的同時修改操作。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章