STM32F4(正点原子)学习笔记(一):GPIO及其小实验
目錄
一、寫(xiě)在前面:
二、GPIO基本情況
1.概述
2.引腳說(shuō)明
3.GPIO工作方式
(1)4種輸入模式
(2)4種輸出模式
(3)4種最大輸出速度
(4)主要特性
4.GPIO相關(guān)配置寄存器
三、GPIO的那一堆寄存器
1.端口模式寄存器 (GPIOx_MODER)
GPIO port mode register
2.端口輸出類型寄存器(GPIOx_OTYPER)
GPIO port output type register
3.端口輸出速度寄存器(GPIOx_OSPEEDR)
GPIO port output speed register
4.端口上拉/下拉寄存器(GPIOx_PUPDR)
GPIO port pull-up/pull-down register
5.端口輸入數(shù)據(jù)寄存器(GPIOx_IDR)
GPIO port input data register
6.端口輸出數(shù)據(jù)寄存器(GPIOx_ODR)
GPIO port output data register
7.端口置位/復(fù)位寄存器(GPIOx_BSRR)
GPIO port bit set/reset register
8.GPIO端口配置鎖定寄存器 (GPIOx_LCKR) (x = A..I)
GPIO port configuration lock register
9.GPIO 復(fù)用功能低位寄存器 (GPIOx_AFRL) (x = A..I)
GPIO alternate function low register
10.GPIO 復(fù)用功能高位寄存器 (GPIOx_AFRH) (x = A..I)
GPIO alternate function high register
四、GPIO小實(shí)驗(yàn):跑馬燈
1.硬件
2.庫(kù)函數(shù)版(library function):
(1)重要函數(shù)
(2)led.c
3.寄存器版(register):
(1)RCC AHB1 外設(shè)時(shí)鐘使能寄存器 (RCC_AHB1ENR)
(2)led.c
4.位操作版(Bit-band operations):
(1)位帶操作
(2)步驟
(3)led.c
一、寫(xiě)在前面:
? ? ? ? 之前上過(guò)嵌入式的課程,也曾用rt1052/64把別人的程序編編改改,但對(duì)于單片機(jī)的理解僅停留在胎教的階段。此次利用老師給的stm32f4(探索者)開(kāi)發(fā)板,對(duì)單片機(jī)進(jìn)行一個(gè)全面的學(xué)習(xí)。
????????該文章為學(xué)習(xí)筆記,內(nèi)容主要來(lái)自《Cortex M3與M4權(quán)威指南》、《STM32F4xx中文參考手冊(cè)》、《STM32F4開(kāi)發(fā)指南-寄存器版本_V1.2》、《STM32F4開(kāi)發(fā)指南-庫(kù)函數(shù)版本_V1.2》、正點(diǎn)原子的教學(xué)視頻及網(wǎng)絡(luò)。環(huán)境選擇Keil uVision5。
? ? ? ? 由于我編程和模電水平確實(shí)較差,望大家多批評(píng)指正了😏
二、GPIO基本情況
1.概述
????????GPIO(General-purpose input/output),通用型輸入輸出的簡(jiǎn)稱。既然一個(gè)引腳可以用于輸入、輸出或其他特殊功能,那么一定有寄存器用來(lái)選擇這些功能。對(duì)于輸入,一定可以通過(guò)讀取某個(gè)寄存器來(lái)確定引腳電位的高低;對(duì)于輸出,一定可以通過(guò)寫(xiě)入某個(gè)寄存器來(lái)讓這個(gè)引腳輸出高電位或者低電位;而對(duì)于其他特殊功能,則有另外的寄存器來(lái)控制它們。
2.引腳說(shuō)明
????????①一共有7組IO口:GPIOA—GPIOG
????????②每組IO口有16個(gè)IO:GPIOA_0—GPIOA_15
????????③一共7*16=112個(gè)IO
? ? ? ? ④所有IO口都可以作為中斷輸入
3.GPIO工作方式
?
?
?圖1、2? 5V容忍I/O端口位的基本結(jié)構(gòu)
(1)4種輸入模式
????????①輸入浮空(input floating)
? ? ? ? ? ? ? ? 😃邏輯器件與引腳即不接高電平,也不接低電平,電壓不確定
????????②輸入上拉(input pull-up)
? ? ? ? ? ? ? ? 🙀將不確定的信號(hào)通過(guò)一個(gè)電阻嵌位在高電平,上拉電阻同時(shí)可起到限流作用,IO口的常態(tài)為高電平
????????③輸入下拉(input pull-down)
? ? ? ? ? ? ? ? 🍟把電壓拉低到GND,IO口的常態(tài)為低電平
????????④模擬功能(analog)
? ? ? ? ? ? ? ? 👼關(guān)閉施密特觸發(fā)器,將電壓信號(hào)傳送到片上外設(shè)模塊,不接上下拉電阻
(2)4種輸出模式
????????①帶上拉或下拉的開(kāi)漏輸出(output open-drain)?
? ? ? ? ? ? ? ? 🙊相當(dāng)于三極管的集電極
????????????????🙊開(kāi)漏輸出只可以輸出強(qiáng)低電平 ,高電平靠外部電阻拉高
????????????????🙊利用外部電路的驅(qū)動(dòng)能力,減少IC(integrated circuit)內(nèi)部的驅(qū)動(dòng)。驅(qū)動(dòng)電流從外部的VCC流出,IC內(nèi)部?jī)H需很小的柵極驅(qū)動(dòng)電流
????????②帶上拉或下拉的開(kāi)漏復(fù)用功能(alternate function open-drain)
? ? ? ? ? ? ? ? 🤡可同時(shí)當(dāng)作普通GPIO及內(nèi)部外設(shè)(片上外設(shè))控制器的引腳來(lái)使用
????????????????🤡I/O引腳通過(guò)一個(gè)復(fù)用器連接到板載外設(shè),該復(fù)用器一次僅允許一個(gè)外設(shè)的復(fù)用功能(AF)連接到I/O引腳,確保共用同一個(gè)I/O引腳的外設(shè)之間不會(huì)發(fā)生沖突
????????③帶上拉或下拉的推挽輸出(output push-pull)
? ? ? ? ? ? ? ? 🐶推挽輸出可輸出強(qiáng)高低電平,連接數(shù)字器件。
? ? ? ? ? ? ? ? 🐶推挽結(jié)構(gòu)一般指兩個(gè)三極管分別受兩互補(bǔ)信號(hào)的控制,總是一個(gè)導(dǎo)通一個(gè)截止
? ? ? ? ? ? ? ? 🐶推挽電路是兩個(gè)參數(shù)一樣的三極管以推挽形式置于電路中,每次只有一個(gè)導(dǎo)通,導(dǎo)通功耗小、效率高。輸出即可向負(fù)載灌電流,也可從負(fù)載抽取電流。因此可提高電路的負(fù)載能力以及開(kāi)關(guān)速度。
????????④帶上拉或下拉的推挽復(fù)用功能(alternate function push-pull)
???????????????🤯同②
????????關(guān)于推挽輸出和開(kāi)漏輸出可用圖3來(lái)概括:
?
??圖3? 左為推挽、右為開(kāi)漏
(3)4種最大輸出速度
????????2MHz / 25MHz / 50MHz?/?100MHz
(4)主要特性
????????🦞受控 I/O 多達(dá) 16 個(gè)
????????🦞輸出狀態(tài):推挽或開(kāi)漏 + 上拉/下拉
????????🦞從輸出數(shù)據(jù)寄存器 (GPIOx_ODR) 或外設(shè)(復(fù)用功能輸出)輸出數(shù)據(jù)
????????🦞可為每個(gè) I/O 選擇不同的速度
????????🦞輸入狀態(tài):浮空、上拉/下拉、模擬
????????🦞將數(shù)據(jù)輸入到輸入數(shù)據(jù)寄存器 (GPIOx_IDR) 或外設(shè)(復(fù)用功能輸入)
????????🦞置位和復(fù)位寄存器 (GPIOx_BSRR),對(duì) GPIOx_ODR 具有按位寫(xiě)權(quán)限
????????🦞鎖定機(jī)制 (GPIOx_LCKR),可凍結(jié) I/O 配置
????????🦞模擬功能
????????🦞復(fù)用功能輸入/輸出選擇寄存器(一個(gè) I/O 最多可具有 16 個(gè)復(fù)用功能)
????????🦞快速翻轉(zhuǎn)(toggle),每次翻轉(zhuǎn)最快只需要兩個(gè)時(shí)鐘周期
????????🦞引腳復(fù)用非常靈活,允許將 I/O 引腳用作 GPIO 或多種外設(shè)功能中的一種
4.GPIO相關(guān)配置寄存器
????????🤑每組IO口含下面10個(gè)寄存器,即10個(gè)寄存器可以控制一組GPIO的16個(gè)IO口。
????????🤑均為32位
????????🤑每個(gè)通用 I/O 端口包括:
????????????????4 個(gè) 32 位配置寄存器(GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR 和GPIOx_PUPDR)
????????????????2 個(gè) 32 位數(shù)據(jù)寄存器(GPIOx_IDR 和GPIOx_ODR)
????????????????1 個(gè) 32 位置位/復(fù)位寄存器 (GPIOx_BSRR)
????????????????1 個(gè) 32 位鎖定寄存器 (GPIOx_LCKR)
????????????????2 個(gè) 32 位復(fù)用功能選擇寄存器(GPIOx_AFRH 和 GPIOx_AFRL)
三、GPIO的那一堆寄存器
1.端口模式寄存器 (GPIOx_MODER)
GPIO port mode register
?
????????👵MODER寄存器每2位控制一個(gè)IO。32個(gè)位控制一組IO的16個(gè)IO
????????👵00:輸入(復(fù)位狀態(tài))
????????👵01:通用輸出狀態(tài)
????????👵10:復(fù)用功能模式
????????👵11:模擬模式
2.端口輸出類型寄存器(GPIOx_OTYPER)
GPIO port output type register
?
????????🐎位31-16保留,必須保持復(fù)位值。
????????🐎位15-0 端口x配置位,每位控制一個(gè)IO? 0:輸出推挽(復(fù)位狀態(tài))1:輸出開(kāi)漏
3.端口輸出速度寄存器(GPIOx_OSPEEDR)
GPIO port output speed register
?
????????🐼每2位控制一個(gè)IO口。32位控制一組IO口的16個(gè)IO
????????🐼00:2MHz(低速)
????????🐼01:25MHz(中速)
????????🐼10:50MHz(快速)
????????🐼11:30pF時(shí)為100MHz(高速)【15pF時(shí)為80MHz(高速)】??????? 皮法 (pF)
4.端口上拉/下拉寄存器(GPIOx_PUPDR)
GPIO port pull-up/pull-down register
?
????????🤠00:無(wú)上拉或下拉
????????🤠01:上拉
????????🤠10:下拉
????????🤠11:保留
5.端口輸入數(shù)據(jù)寄存器(GPIOx_IDR)
GPIO port input data register
????????🤢31:16保留,必須保持復(fù)位值
????????🤢15:0這些位為只讀形式,只能在字模式下訪問(wèn)。它們包含相應(yīng)I/O端口的輸入值
6.端口輸出數(shù)據(jù)寄存器(GPIOx_ODR)
GPIO port output data register
????????🦁31:16保留,必須保持復(fù)位值
????????🦁15:0? 通過(guò)寫(xiě)入該寄存器,可分別對(duì)ODR位進(jìn)行置位(1)和復(fù)位(0)
7.端口置位/復(fù)位寄存器(GPIOx_BSRR)
GPIO port bit set/reset register
?
????????🦥31:16BRy:用于端口復(fù)位
????????????????這些位為只寫(xiě)形式,只能在字、半字或字節(jié)模式下訪問(wèn)。讀取這些位可返回值0x0000
? ? ? ? ? ? ? ? 0:不會(huì)對(duì)相應(yīng)的ODRx位執(zhí)行任何操作
? ? ? ? ? ? ? ? 1:對(duì)相應(yīng)ODRx位進(jìn)行復(fù)位
????????🦥15:0? BSy:用于端口置位
????????????????這些位為只寫(xiě)形式,只能在字、半字或字節(jié)模式下訪問(wèn)。讀取這些位可返回值0x0000
????????????????0:不會(huì)對(duì)相應(yīng)的ODRx位執(zhí)行任何操作
????????????????1:對(duì)相應(yīng)ODRx位進(jìn)行置位
????????🦥如果同時(shí)對(duì)BSx和BRx置位,則BSx的優(yōu)先級(jí)更高
8.GPIO端口配置鎖定寄存器 (GPIOx_LCKR) (x = A..I)
GPIO port configuration lock register
9.GPIO 復(fù)用功能低位寄存器 (GPIOx_AFRL) (x = A..I)
GPIO alternate function low register
???圖4? 引腳0到7所用復(fù)用器
?????????💩31:0ADRLy:端口x位y的復(fù)用功能選擇(Alternate function selection for port x bit y) (y = 0..7) 這些位通過(guò)軟件寫(xiě)入,用于配置復(fù)用功能 I/O。AFRLy 選擇:
????????0000:AF0 ????????0001:AF1 ????????0010:AF2 ????????0011:AF3 ????????0100:AF4 ????????0101:AF5 ????????0110:AF6 ????????0111:AF7 ????????1000:AF8 ????????1001:AF9 ????????1010:AF10 ????????1011:AF11 ????????1100:AF12 ????????1101:AF13 ????????1110:AF14 ????????1111:AF1510.GPIO 復(fù)用功能高位寄存器 (GPIOx_AFRH) (x = A..I)
GPIO alternate function high register
? ? ? ??
????圖5? 引腳8到15所用復(fù)用器
?????????🙄功能同復(fù)用功能低位寄存器。
四、GPIO小實(shí)驗(yàn):跑馬燈
????????注:任何方式操作IO口,都必須先使能相應(yīng)的IO口時(shí)鐘
???????? ? ? ? ?go to defination的快捷鍵為F12
1.硬件
????????GPIO:推挽輸出(上拉)
2.庫(kù)函數(shù)版(library function):
(1)重要函數(shù)
????????1個(gè)初始化函數(shù):
????????????????🤡void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
????????????????🤡作用:初始化一個(gè)或者多個(gè)IO口(同一組)的工作模式,輸出類型,速度以及上下拉方式。也就是一組IO口的4個(gè)配置寄存器。
????????????????🤡(GPIOx->MODER, GPIOx->OSPEEDR,GPIOx->OTYPER,GPIOx->PUPDR)
????????2個(gè)讀取輸入電平函數(shù):
????????????????😛uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
????????????????😛作用:讀取某個(gè)GPIO的輸入電平。實(shí)際操作的是GPIOx_IDR寄存器。
????????????????😛uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
????????????????😛作用:讀取某組GPIO的輸入電平。實(shí)際操作的是GPIOx_IDR寄存器。
????????2個(gè)讀取輸出電平函數(shù):
????????????????🙉uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
????????????????🙉作用:讀取某個(gè)GPIO的輸出電平。實(shí)際操作的是GPIO_ODR寄存器。
????????????????🙉uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
????????????????🙉作用:讀取某組GPIO的輸出電平。實(shí)際操作的是GPIO_ODR寄存器。
????????4個(gè)設(shè)置輸出電平函數(shù):
????????????????👾void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
????????????????👾作用:設(shè)置某個(gè)IO口輸出為高電平(1)。實(shí)際操作BSRRL寄存器
????????????????👾void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
????????????????👾作用:設(shè)置某個(gè)IO口輸出為低電平(0)。實(shí)際操作的BSRRH寄存器。
????????????????👾void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
????????????????👾void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
????????????????👾這兩個(gè)函數(shù)不常用,也是用來(lái)設(shè)置IO口輸出電平。
????????使能IO口時(shí)鐘
????????????????🐖RCC_AHB1PeriphClockCmd();
(2)led.c
#include "led.h" #include "stm32f4xx.h" void LED_Init(void) {GPIO_InitTypeDef GPIO_InitStructure; //定義結(jié)構(gòu)體RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE); //IO口時(shí)鐘使能GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10; //對(duì)結(jié)構(gòu)體進(jìn)行賦值GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOF,&GPIO_InitStructure);GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10); //置位 }3.寄存器版(register):
(1)RCC AHB1 外設(shè)時(shí)鐘使能寄存器 (RCC_AHB1ENR)
????????🐲RCC(Reset Clock Controller)
????????🐲RCC AHB1 peripheral clock enable register
(2)led.c
#include "stm32f4xx.h"void LED_Init(void) {RCC->AHB1ENR|= 1<<5; //IO口時(shí)鐘使能//PF9GPIOF->MODER &= ~(3<<2*9); //通用輸出GPIOF->MODER |= 1<<(2*9);GPIOF->OSPEEDR &= ~(3<<2*9); //50MHzGPIOF->OSPEEDR |= 2<<(2*9);GPIOF->OTYPER &= ~(1<<9); //推挽GPIOF->OTYPER |= (0<<9);GPIOF->PUPDR &= ~(3<<2*9); //上拉GPIOF->PUPDR |= 1<<(2*9);GPIOF->ODR |= 1<<9; //高電平//PF10GPIOF->MODER &= ~(3<<2*10);GPIOF->MODER |= 1<<(2*10);GPIOF->OSPEEDR &= ~(3<<2*10);GPIOF->OSPEEDR |= 2<<(2*10);GPIOF->OTYPER &= ~(1<<10);GPIOF->OTYPER |= (0<<10);GPIOF->PUPDR &= ~(3<<2*10);GPIOF->PUPDR |= 1<<(2*10);GPIOF->ODR |= 1<<10; }4.位操作版(Bit-band operations):
(1)位帶操作
????????位帶別名區(qū)(Bit Band alias address)把每個(gè)比特膨脹成一個(gè) 32 位的字。當(dāng)你通過(guò)位帶別名區(qū)訪問(wèn)這些字時(shí),就可以達(dá)到訪問(wèn)原始比特的目的。
(2)步驟
????????😤使能IO口時(shí)鐘,調(diào)用RCC_AHB1PeriphClockCmd();
????????😤初始化IO口模式
????????😤位帶操作
(3)led.c
#include "stm32f4xx.h" #include "led.h" #include "delay.h"int main(void) {delay_init(168); //初始化延時(shí)函數(shù)LED_Init();while(1){PFout(9) = 1; //PFout()為IO口操作宏定義PFout(10) = 1;delay_ms(500);PFout(9) = 0;PFout(10) = 0;delay_ms(500);} }本文結(jié)束🐮
STM32F4學(xué)習(xí)筆記(二):時(shí)鐘樹(shù)及SysTick定時(shí)器
總結(jié)
以上是生活随笔為你收集整理的STM32F4(正点原子)学习笔记(一):GPIO及其小实验的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 硬件测试和软件测试的区别以及概念
- 下一篇: 机器人抓取 三维重建机器人抓取