STM32GPIO超全面知识点总结(含代码实例)

什么是 GPIO

GPIO 是通用输入输出端口(General-purpose input/output)的英文简写,是所有的微控制器必不可少的外设之一,可以由 STM32 直接驱动从而实现与外部设备通信、控制以及采集和捕获的功能。

STM32 单片机的 GPIO 被分为很多组,每组有 16 个引脚,不同型号的 MCU 的 GPIO 个数是不同的,比如 STM32F103C8T6 只有 PA、PB 以及个别 PC 引脚而 STM32F103ZET6 拥有 PA~PG 的全部 112 个引脚。

所有的 GPIO 都有基本的输入输出功能,同时 GPIO 还可以作为其它的外设功能引脚。

GPIO 的工作原理

GPIO 的工作原理可以用下图来表示1

![GPIO 的工作原理]

从图中可以看出,GPIO 的硬件结构包括以下几个部分:

  • I/O 引脚:就是 STM32 芯片引出的 GPIO 引脚,其它的部件都位于芯片内部。
  • 保护二极管:为了防止芯片被外部过高或者过低的输入电压烧坏,STM32 内置保护二极管,当引脚输入电压高于 VDD-FT(FT 标识代表可以容忍 5V 电压,不同的引脚对电压的容忍值不同,需要在芯片数据手册上查找)时上方的二极管导通,当引脚电压低于 Vss 时,下方的二极管导通,这样就可以防止不正常的电压引入芯片导致芯片烧毁。
  • 上下拉电阻:STM32 的 GPIO 引脚可以配置为上拉或下拉输入模式,这时会启用内部的上下拉电阻,用来提供默认的输入电平,避免浮空状态。
  • 施密特触发器:STM32 的 GPIO 引脚都有施密特触发器,用来消除输入信号的抖动,提高输入信号的稳定性。
  • 输入数据寄存器:STM32 的 GPIO 引脚的输入电平会被保存在输入数据寄存器中,可以通过读取该寄存器来获取引脚的输入状态。
  • 输出控制电路:STM32 的 GPIO 引脚的输出电平由输出控制电路来决定,输出控制电路包括 P-MOS 管和 N-MOS 管,根据不同的输出模式,可以输出强高电平、强低电平或高阻态。
  • 输出数据寄存器:STM32 的 GPIO 引脚的输出电平可以通过写入输出数据寄存器来设置,也可以通过读取该寄存器来获取引脚的输出状态。
  • 复用功能:STM32 的 GPIO 引脚除了可以作为通用的输入输出端口外,还可以复用为一些外设的功能引脚,比如串口、SPI、I2C、ADC、DAC 等,这时需要配置相应的复用功能寄存器。

GPIO 的工作模式

STM32 的 GPIO 共有 8 种工作模式,分别是输入模式的模拟输入、上拉输入、下拉输入和浮空输入以及输出模式的推挽输出、开漏输出、推挽复用输出和开漏复用输出。为了便于理解,使用结构框图来详细讲解每一种模式:

浮空输入模式

![浮空输入模式]

GPIO 作为输入功能的浮空输入时,电信号是由外部流向内部的,从结构图的右侧往左侧看,信号流经顺序是 I/O 端口——施密特触发器——输入数据寄存器——读取。

浮空输入模式的特点是没有内部的上下拉电阻,因此当引脚没有连接外部电路时,其输入电平是不确定的,可能会受到干扰而产生抖动。因此,浮空输入模式一般用于连接外部的上下拉电阻或者按键电路,通过电平的高低变化来识别外部的信号。

上拉输入模式

![上拉输入模式]

上拉输入和浮空输入的区别就是在 I/O 端口和施密特触发器之间多了一个上拉电阻,这样 GPIO 在没有连接外部部件时的默认电平是高电平,其它流程和原来一样。

上拉输入模式的特点是有内部的上拉电阻,因此当引脚没有连接外部电路时,其输入电平是确定的,不会受到干扰而产生抖动。因此,上拉输入模式一般用于连接外部的开关或者传感器,通过电平的高低变化来识别外部的信号。

下拉输入模式

![下拉输入模式]

下拉输入和浮空输入的区别就是在 I/O 端口和施密特触发器之间多了一个下拉电阻,这样 GPIO 在没有连接外部部件时的默认电平是低电平,其它流程和原来一样。

下拉输入模式的特点是有内部的下拉电阻,因此当引脚没有连接外部电路时,其输入电平是确定的,不会受到干扰而产生抖动。因此,下拉输入模式一般用于连接外部的开关或者传感器,通过电平的高低变化来识别外部的信号。

模拟输入模式

![模拟输入模式]

模拟输入模式和其它三种输入模式不同,它的外部电平信号没有流入输入数据寄存器,而是直接流入模拟输入部分。

模拟输入模式的特点是可以接收连续变化的电压信号,而不是只能识别高低电平。因此,模拟输入模式一般用于连接外部的模拟信号源,比如电位器、温度传感器等,通过 ADC 模块来读取和转换模拟信号的数值。

推挽输出模式

![推挽输出模式]

推挽输出模式和开漏输出模式有一定的区别,其控制输出的寄存器是一样的,但是输出控制电路输出 1 的时候,P-MOS 管导通,N-MOS 管截止,这样 I/O 口电平就会被 P-MOS 管拉高,输出强高电平;相反,当输出控制电路输出 0 时,P-MOS 管截止,N-MOS 管导通,I/O 端口电平被 N-MOS 管拉低,输出强低电平。

推挽输出模式的特点是可以输出强高低电平(高电平为 3.3V),一般用来连接数字器件,比如 LED 灯、比如数码管、蜂鸣器等,通过输出电平的高低来控制外部设备的状态。

开漏输出模式

![开漏输出模式]

开漏输出模式和推挽输出模式的区别就是输出控制电路输出 1 的时候,P-MOS 管和 N-MOS 管都截止,这样 I/O 口电平就会处于高阻态,输出高阻态;相反,当输出控制电路输出 0 时,P-MOS 管截止,N-MOS 管导通,I/O 端口电平被 N-MOS 管拉低,输出强低电平。

开漏输出模式的特点是只能输出强低电平(低电平为 0V),不能输出高电平,因此需要外接上拉电阻来提供高电平。一般用来连接模拟器件,比如 I2C 总线、温湿度传感器等,通过输出高阻态和低电平来控制外部设备的状态。

推挽复用输出模式

![推挽复用输出模式]

推挽复用输出模式和推挽输出模式的区别就是在输出控制电路和输出数据寄存器之间多了一个复用功能部分,这样 GPIO 不仅可以作为通用的输出端口,还可以作为一些外设的功能引脚,比如串口、SPI、ADC、DAC 等,这时需要配置相应的复用功能寄存器。

推挽复用输出模式的特点是可以输出强高低电平(高电平为 3.3V),一般用来连接数字器件,比如串口、SPI、ADC、DAC 等,通过输出电平的高低来传输数据或者控制外部设备的状态。

开漏复用输出模式

![开漏复用输出模式]

开漏复用输出模式和开漏输出模式的区别就是在输出控制电路和输出数据寄存器之间多了一个复用功能部分,这样 GPIO 不仅可以作为通用的输出端口,还可以作为一些外设的功能引脚,比如 I2C、PWM 等,这时需要配置相应的复用功能寄存器。

开漏复用输出模式的特点是只能输出强低电平(低电平为 0V),不能输出高电平,因此需要外接上拉电阻来提供高电平。一般用来连接模拟器件,比如 I2C、PWM 等,通过输出高阻态和低电平来传输数据或者控制外部设备的状态。

GPIO 的配置方法

STM32 的 GPIO 的配置方法主要有两种,一种是使用 STM32CubeMX 工具来生成初始化代码,另一种是使用寄存器操作来手动配置。下面分别介绍这两种方法的步骤和示例。

使用 STM32CubeMX 工具

STM32CubeMX 是 ST 官方提供的一款图形化配置工具,可以帮助用户快速生成 STM32 的初始化代码,包括 GPIO 的配置。使用 STM32CubeMX 工具的步骤如下:

  • 打开 STM32CubeMX 工具,选择 File -> New Project,然后选择目标芯片,比如 STM32F103C8T6。
  • 在 Pinout & Configuration 界面,可以看到芯片的引脚分布图,点击想要配置的 GPIO 引脚,比如 PA0,然后在右侧的 GPIO 配置栏中,选择想要的 GPIO 模式,比如 Analog,然后点击 Apply。
  • 重复上一步,配置其它需要的 GPIO 引脚,比如 PA1,选择 GPIO_Output,然后点击 Apply。
  • 点击 Project -> Generate Code,选择想要的工程类型,比如 Keil,然后点击 OK,等待代码生成完成。
  • 打开生成的工程,可以看到 GPIO 的初始化代码在 main.c 文件的 MX_GPIO_Init 函数中,如下所示:
/* GPIO init function */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_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_ANALOG;
  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);
}

从代码中可以看出,使用 STM32CubeMX 工具配置 GPIO 的优点是简单方便,不需要了解寄存器的细节,只需要选择想要的 GPIO 模式即可。但是缺点是生成的代码比较冗余,占用了一定的内存空间,而且不利于深入理解 GPIO 的工作原理。

使用寄存器操作

使用寄存器操作来配置 GPIO 的方法是直接对 GPIO 相关的寄存器进行读写,这种方法需要了解 GPIO 的寄存器结构和功能,比较复杂,但是可以实现更灵活的配置,而且代码更加精简,占用的内存空间更小,而且有利于深入理解 GPIO 的工作原理。

STM32 的 GPIO 相关的寄存器有以下几个:

  • GPIOx_CRL 和 GPIOx_CRH:这两个寄存器用来配置 GPIO 引脚的模式和速度,每个引脚占用 4 个位,其中 GPIOx_CRL 配置低 8 位引脚,GPIOx_CRH 配置高 8 位引脚。每个引脚的配置位由两个部分组成,分别是 MODE 和 CNF,如下图所示:

![GPIOx_CRL 和 GPIOx_CRH]

MODE 位用来配置 GPIO 引脚的工作模式,有以下四种取值:

MODE[1:0]模式
00输入模式
01输出模式,最大速度 10MHz
10输出模式,最大速度 2MHz
11输出模式,最大速度 50MHz

CNF 位用来配置 GPIO 引脚的输出类型或者输入类型,有以下四种取值:

CNF[1:0]输入模式输出模式
00模拟输入推挽输出
01浮空输入开漏输出
10上拉输入或下拉输入推挽复用输出
11保留开漏复用输出
  • GPIOx_IDR:这个寄存器用来读取 GPIO 引脚的输入数据,每个引脚占用 1 个位,其中 GPIOx_IDR[0] 对应低 0 位引脚,GPIOx_IDR[15] 对应高 15 位引脚。每个引脚的数据位的含义如下:
GPIOx_IDR[n]含义
0引脚输入低电平
1引脚输入高电平
  • GPIOx_ODR:这个寄存器用来读写 GPIO 引脚的输出数据,每个引脚占用 1 个位,其中 GPIOx_ODR[0] 对应低0 位引脚,GPIOx_ODR[15] 对应高 15 位引脚。每个引脚的数据位的含义如下:
    GPIOx_ODR[n]含义
    0引脚输出低电平
    1引脚输出高电平
  • GPIOx_BSRR:这个寄存器用来设置或者清除 GPIO 引脚的输出数据,每个引脚占用 2 个位,其中 GPIOx_BSRR[0:15] 对应低 0 位引脚到高 15 位引脚的置位操作,GPIOx_BSRR[16:31] 对应低 0 位引脚到高 15 位引脚的复位操作。每个引脚的数据位的含义如下:
  • GPIOx_BSRR[n]含义
    0无操作
    1引脚置位或复位

    使用寄存器操作来配置 GPIO 的示例代码如下:     

  • /* GPIO init function */
    static void MX_GPIO_Init(void)
    {
      /* GPIO Ports Clock Enable */
      RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // 使能 GPIOA 时钟
    
      /*Configure GPIO pin : PA0 */
      GPIOA->CRL &= ~(0xF << 0); // 清除 PA0 的配置位
      GPIOA->CRL |= (0x0 << 0); // 配置 PA0 为模拟输入模式
    
      /*Configure GPIO pin : PA1 */
      GPIOA->CRL &= ~(0xF << 4); // 清除 PA1 的配置位
      GPIOA->CRL |= (0x3 << 4); // 配置 PA1 为推挽输出模式,最大速度 50MHz
    }
    {
      GPIOA->BSRR = (1 << 1); // 置位 PA1 引脚,输出高电平,点亮 LED 灯
    }
    else // 如果 ADC 值小于等于 2048,即输入电压小于等于 1.65V
    {
      GPIOA->BSRR = (1 << 17); // 复位 PA1 引脚,输出低电平,熄灭 LED 灯
    }
    

从代码中可以看出,使用寄存器操作来配置和使用 GPIO 的优点是代码更加精简,占用的内存空间更小,而且有利于深入理解 GPIO 的工作原理。但是缺点是比较复杂,需要了解寄存器的结构和功能,而且不易于移植。

总结

本文介绍了 STM32 的 GPIO 的基本概念、工作原理、工作模式、配置方法和使用示例,希望对你有所帮助。GPIO 是 STM32 最基本也最常用的外设之一,掌握 GPIO 的使用方法,可以为后续的学习打下坚实的基础。

 

  • 24
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值