通用输入输出接口

通用输入输出接口

点击获取笔记和代码文件

GPIO功能概述

GPIO是通用输入/输出(General Purpose I/O)的简称,主要用于工业现场需要用到数字量输入/输出的场合,例如:

  • 输出功能:继电器、 LED、蜂鸣器等的控制
  • 输入功能:传感器状态、高低电平等信息的读取
  • 复用功能:片内外设的对外接口
  • 时序模拟:模拟SPI、I2C和UART等常用接口的时序

STM32的GPIO特性

  • 多种工作模式:输出/输入/复用/模拟
  • 灵活的复用模式
  • 5V电压容限
  • 外部中断功能

端口和引脚

  • **端口(PORT):**独立的外设子模块,包括多个引脚,通过多个硬件寄存器控制引脚。

    GPIO模块由端口GPIOA、GPIOB、GPIOC等多个独立的子模块构成。

    例如:端口GPIOA包括PA0~PA15这16个引脚,通过10个硬件寄存器控制引脚工作。

  • **引脚(PIN):**对应微控制器的一个管脚,归属于端口,由端口寄存器的对应位控制。

    PA0,属于端口GPIOA,输出电平由端口GPIOA的输出数据寄存器GPIOA_ODR的第0位决定。

GPIO电路

通用输入输出接口_第1张图片

GPIO工作模式

工作模式

  • 输入模式:浮空输入/上拉输入/下拉输入

    • 浮空输入:按键识别
    • 上拉输入:IO内部上拉电阻输入
    • 下拉输入:IO内部下拉电阻输入
  • 输出模式:推挽输出/开漏输出

    • 推挽输出时,P-MOS管和NMOS管轮流工作,可以输出高电平或低电平。主要用于连接数字器件,如指示灯和继电器等模块;
    • 开漏输出时,P-MOS管关闭,只有N-MOS管工作,此时只能输出低电平。要输出高电平必须外加上拉电阻,主要用于I2C总线。
  • 模拟模式

    • 模拟状态:表示引脚功能选择为模拟模式,但不作为任何片内模拟外设的复用脚,只是为了减少系统功耗。
    • 模拟外设复用引脚:表示引脚作为片内模拟外设(A/D转换模块、D/A转换模块、模拟比较器等)的复用脚,用于完成相应的功能操作。

    通用输入输出接口_第2张图片

  • 复用模式

    在CubeMX软件的引脚分配图中点击引脚即可弹出引脚的复用功能

    • 复用推挽:片内外设功能(URAT的TX,RX,SPI的MOSI,MISO,SCK,SS );
    • 复用开漏:片内外设功能( I2C的SCL,SDA )。

基于HAL库控制GPIO

GPIO外设的数据类型

  1. **引脚初始化:**采用结构体类型实现,用于定义引脚的序号、工作模式、输出速度等基本特性。
  2. **引脚电平状态:**采用枚举类型实现,用于定义引脚的电平状态:高电平和低电平。
  3. **引脚所属端口:**采用结构体指针实现,用于访问该端口所对应的寄存器组。

引脚初始化数据类型

通用输入输出接口_第3张图片

  • 成员变量Pin的取值范围:GPIO_PIN_0 ~ GPIO_PIN15

  • 成员变量Pin的取值范围:

    GPIO_MODE_INPUT 浮空输入模式
    GPIO_MODE_OUTPUT_PP 推挽输出模式
    GPIO_MODE_OUTPUT_OD 开漏输出模式
    GPIO_MODE_AF_PP 复用功能下的推挽模式
    GPIO_MODE_AF_OD 复用功能下的开漏模式
    GPIO_MODE_ANALOG 模拟模式
  • 成员变量Pull的取值范围:

    GPIO_NOPULL 没有上拉或下拉电阻激活
    GPIO_PULLUP 上拉电阻激活
    GPIO_PULLDOWN 下拉电阻激活
  • 成员变量Speed的取值范围:

    GPIO_SPEED_FREQ_LOW 引脚输出速度2MHz
    GPIO_SPEED_FREQ_MEDIUM 引脚输出速度12.5MHz~50MHz
    GPIO_SPEED_FREQ_HIGH 引脚输出速度25MHz~100MHz
    GPIO_SPEED_FREQ_VERY_HIGH 引脚输出速度50MHz~200MHz
  • 成员变量Alternate的取值范围

    • Alternate表示引脚的复用功能;
    • 由于不同型号的STM32微控制器片内集成的外设不同,因此该成员变量的取值范围由芯片型号决定。
    • 以STM32F4系列芯片为例,通过查阅stm32f1xx_hal_gpio_ex.h文件可以了解Alternate的取值范围;
    • 该成员变量的取值一般通过CubeMX软件分配,不需要用户手动设置;

引脚电平状态数据类型

通用输入输出接口_第4张图片

端口数据类型:指向端口寄存器组的结构体指针

GPIOA,GPIOB,GPIOC

  • 不同型号的STM32微控制器的端口数量各不相同;
  • 端口数据类型的定义是在以芯片型号命名的.h文件中.

使用HAL库的引脚初始化步骤

  1. **定义变量:**利用引脚初始化结构体类型GPIO_InitTypeDef 定义一个结构体变量。
  2. **设置模式:**按照引脚的工作模式,依次对该结构体的成员变量赋值,如pin、mode、pull等。
  3. **调用函数:**调用初始化函数HAL_GPIO_Init将配置参数写入到对应的寄存器,入口参数为端口号和结构体变量。

GPIO外设接口函数的概述

  1. 引脚初始化函数:HAL_GPIO_Init

    函数原型 复位引脚到初始状态
    功能描述 引脚初始化
    入口参数1 GPIOx:引脚端口号,取值范围是GPIOA~GPIOK
    入口参数2 GPIO_Init:指向引脚初始化类型GPIO_InitTypeDef的结构体指针,该结构体包含指定引脚的配置参数
    返回值
    注意事项 该函数可以由CubeMX软件自动生成
  2. 引脚复位函数:HAL_GPIO_DeInit

    函数原型 void HAL_GPIO_DeInit (GPIO_TypeDef * GPIOx, uint32_t GPIO_Pin)
    功能描述 复位引脚到初始状态
    入口参数1 GPIOx:引脚端口号,取值范围是GPIOA~GPIOK
    入口参数2 GPIO_Init:指向引脚初始化类型GPIO_InitTypeDef的结构体指针,该结构体包含指定引脚的配置参数
    返回值
    注意事项 该函数需要用户调用
  3. 读取引脚函数:HAL_GPIO_ReadPin

    函数原型 GPIO_PinState HAL_GPIO_ReadPin ( GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin )
    功能描述 读取引脚的电平状态
    入口参数1 GPIOx:引脚端口号,取值范围是GPIOA~GPIOK
    入口参数2 GPIO_Init:指向引脚初始化类型GPIO_InitTypeDef的结构体指针,该结构体包含指定引脚的配置参数
    返回值 GPIO_PinState:表示引脚电平状态的枚举类型变量,可以是
    GPIO_PIN_SET或GPIO_PIN_RESET
    注意事项 该函数需要用户调用
  4. 写入引脚函数:HAL_GPIO_WritePin

    函数原型 void HAL_GPIO_WritePin( GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState )
    功能描述 设置引脚输出高/低电平
    入口参数1 GPIOx:引脚端口号,取值范围是GPIOA~GPIOK
    入口参数2 GPIO_Init:指向引脚初始化类型GPIO_InitTypeDef的结构体指针,该结构体包含指定引脚的配置参数
    返回值 GPIO_PinState:表示引脚电平状态的枚举类型变量,可以是
    GPIO_PIN_SET或GPIO_PIN_RESET
    注意事项 该函数需要用户调用
  5. 翻转引脚函数:HAL_GPIO_TogglePin

    函数原型 void HAL_GPIO_TogglePin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)
    功能描述 翻转引脚状态
    入口参数1 GPIOx:引脚端口号,取值范围是GPIOA~GPIOK
    入口参数2 GPIO_Init:指向引脚初始化类型GPIO_InitTypeDef的结构体指针,该结构体包含指定引脚的配置参数
    返回值
    注意事项 该函数需要用户调用

任务实践

采用查询方式检测按键状态,按键按下后执行操作:翻转指示灯LD2的状态。

按键消抖:

通用输入输出接口_第5张图片

  • 前沿抖动5~10ms,后沿抖动5~10ms

  • 按键的抖动会导致一次按键动作被当成多次按键,为确保MCU对按键的一次闭合仅作一次处理,必须消除按键的抖动,在按键处于稳定状态时读取按键的状态。按键的状态机编程实现:

  • 硬件消抖:利用RC低通滤波器滤掉抖动

    通用输入输出接口_第6张图片

  • 软件消抖:

    1. 检测出按键闭合后执行延时程序,延时时间为5ms~10ms,用于去掉前沿抖动;
    2. 再次检测按键状态,如果保持闭合状态,才认为按下,并执行相应的按键任务;
    3. 按键的释放可以采用延时或者循环检测的方式去掉后沿抖动。
  1. 配置PA0为GPIO_Input,PA1为GPIO_Output

    通用输入输出接口_第7张图片

  2. PA1保持默认GPIO输出模式即可

    通用输入输出接口_第8张图片

  3. PA0配置为输入模式,上拉

    通用输入输出接口_第9张图片

以上步骤生成如下代码:

stm32f1xx_hal_gpio.c中生成GPIO引脚初始化函数MX_GPIO_Init,并在main.c中调用

  • 开启外设时钟RCC
  • 配置PA0,PA1两个引脚结构
void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);

  /*Configure GPIO pin : PA0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : PA1 */
  GPIO_InitStruct.Pin = GPIO_PIN_1;
  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);
}
  1. 编写程序

main.c中编写程序

	/* USER CODE BEGIN 3 */
    if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
    {
      HAL_Delay(10);
      if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
      {
        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_1);
      }
      while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET);
    } 
  }
  /* USER CODE END 3 */

你可能感兴趣的:(单片机,stm32,嵌入式硬件)