GPIO 外设的概述
概述
GPIO 指的是通用的输入输出端口,可以由用户通过软件配置的方式来进行控制,GPIO 引脚需要和外设连接在一起的,就可以和外设实现通信以及采集数据等功能。
定义
指的是对芯片的某个引脚进行高低电平的输出,以及可以去检测某个引脚的电平状态。
一般电平采用都是 TTL 电平信号,TTL 电平信号规定:+5V 等价于逻辑“1”,0V 等价于逻辑“0”。
电平其实有一个电平范围:>2.4V 就表示高电平,<0.4V 就表示低电平。
引脚的说明
- 电源引脚:VCC、VDD、VSS、VDDA
- 晶振引脚:PC14、PC15、PH0、PH1 就属于晶振引脚,也可以作为其他的功能使用
- 复位引脚:NRST 属于复位引脚
- BOOT 引脚:BOOT0 是专用引脚,BOOT1 就属于功能引脚 (设置芯片的自举模式)
- GPIO 引脚:芯片一共有 144 引脚,但是 GPIO 引脚有 114 个
- 下载引脚:A13、PA14、PB3、PB4 等都属于下载引脚(JTAG、SWD)
引脚的命名规则
一般是由 P 开头,分为很多组,以字母 AH 来命名,每个组有 16 个引脚,引脚编号为 015,所以如 PA0 ~ PA15、PB0 ~ PB15... ...
引脚的功能
芯片的引脚有很多的功能,一般默认的功能都是作为 GPIO(输入输出),但是引脚也有其他的功能,被称为“第二功能”,只有在使用 ADC 通道和 DAC 需要把引脚设置模拟模式,其他情况下想要把引脚当做别的功能使用,需要把引脚设置复用模式。
引脚的功能必须通过查阅芯片的数据手册,才可以进行配置 如下图所示
带 FT 标志的 IO 口,引脚内部有保护二极管,可以容忍 5V 电压(芯片的标准电压为 3.3V)
GPIO 外设的使用
一般使用函数库开发,流程如下:
-
分析原理图,找到 GPIO 引脚 LED0-PF9
-
分析原理图,理解硬件的控制原理 GPIO 输出高电平 灯灭
-
根据函数库的接口进行开发 参考 ST 公司提供的函数库帮助手册(相当于 man 手册)
GPIO 外设详解
函数库开发的外设使用流程
-
定义一个外设的结构体变量
每个外设都有对应的结构体,结构体定义存放在每个外设的头文件内,比如 GPIO 外设的初始化结构体就定义在 stm32f4xx_gpio.h 中
-
在配置外设结构体之前,需要调用库函数打开外设的时钟 RCC_AHB1PeriphClockCmd
任何一个外设都是由时钟控制的,时钟就相当于外设的开关,因为底层寄存器一般内部结构中都是由触发器组成,而触发器需要触发信号,而触发信号是由时钟提供的。
STM32 低功耗的根本原因就是在芯片复位之后,所有的外设的时钟(开关)都是默认关闭,需要用到哪个外设就打开哪个外设的时钟,不需要的就关闭,有利于降低功耗。
函数库中提供了多个可以打开外设时钟的函数,如下图所示
内核中的外设都会挂载在不同的总线下面,AHB 总线叫做高级高性能总线,APB 总线叫做高级外设总线(APB1 和 APB2) 。每个总线的时钟频率都不同,因为不同类型的外设需要的时钟频率不同,所以为了降低 STM32 的功耗,把不同性能的外设挂载在不同频率的总线下。
函数库中提供的时钟使能的函数在 stm32f4xx_rcc.h 中声明,在 stm32f4xx_rcc.c 定义的
函数原型
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)
函数参数
参数一:RCC_AHB1Periph 指的是外设的时钟 如 RCC_AHB1Periph_GPIOF
参数二:NewState 指的是打开或者关闭 如 ENABLE or DISABLE
返回值:None
在调用函数库的时候,大家不需要关注函数内部的实现过程,只需要掌握函数的传参和返回值即可。
-
打开外设时钟后,需要对外设的结构体成员进行赋值操作(引脚、模式、速率、类型....)
GPIO 外设的结构体成员有 5 个,可以参考 stm32f4xx_gpio.h
-
需要指定配置的引脚 GPIO_Pin
一个端口有 16 个引脚,在操作端口的某个引脚的时候,需要说清楚用哪个引脚,这样才可以对寄存器的某些位进行操作
-
需要指定引脚的模式 GPIO_Mode
GPIO 提供了 3 种输入模式(浮空输入、上拉输入、下拉输入),参考 GPIO 内部结构示意图
GPIO 提供了 4 种输出模式(上拉 + 下拉推挽输出、上拉 + 下拉开漏输出),参考 GPIO 内部结构示意图
PMOS 管和 NMOS 管循环依次导通,好处是可以提高电路的负载能力和切换速度,并且可以降低功耗
-
设置引脚的输出速率 GPIO_Speed
指的是 IO 驱动电路的输出能力(其实就是在不失真的情况下能输出的最大速率),引脚的输出速率影响 GPIO 的引脚的功耗和噪声,一般大家可以根据实际需要来选择,速率越高,则功耗越高,噪声越大,如果对产品的实时性要求不高,则选择一个低速的即可,有利于降低 EMI(电磁干扰),一般指的是影响引脚在切换高低电平的过程中上升沿和下降沿的陡度。如果自己也不知道选哪个,就选高的。
-
设置引脚的输出类型 GPIO_OType
推挽输出:可以利用驱动器直接输出高电平和低电平
开漏输出:可以利用驱动器直接输出低电平,但是不能直接输出高电平(需要外接上拉电阻)
-
设置引脚的上下拉电阻 GPIO_PuPd
一般都会在引脚未使用的情况给引脚一个默认的电平状态,防止引脚出现电平不定(高组态)的情况。
-
-
在对结构体成员赋值之后,调用初始化函数把结构体成员的值写入到对应外设的寄存器
函数原型
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
函数参数
参数一:GPIOx 指的是想要初始化的 GPIO 外设的端口 A~K 如 GPIOF
参数二:GPIO_InitStruct 指的是配置好的 GPIO 结构体变量的地址 记得取地址 &
返回值 None
-
设置引脚输出高电平(输出模式有效) 调用 GPIO_SetBits()
函数原型
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
函数参数
参数一:GPIOx 想要输出高电平的引脚端口 如 GPIOx A~K 如 GPIOF
参数二:GPIO_Pin 想要输出高电平的引脚位置 GPIO_Pin_x where x can be (0..15)
返回值 None
-
设置引脚输出低电平(输出模式有效) 调用 GPIO_ResetBits()
函数原型
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
函数参数
参数一:GPIOx 想要输出高电平的引脚端口 如 GPIOx A~K 如 GPIOF
参数二:GPIO_Pin 想要输出高电平的引脚位置 GPIO_Pin_x where x can be (0..15)
返回值 None
-
获取引脚的电平状态(输入模式有效) 调用 GPIO_ReadInputDataBit()
函数原型
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
函数参数
参数一:GPIOx 想要读取的引脚端口 如 GPIOx A~K 如 GPIOF
参数二:GPIO_Pin 想要读取的引脚位置 GPIO_Pin_x where x can be (0..15)
返回值 返回读取到的引脚的电平状态 0 或者 1
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于