gpio

简介

GPIO(General Purpose Input/Output)是通用输入/输出的缩写,它是嵌入式系统、微控制器(如STM32系列)以及某些专用集成电路(ASICs)中一种非常基础且重要的接口资源。GPIO模块为用户提供了一组可编程的引脚,这些引脚可以被配置为接收外部输入信号或驱动外部设备,实现系统与外部环境的数字信号交互。以下是GPIO的详细介绍:

基本概念

  1. 引脚功能

    • 输入模式:GPIO引脚可以被配置为输入模式,用于读取外部设备(如按钮、传感器、其他电路)的数字信号。当设置为输入时,引脚电平可以反映外部电路的状态,如高电平(逻辑1)或低电平(逻辑0)。
    • 输出模式:GPIO引脚也可以被配置为输出模式,用于向外部设备(如LED、继电器、驱动电路)发送控制信号。通过编程改变输出引脚的电平,可以控制外部设备的开启、关闭或状态切换。
  2. 工作模式

    • 推挽输出:提供完整的高电平和低电平驱动,内部包含上拉和下拉晶体管。适用于直接驱动负载,输出能力强,速度快。
    • 开漏输出:仅提供下拉晶体管,输出高电平时引脚呈高阻态。适用于需要线与功能、需要外部上拉电阻的总线通信(如I²C、SPI),以及需要多个设备共享同一信号线的场景。
    • 浮空输入:无内部上拉或下拉电阻,引脚电平完全由外部电路决定。适用于检测微弱信号或需要无偏置输入的场合。
    • 上拉/下拉输入:内部包含上拉或下拉电阻,用于避免引脚悬空,提供默认电平。常用于按键输入、与开漏输出设备通信等。
  3. 复用功能

    • 许多GPIO引脚具有复用功能,即除了作为通用IO使用外,还可以连接到片上外设(如UART、SPI、I²C、ADC、定时器等)的接口,实现特定的通信或控制功能。通过配置寄存器,可以将这些引脚分配给所需的外设使用。
  4. 中断能力

    • 多数GPIO引脚支持中断功能。当引脚电平发生特定变化(如上升沿、下降沿、电平变化)时,可以触发中断请求,使处理器暂停当前任务,迅速处理该事件。这对于实时响应外部事件(如按键按下、传感器状态变化)非常有用。

操作原理

  1. 寄存器控制

    • GPIO的操作主要通过对其相关寄存器的编程来完成。这些寄存器包括端口配置寄存器(设置输入/输出模式、速度等级等)、输入数据寄存器(读取引脚电平)、输出数据寄存器(设置引脚电平)、中断控制寄存器(使能中断、设置触发方式等)等。
  2. 软件编程

    • 用户通过编写代码(如C、汇编、Python等)访问这些寄存器,配置GPIO的工作模式、电平、中断等属性,并通过读写操作实现与外部设备的数据交换。

应用领域

GPIO广泛应用于各种嵌入式系统和物联网(IoT)设备中,包括但不限于:

  • 工业控制:检测传感器状态、控制电机、驱动指示灯、与PLC通信等。
  • 消费电子:按键输入处理、LED显示、蜂鸣器控制、电池电量监测等。
  • 通信设备:串行通信接口(UART、SPI、I²C)的数据收发、RF模块控制等。
  • 智能家居:环境监测(温湿度、光照、烟雾等)、家电控制、安防系统等。
  • 医疗设备:生理信号采集(心率、血压、血糖等)、仪器控制与状态显示等。

关键特性

  • 可配置性:每个GPIO引脚可以独立配置为输入、输出或特定的复用功能。
  • 可编程性:通过编程语言控制GPIO状态,实现对外部设备的实时控制与数据处理。
  • 高可靠性:具备一定的抗干扰能力和故障保护机制,适用于各种环境下的应用。
  • 易于扩展:根据系统需求,可通过增加GPIO数量来支持更多输入输出通道。

工作模式

工作模式描述特点应用场景
输入模式
浮空输入 (GPIO_Mode_IN_FLOATING)引脚既无内部上拉也无内部下拉电阻,电平完全由外部电路决定。可检测微弱变化,对外部信号无偏置影响。无线射频接收、环境噪声检测等。不建议在引脚未明确接外部电路时使用。
上拉输入 (GPIO_Mode_IPU)内部上拉电阻使引脚在无外部驱动时默认为高电平。避免引脚悬空,常用于与开漏输出设备通信或保持默认高电平状态。I²C总线的SDA/SCL线、按键输入(常态下为高电平)等。
下拉输入 (GPIO_Mode_IPD)内部下拉电阻使引脚在无外部驱动时默认为低电平。避免引脚悬空,常用于与开漏输出设备通信或保持默认低电平状态。SPI总线的NSS/CS线、按键输入(常态下为低电平)等。
输出模式
推挽输出 (GPIO_Mode_Out_PP)强制驱动引脚至高电平或低电平,内部集成了上拉和下拉晶体管。输出能力强,速度快,但不能实现线与功能。直接驱动LED、数码管、电机控制等。
开漏输出 (GPIO_Mode_Out_OD)只有下拉晶体管,无上拉晶体管。输出高电平时,引脚呈高阻态。可实现线与功能,适合总线通信,需外接上拉电阻。I²C、SPI总线的SCK/MISO/MOSI线、多个设备共享同一信号线等。
模拟功能
模拟输入 (GPIO_Mode_AIN)将GPIO引脚配置为模拟信号输入,连接到ADC通道或其他模拟外设。不具备数字功能,仅用于采集模拟信号。ADC采样、温度传感器、光照强度传感器等模拟信号接入。

中断触发方式

触发方式描述特点应用场景
上升沿触发当GPIO引脚电平从低电平变为高电平时触发中断。只响应电平从低到高的变化,过滤掉持续高电平或低电平的变化。键盘按键按下检测、脉冲计数、传感器触发等。
下降沿触发当GPIO引脚电平从高电平变为低电平时触发中断。只响应电平从高到低的变化,过滤掉持续高电平或低电平的变化。键盘按键释放检测、脉冲计数反向、传感器解除触发等。
双边沿触发当GPIO引脚电平从低电平变为高电平或从高电平变为低电平时均触发中断。对任何电平变化(无论上升还是下降)都响应。快速变化信号的捕获、双向通信握手信号检测等。
电平触发当GPIO引脚电平达到特定阈值(高电平或低电平)并保持该状态时触发中断。在电平稳定在触发阈值时触发,不关心电平变化的过程。长按键检测、持续状态监控、阈值报警等。

示例代码

void reg_gpio_init(void)
{
    //GPIO时钟开启
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;

    //配置输出,速度
    GPIOB->CRH &= ~GPIO_CRH_MODE8;
    GPIOB->CRH |= GPIO_CRH_MODE8_1;		//2MHz
    //推挽输出
    GPIOB->CRH &= ~GPIO_CRH_CNF8;

    //初始配置为1
    GPIOB->ODR |= GPIO_ODR_ODR8;
}

void LED_Init(void)
{
    GPIO_InitTypeDef gpio;

    /* GPIOD Periph clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    //GPIO_StructInit(&gpio);
    gpio.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
    gpio.GPIO_Mode = GPIO_Mode_Out_PP;
    gpio.GPIO_Speed = GPIO_Speed_10MHz;

    GPIO_Init(GPIOB,&gpio);
}