STM32 LED 闪烁实验(点灯 & 流水灯)
STM32 最基础的实验之一就是 点亮 LED,即控制 GPIO 引脚高低电平来点亮或熄灭 LED。这里将介绍 单灯闪烁 和 流水灯 实验,包括 使用 STM32CubeMX 配置 GPIO,并在 Keil/STM32CubeIDE 中编写代码。
1. 实验硬件
开发板:常见 STM32 开发板(如 STM32F103C8T6、STM32F407)
LED 连接方式:
- 共阴 LED:LED 负极接 GND,正极接 GPIO,输出高电平点亮
- 共阳 LED:LED 正极接 VCC,负极接 GPIO,输出低电平点亮
例如:STM32F103C8T6 开发板的 PC13 通常连接 LED。
2. 使用 STM32CubeMX 配置 GPIO
2.1 新建 STM32 工程
- 打开 STM32CubeMX,选择 目标芯片/开发板(如 STM32F103C8T6)
- 进入 Pinout & Configuration,找到 GPIO 配置
2.2 配置 LED 引脚
- 选择 PC13(或其他 LED 连接的 GPIO)
- 设置 GPIO Mode 为 Output Push-Pull(推挽输出)
- 设置 GPIO Speed 为 Low / Medium / High(可根据实际情况选择)
2.3 配置时钟
- 进入 Clock Configuration 选项卡
- 设置 HSE(外部晶振)8MHz,系统主频 72MHz(F1)或 168MHz(F4)
2.4 生成代码
- 进入 Project Manager
- 设置工程名称(如
LED_Test
) - 选择开发工具(Keil / STM32CubeIDE / IAR)
- 点击 Generate Code,STM32CubeMX 自动生成 GPIO 初始化代码
3. 代码编写
STM32CubeMX 生成的 MX_GPIO_Init()
会自动初始化 LED 引脚,接下来我们只需编写 LED 控制逻辑。
3.1 LED 闪烁(点灯实验)
📌 基础版(HAL 库)
main.c
#include "main.h"
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void) {
HAL_Init(); // 初始化 HAL 库
SystemClock_Config(); // 配置系统时钟
MX_GPIO_Init(); // 初始化 GPIO
while (1) {
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); // 翻转 LED 状态
HAL_Delay(500); // 延时 500ms
}
}
解释:
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13)
:翻转 GPIO 状态,实现 LED 闪烁HAL_Delay(500)
:延时 500ms,使 LED 以 1Hz 频率闪烁
3.2 LED 流水灯
流水灯需要 多个 LED,通常连接到 GPIOA、GPIOB 或 GPIOC 端口。
📌 多个 LED 流水灯(HAL 库)
main.c
#include "main.h"
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1) {
for (uint16_t i = 0x0001; i <= 0x0008; i <<= 1) {
GPIOA->ODR = i; // 输出到 GPIOA
HAL_Delay(200); // 200ms 延时
}
}
}
解释:
GPIOA->ODR = i;
直接控制 GPIOA 输出,实现流水灯效果i <<= 1
让 LED 依次点亮,形成流动效果
📌 如果使用 HAL 库操作 GPIO,而不是直接修改寄存器,可以这样写:
for (int i = 0; i < 8; i++) {
HAL_GPIO_WritePin(GPIOA, (1 << i), GPIO_PIN_SET); // 点亮 LED
HAL_Delay(200);
HAL_GPIO_WritePin(GPIOA, (1 << i), GPIO_PIN_RESET); // 熄灭 LED
}
4. 使用 FreeRTOS 实现 LED 多任务
如果要同时控制多个 LED,可以使用 FreeRTOS 创建多任务。
📌 FreeRTOS 版本
led_task.c
#include "cmsis_os.h"
void LED_Task1(void *argument) {
while (1) {
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
osDelay(500);
}
}
void LED_Task2(void *argument) {
while (1) {
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
osDelay(200);
}
}
解释:
osDelay(500)
让任务 1 以 500ms 频率闪烁 LEDosDelay(200)
让任务 2 以 200ms 频率闪烁 LED
📌 需在 main.c
里创建任务
osThreadNew(LED_Task1, NULL, NULL);
osThreadNew(LED_Task2, NULL, NULL);
5. 代码下载 & 运行
5.1 使用 Keil 进行代码烧录
- 编写代码后,点击 Build(F7)
- 选择 Download(Ctrl+F8),代码将烧录到 STM32
- 选择 Debug(F5),进入在线调试模式
5.2 使用 STM32CubeIDE 进行代码烧录
- 点击 Build(Ctrl+B) 编译代码
- 选择 Debug > Run,代码将烧录到 STM32
- 进入 Debug 模式,可使用 断点、变量监测、单步执行
6. 结论
✅ LED 点灯是 STM32 开发的第一步,掌握 GPIO 操作是关键
✅ STM32CubeMX 生成 GPIO 初始化代码,可减少手写代码
✅ 流水灯需要使用多个 GPIO,同时控制多个 LED
✅ 可以结合 FreeRTOS 任务,实现多线程 LED 控制
📌 建议新手从 LED 点灯开始,再学习按键输入、中断、串口等功能! 🚀