STM32 基于HAL库的LED流水灯
STM32 基于HAL库的LED流水灯
一、STM32CubeMX安装
(1)如果未安装 Java 环境,直接安装STM32CubeMX将会出现报错;

1.1下载Java
Java 官网下载
下载地址: https://www.java.com/zh_CN/download/windows-64bit.jsp(尽量安装最新版 64 位的Java)
下载方法:打开官网下载地址,点击 同意并开始免费下载;

(1)打开 jre-8u261-windows-x64.exe 安装包,勾选更改目标文件夹,点击 安装;
(2)选择合适的安装目录,点击 下一步;
(3)等待自动安装;
(4)安装完毕,点击 关闭;

1.2CubeMX 官网下载
1.下载地址: 官网下载地址 --> https://www.st.com/stm32cubemx
下载方法:打开官网下载地址,点击 获取软件;

2.选择对应的版本进行下载。(需要登陆账号,其中 Linux 和 MacOS 的配置文件和 Windows 安装包在同一个文件中)


云盘下载
下载地址:https://pan.baidu.com/s/1-7z6Q0Mlscaw8yiCZzfkug(提取码:5eby)
下载方法:直接下载。(云盘收录了 STM32Cube 系列软件)
1.3CubeMX 安装
1.安装 Java 后,打开 SetupSTM32CubeMX-6.0.0.exe 文件,其他系统安装参考 Readme.html,点击 Next;
2.勾选 I accpt,点击 Next;
3.勾选第一个,点击 Next;
4.选择合适的安装路径,点击 Next;(若路径未创建,会提示路径将被创建);

5.根据需求勾选,点击 Next;

6程序自动安装,安装完成后,点击 Next;
7提示安装成功和一个卸载程序被创建在安装目录的 Uninstaller 文件夹中,点击 Done;

8打开 STM32CubeMX 软件;
9软件界面如下;

二、CubeMX项目创建
1.打开安装好的STMCubeMX
2.点击HLP->Manage embedded software
3.会跳出来一个选择型号界面 勾选上你要安装的HAL库, 点击“Install Now” 直到安装成功。 如下图:
4回到STMCubeMX的主界面,创建新项目:(选择ACCESS TO MCU SELECTOR)
5.点击system core,进入SYS,在debug下选择serial wire:

6.配置时钟,进入上面的rcc,有两个时钟,一个是hse和lse,我们要用是GPIO接口,而这些接口都在APB2里:

7接下来观察时钟架构,APB2总线的时钟由hse控制,同时在这个界面得把PLLCLK右边选上:

8.将hse那里设为Crystal/Ceramic Resonator:
9.接下来就是点击相应的引脚设置输出寄存器了,就是output那一项,一共选了三个,是PA0 PA1 PA3 开关接PA15

10.点击project manager,配置好自己的路径和项目名,然后IDE那项改为MDK-ARM进入 code generate界面,选择生成初始化.c/.h文件,后面点击generate code,选择open project:
11.打开.uvprojx文件(或者在上一步选择open project)
三、项目代码
STM32 LED控制程序功能分块说明
1. 头文件包含和宏定义部分
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"
功能说明:
- 包含必要的头文件
main.h:包含HAL库核心头文件和项目配置gpio.h:包含GPIO外设的初始化函数声明
2. 全局变量定义部分
/* USER CODE BEGIN PV */
uint8_t led_mode = 0; // 0:流水灯模式, 1:全亮模式, 2:全灭模式
uint8_t current_led = 0; // 当前亮的LED索引
/* USER CODE END PV */
功能说明:
- led_mode:控制程序工作模式的状态变量
- 0 = 流水灯模式(LED依次点亮)
- 1 = 全亮模式(所有LED同时亮)
- 2 = 全灭模式(所有LED同时灭)
- current_led:记录流水灯模式下当前点亮的LED序号
3. 函数声明部分
/* USER CODE BEGIN PFP */
void LED_Flow_Mode(void); // 流水灯模式控制函数
void LED_All_On(void); // 全亮模式控制函数
void LED_All_Off(void); // 全灭模式控制函数
void Check_Switch(void); // 开关检测函数
/* USER CODE END PFP */
功能说明:
- 声明所有自定义函数,便于编译器识别
- 这些函数在主函数之前声明,确保调用时已被识别
4. 主函数初始化部分
/* USER CODE BEGIN 2 */
/* 初始状态:所有LED熄灭 */
LED_All_Off();
/* USER CODE END 2 */
功能说明:
- 系统初始化完成后执行的代码
- 设置LED初始状态为全灭
- 确保程序启动时所有LED处于可控状态
5. 主循环部分
/* USER CODE BEGIN WHILE */
while (1)
{
/* 检测开关状态 */
Check_Switch();
/* 根据模式执行相应的LED控制 */
switch(led_mode)
{
case 0: // 流水灯模式
LED_Flow_Mode();
break;
case 1: // 全亮模式
LED_All_On();
HAL_Delay(100); // 短延时,减少CPU占用
break;
case 2: // 全灭模式
LED_All_Off();
HAL_Delay(100); // 短延时,减少CPU占用
break;
default:
led_mode = 0;
break;
}
/* USER CODE END WHILE */
功能说明:
- 无限循环:程序的主要执行部分
- 模式检测:每次循环都检查开关状态
- 模式切换:根据led_mode值执行不同的LED控制模式
- 延时优化:在全亮/全灭模式中使用短延时减少CPU占用率
6. 开关检测函数
void Check_Switch(void)
{
static uint32_t last_press_time = 0;
static uint8_t last_switch_state = 1; // 默认上拉为高电平
uint8_t current_switch_state = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_15);
// 检测下降沿(开关按下)
if(last_switch_state == 1 && current_switch_state == 0)
{
// 简单的按键消抖,检测时间间隔
if(HAL_GetTick() - last_press_time > 200) // 200ms消抖
{
led_mode = (led_mode + 1) % 3; // 循环切换模式:0→1→2→0
last_press_time = HAL_GetTick();
}
}
last_switch_state = current_switch_state;
}
功能说明:
- 状态检测:读取PA15引脚的电平状态
- 边沿检测:检测开关从高电平到低电平的跳变(按下动作)
- 按键消抖:通过时间间隔判断,防止机械开关抖动导致的误触发
- 模式切换:每次有效按键将led_mode循环递增(0→1→2→0)
7. 流水灯模式函数
void LED_Flow_Mode(void)
{
static uint32_t last_change_time = 0;
// 每1秒切换一次LED
if(HAL_GetTick() - last_change_time >= 1000)
{
// 熄灭所有LED
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // PA0高电平,LED1灭
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); // PA1高电平,LED2灭
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); // PA3高电平,LED3灭
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); // PC13高电平,板载LED灭
// 根据当前索引点亮对应的LED
switch(current_led)
{
case 0: // LED1亮
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
break;
case 1: // LED2亮
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
break;
case 2: // LED3亮
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
break;
case 3: // 板载LED亮
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
break;
}
// 更新LED索引
current_led = (current_led + 1) % 4;
last_change_time = HAL_GetTick();
}
}
功能说明:
- 定时控制:使用系统滴答定时器实现1秒间隔
- 循环点亮:按顺序依次点亮PA0→PA1→PA3→PC13
- 状态保持:每个LED点亮1秒后切换到下一个
- 索引管理:current_led变量记录当前点亮位置,循环0-3
8. 全亮模式函数
void LED_All_On(void)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // PA0低电平,LED1亮
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); // PA1低电平,LED2亮
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); // PA3低电平,LED3亮
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); // PC13低电平,板载LED亮
}
功能说明:
- 同时点亮:将所有LED引脚设置为低电平
- 简单控制:无定时逻辑,持续保持全亮状态
9. 全灭模式函数
void LED_All_Off(void)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // PA0高电平,LED1灭
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); // PA1高电平,LED2灭
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); // PA3高电平,LED3灭
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); // PC13高电平,板载LED灭
}
功能说明:
- 同时熄灭:将所有LED引脚设置为高电平
- 初始状态:也用作程序的初始状态设置
程序工作流程总结
- 启动初始化 → 所有LED熄灭
- 主循环检测 → 持续检测开关状态
- 模式切换 → 按键触发模式循环切换
- LED控制 → 根据当前模式执行相应显示效果
- 状态保持 → 直到下一次按键改变模式
这个程序实现了完整的LED控制功能,通过物理开关可以在三种显示模式间切换,展示了STM32 HAL库的基本GPIO操作和状态机编程思想。
四、实践结果
mmexport1760022977844
proteus仿真
1.配置供电网

2.添加HEX文件
3.仿真图
STM32 LED控制实验总结与心得
实验总结
标题完成的功能
- ✅ 控制4个LED灯(3个外接+1个板载)
- ✅ 实现3种显示模式:流水灯、全亮、全灭-
- ✅ 通过按键切换模式-
- ✅ 用三种不同方法编程实现
-
技术要点
-
- GPIO配置 - 输出控制LED,输入检测按键
-
- 时钟使能 - 使用外设前必须先开启时钟
-
- 按键消抖 - 200ms延时防止误触发
-
- 状态管理 - 用变量记录当前模式和LED状态
学习心得
- 编程方法的演进
- 寄存器方式 → 理解了硬件底层工作原理,知道每个配置位的含义标准库方式 → 学会了使用官方库函数,代码更规范
- HAL库方式 → 掌握了现代嵌入式开发流程,
- 效率最高
遇到的困难与解决
链接错误:
因为启动文件缺失,学会检查项目结构- 按键抖动:通过软件消抖解决,理解了实际工程问题-
模式切换:用状态机思想设计,代码更清晰### 3. 实践收获- 从理论到实践的跨越:看手册→写代码→调试→成功运行- 理解了"点亮LED"是嵌入式开发的"Hello World"- 学会了使用STM32CubeMX提高开发效率- 掌握了Keil MDK的基本调试方法### 4. 工程思维培养- 代码要分层:硬件操作与业务逻辑分离- 考虑可靠性:按键消抖、异常处理- 注重可维护性:添加注释、模块化设计## 未来展望这个实验是STM32学习的起点,后续可以:- 加入中断处理- 使用定时器精确控制- 添加通信功能(UART、I2C等)- 移植到RTOS实现多任务
最大的体会:嵌入式开发既要懂硬件原理,又要会软件设计,只有亲手实践才能真正掌握。从最初的寄存器配置到最后的HAL库应用,每一步都是成长!
感谢友情链接
https://blog.csdn.net/Brendon_Tan/article/details/107685563
https://blog.csdn.net/weixin_56102526/article/details/120877293
https://blog.csdn.net/weixin_46129506/article/details/120780184
https://blog.csdn.net/LX567567/article/details/133994620
更多推荐



所有评论(0)