1. 项目简介
1.1 实验目标
本实验在 NUCLEO-C542RC 开发板上,使用 STM32C542RCT6 的 TIM6 基本定时器产生周期中断,在中断回调中翻转板载 LED(PA5)状态,实现 LED 每 500 ms 切换一次,掌握 STM32C5 系列定时器周期中断的配置与使用方法。
功能需求:
- 使用 TIM6 产生周期中断,不使用软件延时
- 每次更新事件触发一次中断(每 500 ms)
- 在中断回调中翻转 LD1(PA5),LED 每 500 ms 切换一次
开发板和 MCU 型号: NUCLEO-C542RC 开发板,搭载 STM32C542RCT6 MCU。
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,无需额外外设。
<br>
2.2 引脚说明
| 引脚 |
别名 |
功能 |
方向 |
有效电平 |
| PA5 |
LD1 |
板载用户 LED |
GPIO 输出 |
高电平点亮 |
PA5(LD1):配置为推挽输出,输出高电平时 LED 点亮,输出低电平时 LED 熄灭。复位后初始状态为低电平(LED 熄灭)。
<br>
3. STM32CubeMX2 工程配置
3.1 新建工程
本实验采用 MCU 方式创建工程,即以芯片型号 STM32C542RC 为起点,而非开发板方式。
- 进入 MCU 选择界面
启动 STM32CubeMX2,在首页点击 MCU,进入芯片型号选择列表。
- 搜索并选中芯片
在 MCU name 输入框中输入 STM32C542RC(或完整型号 STM32C542RCT6),从筛选出的列表中选择对应型号。
- 填写项目信息
输入项目名称 TIM_IT_500ms 和项目保存路径。项目名称避免使用特殊字符,路径建议使用纯英文目录。

3.2 基础配置
工程创建后,软件自动进入 Pinout 视图。
时钟配置:本工程系统时钟配置为 144 MHz,APB1 分频系数为 1,TIM6 输入时钟为 144 MHz。

<br>
3.3 GPIO 配置(PA5 输出)
- 在 Pinout 视图中找到 PA5 引脚。
- 右键点击 PA5,选择 Assign signal → GPIO。
- 再次右键点击 PA5,选择 Configure GPIO,进入 GPIO 详细配置界面。
- 将 PA5 的 Mode 设置为 Output。
- 保持默认参数:Output level 为 Low,Output mode 为 Push Pull,Pull-up/Pull-down 为 No pull-up and no pull-down,Maximum output speed 为 Low。
- 在 User Label 输入框中填入 LD1。
设置别名后,CubeMX2 会自动生成宏定义
LD1_PORT 和 LD1_PIN。
<br>
3.4 TIM6 配置
(1)启用 TIM6
在左侧外设列表中找到 Timers → TIM6,点击展开,将 Clock Source 设置为 Internal Clock(内部时钟)。
(2)配置定时参数
在 TIM6 的 Parameter Settings 中设置:
| 参数 |
值 |
说明 |
| Prescaler (PSC) |
14399 |
144 MHz ÷ 14400 = 10 kHz |
| Counter Mode |
Up |
向上计数 |
| Counter Period (ARR) |
4999 |
10 kHz ÷ 5000 = 2 Hz |
| auto-reload preload |
Enable |
建议启用自动重装载预装载 |


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

4. 编程实现
4.1 实现思路
采用 “TIM6 周期中断 + 回调中翻转 LED” 的方案:
TIM6 计数到 ARR(4999)溢出
│
▼ 置位更新标志 UIF
触发 TIM6 全局中断(NVIC)
│
▼
TIM6_IRQHandler() // CubeMX 生成,无需修改
│
▼
HAL_TIM_IRQHandler() // 清中断标志
│
▼
HAL_TIM_UpdateCallback() // 用户重写的回调
│
▼
HAL_GPIO_TogglePin() // 翻转 LD1
与软件延时的区别:使用 HAL_Delay() 延时会让 CPU 空转等待,期间无法响应其他事件;使用 TIM6 硬件定时中断,定时精度由硬件保证,CPU 不阻塞。
必须手动启动定时器:CubeMX2 生成的初始化代码只配置了 TIM6 的寄存器,不会自动启动定时器和使能中断。必须在 main() 中调用 HAL_TIM_Start_IT() 才能真正开始周期性中断。
各步骤使用的 HAL 函数:
| 步骤 |
HAL 函数 |
作用 |
| 启动定时器中断 |
HAL_TIM_Start_IT() |
使能更新中断并启动计数 |
| 获取 TIM6 句柄 |
mx_tim6_gethandle() |
返回 CubeMX 生成的 TIM6 句柄 |
| 翻转 LED |
HAL_GPIO_TogglePin(LD1_PORT, LD1_PIN) |
切换 PA5 输出电平 |
<br>
4.2 关键代码
在 VS Code 中打开生成的 CMake 工程,找到 Core/Src/main.c,添加以下代码。
(1)主函数
int main(void)
{
if (mx_system_init() != SYSTEM_OK)
{
return (-1);
}
else
{
/*
* Start the periodic interrupt generation of TIM6.
* TIM6 is configured to generate an update event every 500 ms,
* the LD1 (PA5) LED is toggled in the HAL_TIM_UpdateCallback().
*/
if (HAL_TIM_Start_IT(mx_tim6_gethandle()) != HAL_OK)
{
return (-1);
}
while (1) {}
}
}
(2)TIM6 更新中断回调函数
/**
* brief: TIM6 update interrupt callback (period elapsed).
* Called by the HAL in IRQ context each time TIM6 reaches its period
* (every 500 ms). Toggle the on-board LED LD1 on PA5.
* param: htim Pointer to the TIM handle.
*/
void HAL_TIM_UpdateCallback(hal_tim_handle_t *htim)
{
HAL_GPIO_TogglePin(LD1_PORT, LD1_PIN);
}
代码说明:
- LD1_PORT、LD1_PIN 两个宏由 CubeMX2 生成在 generated/hal/mx_gpio_default.h,通过main.h 链入,在 main.c 中可直接使用。
- mx_tim6_gethandle() 返回 CubeMX2 生成的 TIM6 句柄。
- HAL_TIM_Start_IT() 启动 TIM6 并使能更新中断。这一步必须手动调用,否则定时器不会开始计数,中断永远不会产生。
- HAL_TIM_UpdateCallback() 是 HAL 库中已经声明好的回调入口,HAL 库中有一个空的默认实现。用户在自己的源文件中重写这个同名函数,中断发生时 HAL 就会自动调用它,无需修改驱动源码。
- 回调在中断上下文中执行,应保持简短。这里只有一条翻转语句,非常合适。
- 参数 htim 在本实验中没有使用,保留它是为了与回调签名一致。
<br>
5. 编译烧录与运行测试
5.1 编译与烧录
- 打开工程:用 VS Code 打开 CubeMX2 生成的 CMake 工程文件夹(如 TIM_IT_500ms_cmake)。
- 编译:点击 VS Code 底部状态栏的 Build 按钮,或使用命令面板执行 CMake 构建。编译完成后,终端应输出
Build finished with exit code 0,无 error。
- 连接开发板:用支持数据传输的 USB Type-C 线连接 NUCLEO-C542RC 的 ST-LINK USB 口(CN1)。
- 确认设备识别:打开设备管理器,在“端口 (COM 和 LPT)”下应能看到 STLink COMx。
- 烧录:点击 VS Code 中的运行按钮,将固件下载到开发板。


5.2 运行与测试
烧录完成后,程序自动开始运行。观察板载 LED LD1 的闪烁情况:
- 测试 1:初始状态
复位开发板(按下黑色复位按键 B2),观察 LD1。复位后程序开始运行,TIM6 立即启动,LD1 开始以 500 ms 间隔翻转。
- 测试 2:闪烁周期
观察 LD1 的闪烁节奏:亮 500 ms → 灭 500 ms → 亮 500 ms → ……
闪烁周期为 1 秒(亮灭各 500 ms)。可用手机秒表计时核对。
测试结果:
☑ 编译通过,无错误
☑ 烧录成功
☑ 上电后 LD1 每 500 ms 翻转一次,闪烁周期为 1 s
☑ 闪烁间隔均匀、稳定
功能正常。
<br>
6. 小结
本实验通过 TIM6 定时器周期中断实现了板载 LED 的周期性闪烁,掌握了 STM32C5 系列定时器中断的配置与使用方法。
核心逻辑可以概括为:“TIM6 硬件计数 → 溢出产生更新中断 → 回调翻转 LED”。
有两点需要注意:
- 第一,定时器中断必须手动启动。 CubeMX2 生成的初始化代码只完成寄存器配置,不会自动开始计数。必须在 main() 中调用 HAL_TIM_Start_IT(),中断才会周期性产生。
- 第二,中断回调应保持简短。 回调在中断上下文中执行,耗时操作会影响系统响应其他中断。本实验只有一条翻转语句,非常合适。
如果需要改变闪烁周期,只需在 CubeMX2 中修改 TIM6 的 Prescaler 和 Counter Period,重新生成代码即可,main.c 无需改动。
<br>
版权声明:
Copyright by [email]ai4mcu@qq.com[/email] 2026
Crated:2026-10