流心
发布于 2024-06-16 / 8 阅读
0

GPIO输入/输出函数

输入模式(Input Mode)

GPIO 引脚接收外部信号,STM32 可以读取电平状态,输入模式包括:

1、浮空输入(Floating input)

  • 不连接上拉或下拉电阻,直接读取外部信号

  • 特点:功耗低,但容易受干扰导致电平不稳定

GPIO_InitTypeDef GPIO_InitStruct = {0};

// 打开 GPIO 时钟
__HAL_RCC_GPIOA_CLK_ENABLE();

// 配置 PA0 为浮空输入
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;   // 浮空
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

// 读取输入状态
uint8_t state = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);

2、上拉输入(Input with Pull-Up)

  • 内部连接上拉电阻,默认电平为高

  • 外部拉低电压时,读取为低

  • 特点:避免悬空,常用于按钮输入

GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;   // 内部上拉
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

3、下拉输入(Input with Pull-Down)

  • 内部连接下拉电阻,默认电平为高

  • 外部拉高电平时,读取为高

  • 特点:避免悬空

GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN; // 内部下拉
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

4、模拟输入(Analog Input)

  • 引脚直接连接到 ADC(模数转换器),用于采集模拟电压

  • 特点:不能用作数字输入,适合传感器、采集类应用

输出模式

GPIO 引脚输出信号,STM32 可以控制外部电路,输出模式包括:

1、推挽输出(Push-Pull Output)

  • 高电平和低电平都能驱动输出

  • 特点:输出强、速度快,适合LED、继电器等负载

GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  // 推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 输出速度
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

// 输出高低电平
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);   // 高
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); // 低

2、开漏输出(Open-Drain Output)

  • 低电平有效,高电平悬空,需要外部上拉电阻

  • 特点:适合 IC2 总线、与不同电压电平接口

GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;  // 开漏输出
GPIO_InitStruct.Pull = GPIO_PULLUP;          // 外部上拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

3、输出速度设置(Output Speed)

  • GPIO 输出可以选择速度等级:低速、中速、高速、超高速

  • 高速输出上升/下降沿快,功耗较高

  • 用途:高速通信或脉冲信号控制

GPIO_InitTypeDef GPIO_InitStruct = {0};

// 打开 GPIOA 时钟
__HAL_RCC_GPIOA_CLK_ENABLE();

// 配置 PA5 为推挽输出
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  // 推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL;

// 设置输出速度
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;       // 低速
// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; // 中速
// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;   // 高速
// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // 超高速

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

// 控制 LED
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);   // 输出高电平
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // 输出低电平

4、上下拉选择(Pull-Up/Pull-Down)

  • 输出模式下也可以配置内部上拉/下拉,保证输出状态稳定

复用功能模式(Alternate Function Mode)

  • GPIO 引脚复用为外设功能(AF),如 UART、SPI、IC2 、定时器PWM、CAN等

  • 输出类型可以是推挽或开漏,根据外设要求设置

  • 优势:硬件驱动信号,不用软件手动控制,提高效率

GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;            // 复用推挽
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;         // 复用 SPI1
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

模拟模式(Analog Mode)

  • GPIO 引脚直接接入 ADC/DAC/比较器等模拟功能模块

  • 特点:不驱动数字电平,也不参与数字输入输出

  • 用途:信号采集、模拟控制、音频输出等

GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;  // 模拟模式
GPIO_InitStruct.Pull = GPIO_NOPULL;       // 不上拉不下拉
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

附加功能

  • EXTI(外部中断)输入:输入模式可以使能中断,响应上升沿、下降沿或双沿触发事件

  • 高速/低功耗模式:不同模式下可以优化功耗或输出速度

GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; // 上升沿触发
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

// 使能中断
HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);

// 中断服务函数
void EXTI0_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if(GPIO_Pin == GPIO_PIN_0)
    {
        // 中断触发处理
    }
}

输入函数

  1. uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    功能:读取 GPIO 端口中某个引脚的输入状态(高电平或低电平)。

参数:

GPIOx:要读取的 GPIO 端口,比如 GPIOA、GPIOB 等。

GPIO_Pin:指定的引脚,如 GPIO_Pin_0、GPIO_Pin_5。

返回值:

1 表示高电平

0 表示低电平

if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 1) {
    // GPIOA的0号引脚为高电平
}
  1. uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
    功能:读取整个 GPIO 端口的输入状态(16位,每位对应一个引脚)。

参数:

GPIOx:要读取的 GPIO 端口。

返回值:

16 位值,每一位对应 GPIOx 的每个引脚状态。例如 0x0001 表示第 0 号引脚为高电平,其他引脚为低电平。

uint16_t value = GPIO_ReadInputData(GPIOB);
if(value & GPIO_Pin_3) {
    // GPIOB的3号引脚为高电平
}
  1. uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    功能:读取 GPIO 端口中某个引脚的输出状态(高电平或低电平)。

参数:

GPIOx:GPIO 端口

GPIO_Pin:引脚编号

返回值:

1 表示输出高电平

0 表示输出低电平

if(GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_5) == 1) {
    // GPIOC的5号引脚输出高电平
}
  1. uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
    功能:读取整个 GPIO 端口的输出状态(16位)。

参数:

GPIOx:GPIO 端口

返回值:

16 位值,每一位对应 GPIOx 的输出状态。

uint16_t out_val = GPIO_ReadOutputData(GPIOC);
if(out_val & GPIO_Pin_1) {
    // GPIOC的1号引脚输出高电平
}

输出函数

  1. void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    功能:将 GPIO 指定引脚置为高电平(1)。

参数:

GPIOx:GPIO 端口

GPIO_Pin:引脚编号

GPIO_SetBits(GPIOA, GPIO_Pin_0); // 将 GPIOA的0号引脚置高
  1. void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    功能:将 GPIO 指定引脚置为低电平(0)。

GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 将 GPIOA的0号引脚置低	
  1. void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
    功能:根据 BitVal 设置 GPIO 指定引脚的状态。

参数:

GPIOx:GPIO 端口

GPIO_Pin:引脚编号

BitVal:Bit_SET 或 Bit_RESET

GPIO_WriteBit(GPIOB, GPIO_Pin_3, Bit_SET);   // 置高
GPIO_WriteBit(GPIOB, GPIO_Pin_3, Bit_RESET); // 置低
  1. void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
    功能:一次性写入整个 GPIO 端口的输出状态(16 位)。

参数:

GPIOx:GPIO 端口

PortVal:16位输出值,每位对应引脚状态

GPIO_Write(GPIOC, 0x00FF); // 将 GPIOC的低8位引脚置高,高8位保持低