PWM实现LED灯闪烁
·
STM32 用 PWM 做 1s / 0.5s 闪烁 + 开关控制(最详细教程)
我直接给你标准、可直接复制、稳定运行的方案,用 STM32CubeMX + HAL库(最常用),不用复杂寄存器,新手也能直接用。
核心结论(先记牢)
- 1秒闪一次:PWM 频率 = 1Hz,占空比 50%
- 0.5秒闪一次:PWM 频率 = 2Hz,占空比 50%
- 用 定时器 PWM 输出 实现,CPU 完全不参与,硬件自动闪
- 可以随时开关 PWM,控制灯亮/灭/闪烁
一、硬件选择
- 任意 STM32(F103/F407/F030 等通用)
- LED 正极 → 电阻 → 定时器 PWM 通道引脚
- LED 负极 → GND
- 例:TIM2_CH1 → PA0(最常用,你也可以换其他定时器通道)
二、STM32CubeMX 配置(一步一步)
1. 选择定时器
比如用 TIM2
- Clock Source 选择 Internal Clock
- Channel 1 选择:PWM Generation CH1
2. 关键参数(决定闪烁频率)
目标:产生 1Hz / 2Hz 的超低频 PWM
STM32 定时器公式:
PWM频率 = 定时器时钟 / [(PSC+1) * (ARR+1)]
① 实现 1Hz 闪烁(1秒一次)
- PSC = 7199
- ARR = 9999
- 频率 = 72M / (7200 * 10000) = 1Hz
② 实现 0.5Hz 闪烁(0.5秒一次)
- PSC = 7199
- ARR = 4999
- 频率 = 72M / (7200 * 5000) = 2Hz
3. 占空比
- CCR1 = ARR / 2 → 50% 占空比(亮50%、灭50%)
4. 生成代码
选择 MDK-ARM 生成工程即可。
三、直接可用代码(HAL库)
1. 定义(main.c 顶部)
// PWM句柄(CubeMX自动生成)
extern TIM_HandleTypeDef htim2;
// 宏定义
#define PWM_HANDLE htim2
#define PWM_CHANNEL TIM_CHANNEL_1
2. 启动 PWM(硬件自动开始闪烁)
// 启动 PWM 输出 → LED 开始闪烁
HAL_TIM_PWM_Start(&PWM_HANDLE, PWM_CHANNEL);
3. 停止 PWM → 灯灭
// 停止 PWM → LED 熄灭
HAL_TIM_PWM_Stop(&PWM_HANDLE, PWM_CHANNEL);
4. 切换 1s / 0.5s 闪烁
切换到 1秒闪烁一次
// 停止 PWM
HAL_TIM_PWM_Stop(&PWM_HANDLE, PWM_CHANNEL);
// 设置新频率:1Hz
__HAL_TIM_SET_PRESCALER(&PWM_HANDLE, 7199); // PSC
__HAL_TIM_SET_AUTORELOAD(&PWM_HANDLE, 9999); // ARR
__HAL_TIM_SET_COMPARE(&PWM_HANDLE, PWM_CHANNEL, 5000); // 50%占空比
// 重新启动
HAL_TIM_PWM_Start(&PWM_HANDLE, PWM_CHANNEL);
切换到 0.5秒闪烁一次
HAL_TIM_PWM_Stop(&PWM_HANDLE, PWM_CHANNEL);
// 设置新频率:2Hz
__HAL_TIM_SET_PRESCALER(&PWM_HANDLE, 7199);
__HAL_TIM_SET_AUTORELOAD(&PWM_HANDLE, 4999);
__HAL_TIM_SET_COMPARE(&PWM_HANDLE, PWM_CHANNEL, 2500);
HAL_TIM_PWM_Start(&PWM_HANDLE, PWM_CHANNEL);
四、完整开关控制逻辑(你要的功能)
// 开关状态
uint8_t pwm_enable = 1; // 1=开启闪烁 0=关闭
// 按键控制例子(按下按键切换)
if(KEY_Press()){
pwm_enable = !pwm_enable;
if(pwm_enable){
// 开启:1s闪烁
HAL_TIM_PWM_Start(&PWM_HANDLE, PWM_CHANNEL);
}else{
// 关闭:灯灭
HAL_TIM_PWM_Stop(&PWM_HANDLE, PWM_CHANNEL);
}
}
五、最精简总结(直接背)
- 1s闪烁 = PWM 1Hz
- 0.5s闪烁 = PWM 2Hz
- 开启闪烁 =
HAL_TIM_PWM_Start() - 关闭灯 =
HAL_TIM_PWM_Stop() - 切换速度 = 修改 PSC + ARR + CCR
你告诉我 3 个信息,我直接给你完整工程代码
- 你用的 STM32 型号(如 F103C8T6)
- LED 接在哪个引脚
- 用库还是寄存器
我可以直接给你复制就能跑的完整代码!
三个LED用STM32 PWM独立控制:1s闪 / 0.5s闪 / 开关控制(完美方案)
我直接给你3路独立PWM控制3个LED,每个灯可以:
- 独立设置 1秒闪烁
- 独立设置 0.5秒闪烁
- 独立开关(亮/灭/闪烁)
- 互不干扰,硬件自动运行,不占CPU
核心方案
用 1个定时器 + 3个通道(比如TIM2_CH1、CH2、CH3)输出3路独立PWM
- LED1:1Hz(1秒闪一次)
- LED2:2Hz(0.5秒闪一次)
- LED3:可开关、可切换频率
完全满足你控制三个LED的需求!
一、硬件接线(通用STM32)
以最常用 TIM2 为例(所有STM32都能用)
- LED1 → PA0(TIM2_CH1)
- LED2 → PA1(TIM2_CH2)
- LED3 → PA2(TIM2_CH3)
- 每个LED串联 220Ω电阻 再接 GND
二、STM32CubeMX 一键配置
-
定时器选择 TIM2
-
Clock Source:Internal Clock
-
Channel1 / Channel2 / Channel3 都选:PWM Generation CHx
-
关键参数(固定,直接抄)
- PSC = 7199
- ARR = 9999
- 这样基础频率 = 1Hz(1秒闪烁)
-
时钟:72MHz(STM32F103默认)
-
生成MDK-ARM工程
三、3路LED控制代码(直接复制用)
1. 声明(main.c顶部)
// 定时器句柄(CubeMX自动生成)
extern TIM_HandleTypeDef htim2;
// 3路PWM定义
#define LED1_PWM_TIM &htim2
#define LED1_CHANNEL TIM_CHANNEL_1
#define LED2_PWM_TIM &htim2
#define LED2_CHANNEL TIM_CHANNEL_2
#define LED3_PWM_TIM &htim2
#define LED3_CHANNEL TIM_CHANNEL_3
2. 初始化(main函数里)
// 启动3路PWM,默认:
// LED1:1秒闪烁 LED2:0.5秒闪烁 LED3:关闭
HAL_TIM_PWM_Start(LED1_PWM_TIM, LED1_CHANNEL);
LED1_Set_1s_Flash(); // LED1 = 1s闪
HAL_TIM_PWM_Start(LED2_PWM_TIM, LED2_CHANNEL);
LED2_Set_05s_Flash(); // LED2 = 0.5s闪
HAL_TIM_PWM_Stop(LED3_PWM_TIM, LED3_CHANNEL); // LED3 = 灭
四、3个LED独立控制函数(核心!)
1. LED1:1秒闪烁一次
void LED1_Set_1s_Flash(void)
{
// 1Hz = 1秒周期
__HAL_TIM_SET_PRESCALER(LED1_PWM_TIM, 7199);
__HAL_TIM_SET_AUTORELOAD(LED1_PWM_TIM, 9999);
__HAL_TIM_SET_COMPARE(LED1_PWM_TIM, LED1_CHANNEL, 5000); // 50%占空比
}
2. LED2:0.5秒闪烁一次
void LED2_Set_05s_Flash(void)
{
// 2Hz = 0.5秒周期
__HAL_TIM_SET_PRESCALER(LED2_PWM_TIM, 7199);
__HAL_TIM_SET_AUTORELOAD(LED2_PWM_TIM, 4999);
__HAL_TIM_SET_COMPARE(LED2_PWM_TIM, LED2_CHANNEL, 2500); // 50%占空比
}
3. LED3:任意控制(开关 + 频率)
// LED3 开启 1s闪烁
void LED3_1s_On(void)
{
__HAL_TIM_SET_PRESCALER(LED3_PWM_TIM, 7199);
__HAL_TIM_SET_AUTORELOAD(LED3_PWM_TIM, 9999);
__HAL_TIM_SET_COMPARE(LED3_PWM_TIM, LED3_CHANNEL, 5000);
HAL_TIM_PWM_Start(LED3_PWM_TIM, LED3_CHANNEL);
}
// LED3 开启 0.5s闪烁
void LED3_05s_On(void)
{
__HAL_TIM_SET_PRESCALER(LED3_PWM_TIM, 7199);
__HAL_TIM_SET_AUTORELOAD(LED3_PWM_TIM, 4999);
__HAL_TIM_SET_COMPARE(LED3_PWM_TIM, LED3_CHANNEL, 2500);
HAL_TIM_PWM_Start(LED3_PWM_TIM, LED3_CHANNEL);
}
// LED3 关闭(灯灭)
void LED3_Off(void)
{
HAL_TIM_PWM_Stop(LED3_PWM_TIM, LED3_CHANNEL);
}
五、独立开关控制(你要的功能)
// 例子:循环测试
while (1)
{
// LED1:固定 1秒闪烁(一直运行)
// LED2:固定 0.5秒闪烁(一直运行)
// LED3:自己控制
LED3_1s_On(); // 1s闪烁
HAL_Delay(5000);
LED3_05s_On(); // 0.5s闪烁
HAL_Delay(5000);
LED3_Off(); // 关闭
HAL_Delay(3000);
}
六、最终效果(完美满足你)
- LED1:永远 1秒 闪烁一次
- LED2:永远 0.5秒 闪烁一次
- LED3:可随时开关、切换1s/0.5s闪烁
- 三路完全独立,互不影响
- 硬件PWM自动运行,不占用CPU资源
七、最简单总结(背会就会用)
- 3个LED → 用定时器3个PWM通道
- 1s闪烁 = 1Hz
- 0.5s闪烁 = 2Hz
- 开启:
HAL_TIM_PWM_Start() - 关闭:
HAL_TIM_PWM_Stop() - 改频率:改PSC、ARR、CCR
我可以直接给你 完整的main.c代码,你复制进去就能跑!
你只需要告诉我:
你用的STM32型号?(如F103C8T6)
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)