描述
在做嵌入式开发的时候,PWM(脉宽调制)几乎是必学技能。LED 想要呼吸效果?PWM。蜂鸣器要发“滴滴”的提示音?PWM。电机需要调速?还是 PWM。
问题是:同样一个 HAL_TIM_PWM_Start(),有人做出来的 LED 灯效果柔和自然,有人却像手电筒闪烁;有人做的电机转速平稳安静,有人却抖得像要散架。
为什么差别这么大?答案就在 频率、占空比 和 应用场景的差异 上。今天我们就结合 LED、蜂鸣器和电机,讲透 PWM 的核心要点。

一、PWM 原理回顾
PWM 的本质:通过改变高电平持续时间,来控制平均电压。
- 周期(Period):决定频率。
- 占空比(Duty Cycle):决定平均电压。
比如:3.3V 的信号,频率固定,改变占空比:
- 10% → 平均电压 ≈ 0.33V
- 50% → 平均电压 ≈ 1.65V
- 90% → 平均电压 ≈ 2.97V
二、LED 调光:呼吸灯怎么才能柔和?
1. 常见错误:线性调节占空比
很多人写一个循环:
- for(int duty =0; duty <=100; duty++){
- __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, duty);
- HAL_Delay(20);
- }
结果:前半段几乎看不到亮度变化,后半段突然“闪瞎”。
原因:人眼对光的感知不是线性的,而是对数曲线。
2. 正确做法:Gamma 校正
- float gamma =2.2;// 常见 Gamma 值
- for(int i =0; i <=100; i++){
- float percent = pow((float)i /100.0, gamma);
- __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, percent * htim3.Init.Period);
- HAL_Delay(20);
- }
这样才能实现真正的“呼吸灯”。
3. 频率选择
- 推荐 200Hz ~ 1kHz
- <100Hz 会闪烁,人眼能察觉
三、蜂鸣器:频率决定音调
蜂鸣器分为:
- 有源蜂鸣器:上电就响,不需要 PWM。
- 无源蜂鸣器:需要 PWM,不同频率 → 不同音调。
1. PWM 频率与音调对应
- // 让无源蜂鸣器发出 "Do Re Mi"
- void buzzer_play(){
- set_pwm_freq(262);// Do
- HAL_Delay(500);
- set_pwm_freq(294);// Re
- HAL_Delay(500);
- set_pwm_freq(330);// Mi
- HAL_Delay(500);
- }
2. 占空比决定音量
- 占空比 50% → 声音最响
- 占空比 <30% → 声音较小
- 占空比 >70% → 容易失真
四、电机控制:PWM 是核心调速手段
1. 直流电机
转速 ≈ 电压 ≈ PWM 占空比 × 电源电压。
- 低频 PWM:电机会抖动
- 高频 PWM(>20kHz):更平稳,人耳听不到噪音
- // 控制直流电机转速
- void motor_set_speed(uint8_t percent){
- uint32_t duty = percent * htim2.Init.Period/100;
- __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, duty);
- }
2. 步进电机
PWM 用来调电流,而转速靠 脉冲序列,不是直接调占空比。
3. 无刷电机(BLDC)
需要 三相 PWM + 换相控制,常用 FOC 算法。
五、常见坑点总结
- LED:亮度变化不平滑? → 加 Gamma 校正。
- 蜂鸣器:声音刺耳? → 频率不对,或者占空比过高。
- 电机:转速不稳? → 频率太低,选高于 20kHz。
- 通用错误:用软件延时做 PWM,波形抖动严重 → 应该用定时器硬件 PWM。
六、调试小技巧
- 用 示波器看波形,确认频率与占空比是否正确。
- 用 LED 替代电机 测试 PWM,直观判断调速效果。
- 给 蜂鸣器输出波形,用音频软件测频率,验证是否对上音符。
七、结语
PWM 的套路远不止“点灯”,它背后有着不同应用的门道。搞懂了频率和占空比的关系,理解不同器件对 PWM 的敏感性,你就能做出柔和的呼吸灯、悦耳的蜂鸣器提示音、以及平稳高效的电机调速。
下次写 HAL_TIM_PWM_Start() 的时候,别只想着“能跑起来就行”,要先问自己:这个 PWM 的参数,适合我现在的应用吗?
打开APP阅读更多精彩内容