目录
今天我们来学习GPIO
GPIO简介
GPIO(General Purpose Input/Output,通用输入/输出)是微控制器和嵌入式系统中常见的功能模块,用于实现简单的数字信号的输入和输出。即通用输入输出端口,简称GPIO作用:负责采集外部器件的信息或者控制外部器件工作,即输入输出
特点: 1,不同型号,IO口数量可能不一样,可通过选型手册快速查询
2,快速翻转,每次翻转最快只需要两个时钟周期(F1最高速度可以到50Mhz)
3,每个IO口都可以做中断
4,支持8种工作模式
IO端口基本结构介绍
GPIO的基本结构组成部分及其功能:
- 保护二极管:
- 通常每个GPIO引脚都会配备一对反向并联的保护二极管,连接到VDD(供电电压)和GND(地)。这些二极管的作用是在引脚上出现超过电源电压或低于地电压的异常电平时,导通并保护内部电路不受损害,避免过压或欠压损坏器件。
- 上/下拉电阻:
- 上拉电阻连接GPIO引脚到VDD,下拉电阻则连接到GND。这些电阻可以设置,以确保在没有外部信号连接到引脚时,引脚有一个默认的稳定电平状态(高电平或低电平)。这对于避免不确定状态和减少噪声干扰非常重要。
- 输入缓冲器:
- 输入缓冲器用于读取外部信号,并将其转换为微控制器内部电路可以处理的电平。它通常具有高阻抗,以最小化对外部电路的影响。
- 输出驱动器:
- 输出驱动器负责将微控制器内部的逻辑电平转换为足以驱动外部负载的电平。根据设计,输出驱动器可以采用以下几种常见结构:
- 推挽输出:包含一个P沟道MOSFET和一个N沟道MOSFET,能够输出高电平和低电平,适用于驱动负载。
- 开漏输出:仅包含一个N沟道MOSFET,可以拉低输出但不能主动拉高,需要外部上拉电阻配合。
- 开漏与上拉组合:结合开漏输出和外部上拉或片上上拉电阻,既节省功耗又能提供双向通信能力。
- 输出驱动器负责将微控制器内部的逻辑电平转换为足以驱动外部负载的电平。根据设计,输出驱动器可以采用以下几种常见结构:
- 复用功能选择:
- 许多GPIO引脚还可以配置为其他功能,如SPI、I2C、USART等串行通信接口的一部分。这种情况下,会有一个复用器来选择是作为GPIO还是其他外设功能使用。
- 寄存器:
- GPIO的操作通常由一组寄存器控制,包括但不限于:
- 输出数据寄存器(ODR):控制输出引脚的电平。
- 输入数据寄存器(IDR):反映引脚的当前输入状态。
- 模式配置寄存器(MODER):定义引脚的工作模式(输入、输出、复用等)。
- 速度配置寄存器(OSPEEDR):设置输出速度。
- 上拉/下拉寄存器(PUPDR):控制引脚的上拉或下拉电阻设置。
- 中断配置和状态寄存器(EXTI相关寄存器):用于配置GPIO中断。
- GPIO的操作通常由一组寄存器控制,包括但不限于:
GPIO的八种模式
GPIO的八种模式主要分为四类输入模式和四类输出模式,这些模式允许GPIO引脚以不同的方式与外部电路交互。以下是对这八种模式的详细解释:
输入模式(4种)
-
浮空输入(GPIO_Mode_IN_FLOATING)
在此模式下,GPIO引脚不连接任何内部上拉或下拉电阻,因此引脚的电平完全由外部电路决定,且可能因噪声影响而不稳定。 -
上拉输入(GPIO_Mode_IPU)
GPIO内部连接了一个上拉电阻到VDD,当没有外部信号驱动时,默认状态为高电平。这有助于消除噪声并确保在无信号时有一个确定的电平状态。 -
下拉输入(GPIO_Mode_IPD)
GPIO内部连接了一个下拉电阻到GND,当没有外部信号驱动时,默认状态为低电平。同样,这也有助于稳定无信号时的电平状态,并减少噪声影响。 -
模拟输入(GPIO_Mode_AIN)
用于模拟信号的直接读取,比如ADC输入。在这种模式下,GPIO不经过施密特触发器,允许读取连续变化的模拟电压值,适用于ADC转换前的信号采样。
输出模式(4种)
-
推挽输出(GPIO_Mode_Out_PP)
提供完整的高低电平输出能力。当输出高电平时,上MOS管导通而下MOS管截止,引脚连接到VDD;输出低电平时则相反,下MOS管导通而上MOS管截止,引脚连接到GND。适合驱动负载。 -
开漏输出(GPIO_Mode_Out_OD)
GPIO只能拉低输出,不能主动拉高。当输出低电平时,N沟道MOSFET导通,引脚接地;输出高电平时,MOSFET关闭,引脚处于高阻态,需要外部上拉电阻才能获得高电平。适用于I2C等需要线与逻辑的总线。 -
复用推挽输出(GPIO_Mode_AF_PP)
当GPIO被配置为外设功能的输出时使用,如USART的TX输出。与推挽输出相似,但此时GPIO被外设而不是软件直接控制。 -
复用开漏输出(GPIO_Mode_AF_OD)
同样用于外设复用,但输出为开漏形式。需要外部上拉电阻以实现高电平输出。适用于需要低功耗或线与逻辑的复用场景。
这些模式的选择取决于应用的具体需求,比如是否需要驱动负载、信号的稳定性、功耗考虑以及是否需要支持模拟信号的读取等。在编程时,通过配置相应的寄存器或使用HAL库等高级抽象层的API来设定GPIO的工作模式。
GPIO配置步骤
通用外设驱动模型
GPIO配置步骤简图
相关HAL库函数
配置步骤
1. 时钟使能
确保GPIO端口的时钟已经打开。这通常在系统初始化的时候完成,使用如下宏来实现:
__HAL_RCC_GPIOx_CLK_ENABLE(); // 将x替换为相应GPIO端口,如'A'、'B'等
2. 定义初始化结构体
创建一个GPIO_InitTypeDef类型的结构体实例,并设置GPIO的配置参数,如模式、速度、引脚状态等:
GPIO_InitTypeDef gpio_init_struct;
// 配置参数示例
GPIO_InitStruct.Pin = GPIO_PIN_x; // 配置的引脚号,如GPIO_PIN_5
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 输出模式,推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL; // 不使用上拉或下拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; // 中速
3. 调用初始化函数
使用前面定义的结构体参数,调用HAL_GPIO_Init()函数初始化指定的GPIO端口和引脚:
HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); // GPIOx为端口号,如GPIOA、GPIOB等
4. 操作GPIO
输出操作:使用HAL_GPIO_WritePin()来设置GPIO引脚的电平,或者使用HAL_GPIO_TogglePin()来翻转电平状态。
HAL_GPIO_WritePin(GPIOx, GPIO_PIN_x, GPIO_PIN_SET); // 设置为高电平
HAL_GPIO_WritePin(GPIOx, GPIO_PIN_x, GPIO_PIN_RESET); // 设置为低电平
HAL_GPIO_TogglePin(GPIOx, GPIO_PIN_x); // 切换电平
输入读取:使用HAL_GPIO_ReadPin()来读取GPIO引脚的当前电平状态。
GPIO_PinState state = HAL_GPIO_ReadPin(GPIOx, GPIO_PIN_x);
e.g.LED配置
void led_init(void)
{
GPIO_InitTypeDef gpio_init_struct;
__HAL_RCC_GPIOF_CLK_ENABLE(); /* LED0时钟使能 */
__HAL_RCC_GPIOF_CLK_ENABLE(); /* LED1时钟使能 */
gpio_init_struct.Pin = GPIO_PIN_9; /* LED0引脚 */
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
HAL_GPIO_Init(GPIOF, &gpio_init_struct); /* 初始化LED0引脚 */
gpio_init_struct.Pin = GPIO_PIN_10; /* LED1引脚 */
HAL_GPIO_Init(GPIOF, &gpio_init_struct); /* 初始化LED1引脚 */
}