5.1 STM32單片機(jī)GPIO概述
STM32中每個(gè)IO口都有很多個(gè)作用,比如這次我們使用的STM32F103ZET6的PA0口,既可以作為IO口使用,還可以作為待機(jī)喚醒(WAKEUP),模擬輸入(ADC功能)等。根據(jù)數(shù)據(jù)手冊(cè)中列出的每個(gè)I/O端口的特定硬件特征,GPIO端口的每個(gè)位可以由軟件分別配置成多種模式。
(1)輸入浮空
(2)輸入上拉
(3)輸入下拉
(4)模擬輸入
(5)開漏輸出
(6)推挽式輸出
(7)推挽式復(fù)用功能
(8)開漏復(fù)用功能
每個(gè)I/O端口位可以自由編程,然而I/O端口寄存器必須按32位字被訪問(不允許半字或字節(jié)訪問)。GPIOx_BSRR和GPIOx_BRR寄存器允許對(duì)任何GPIO寄存器的讀/更改的獨(dú)立訪問;這樣,在讀和更改訪問之間產(chǎn)生IRQ時(shí)不會(huì)產(chǎn)生異常錯(cuò)誤。
STM32F103系列的基本IO口結(jié)構(gòu)如下圖所示
從結(jié)構(gòu)圖可以看出來,STM32的GPIO口可以配置好幾個(gè)選項(xiàng),內(nèi)部上拉下拉電阻的選擇,推挽輸出或者開漏輸出,對(duì)于復(fù)用功能,有專門的復(fù)用輸入支路和輸出支路。STM32F103的端口由10個(gè)寄存器控制,但是常用的并不多,時(shí)鐘控制寄存器APB2ENR,模式控制寄存器CRH和CRL,輸入寄存器IDR,輸出寄存器ODR。
5.2 相關(guān)寄存器
5.2.1 APB2 外設(shè)時(shí)鐘使能寄存器:RCC_APB2ENR
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- | |||||||||||||||
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- | USART1EN | - | SPI1EN | TIM1EN | ADC2EN | ADC1EN | - | IOPEEN | IOPDEN | IOPCEN | IOPBEN | IOPAEN | - | AFIOEN |
Bit 14:串口1時(shí)鐘使能(寫1開啟,寫0關(guān)閉)
Bit 12:SPI1時(shí)鐘使能(寫1開啟,寫0關(guān)閉)
Bit 11:定時(shí)器1時(shí)鐘使能(寫1開啟,寫0關(guān)閉)
Bit 10:ADC2時(shí)鐘使能(寫1開啟,寫0關(guān)閉)
Bit 9:ADC1時(shí)鐘使能(寫1開啟,寫0關(guān)閉)
Bit 6:GPIOE時(shí)鐘使能(寫1開啟,寫0關(guān)閉)
Bit 5:GPIOD時(shí)鐘使能(寫1開啟,寫0關(guān)閉)
Bit 4:GPIOC時(shí)鐘使能(寫1開啟,寫0關(guān)閉)
Bit 3:GPIOB時(shí)鐘使能(寫1開啟,寫0關(guān)閉)
Bit 2:GPIOA時(shí)鐘使能(寫1開啟,寫0關(guān)閉)
Bit 0:輔助時(shí)鐘IO時(shí)鐘使能(寫1開啟,寫0關(guān)閉)
5.2.2 端口配置低寄存器:GPIOx_CRL(x=A..E)
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
CNF7 | MODE7 | CNF6 | MODE6 | CNF5 | MODE5 | CNF4 | MODE4 | ||||||||
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
CNF3 | MODE3 | CNF2 | MODE2 | CNF1 | MODE1 | CNF0 | MODE0 |
端口配置表:
bit 31 |
CNFy[1:0]:端口y的配置位(y=0……7)輸入模式下:00:模擬輸入模式01:浮空輸入模式(復(fù)位后的狀態(tài))10:上拉/下拉輸入模式11:保留輸出模式下:00:通用推挽輸出模式01:通用開漏輸出模式10:復(fù)用功能推挽輸出模式11:復(fù)用功能開漏輸出模式 |
---|---|
bit 29 |
MODEy[1:0]:端口y的模式位(y=0……7)00:輸入模式(復(fù)位后的狀態(tài))01:輸出模式,最大速度10MHz10:輸出模式,最大速度2MHz11:輸出模式,最大速度50MHz |
5.2.3 端口配置高寄存器:GPIOx_CRH(x=A..E)
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
CNF15 | MODE15 | CNF14 | MODE14 | CNF13 | MODE13 | CNF12 | MODE12 | ||||||||
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
CNF11 | MODE11 | CNF10 | MODE10 | CNF9 | MODE9 | CNF8 | MODE8 |
配置方式和端口配置低寄存器一致。
5.2.4 端口輸入數(shù)據(jù)寄存器:GPIOx_IDR(x=A..E)
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- | |||||||||||||||
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
Bit 15~Bit 0:端口輸入數(shù)據(jù)(這些位屬于只讀并只能以字的形式讀出)
5.2.5 端口輸出數(shù)據(jù)寄存器:GPIOx_ODR(x=A..E)
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- | |||||||||||||||
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
Bit 15~Bit 0:端口輸出數(shù)據(jù)(這些位屬于只讀并只能以字的形式操作)
注:在輸入模式下,ODR的數(shù)據(jù)可以控制端口內(nèi)部是上拉還是下拉,寫入1意味著端口上拉輸入。
5.3 GPIO的輸入與輸出例程
我們現(xiàn)在在PA0端口接一個(gè)按鍵,PA端口接一個(gè)LED,當(dāng)按下按鍵的時(shí)候,LED以100ms亮,100ms滅,抬起按鍵后LED常亮。
(1)在stm32f103x.h文件中添加GPIO的結(jié)構(gòu)體和地址映射。
(2)在HEADERWARE目錄下創(chuàng)建GPIO文件夾,并創(chuàng)建gpio.c和gpio.h兩個(gè)文件。
(3)在gpio.h文件中輸入以下內(nèi)容:
(4)在gpio.c文件中輸入以下內(nèi)容
(5)將gpio.c文件和gpio.h文件添加進(jìn)項(xiàng)目
(6)在1.c文件中輸入以下內(nèi)容:
注:實(shí)驗(yàn)中,按鍵一端接GND,LED一端接VCC,所以按鍵是檢測到0代表按下,端口輸出低電平代表LED點(diǎn)亮。
5.4 CM3內(nèi)核的位帶操作
Cortex-M3內(nèi)核中有一個(gè)非常有用的功能,叫做位帶操作,支持了位帶操作以后,可以使用普通的加載/存儲(chǔ)指令來對(duì)單一的比特進(jìn)行讀寫。在CM3中,有兩個(gè)區(qū)中實(shí)現(xiàn)了位帶。其中一個(gè)是SRAM區(qū)的最低1MB范圍,第二個(gè)則是片內(nèi)外設(shè)區(qū)的最低1MB范圍。這兩個(gè)區(qū)中的地址除了可以像普通的RAM一樣使用外,它們還都有自己的“位帶別名區(qū)”,位帶別名區(qū)把每個(gè)比特膨脹成一個(gè)32位的字。當(dāng)你通過位帶別名區(qū)訪問這些字時(shí),就可以達(dá)到訪問原始比特的目的。下圖從另一個(gè)側(cè)面演示比特的膨脹對(duì)應(yīng)關(guān)系。
欲設(shè)置地址0x20000000中的比特2,則使用位帶操作的設(shè)置過程如下圖所示。
30年前其實(shí)就已經(jīng)有位帶操作的概念了,自8051單片機(jī)開始,到現(xiàn)在的CM3內(nèi)核,位帶操作有什么優(yōu)越性呢?最容易想到的就是通過GPIO的管腳來單獨(dú)控制每盞LED的點(diǎn)亮與熄滅。另一方面,也對(duì)操作串行接口器件提供了很大的方便(典型如74HC165,CD4094)。位帶操作使代碼更簡潔,這只是位帶操作優(yōu)越性的初等體現(xiàn),位帶操作還有一個(gè)重要的好處是在務(wù)中,用于實(shí)現(xiàn)共享資源在任務(wù)間的“互鎖”訪問。多任務(wù)的共享資源必須滿足一次只有一個(gè)任務(wù)訪問它——亦即所謂的“原子操作”。
5.5 利用位帶操作實(shí)現(xiàn)GPIO的輸入與輸出
現(xiàn)在利用位帶操作來實(shí)現(xiàn)上一題目中的功能。
(1)在sys.h文件中添加實(shí)現(xiàn)位帶操作的代碼。
(2)修改gpio.h中的代碼如下圖所示。
(3)修改gpio.c中的代碼如下圖所示。
(4)修改1.c中的代碼如下圖所示。
5.6 外部中斷的實(shí)現(xiàn)
關(guān)于STM32F103的中斷機(jī)制在之前已經(jīng)詳細(xì)講述過,現(xiàn)在利用外部中斷來實(shí)現(xiàn)上一題目的功能。
(1)修改gpio.c中的代碼如下圖所示。
(2)添加代碼到文件stm32f103.h中。
(3)修改1.c中的代碼如下圖所示。
-
IO
+關(guān)注
關(guān)注
0文章
448瀏覽量
39156 -
STM32
+關(guān)注
關(guān)注
2270文章
10900瀏覽量
356053 -
GPIO
+關(guān)注
關(guān)注
16文章
1204瀏覽量
52104
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論