【STM32】SMT32标准库与HAL库对照学习教程特别篇--GPIO详讲
一、前言
本篇内容是的STM32GPIO的详讲,是为库函数配置做铺垫,本篇以STM32F103ZE为例,详细对GPIO进行讲解。
二、GPIO简介
1、定义
GPIO英文全称general purpose intput output,是通用输入输出端口的简称,可以通过软件来控制其输入和输出。STM32芯片的GPIO引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能。
2、分类
- STM32从管脚类型被分为了:电源管脚、晶振管脚、复位管脚、下载管脚、BOOT管脚、GPIO管脚。
- GPIO管脚类的所有管脚又被分为了:PA类、PB类、PC类、PD类…,根据芯片类型不同类数也不同,但每类引脚最多只有16个,例如:PA0~PA15。
3、复用
STM32芯片有很多的内置外设,些外设的外部引脚都是与GPIO共用的,也就是说,一个引脚除了输入输出电平,还可以使用别的功能,但默认功能是电平的输入输出,要使用其他功能的时候,就需要GPIO的复用。例如:IIC通信就是GPIO引脚的复用。
三、GPIO工作模式
1、输入模式
2、输出模式
3、输出速度
四、GPIO图形分析
1、GPIO的基本构成
GPIO其内部结构图,如下:
图片在STN32F1xx中文参考手册的105页
- (1)保护二极管:IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入,当引脚电压高于VDD_FT时,上方的二极管导通,当引脚电压低于VSS时,下方的二极管导通,防止异常常电压引入芯片导致芯片烧毁。
- (2)上拉、下拉电阻:控制引脚默认状态的电压。打开上拉的时候引脚默认电压为高电平,打开下拉的时候引脚默认电压为低电平。
- (3)TTL施密特触发器:基本原理是当输入电压高于正向阈值电压,输出为高;当输入电压低于负向阈值电压,输出为低;IO口信号经过触发器后,可以将电平分为高电平与低电平,也就是1和0的数字信号,并且符合TTL电平协议,这就是STM32可以产生TTL信号的原因。
- (4)P-MOS管和N-MOS管:输出电平信号由P-MOS管和N-MOS管决定,高电平时,P-MOS管导通,N-MOS管关闭输出高电平,低电平时,P-MOS管关闭,N-MOS管导通输出低电平,这就使得GPIO具有“推挽输出”和“开漏输出”的模式 。
注释: VDD_FT 代表IO口,兼容3.3V和5V,如果没有标注“FT”,就代表着不兼容5V
图片在数据手册34页
2、GPIO八种模式分析
- 浮空输入模式
浮空输入模式下,I/O端口的电平信号直接进入输入数据寄存器。MCU直接读取I/O口电平,但I/O的电平状态是不确定的,完全由外部输入决定;如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的。
- 上拉输入模式
IO内部闭合上拉电阻的开关,此时如果IO口外部没有信号输入或者引脚悬空,IO口默认为高电平,如果I/O口输入低电平,那么引脚就为低电平,MCU读取到的就是低电平
- 下拉输入模式
IO内部打开下拉电阻开关,此时如果IO口外部没有信号输入或者引脚悬空,IO口默认为低电平 如果I/O口输入高电平,那么引脚就为高电平,MCU读取到的就是高电平。
- 模拟输入模式
当GPIO引脚用于ADC采集电压的输入通道时,用作"模拟输入"功能,此时信号不经过施密特触发器,直接直接进入ADC模块,并且输入数据寄存器为空 ,CPU不能在输入数据寄存器上读到引脚状态。
注:当GPIO用于模拟功能时,引脚的上、下拉电阻是不起作用的,这个时候即使配置了上拉或下拉模式,也不会影响到模拟信号的输入输出。
除了 ADC 和 DAC 要将 IO 配置为模拟通道之外其他外设功能一律 要配置为复用功能模式。
- 开漏输出模式
在开漏输出模式时,只有N-MOS管工作,如果我们控制输出为低电平时,则P-MOS管关闭,N-MOS管导通,使输出低电平,I/O端口的电平就是低电平,若控制输出为1高电平时,则P-MOS管和N-MOS管都关闭,输出指令不会起到作用,此时IO端口要输出高电平,就要让I/O端口外部的上拉或者下拉决定,如果没有上拉或者下拉 IO口就处于悬空状态。
- 推挽输出模式
在推挽输出模式时,N-MOS管和P-MOS管都工作,如果我们控制输出为低电平,则P-MOS管关闭,N-MOS管导通,I/O端口输出低电平,若控制输出为高电平,则P-MOS管导通N-MOS管关闭,I/O端口输出高电平。
注:此时输入是可用,通过输入数据寄存器GPIOx_IDR可读取I/O的实际状态。I/O口的电平是输出的电平。
- 开漏复用输出模式
GPIO复用为其他外设,输出数据寄存器GPIOx_ODR无效; 输出的高低电平的来源于其它外设,输入同样可用,通过输入数据寄存器可获取I/O实际状态 除了输出信号的来源改变,其他与开漏输出功能相同。
- 复用推挽输出模式
GPIO复用为其他外设(如 I2C),输出数据寄存器GPIOx_ODR无效;输出的高低电平的来源于其它外设,输入同样可用,通过输入数据寄存器可获取I/O实际状态,除了输出信号的来源改变其他与开漏输出功能相同。
五、HAL库与标准库的GPIO配置结构体对比
1、标准库定义
typedef struct
{
uint16_t GPIO_Pin;
GPIOSpeed_TypeDef GPIO_Speed;
GPIOMode_TypeDef GPIO_Mode;
}GPIO_InitTypeDef;
结构体第一个元素可配置的引脚
#define GPIO_Pin_0 ((uint16_t)0x0001)
#define GPIO_Pin_1 ((uint16_t)0x0002)
#define GPIO_Pin_2 ((uint16_t)0x0004)
#define GPIO_Pin_3 ((uint16_t)0x0008)
#define GPIO_Pin_4 ((uint16_t)0x0010)
#define GPIO_Pin_5 ((uint16_t)0x0020)
#define GPIO_Pin_6 ((uint16_t)0x0040)
#define GPIO_Pin_7 ((uint16_t)0x0080)
#define GPIO_Pin_8 ((uint16_t)0x0100)
#define GPIO_Pin_9 ((uint16_t)0x0200)
#define GPIO_Pin_10 ((uint16_t)0x0400)
#define GPIO_Pin_11 ((uint16_t)0x0800)
#define GPIO_Pin_12 ((uint16_t)0x1000)
#define GPIO_Pin_13 ((uint16_t)0x2000)
#define GPIO_Pin_14 ((uint16_t)0x4000)
#define GPIO_Pin_15 ((uint16_t)0x8000)
#define GPIO_Pin_All ((uint16_t)0xFFFF)
结构体第二个元素配置的速度
typedef enum
{
GPIO_Speed_10MHz = 1,
GPIO_Speed_2MHz,
GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
结构体第三个元素配置的模式
typedef enum
{ GPIO_Mode_AIN = 0x0,
GPIO_Mode_IN_FLOATING = 0x04,
GPIO_Mode_IPD = 0x28,
GPIO_Mode_IPU = 0x48,
GPIO_Mode_Out_OD = 0x14,
GPIO_Mode_Out_PP = 0x10,
GPIO_Mode_AF_OD = 0x1C,
GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;
定义文件在stm32f10x.gpio.h中
2、HAL库定义
typedef struct
{
uint32_t Pin;
uint32_t Mode;
uint32_t Pull;
uint32_t Speed;
} GPIO_InitTypeDef;
结构体第一个元素可配置的引脚
#define GPIO_PIN_0 ((uint16_t)0x0001)
#define GPIO_PIN_1 ((uint16_t)0x0002)
#define GPIO_PIN_2 ((uint16_t)0x0004)
#define GPIO_PIN_3 ((uint16_t)0x0008)
#define GPIO_PIN_4 ((uint16_t)0x0010)
#define GPIO_PIN_5 ((uint16_t)0x0020)
#define GPIO_PIN_6 ((uint16_t)0x0040)
#define GPIO_PIN_7 ((uint16_t)0x0080)
#define GPIO_PIN_8 ((uint16_t)0x0100)
#define GPIO_PIN_9 ((uint16_t)0x0200)
#define GPIO_PIN_10 ((uint16_t)0x0400)
#define GPIO_PIN_11 ((uint16_t)0x0800)
#define GPIO_PIN_12 ((uint16_t)0x1000)
#define GPIO_PIN_13 ((uint16_t)0x2000)
#define GPIO_PIN_14 ((uint16_t)0x4000)
#define GPIO_PIN_15 ((uint16_t)0x8000)
#define GPIO_PIN_All ((uint16_t)0xFFFF)
结构体第二个元素配置的模式
#define GPIO_MODE_INPUT 0x00000000u
#define GPIO_MODE_OUTPUT_PP 0x00000001u
#define GPIO_MODE_OUTPUT_OD 0x00000011u
#define GPIO_MODE_AF_PP 0x00000002u
#define GPIO_MODE_AF_OD 0x00000012u
#define GPIO_MODE_AF_INPUT GPIO_MODE_INPUT
结构体第三个元素上拉下拉的配置模式
#define GPIO_NOPULL 0x00000000u
#define GPIO_PULLUP 0x00000001u
#define GPIO_PULLDOWN 0x00000002u
结构体第四个元素输出速度配置
#define GPIO_SPEED_FREQ_LOW (GPIO_CRL_MODE0_1)
#define GPIO_SPEED_FREQ_MEDIUM (GPIO_CRL_MODE0_0)
#define GPIO_SPEED_FREQ_HIGH (GPIO_CRL_MODE0)
#define GPIO_CRL_MODE_Pos (0U)
#define GPIO_CRL_MODE_Msk (0x33333333UL << GPIO_CRL_MODE_Pos)
#define GPIO_CRL_MODE GPIO_CRL_MODE_Msk
#define GPIO_CRL_MODE0_Pos (0U)
#define GPIO_CRL_MODE0_Msk (0x3UL << GPIO_CRL_MODE0_Pos)
#define GPIO_CRL_MODE0 GPIO_CRL_MODE0_Msk
#define GPIO_CRL_MODE0_0 (0x1UL << GPIO_CRL_MODE0_Pos)
#define GPIO_CRL_MODE0_1 (0x2UL << GPIO_CRL_MODE0_Pos)
定义在stm32f1xx_hal_gpio.h文件内
到这里,STM32GPIO的介绍就结束啦!
|