1.瞭解什麼是GPIO
GPIO 是通用輸入輸出埠的簡稱,簡單來說就是STM32 可控制的引腳,STM32 晶片的GPIO 引腳與外部裝置連線起來,從而實現與外部通訊、控制以及數據採集的功能。
GPIO 框圖剖析
2.基本結構分析
2.1 保護二極管及上、下拉電阻
引腳的兩個保護二級管可以防止引腳外部過高或過低的電壓輸入,當引腳電壓高於VDD 時,上方的二極管導通,當引腳電壓低於VSS 時,下方的二極管導通,防止不正常電壓引入晶片導致晶片燒燬。
2.2 P-MOS 管和N-MOS 管
GPIO 引腳線路經過兩個保護二極管後,向上流向「輸入模式」結構,向下流向「輸出模式」結構。先看輸出模式部分,線路經過一個由P-MOS 和N-MOS 管組成的單元電路。這個結構使GPIO 具有了「推輓輸出」和「開漏輸出」兩種模式。
推輓等效電路:
(P 管負責灌電流,N 管負責拉電流)
開漏電路:
3.GPIO工作模式
(上圖通過C語言對GPIO工作模式進行封裝)
4.實驗:使用暫存器點亮LED 燈
4.1硬體連線
這是一個RGB 燈,裏面由紅藍綠三個小燈構成,使用PWM控制時可以混合成256 不同的顏色。
圖中從3 個LED 燈的陽極引出連線到3.3V 電源,陰極各經過1 個限流電阻引入至STM32 的3 個GPIO 引腳中,所以我們只要控制這三個引腳輸出高低電平,即可控制其所連線LED 燈的亮滅。
(PS:暫存器就是給一個已經分配好地址的特殊的記憶體空間取的一個別名,這個特殊的記憶體空間可以通過指針來操作。)
4.2程式編寫
(啓動檔案:startup_stm32f10x_hd.s)
main檔案:
4.2.1 首先我們把連線到LED 燈的GPIO 引腳PB0 設定成輸出模式,即設定GPIO 的埠設定低暫存器CRL。
設定輸出模式
1 // 清空控制PB0 的埠位
2 GPIOB_CRL &= ~( 0x0F<< (4*0));
3 // 設定PB0 爲通用推輓輸出,速度爲10M
4 GPIOB_CRL |= (1<<4*0);
假如我們直接給CRL 暫存器賦值:
GPIOB_CRL = 0x0000001;
這時CRL 的的低4 位被設定成「0001」輸出模式,但其它GPIO引腳就有意見了,因爲其它引腳的MODER 位都已被設定成輸入模式。
4.2.2 控制引腳輸出電平
在輸出模式時,對埠位設定/清除暫存器BSRR 暫存器、埠位清除暫存器BRR 和ODR 暫存器寫入參數即可控制引腳的電平狀態,其中操作BSRR 和BRR 最終影響的都是ODR 寄器,然後再通過ODR 暫存器的輸出來控制GPIO。爲了一步到位,我們在這裏直接操作ODR 暫存器來控制GPIO 的電平。
控制引腳輸出電平
1 // PB0 輸出低電平
2 GPIOB_ODR &= ~(1<<0);
4.2.3 開啓外設時鐘
設定完GPIO 的引腳,控制電平輸出,以爲現在總算可以點亮 LED 了吧,其實還差最後一步。由於STM32 的 外設很多,爲了降低功耗,每個外設都對應着一個時鐘,在晶片剛上電的時候這些時鐘都是被關閉的,如果想要外設工作,必須把相應的時鐘開啓。
開啓埠時鐘
1 // 開啓 GPIOB 埠 時鐘
2 RCC_APB2ENR |= (1<<3);
4.2.4水到渠成
開啓時鐘,設定引腳模式,控制電平,經過這三步,我們總算可以控制一個 LED 了。
1 int main(void)
2 {
3 // 開啓GPIOB 埠時鐘
4 RCC_APB2ENR |= (1<<3);
5
6 //清空控制PB0 的埠位
7 GPIOB_CRL &= ~( 0x0F<< (4*0));
8 // 設定PB0 爲通用推輓輸出,速度爲10M
9 GPIOB_CRL |= (1<<4*0);
10
11 // PB0 輸出 低電平
12 GPIOB_ODR |= (0<<0);
13
14 while (1);
15
16 }
5.下載驗證
(謝謝觀看!
寫在後面:2020.08.12)