電子商務(wù)網(wǎng)站制作重慶seo整站優(yōu)化設(shè)置
第2章 STM32-GPIO口
2.1 GPIO口概述
通用輸入/輸出口
2.1.1 GPIO口作用
GPIO是單片機與外界進行數(shù)據(jù)交流的窗口。
2.1.2 STM32的GPIO口
在51單片機中,IO口,以數(shù)字進行分組(P0~P3),每一組里面又有8個IO口。
在STM32里面,GPIO口,以英文字母進行分組,針對M4系列最多可以分為AI組,而在我們現(xiàn)在使用的stm32f407zgt6這款芯片一共分成AG組。每一組里面有16個IO口(以0~15進行編號),所以我們這款芯片一共有112個GPIO口。
并不是所以的管腳都是GPIO口
每一個GPIO口都是多功能的,在使用之前需要先配置好特定的一個功能,需要用什么功能就要配置成什么功能。
對GPIO的配置就是學(xué)習(xí)如何使用GPIO口。
對GPIO口操作其實就是操作GPIO對應(yīng)的寄存器。
寄存器其實就是一段內(nèi)存空間。芯片內(nèi)部有很多模塊,系統(tǒng)會給每一個模塊都分配一段特定的內(nèi)存空間,這些內(nèi)存空間的地址其實就是這些模塊的寄存器地址。每個寄存器都有自己特定的一些功能,我們往寄存器里面讀寫的數(shù)據(jù)也都是有一定意義的,不是隨意的。如果我們想要操作一個模塊做某些事情,就需要找到這個模塊對應(yīng)有這個功能的寄存器,往這個寄存器里面寫入特定的指令數(shù)據(jù),系統(tǒng)就會根據(jù)你的操作對這個模塊進行控制。
補充:
變量:聲明變量其實就是在內(nèi)存中申請了一段內(nèi)存空間,我們可以在這個內(nèi)存空間進行讀寫操作。這個內(nèi)存空間的地址是隨機。
寄存器:寄存器其實也是一段內(nèi)存空間,同樣可以往里面進行讀寫操作,但是寄存器的地址是固定的,是已知的,是芯片廠家出廠時就已經(jīng)固化了,不可更改的。
從上圖可以知道GPIO模塊寄存器邊界地址和所在的總線(AHB1)
相鄰兩組GPIO之間的偏移量是0x0400,換句話說每組GPIO的空間大小為1024字節(jié)。
總結(jié):
相鄰GPIO組之間的偏移量為1K字節(jié),每一組GPIO相鄰寄存器之間的偏移量為0x04.
2.1.3 STM32的GPIO口特征
每個通用 I/O 端口包括 4 個 32 位配置寄存器(GPIOx_MODER、 GPIOx_OTYPER、GPIOx_OSPEEDR 和 GPIOx_PUPDR)、 2 個 32 位數(shù)據(jù)寄存器(GPIOx_IDR 和GPIOx_ODR)、 1 個 32 位置位/復(fù)位寄存器 (GPIOx_BSRR)、 1 個 32 位鎖定寄存器(GPIOx_LCKR) 和 2 個 32 位復(fù)用功能選擇寄存器(GPIOx_AFRH 和 GPIOx_AFRL)。
● 受控 I/O 多達 16 個
● 輸出狀態(tài):推挽或開漏 + 上拉/下拉
● 從輸出數(shù)據(jù)寄存器 (GPIOx_ODR) 或外設(shè)(復(fù)用功能輸出)輸出數(shù)據(jù)
● 可為每個 I/O 選擇不同的速度
● 輸入狀態(tài):浮空、上拉/下拉、模擬
● 將數(shù)據(jù)輸入到輸入數(shù)據(jù)寄存器 (GPIOx_IDR) 或外設(shè)(復(fù)用功能輸入)
● 置位和復(fù)位寄存器 (GPIOx_BSRR),對 GPIOx_ODR 具有按位寫權(quán)限
● 鎖定機制 (GPIOx_LCKR),可凍結(jié) I/O 配置
● 模擬功能
● 復(fù)用功能輸入/輸出選擇寄存器(一個 I/O 最多可具有 16 個復(fù)用功能)
● 快速翻轉(zhuǎn),每次翻轉(zhuǎn)最快只需要兩個時鐘周期
● 引腳復(fù)用非常靈活,允許將 I/O 引腳用作 GPIO 或多種外設(shè)功能中的一種
2.1.4 STM32的GPIO功能
根據(jù)數(shù)據(jù)手冊中列出的每個 I/O 端口的特性,可通過軟件將通用 I/O (GPIO) 端口的各個端口
位分別配置為多種模式:
● 輸入浮空
● 輸入上拉
● 輸入下拉
● 模擬功能----用在模數(shù)轉(zhuǎn)換/數(shù)模轉(zhuǎn)換上
● 具有上拉或下拉功能的開漏輸出
● 具有上拉或下拉功能的推挽輸出
● 具有上拉或下拉功能的復(fù)用功能推挽
● 具有上拉或下拉功能的復(fù)用功能開漏
每個 I/O 端口位均可自由編程,但 I/O 端口寄存器必須按 32 位字、半字或字節(jié)進行訪問。
GPIOx_BSRR 寄存器旨在實現(xiàn)對 GPIO ODR 寄存器進行原子讀取/修改訪問。這樣便可確保
在讀取和修改訪問之間發(fā)生中斷請求也不會有問題。
2.2 STM32的GPIO口框架(重點)
輸入電路和輸出電路是獨立的。
2.2.1 輸出配置框架分析
對 I/O 端口進行編程作為輸出時:
● 輸出緩沖器被打開:
— 開漏模式:輸出寄存器中的“0”可激活 N-MOS,而輸出寄存器中的“1”會使端
口保持高組態(tài) (Hi-Z)(P-MOS 始終不激活)。
— 推挽模式:輸出寄存器中的“0”可激活 N-MOS,而輸出寄存器中的“1”可激活
P-MOS。
● 施密特觸發(fā)器輸入被打開
● 根據(jù) GPIOx_PUPDR 寄存器中的值決定是否打開弱上拉電阻和下拉電阻
● 輸入數(shù)據(jù)寄存器每隔 1 個 AHB1 時鐘周期對 I/O 引腳上的數(shù)據(jù)進行一次采樣
● 對輸入數(shù)據(jù)寄存器的讀訪問可獲取 I/O 狀態(tài)
● 對輸出數(shù)據(jù)寄存器的讀訪問可獲取最后的寫入值
在配置成輸出模式時,輸入功能并沒有被關(guān)閉。
推挽輸出:當配置成推挽模式時,P-MOS和N-MOS均可以工作(都被打開)
當要輸出高電平‘1’時,P-MOS導(dǎo)通,N-MOS不導(dǎo)通,VDD電源正極(高電平)連接到IO引腳
當要輸出低電平‘0’時,P-MOS不導(dǎo)通,N-MOS導(dǎo)通,VSS電源負極(低電平)連接到IO引腳
推挽輸出即可以輸出高電平也可以輸出低電平
開漏輸出:當配置成開漏模式時,P-MOS被關(guān)閉(高阻態(tài)),N-MOS被打開
當要輸出高電平‘1’時,P-MOS不導(dǎo)通,N-MOS不導(dǎo)通,不能把高電平從輸出驅(qū)動器輸出出去,IO引腳的電平值取決外界環(huán)境。
當要輸出低電平‘0’時,P-MOS不導(dǎo)通,N-MOS導(dǎo)通,VSS電源負極(低電平)連接到IO引腳
開漏輸出只具有輸出低電平的能力,不具有輸出高電平的能力。
如果仍然想輸出高電平‘1’,那么需要在外部電路中接一個上拉電阻
上拉電阻:電阻的一端接著電源正極,在IO口沒有電流流過時,保證電阻另外一端有一個穩(wěn)定高電平
下拉電阻:電阻的一端接著電源負極(GND),在IO口沒有電流流過時,保證電阻另外一端有一個穩(wěn)定低電平
芯片內(nèi)部上拉電阻和下拉電阻都是弱上拉和弱下拉,驅(qū)動能力比較弱
2.2.2 輸入配置框架分析
對 I/O 端口進行編程作為輸入時:
● 輸出緩沖器被關(guān)閉
● 施密特觸發(fā)器輸入被打開
● 根據(jù) GPIOx_PUPDR 寄存器中的值決定是否打開上拉和下拉電阻
● 輸入數(shù)據(jù)寄存器每隔 1 個 AHB1 時鐘周期對 I/O 引腳上的數(shù)據(jù)進行一次采樣
● 對輸入數(shù)據(jù)寄存器的讀訪問可獲取 I/O 狀態(tài)
變換一下如下圖:
這種情況下,配置成輸入浮空(不上拉也不下拉)
這種情況下可以配置成輸入上拉
這種情況下可以配置成輸入下拉
2.2.3 模擬功能框架分析
對 I/O 端口進行編程作為模擬配置時:
● 輸出緩沖器被禁止。
● 施密特觸發(fā)器輸入停用, I/O 引腳的每個模擬輸入的功耗變?yōu)榱?。施密特觸發(fā)器的輸出被
強制處理為恒定值 (0)。
● 弱上拉和下拉電阻被關(guān)閉。
● 對輸入數(shù)據(jù)寄存器的讀訪問值為“0”。
2.2.4 復(fù)用功能框架分析
對 I/O 端口進行編程作為復(fù)用功能時:
● 可將輸出緩沖器配置為開漏或推挽
● 輸出緩沖器由來自外設(shè)的信號驅(qū)動(發(fā)送器使能和數(shù)據(jù))
● 施密特觸發(fā)器輸入被打開
● 根據(jù) GPIOx_PUPDR 寄存器中的值決定是否打開弱上拉電阻和下拉電阻
● 輸入數(shù)據(jù)寄存器每隔 1 個 AHB1 時鐘周期對 I/O 引腳上的數(shù)據(jù)進行一次采樣
● 對輸入數(shù)據(jù)寄存器的讀訪問可獲取 I/O 狀態(tài)
2.3 STM32的GPIO口相關(guān)寄存器
2.3.1 GPIO 端口模式寄存器 (GPIOx_MODER) (x = A…I)
偏移地址: 0x00
復(fù)位值:(默認值)
● 0xA800 0000(端口 A)
● 0x0000 0280(端口 B)
● 0x0000 0000(其它端口)
位 2y:2y+1 MODERy[1:0]: 端口 x 配置位 (Port x configuration bits) (y = 0…15)
這些位通過軟件寫入,用于配置 I/O 方向模式。
00:輸入(復(fù)位狀態(tài))
01:通用輸出模式
10:復(fù)用功能模式
11:模擬模式
2.3.2 GPIO 端口輸出類型寄存器 (GPIOx_OTYPER) (x = A…I)
偏移地址: 0x04
復(fù)位值: 0x0000 0000
位 31:16 保留,必須保持復(fù)位值。
位 15:0 OTy[1:0]: 端口 x 配置位 (Port x configuration bits) (y = 0…15)
這些位通過軟件寫入,用于配置 I/O 端口的輸出類型。
0:輸出推挽(復(fù)位狀態(tài))
1:輸出開漏
2.3.3 GPIO 端口輸出速度寄存器 (GPIOx_OSPEEDR) (x = A…I/)
偏移地址: 0x08
復(fù)位值:
● 0x0000 00C0(端口 B)
● 0x0000 0000(其它端口)
位 2y:2y+1 OSPEEDRy[1:0]: 端口 x 配置位 (Port x configuration bits) (y = 0…15)
這些位通過軟件寫入,用于配置 I/O 輸出速度。
00: 2 MHz(低速)
01: 25 MHz(中速)
10: 50 MHz(快速)
11: 30 pF 時為 100 MHz(高速)(15 pF 時為 80 MHz 輸出(最大速度))
2.3.4 GPIO 端口上拉/下拉寄存器 (GPIOx_PUPDR) (x = A…I/)
偏移地址: 0x0C
復(fù)位值:
● 0x6400 0000(端口 A)
● 0x0000 0100(端口 B)
● 0x0000 0000(其它端口)
位 2y:2y+1 PUPDRy[1:0]: 端口 x 配置位 (Port x configuration bits) (y = 0…15)
這些位通過軟件寫入,用于配置 I/O 上拉或下拉。
00:無上拉或下拉(浮空)
01:上拉
10:下拉
11:保留
2.3.5 GPIO 端口輸入數(shù)據(jù)寄存器 (GPIOx_IDR) (x = A…I)
偏移地址: 0x10
復(fù)位值: 0x0000 XXXX(其中 X 表示未定義)
位 31:16 保留,必須保持復(fù)位值。
位 15:0 IDRy[15:0]: 端口輸入數(shù)據(jù) (Port input data) (y = 0…15)
這些位為只讀形式,只能在字模式下訪問。它們包含相應(yīng) I/O 端口的輸入值。
2.3.6 GPIO 端口輸出數(shù)據(jù)寄存器 (GPIOx_ODR) (x = A…I)
偏移地址: 0x14
復(fù)位值: 0x0000 0000
位 31:16 保留,必須保持復(fù)位值。
位 15:0 ODRy[15:0]: 端口輸出數(shù)據(jù) (Port output data) (y = 0…15)
這些位可通過軟件讀取和寫入。
注意: 對于原子置位/復(fù)位,通過寫入 GPIOx_BSRR 寄存器,可分別對 ODR 位進行置位和復(fù)
位 (x = A…I/)。
2.4 寄存器訪問方法
操作GPIOA_MODE,寫入data值
第一種:
*(unsigned int *)0x4002 0000=data;
第二種:
#define GPIOA_MODE *(unsigned int *)0x4002 0000
GPIOA_MODE=data;
第三種:
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE)#define GPIOI ((GPIO_TypeDef ) GPIOI_BASE) typedef struct{ __IO uint32_t MODER; /!< GPIO port mode register, Address offset: 0x00 / __IO uint32_t OTYPER; /!< GPIO port output type register, Address offset: 0x04 / __IO uint32_t OSPEEDR; /!< GPIO port output speed register, Address offset: 0x08 / __IO uint32_t PUPDR; /!< GPIO port pull-up/pull-down register, Address offset: 0x0C / __IO uint32_t IDR; /!< GPIO port input data register, Address offset: 0x10 / __IO uint32_t ODR; /!< GPIO port output data register, Address offset: 0x14 / __IO uint16_t BSRRL; /!< GPIO port bit set/reset low register, Address offset: 0x18 / __IO uint16_t BSRRH; /!< GPIO port bit set/reset high register, Address offset: 0x1A / __IO uint32_t LCKR; /!< GPIO port configuration lock register, Address offset: 0x1C / __IO uint32_t AFR[2]; /!< GPIO alternate function registers, Address offset: 0x20-0x24 /} GPIO_TypeDef; 說明:GPIO_TypeDef :結(jié)構(gòu)體 GPIO_TypeDef:結(jié)構(gòu)體指針 #define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000)#define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400)#define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800)#define GPIOD_BASE (AHB1PERIPH_BASE + 0x0C00)#define GPIOE_BASE (AHB1PERIPH_BASE + 0x1000)#define GPIOF_BASE (AHB1PERIPH_BASE + 0x1400)#define GPIOG_BASE (AHB1PERIPH_BASE + 0x1800)#define GPIOH_BASE (AHB1PERIPH_BASE + 0x1C00)#define GPIOI_BASE (AHB1PERIPH_BASE + 0x2000)//---------------------------------------------------------------------------------------#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000)//---------------------------------------------------------------------------------------#define PERIPH_BASE ((uint32_t)0x40000000) 分析:#define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000) ((PERIPH_BASE + 0x00020000)+0x0000) ((((uint32_t)0x40000000)+ 0x00020000)+0x0000) ((uint32_t)0x40020000) #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)#define GPIOA ((GPIO_TypeDef *) (uint32_t)0x40020000)GPIOA—結(jié)構(gòu)體常量指針 操作寄存器方法:GPIOA->MODE=data;
2.5 STM32的GPIO口相關(guān)實驗
2.5.1 通用輸出功能實驗
通過GPIO口點亮LED燈
LED其實是發(fā)光二極管,當給陽極高電平,給陰極低電平,會讓二極管正向?qū)?#xff0c;LED點亮
2.5.1.1 硬件設(shè)計
2.5.1.2 軟件設(shè)計
點亮LED1,把PF6配置成普通功能推挽輸出
配置流程:
\1. 配置模式寄存器(把GPIOF的MODER寄存器的第13和12位分配成01)—輸出模式
\2. 配置輸出類型寄存器(把GPIOF的OTYPER寄存器的第6位分配成0)—輸出推挽
\3. 配置輸出速度寄存器(把GPIOF的OSPEEDR寄存器的第13和12位分配成00)–低速2Mhz
\4. 配置上/下拉寄存器(把GPIOF的PUPDR寄存器的第13和12位分配成00)–浮空
點亮LED1----往GPIOF的ODR寄存器的第6位寫入0
熄滅LED1----往GPIOF的ODR寄存器的第6位寫入1
操作寄存器的原則:操作你要操作的相關(guān)位,而不能影響到其他位的值。
2 軟件設(shè)計
點亮LED1,把PF6配置成普通功能推挽輸出
配置流程:
\1. 配置模式寄存器(把GPIOF的MODER寄存器的第13和12位分配成01)—輸出模式
\2. 配置輸出類型寄存器(把GPIOF的OTYPER寄存器的第6位分配成0)—輸出推挽
\3. 配置輸出速度寄存器(把GPIOF的OSPEEDR寄存器的第13和12位分配成00)–低速2Mhz
\4. 配置上/下拉寄存器(把GPIOF的PUPDR寄存器的第13和12位分配成00)–浮空
點亮LED1----往GPIOF的ODR寄存器的第6位寫入0
熄滅LED1----往GPIOF的ODR寄存器的第6位寫入1
操作寄存器的原則:操作你要操作的相關(guān)位,而不能影響到其他位的值。