> 技术文档 > 超详细 STM32 呼吸灯教程:从 0 到 1 实现 LED 亮度渐变(含完整代码 + 调试指南)_stm32 rbg 灯呼吸

超详细 STM32 呼吸灯教程:从 0 到 1 实现 LED 亮度渐变(含完整代码 + 调试指南)_stm32 rbg 灯呼吸


一、为什么学呼吸灯?—— 用生活现象理解专业概念

想象一下:黑暗中一盏 LED 像呼吸一样,从暗到亮再到暗,循环往复。这种效果的核心是PWM(脉冲宽度调制)技术—— 通过快速开关 LED,调节 “亮” 和 “灭” 的时间比例,人眼就会感知到不同的亮度(就像用闪光灯快速闪烁,闪得越久越亮)。

本教程用最通俗的语言 + 完整代码,带你用 STM32 实现这个效果。即使你是嵌入式新手,也能一步步跟下来!

二、准备工作:硬件 + 软件清单

2.1 硬件清单(总价<50 元)

名称 型号 / 规格 作用说明 备注 STM32 开发板 STM32F103C8T6(最小系统板) 核心控制器,输出 PWM 信号 性价比最高的入门款,淘宝约 25 元 LED 模块 单色 LED+220Ω 电阻 实现亮度变化 普通红色 LED 即可,电阻防烧灯 ST-Link 调试器 ST-Link/V2 下载程序到开发板 淘宝约 10 元,部分开发板自带 杜邦线 + 面包板 公对母杜邦线 连接开发板与 LED 面包板可选,直接接线也行

2.2 软件环境(傻瓜式安装)

  • STM32CubeIDE:ST 官方集成开发环境(含代码编辑、编译、调试功能),点击下载(选 Windows 版本)。
  • CH340 驱动:如果开发板用 USB 转串口,需安装 CH340 驱动(淘宝买开发板一般会送驱动包)。

2.3 硬件连接

按下图连接开发板与 LED:

plaintext:

开发板引脚 → LED模块 PA6(TIM3_CH1) → LED正极(长脚) GND(地) → LED负极(短脚)→ 220Ω电阻 → 开发板3.3V 

注意:LED 长脚是正极(阳极),短脚是负极(阴极);电阻必须串联,否则会烧 LED!

三、软件配置:用 CubeMX 图形化配置(新手友好)

STM32CubeMX 是 ST 官方的图形化配置工具,能自动生成初始化代码。我们用它配置定时器和 PWM,避免手动写寄存器代码!

3.1 新建项目(5 步完成)

  1. 打开 STM32CubeMX → 点击 “New Project” → 搜索芯片型号(如STM32F103C8Tx) → 点击 “Start Project”。
  2. 配置系统时钟:
    • 左侧选 “RCC” → 右侧 “High Speed Clock (HSE)” 选 “Crystal/Ceramic Resonator”(外部晶振)。
    • 顶部切到 “Clock Configuration” → 输入72(系统时钟设为 72MHz),CubeMX 会自动计算分频参数(无需手动改)。
  3. 配置定时器 TIM3(输出 PWM):
    • 左侧选 “TIM3” → 右侧 “Mode” 栏,“Channel 1” 选 “PWM Generation CH1”(PWM 输出通道 1)。
    • 下方 “Parameter Settings” 配置:
      • Prescaler(预分频):71(72MHz / (71+1) = 1MHz → 定时器计数频率 1MHz)。
      • Counter Period(自动重装载值):999(计数到 999 后归零,周期 = 1MHz / 1000 = 1ms → PWM 频率 1kHz)。
      • 其他参数默认即可。
  4. 配置 GPIO 引脚(PA6):
    • 回到 “Pinout” 界面,找到 PA6 引脚(标有 “TIM3_CH1”) → 确认引脚模式为 “Alternate Function Push Pull”(复用推挽输出)。
  5. 生成代码:
    • 顶部选 “Project Manager” → 填写项目名(如BreathingLED)、路径 → 工具链选 “STM32CubeIDE”。
    • 点击 “Generate Code” → 弹出窗口选 “Open Project”(自动用 CubeIDE 打开项目)。

四、核心代码:逐行注释 + 逻辑讲解

CubeMX 生成的代码已包含定时器和 GPIO 的初始化,我们只需在main.c中添加呼吸灯逻辑。

4.1 完整代码(可直接复制)

#include \"main.h\" // 包含所有外设的头文件/* 定义全局变量 */TIM_HandleTypeDef htim3; // 定时器3的句柄(CubeMX自动生成)/* 主函数:程序入口 */int main(void) { HAL_Init(); // 初始化HAL库(必须) SystemClock_Config(); // 配置系统时钟(CubeMX自动生成) MX_TIM3_Init(); // 初始化定时器3(CubeMX自动生成,含PWM配置) /* 启动PWM输出(关键!不启动则无信号) */ HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // 启动TIM3通道1的PWM输出 /* 呼吸灯主循环 */ while (1) { /* 阶段1:LED渐亮(占空比从0%到100%) */ for (uint16_t duty = 0; duty  0; duty--) { // duty从999递减到1(避免duty=0时重复) __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, duty); // 设置PWM占空比 HAL_Delay(2); // 延时2ms,控制渐变速度 } }}/* 以下代码由CubeMX自动生成,无需修改(仅展示关键部分) */void MX_TIM3_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; htim3.Instance = TIM3; // 选择定时器3 htim3.Init.Prescaler = 71; // 预分频值(71+1=72分频,计数频率=72MHz/72=1MHz) htim3.Init.CounterMode = TIM_COUNTERMODE_UP; // 向上计数模式(从0增加到999) htim3.Init.Period = 999; // 自动重装载值(计数到999后归零,周期=1MHz/1000=1ms) htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; // 时钟分频(无分频) HAL_TIM_Base_Init(&htim3); // 初始化定时器基础参数 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; // 内部时钟源 HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig); // 配置时钟源 HAL_TIM_PWM_Init(&htim3); // 初始化PWM功能 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; // 主触发输出(无需修改) sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; // 主从模式(禁用) HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig); // 配置主从同步 sConfigOC.OCMode = TIM_OCMODE_PWM1; // PWM模式1(当计数值<占空比时输出高电平) sConfigOC.Pulse = 0; // 初始占空比(0%) sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; // 输出极性(高电平有效) sConfigOC.OCFastMode = TIM_OCFASTMODE_DISABLE; // 快速模式(禁用) HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1); // 配置PWM通道1}

4.2 代码关键注释

  • HAL_TIM_PWM_Start:启动 PWM 输出,必须调用,否则定时器不会输出信号。
  • __HAL_TIM_SET_COMPARE:设置 PWM 占空比(参数duty范围 0~999,对应占空比 0%~100%)。
  • HAL_Delay(2):延时函数控制渐变速度(数值越大,亮度变化越慢)。
  • 定时器参数计算
    • 计数频率 = 系统时钟 / (预分频 + 1) = 72MHz / (71+1) = 1MHz。
    • PWM 周期 = 1 / 计数频率 × (自动重装载值 + 1) = 1MHz⁻¹ × 1000 = 1ms → PWM 频率 1kHz(人眼无法感知闪烁)。
       

五、编译 + 下载 + 调试

5.1 编译程序

在 CubeIDE 中,点击顶部 “Build” 按钮(图标是锤子),等待编译完成(输出 “0 errors” 即成功)。

5.2 下载程序到开发板

  1. 用 ST-Link 连接开发板(ST-Link 的 SWDIO 接开发板 SWDIO,SWCLK 接 SWCLK,GND 接 GND,3.3V 接 3.3V)。
  2. 开发板插电(用 USB 线连接电脑)。
  3. 在 CubeIDE 中,点击顶部 “Debug” 按钮(图标是虫子),程序会自动下载到开发板并启动。

 

5.3 常见问题与解决

问题现象 可能原因 解决方法 LED 不亮 1. 硬件连接错误
2. PWM 未启动 1. 检查 LED 正负极、电阻是否串联
2. 确认代码中调用了HAL_TIM_PWM_Start LED 闪烁(不渐变) 延时时间过短(HAL_Delay数值太小) 增大延时(如改为HAL_Delay(5)) 程序下载失败 1. ST-Link 连接松动
2. 驱动未安装 1. 重新插拔 ST-Link 线
2. 安装 ST-Link 驱动(下载地址、下载不了可自行搜索)

六、扩展玩法:让呼吸灯更有趣!

掌握基础后,试试这些进阶操作:

6.1 非线性渐变

用正弦函数生成占空比,模拟真实呼吸的 “先慢后快”:

for (int i = 0; i < 360; i++) { // 角度从0°到360° float radian = i * 3.1416 / 180; // 角度转弧度 uint16_t duty = 500 * (1 - cos(radian)); // 正弦函数生成占空比(0~1000) __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, duty); HAL_Delay(5);}

 

6.2 多 LED 同步渐变

用定时器的多个通道控制多个 LED(如 PA6 和 PA7),实现 “呼吸灯矩阵”:

// 在CubeMX中配置TIM3的Channel 2(对应PA7)为PWM输出 HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // 启动通道1(PA6)HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); // 启动通道2(PA7)// 同步设置两个通道的占空比 __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, duty); __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, duty); 

 

七、总结:从呼吸灯到万物控制

通过这个项目,你不仅学会了用 STM32 实现呼吸灯,更掌握了PWM 技术的核心—— 用数字信号控制模拟量(亮度、电机转速等)。后续可以尝试:

  • 结合光敏电阻(ADC 采集)实现 “自动调光呼吸灯”;
  • 用 RGB LED + 三路 PWM 实现 “色彩渐变呼吸灯”;
  • 控制直流电机(用 PWM 调节转速)。

嵌入式的魅力,就在于用简单的代码驱动物理世界!