【STM32】基础知识 第十二课 GPIO
- 概述
- GPIO 简介
- GPIO 模式
- GPIO 特点
- GPIO 配置
- GPIO 操作
- 施密特触发器
- 案例
概述
本文小白我将来介绍通用输入与输出, GPIO (General-Purpose Input/Output) 在单片机中的应用, 以及如何配合和食用 GPIO 来实现各种功能.
GPIO 简介
GPIO 是单片机中常见的一种接口, 允许开发者通过软件配置将其用做数字输入, 数字输出或特定功能的引脚. GPIO 的灵活性使其称为现实各种功能的理想选择, 如 LED 控制, 按键输入, 传感器接口等.
GPIO 模式
GPIO 引脚通常支持以下模式:
- 数字输入: 在此模式下, GPIO 引脚用作数字输入, 可检测外部信号高电平或低电平
- 数字输出: 在此模式下, GPIO 引脚用作数字输出, 可将内部信号输出为高电平或低电平
- 特定功能: 许多微控制器将特定功能与 GPIO 引脚相关联, 比如 SPI, I2C, UART 等. 在此模式下, GPIO 引脚用于实现特定功能相关的信号传输
GPIO 特点
- 简单性: GPIO 接口相对简单, 只涉及数字高电平和低电平的信号. 这使得 GPIO 成为实现基本硬件接口的理想选择, 例如控制 LED, 读取开关状态等
- 灵活性: GPIO 引脚鱼油很高的灵活性, 因为它们可以通过软件配置为输入或输出模式. 此外, 许多单片机允许将 GPIO 引脚重新分配为特定功能. 如 I2C, SPI 或 UART
- 数字信号: GPIO 仅处理数字信号, 这意味着它们可以表示两个状态: 高电平和低电平. 这使得 GPIO 非常适合处理简单的数字硬件接口, 但不适合模拟信号
- 低速接口: 与其他高速接口 (如 PCIe, USB 等)相比, GPIO 通常用于低速, 短距离通信. 这是因为 GPIO 接口的信号传输速率受限于单片机的时钟频率和信号传输特性
- 低功耗: GPIO 接口通常拥有较低的功耗, 使其称为低功耗应用的理想选择. 在低速通信和简单接口中, GPIO 的功耗通常远低于其他高速接口
- 可配置性: 许多单片机提供了丰富的 GPIO 配置选项, 如内部上拉/下拉电阻, 输出类型 (推挽/开漏), 输出速度等. 这些选项允许开发者根据应用需求优化 GPIO 性能和功耗
- 易于实现中断: GPIO 可以很容易地实现中断功能, 当检测到特定条件 (如电平变化, 上升沿或下降沿) 时触发中断. 这使得 GPIO 成为实现外部事件响应的理想选择, 例如按键按下或传感器信号变化
GPIO 配置
在使用 GPIO 之前, 需要对其进行正确的配置. 常见的配置参数包括:
- 模式: 设置 GPIO 引脚为输入, 输出或特定功能模式
- 输出培新: 设置 GPIO 输出类型, 如推挽 (Push-pull) 或开漏 (Open-drain)
- 上拉/下拉: 为 GPIO 引脚配置内部上拉或下拉电阻, 以确保引脚在未连接外部信号时具有稳定的电平状态
- 速度: 设置 GPIO 引脚的输出速度, 以平衡速度和功耗之间的关系
GPIO 操作
在配置完成后, 可以使用以下方法操作 GPIO 引脚:
- 读取输入: 使用单片机提供的 API 或寄存器操作来读取 GPIO 引脚的当前输入状态 (高电平或低电平)
- 设置输出: 使用 API 或寄存器操作将 GPIO 引脚设置为高电平或低电平
- 翻转输出: 切换 GPIO 引脚的输出状态, 从高电平变为低电平, 或从低电平变为高电平, 或从低电平变为高电平
施密特触发器
施密特触发器 (Schmitt Trigger) 是一种具有滞回特性的电子比较器. 施密特触发器常用将模拟信号转换为数字信号, 消除信号噪声和抖动, 确保数字电路的稳定运行.
施密特触发器的基本原理是在输入信号的上升沿和下降沿分别设置不同的触发阈值. 当输入信号上升到上阈值时, 输出信号变为高电平; 当输入信号下降到下阈值时, 输出信号变为低电平. 这两个阈值之间的区间称为滞回区间. 施密特触发器可以将非标准方形波, 整形成方波.
案例
使用 STM32CubeMX 配置 GPIO 引脚. 将一个引脚配置为数字输出, 用于驱动 LED, 将另一个引脚配置为数字输入, 用于读取按键状态. 同时, 为输入引脚[位置内部上拉电阻.
代码:
#include "stm32f1xx_hal.h"
/* 定义按键输入引脚和LED输出引脚 */
#define BUTTON_PIN GPIO_PIN_0
#define BUTTON_PORT GPIOA
#define LED_PIN GPIO_PIN_1
#define LED_PORT GPIOA
int main(void)
{
/* 初始化HAL库和系统时钟 */
HAL_Init();
SystemClock_Config();
/* 初始化GPIO */
MX_GPIO_Init();
while (1)
{
/* 读取按键状态 */
GPIO_PinState button_state = HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN);
/* 如果按键按下,点亮LED;否则熄灭LED */
if (button_state == GPIO_PIN_RESET) // 按键按下时引脚为低电平
{
HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_RESET);
}
}
}