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