GPIO基本概念

GPIO(General Purpose Input Output)通用输入输出端口,是STM32与外部世界交互的基本接口。

GPIO主要功能

  • 输入模式:读取外部信号(按键、传感器)

  • 输出模式:控制外部设备(LED、继电器)

  • 复用功能:UART、SPI、I2C等外设

  • 模拟功能:ADC输入


GPIO结构框图

复制代码
        ┌─────────────────────────────────┐
        │           GPIO                  │
        │                                 │
输入 ───┤  ┌───┐    ┌────┐    ┌────┐    ├───► 输入数据寄存器
        │  │保护│───►│上拉│───►│施密│    │     (IDR)
        │  │二极│    │下拉│    │特触│    │
        │  │管  │    │电阻│    │发器│    │
        │  └───┘    └────┘    └────┘    │
        │                                 │
输出 ───┤  ┌────┐    ┌────┐    ┌────┐    │
        │  │输出│───►│推挽│───►│I/O │────┼───► 引脚
控制 ───┤  │数据│    │/开 │    │引脚│    │
        │  │寄存│    │漏  │    │    │    │
        │  │器  │    │    │    │    │    │
        │  └────┘    └────┘    └────┘    │
        │                                 │
        └─────────────────────────────────┘

GPIO工作模式

8种工作模式

模式 说明 典型应用
浮空输入 无上下拉 外部按键
上拉输入 内部上拉电阻 按键检测
下拉输入 内部下拉电阻 按键检测
模拟输入 ADC输入 电压采集
开漏输出 无驱动能力,需外接上拉 I2C通信
开漏复用 复用功能开漏 I2C SDA
推挽输出 有驱动能力 LED控制
推挽复用 复用功能推挽 UART TX

输出类型

推挽输出

  • 可以输出高电平(VDD)和低电平(VSS)

  • 驱动能力强

  • 适用于LED、继电器等

开漏输出

  • 只能输出低电平或高阻态

  • 需要外接上拉电阻

  • 适用于I2C、电平转换


GPIO配置步骤

使用HAL库配置

复制代码
/* 1. 开启GPIO时钟 */
__HAL_RCC_GPIOC_CLK_ENABLE();
​
/* 2. 配置GPIO参数 */
GPIO_InitTypeDef GPIO_InitStruct = {0};
​
GPIO_InitStruct.Pin = GPIO_PIN_13;           // 引脚号
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  // 推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL;          // 无上下拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 输出速度
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
​
/* 3. 控制GPIO输出 */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);    // 高电平
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);  // 低电平
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);                 // 翻转

使用CubeMX配置

  1. 选择引脚

    • 在芯片引脚图上点击要使用的引脚

    • 选择GPIO_Output或GPIO_Input

  2. 配置参数

    • GPIO mode:输出模式

    • GPIO Pull-up/Pull-down:上下拉

    • Maximum output speed:输出速度

    • User Label:用户标签

  3. 生成代码

    • 点击Generate Code

    • 在main.c中查看初始化代码


实例1:LED控制

硬件连接

复制代码
STM32 PC13 ─── LED ─── 330Ω ─── GND

代码实现

复制代码
/* main.c */
​
#include "main.h"
​
#define LED_PIN GPIO_PIN_13
#define LED_PORT GPIOC
​
/* LED初始化 */
void LED_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
​
    /* 开启GPIOC时钟 */
    __HAL_RCC_GPIOC_CLK_ENABLE();
​
    /* 配置LED引脚 */
    GPIO_InitStruct.Pin = LED_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
​
    /* 默认熄灭 */
    HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_SET);
}
​
/* LED控制函数 */
void LED_On(void)
{
    HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_RESET);
}
​
void LED_Off(void)
{
    HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_SET);
}
​
void LED_Toggle(void)
{
    HAL_GPIO_TogglePin(LED_PORT, LED_PIN);
}
​
int main(void)
{
    HAL_Init();
    SystemClock_Config();
    LED_Init();
​
    while (1)
    {
        LED_Toggle();
        HAL_Delay(500);
    }
}

实例2:按键检测

硬件连接

复制代码
方法1:外部下拉
STM32 PA0 ─── 按键 ─── 3.3V
        │
       10kΩ
        │
       GND
​
方法2:内部上拉(推荐)
STM32 PA0 ─── 按键 ─── GND
(使用内部上拉电阻)

代码实现

复制代码
/* main.c */
​
#include "main.h"
​
#define KEY_PIN GPIO_PIN_0
#define KEY_PORT GPIOA
#define LED_PIN GPIO_PIN_13
#define LED_PORT GPIOC
​
/* 按键初始化 */
void KEY_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
​
    /* 开启GPIOA时钟 */
    __HAL_RCC_GPIOA_CLK_ENABLE();
​
    /* 配置按键引脚 - 上拉输入 */
    GPIO_InitStruct.Pin = KEY_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;  /* 内部上拉 */
    HAL_GPIO_Init(KEY_PORT, &GPIO_InitStruct);
}
​
/* 按键扫描(带消抖) */
uint8_t KEY_Scan(void)
{
    static uint8_t key_flag = 0;  /* 按键按下标志 */
​
    /* 检测按键按下(低电平有效) */
    if (HAL_GPIO_ReadPin(KEY_PORT, KEY_PIN) == GPIO_PIN_RESET)
    {
        HAL_Delay(10);  /* 消抖延时 */
​
        if (HAL_GPIO_ReadPin(KEY_PORT, KEY_PIN) == GPIO_PIN_RESET)
        {
            if (key_flag == 0)
            {
                key_flag = 1;
                return 1;  /* 返回按键按下 */
            }
        }
    }
    else
    {
        key_flag = 0;  /* 按键释放 */
    }
​
    return 0;  /* 无按键按下 */
}
​
int main(void)
{
    HAL_Init();
    SystemClock_Config();
    LED_Init();
    KEY_Init();
​
    while (1)
    {
        if (KEY_Scan())
        {
            LED_Toggle();  /* 按键按下,LED翻转 */
        }
    }
}

按键消抖原理

复制代码
按键按下时的抖动波形:
    ┌──┐  ┌┐ ┌─┐
────┘  └──┘└─┘ └────
    ↑
  抖动区域(5-20ms)
​
解决方法:
1. 硬件消抖:RC滤波电路
2. 软件消抖:延时检测

实例3:多位LED控制

硬件连接

复制代码
STM32 PC0-PC7 ─── 8个LED ─── 330Ω ─── GND

代码实现

复制代码
/* 流水灯效果 */
void LED_Flow(void)
{
    uint8_t i;
​
    for (i = 0; i < 8; i++)
    {
        /* 清除所有LED */
        GPIOC->ODR &= 0xFF00;
​
        /* 点亮当前LED */
        GPIOC->ODR |= (1 << i);
​
        HAL_Delay(200);
    }
}
​
/* 跑马灯效果 */
void LED_HorseRace(void)
{
    static uint8_t pos = 0;
​
    GPIOC->ODR &= 0xFF00;
    GPIOC->ODR |= (1 << pos);
​
    pos = (pos + 1) % 8;
​
    HAL_Delay(100);
}

GPIO寄存器详解

主要寄存器

寄存器 名称 功能
CRL 配置寄存器低 配置PIN0-PIN7
CRH 配置寄存器高 配置PIN8-PIN15
IDR 输入数据寄存器 读取输入状态
ODR 输出数据寄存器 设置输出状态
BSRR 置位/复位寄存器 快速设置/清除
BRR 复位寄存器 快速清除

直接操作寄存器

复制代码
/* 设置PA5为高电平 */
GPIOA->BSRR = GPIO_PIN_5;
​
/* 设置PA5为低电平 */
GPIOA->BRR = GPIO_PIN_5;
/* 或 */
GPIOA->BSRR = (uint32_t)GPIO_PIN_5 << 16;
​
/* 读取PA5状态 */
if (GPIOA->IDR & GPIO_PIN_5)
{
    /* PA5为高电平 */
}

练习题

  1. 实现一个按键控制两个LED的程序:

    • 短按:LED1翻转

    • 长按(>2s):LED2翻转

  2. 使用4个LED实现二进制计数器(0-15)

  3. 实现呼吸灯效果(使用延时模拟PWM)

  4. 设计一个简单的密码锁:

    • 使用4个按键输入密码

    • 正确密码点亮LED

相关推荐
LCG元2 小时前
STM32 USB CDC 虚拟串口开发实战:从 CubeMX 配置到 printf 重定向与稳定收发
stm32·单片机·嵌入式硬件
zcmodeltech2 小时前
源网荷储一体化沙盘模型多场景控制系统设计——基于STM32与Modbus RTU的源网荷储、多能互补、冷热电三联供全场景联动方案,服务范围覆盖全国
数据库·人工智能·stm32·单片机·嵌入式硬件
威嵌神州3 小时前
军工加固计算机七大核心特性解析|国产化、宽温、强加固工程实现
嵌入式硬件·计算机网络·fpga开发
Brilliantwxx3 小时前
【STM32】 深度详解总线架构 哈佛总线结构
stm32·嵌入式硬件·架构
恶魔泡泡糖3 小时前
stm32F103C8T6标准库DWT应用DHT11温湿度传感器数据手册说明
stm32·单片机·嵌入式硬件
深圳市恒锐丰科技杨生3 小时前
EG1192S 10‑100V 高压集成上管降压 DC‑DC|零功耗使能 Buck 电源芯片
嵌入式硬件·硬件工程
单片机仿真设计3 小时前
【Proteus 仿真】基于 STM32 单片机鸡舍环境监控系统设计(仿真 + 源码)
stm32·单片机·嵌入式硬件·proteus·毕设
李永奉4 小时前
中科蓝讯SDK开发-提示音音频文件格式转换和压缩教程
网络·单片机·嵌入式硬件·mcu·物联网
春风解人意5 小时前
从零开始学习嵌入式P35----数据库
数据库·嵌入式硬件·学习