你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32C5教程】(3)GPIO 按键输入实验

[复制链接]
HuangXF 发布时间:2026-10-21 08:53

1. 项目简介

1.1 实验目标

本实验在 NUCLEO-C542RC 开发板上,通过主循环轮询用户按键 B1(PC13),实现按键控制板载 LED 状态翻转,掌握 STM32C5 系列 GPIO 输入与输出的基本用法。

功能需求:

  • 在主循环中轮询用户按键(PC13)
  • 每次有效按下时切换板载 LED(PA5)的状态
  • 持续按住不重复触发,松开后可响应下一次按键
  • 消抖时间 20 ms

<br>

1.2 实验条件

硬件:

  • NUCLEO-C542RC 开发板
  • 支持数据传输的 USB Type-C 线(用于连接 ST-LINK 接口)

软件:

  • STM32CubeMX2(用于引脚、时钟配置与代码生成)
  • VS Code + STM32Cube 插件(用于编译、烧录、调试)

<br>

2. 硬件说明

2.1 NUCLEO-C542RC 开发板

NUCLEO-C542RC 是 ST 基于 STM32C542RCT6 推出的 Nucleo-64 开发板。主要特性:

  • MCU:STM32C542RCT6,Arm Cortex-M33 内核,最高主频 144 MHz,256 KB Flash,64 KB RAM
  • 调试器:板载 STLINK-V3EC,支持大容量存储、虚拟串口和调试端口三种功能
  • 用户 LED:LD1,连接 PA5
  • 用户按键:B1,连接 PC13
  • 复位按键:B2
  • 扩展接口:Arduino Uno V3 和 ST morpho 连接器

本实验使用板载的 LD1 和 B1,无需额外外设。

image.png

<br>

2.2 引脚说明

引脚 别名 功能 方向 有效电平
PA5 LD1 板载用户 LED GPIO 输出 高电平点亮
PC13 B1 用户按键 GPIO 输入 按下为高电平,松开为低电平

PA5(LD1):配置为推挽输出,输出高电平时 LED 点亮,输出低电平时 LED 熄灭。复位后初始状态为低电平(LED 熄灭)。

PC13(B1):配置为输入模式。PC13 通过外部电阻 R13(10K)下拉到地,按键按下时接 3V3。因此空闲时为低电平,按下时为高电平。

<br>

3. STM32CubeMX2 工程配置

3.1 新建工程

本实验采用 MCU 方式创建工程,即以芯片型号 STM32C542RC 为起点,而非开发板方式。

image.png

  1. 进入 MCU 选择界面 启动 STM32CubeMX2,在首页点击 MCU,进入芯片型号选择列表。
  2. 搜索并选中芯片 在 MCU name 输入框中输入 STM32C542RC(或完整型号 STM32C542RCT6),从筛选出的列表中选择对应型号。
  3. 填写项目信息 输入项目名称 GPIO_Button 和项目保存路径。项目名称避免使用特殊字符,路径建议使用纯英文目录。

<br>

3.2 基础配置

工程创建后,软件自动进入 Pinout 视图。时钟配置保持默认即可:CubeMX2 创建工程后的默认系统主频为 48 MHz,时钟源为 HSI 分频,本实验无需修改。

注意:本工程的系统时钟为 48 MHz,与之前点灯实验(144 MHz)不同。这是 CubeMX2 的默认配置,不影响 GPIO 功能,HAL_Delay() 仍可正常工作。

<br>

3.3 GPIO 配置(PA5 输出)

image.png

  1. 在 Pinout 视图中找到 PA5 引脚。根据 UM3615 手册,向 PA5 写入高逻辑电平(“1”)即可点亮 LD1。
  2. 右键点击 PA5,选择 Assign signal → GPIO,把引脚的功能分配给 GPIO 模块。
  3. 再次右键点击 PA5,选择 Configure GPIO,进入 GPIO 详细配置界面。
  4. 将 PA5 的 Mode 设置为 Output。
  5. 保持默认参数:Output level 为 Low,Output mode 为 Push Pull,Pull-up/Pull-down 为 No pull-up and no pull-down,Maximum output speed 为 Low。
  6. 在 PA5 的配置项中找到 User Label(用户标签)输入框,填入 LD1。

设置别名后,CubeMX2 生成的代码中会自动创建对应的宏定义,例如 LD1_GPIO_Port 和 LD1_Pin,后续在 main.c 中可以直接使用这两个宏来操作 LED,无需再手动记忆 GPIOA 和 GPIO_PIN_5。

<br>

3.4 GPIO 配置(PC13 输入)

image.png

image.png

  1. 在 Pinout 视图中找到 PC13 引脚。
  2. 右键点击 PC13,选择 Assign signal → GPIO。
  3. 再次右键点击 PC13,选择 Configure GPIO,进入 GPIO 详细配置界面。
  4. 将 PC13 的 Mode 设置为 Input。
  5. 保持默认参数:Pull-up/Pull-down 为 No pull-up and no pull-down。
  6. 在 User Label 输入框中填入 B1。

本实验采用轮询方式,不启用外部中断,因此不需要勾选 EXTI 相关选项。

<br>

3.5 项目配置

  1. 点击 Project Settings,进入工程设置页面。
  2. 在 IDE Format 下拉选项中选择 CMake。
  3. 在 CMake Toolchain 下拉选项中选择 GCC。
  4. 确认配置无误后,点击 Generate Code。CubeMX2 会执行配置检查,如果没有错误,开始在指定路径下生成 CMake 工程文件。
  5. 生成完成后,项目路径下会出现标准 CMake 工程结构,包含 Core/、Drivers/、CMakeLists.txt 等。

<br>

4. 编程实现

4.1 实现思路

采用 “检测 → 消抖 → 二次确认 → 翻转 → 等待松开” 的轮询方案:

主循环
    │
    └─ 读取 PC13 电平
          │
          ├─ 非按下(低电平)→ 继续轮询
          │
          └─ 按下(高电平)
                ├─ HAL_Delay(20ms) 消抖
                ├─ 二次确认仍为按下?
                │      └─ 否 → 视为抖动,忽略
                ├─ 是 → 有效按下 → 翻转 PA5 状态
                └─ 阻塞等待松开(读到高电平)后才回到轮询

各步骤使用的 HAL 函数:

步骤 HAL 函数 作用
读取按键 HAL_GPIO_ReadPin(B1_PORT, B1_PIN) 读取 PC13 电平
消抖延时 HAL_Delay(DEBOUNCE_TIME_MS) 延时 20 ms
翻转 LED HAL_GPIO_TogglePin(LD1_PORT, LD1_PIN) 切换 PA5 输出电平

<br>

4.2 关键代码

在 VS Code 中打开生成的 CMake 工程,找到 main.c,添加以下代码。

image.png

(1)文件头部添加宏定义

/* Private define ------------------------------------------------------------*/
#define DEBOUNCE_TIME_MS    20u                 /* 按键消抖时间 */
#define B1_PRESSED_STATE    HAL_GPIO_PIN_SET    /* 按下时 B1(PC13) 为高电平 */

(2)声明按键扫描函数

/* Private functions prototype -----------------------------------------------*/
static void Button_Scan(void);

(3)主函数

int main(void)
{
  if (mx_system_init() != SYSTEM_OK)
  {
    return (-1);
  }
  else
  {
    while (1)
    {
      Button_Scan();
    }
  }
}

(4)按键扫描函数

/**
  * brief:  Poll user button B1 (PC13) and toggle onboard LED LD1 (PA5) on each
  *         valid press. Debounces the press, and waits for the release so that
  *         holding the button down does not re-trigger.
  * retval: none
  */
static void Button_Scan(void)
{
  if (HAL_GPIO_ReadPin(B1_PORT, B1_PIN) == B1_PRESSED_STATE)
  {
    /* A press is detected, confirm it after the debounce time */
    HAL_Delay(DEBOUNCE_TIME_MS);
    if (HAL_GPIO_ReadPin(B1_PORT, B1_PIN) == B1_PRESSED_STATE)
    {
      /* Valid press: toggle the onboard LED */
      HAL_GPIO_TogglePin(LD1_PORT, LD1_PIN);

      /* Wait for the release before scanning again */
      while (HAL_GPIO_ReadPin(B1_PORT, B1_PIN) == B1_PRESSED_STATE)
      {
      }
    }
  }
}

代码说明:

  • B1_PORT、B1_PIN、LD1_PORT、LD1_PIN 四个宏由 CubeMX2 生成在 generated/hal/mx_gpio_default.h,通过 main.h 链入,在 main.c 中可直接使用。
  • 第 1 步检测到高电平后,第 2 步延时 20 ms 消抖,第 3 步再次确认。两次都为低电平才判定为有效按下。
  • 第 4 步翻转 LED 状态。
  • 第 5 步的 while 空循环阻塞等待按键松开,这是实现“按住不重复触发”的关键。松开后回到外层,可响应下一次按下。

<br>

5. 编译烧录与运行测试

5.1 编译与烧录

  1. 打开工程:用 VS Code 打开 CubeMX2 生成的 CMake 工程文件夹(如 GPIO_Button_cmake)。
  2. 编译:点击 VS Code 底部状态栏的 Build 按钮,或使用命令面板执行 CMake 构建。编译完成后,终端应输出 Build finished with exit code 0,无 error。
  3. 连接开发板:用支持数据传输的 USB Type-C 线连接 NUCLEO-C542RC 的 ST-LINK USB 口(CN1)。
  4. 确认设备识别:打开设备管理器,在“端口 (COM 和 LPT)”下应能看到 STLink COMx。
  5. 烧录:点击 VS Code 中的 运行按钮,将固件下载到开发板。

image.png

image.png

5.2 运行与测试

烧录完成后,程序自动开始运行。依次验证以下功能:

  1. 初始状态 复位开发板(按下黑色复位按键 B2),观察 LD1。复位后 LD1 应保持熄灭状态,说明 GPIO 初始化正确。
  2. 按键响应 按下蓝色用户按键 B1,观察 LD1 是否翻转。如果当前 LED 熄灭,按下后应点亮;再次按下,LED 应熄灭。反复测试几次,确认每次按下都能可靠触发翻转。
  3. 按住不重复 按住 B1 不放,观察 LD1。LED 应该只翻转一次,持续按住期间不会再翻转。
  4. 松开可再响应 松开 B1 后再次按下,LD1 应能再次翻转,说明等待松开的逻辑正常。
  5. 消抖验证 快速连续按下 B1 多次,观察 LED 响应。如果消抖正常,每次按下只触发一次翻转,不会因按键机械抖动产生多次翻转。

测试结果:

  • [X] 按一下 B1,LD1 翻转一次
  • [X] 持续按住 B1,LD1 只翻转一次,不重复触发
  • [X] 松开后再次按下,LD1 再次翻转
  • [X] 快速连按无明显误触发,20 ms 消抖生效

功能正常。

<br>

6. 小结

本实验通过轮询方式实现了按键控制 LED 状态翻转,掌握了 STM32C5 GPIO 输入与输出的基本配置和使用方法。

核心逻辑可以概括为:“检测 → 消抖 → 二次确认 → 翻转 → 等待松开”。其中“等待松开”这一步是保证按住不重复触发、松开可再响应的关键,不可缺少。

需要注意的是,本方案采用阻塞式轮询:HAL_Delay(20) 消抖和等待松开的空循环都会占用主循环,期间无法执行其他任务。对于功能简单的应用这是可接受的;如果系统还有其他实时任务,建议改用外部中断方式或非阻塞状态机。下一篇将介绍用外部中断实现同样的按键控制功能。

<br>

版权声明:

Copyright by [email]ai4mcu@qq.com[/email] 2026 Crated:2026-10

image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
赞 收藏 评论0 发布时间:2026-10-21 08:53

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版