玩嵌入式这么多年PWM是我见过应用最广、却又最容易被低估的一个外设功能。从一块钱的LED闪灯驱动芯片到几百瓦的直流电机驱动板核心原理都是同一件事用固定频率的方波信号控制导通和关断的时间比例。很多人第一次接触PWM就是调个LED亮度觉得不过如此。等真正上手用它去驱动直流电机才发现里面的门道远比想象的多——频率选不对电机嗡嗡叫占空比给太小根本转不起来驱动电路漏了续流二极管还会烧管子。这篇文章就把我从LED亮度实验开始一路到驱动直流电机踩过的坑和经验完整梳理一遍希望能帮刚开始玩单片机的朋友建立起一套完整的PWM知识框架。1. PWM 的核心参数与计算逻辑1.1 占空比功率的“开关比例”PWM的全称是脉宽调制英文Pulse Width Modulation。它输出的不是什么复杂的模拟信号就是一组高低电平组成的方波。方波的周期是固定的但高电平持续的时间可以改变。我们把高电平持续的时间叫做脉宽把高电平时间占整个周期的百分比叫作占空比。比如一个周期是1ms的方波高电平持续0.5ms那占空比就是50%。如果把高电平时间改成0.8ms占空比就是80%。对于纯阻性负载来说输出到负载上的平均功率近似等于电源电压乘以占空比。这个逻辑特别好理解——一个水龙头一秒钟内开一半时间关一半时间接到桶里的水就是一秒钟内全开水量的一半。把水龙头的“开”和“关”周期设得足够短桶里的水位就近似平稳地维持在半水状态。实际计算的时候占空比公式很简单占空比 D Ton / (Ton Toff) × 100% 平均电压 V_avg Vcc × D在单片机里我们通常不是直接控制Ton的时间绝对值而是通过定时器的计数寄存器来做比例控制。常见做法是设定一个计数值上限自动重装载值ARR再设定一个比较值CCR计数器从0往上数每计一个数的时间固定当计数值小于CCR时输出高电平大于等于CCR时输出低电平反复循环。这样占空比就是 CCR / (ARR 1)。我用生活化的方式给你拆一下这个逻辑。假设你跑步训练教练给你定的循环是冲刺5秒慢走5秒反复进行。那么你的“高速输出占空比”就是50%。冲刺8秒、慢走2秒占空比就是80%。PWM干的事本质上就是教练给你安排冲刺和休息的时间比例只不过这个比例切换速度极快快到负载根本反应不过来只能感受到平均效果。1.2 频率周期长短决定了系统表现占空比决定“输出多少”频率决定“这个比例多久循环一次”。对于LED调光频率如果低于50Hz人眼就能明显感觉到闪烁看久了眼睛特别累。工程上一般取1kHz以上有些高要求的场合会用到数kHz甚至几十kHz配合光学扩散材料肉眼完全看不出频闪。对于直流电机频率的选择就更有讲究了。电机内部是线圈绕组是感性负载电流变化会被电感“平滑”掉所以即使PWM频率不高电机的电流也是近似连续的波形而不是和PWM波形一样方方正正。但频率太低的时候比如只有几十赫兹电机的转速会跟着PWM的开关节奏一抖一抖的运转起来一顿一顿扭矩输出不平稳噪音还大。那是不是频率越高越好也不是。频率越高MOSFET或者三极管的开关次数就越频繁开关损耗显著上升。我实测过一个实验同一个直流电机在1kHz下驱动MOSFET基本不发热提高到100kHz同样占空比下管子明显发烫电机的效率反而下降了。所以实用中电机驱动PWM频率一般选在15kHz到25kHz之间一个原因是这个频率超出人耳听觉上限没有尖锐的啸叫声另一个原因是在这个范围内开关损耗和电流纹波能达到比较好的平衡。这里补充一个很多新手容易忽略的问题频率的选择和分辨率是互相制约的。如果你用定时器做PWM时钟频率固定的情况下频率越高可调的占空比档位就越少。比如系统时钟72MHz你要100Hz的PWM计数的周期是720000个时钟理论上你可以在0到719999之间调节占空比分辨率非常高但如果你要36MHz的PWM那一个周期只有2个时钟占空比只有0%、50%、100%三档可选。所以选频率不是拍脑袋要根据负载特性和控制精度要求来权衡。2. LED 亮度变化PWM 的第一堂实践课2.1 人眼看不见“瞬时亮度”只记得“平均亮度”LED调光为什么用PWM而不是直接调电压原因很简单LED的发光亮度与正向电流近似成正比而对电压极其敏感。你给LED在额定电压基础上增加0.1V电流可能翻倍亮度突变非常剧烈所以直接调电压很难做到平滑的亮度控制。更麻烦的是LED的正向压降受温度影响很大温度升高时压降降低电流会进一步增大严重时直接烧毁。PWM调光则是让LED以极快的速度在“全亮”和“全灭”之间切换通过调整点亮时间比例来改变人眼感受到的平均亮度。这个原理有点像电影放映电影胶片实际上每秒钟只切换24帧静止画面但人眼因为视觉暂留效应看到的却是连续流畅的动作。LED的PWM频率足够高时我一般建议至少1kHz以上人眼“残留”的光感会把亮暗变化平均掉从而形成稳定的亮度感知。在实际项目中我遇到过很多次因为频率过低导致LED看起来“像蜡烛一样抖动”的情况。尤其是一些驱动方案偷懒把频率做到200Hz甚至100Hz静态看还凑合但如果周围有轻微震动或者人移动视线就能明显感觉到闪烁。后来我统一把LED调光PWM频率定在2kHz这个问题就再也没出现过。这里还要提一下POV余晖效应的有趣应用——热词里那个旋转LED显示套件就是这个原理。LED以极快的速度切换亮灭配合机械旋转让发光点在不同位置残留视觉影像就能“画”出文字和图案。就像拿着发光棒在黑夜里快速挥舞看到的是一条光带而不是离散的点。本质上人眼的视觉暂留时间大约在0.1秒左右所有时间低于这个阈值的快速变化都会被大脑“平滑”成连续影像。这也是PWM能骗过人眼的核心基础。2.2 为什么 51 单片机驱动 LED 偏爱低电平很多初学者学单片机时第一个实验就是点亮LED。在51单片机的学习板上你会发现一个奇怪现象——LED的正极接电源负极接单片机引脚要想点亮LED程序里要写引脚为低电平。也就是说51单片机是“灌电流”驱动LED的而不是“拉电流”驱动。这是为什么这就要说到51单片机IO口的驱动能力了。以经典的STC89C52为例P0口是漏极开路结构内部没有上拉电阻输出高电平时引脚处于高阻态基本提供不了电流P1、P2、P3口内部虽然有弱上拉但驱动能力非常有限大约只能提供几百微安的电流。而如果你让引脚输出低电平IO口内部的N沟道MOSFET导通引脚对地形成通路外部电路可以通过引脚向地灌入电流灌电流能力可以达到10mA以上点亮一颗LED绰绰有余。这个区别很关键。如果你在51上强行用高电平驱动LED你会发现LED要么完全不亮要么亮度极暗——因为IO口根本“推”不动这个负载。实际上51的P0口如果要做高电平输出必须在外部加上拉电阻但即便加了上拉电阻驱动能力也受限于上拉电阻的取值通常也就几毫安。那这和PWM有什么关系关系大了。在51上做LED呼吸灯效果时很多人直接写引脚翻转的延时函数比如让引脚低电平0.5ms、高电平0.5ms交替进行实现50%占空比的PWM。但因为51的IO口高电平驱动能力弱同样的占空比下LED的平均电流比低电平驱动方式小很多呼吸效果明显不对称。所以正确的做法是LED阳极接电源阴极接IO口通过IO口控制低电平的时间比例来调节亮度这样LED的平均电流和占空比才是线性对应关系。顺带提一个经验用51的硬件定时器中断来做PWM比单纯用延时函数靠谱得多。延时函数在单片机执行其他任务时会产生累计误差比如你延时0.1ms控制一个LED但中断里还要处理按键扫描时序就乱了。硬件PWM就没有这个问题定时器独立于CPU运行输出引脚自动翻转完全不影响主程序的其他逻辑。2.3 LED 驱动芯片的 FB 脚和 CS 脚恒流调光的秘密如果是单颗LED用限流电阻加单片机IO口就能搞定。但在LED灯带、大屏显示等场景单颗LED电流可能高达几十毫安甚至几百毫安如果还用电阻限流电阻上消耗的功率太大了效率低还发热。这时候就需要专用的LED驱动芯片。这类芯片通常叫恒流驱动芯片它的核心是让流过LED的电流保持恒定不随电源电压和LED温度漂移。芯片上常有两个关键引脚FB反馈和CS电流采样。FB脚是电压反馈端通过检测输出端的电压变化来调整内部功率管的导通程度CS脚通常外接一个采样电阻流经LED的电流会在这个采样电阻上形成压降芯片将这个压降与内部基准电压比较形成闭环反馈从而恒定电流。具体参数怎么算我这里说一个常见的方法。比如某颗LED驱动芯片的CS基准电压典型值是0.1V你想让LED电流为350mA那CS采样电阻阻值就用0.1V除以0.35A约等于0.286欧姆取标准值0.3欧姆。那么这个电阻上消耗的功率是0.35A的平方乘以0.3欧姆约等于0.037W选个0603封装就够用。这里的电流设置逻辑就是欧姆定律搞清楚基准电压是多少是关键。实际操作中FB和CS脚往往配合一个放大电路来用。有些芯片FB脚内部是一个比较器的负输入端外部的电阻分压网络把输出电压反馈回来调整开关管的占空比目的是让输出电压稳定或者输出电流恒定。我调试过一款降压型LED驱动FB脚外接电阻分压网络一开始把分压比算错了输出电压比设计值高了一倍LED瞬间过流发热。后来用示波器量FB脚的电压波形发现反馈电压超过了参考电压才知道是分压电阻阻值配错了。这里给一个调试思路。调这类芯片先用万用表量CS脚或FB脚的电压判断它是否接近参考电压如果偏离太多优先检查采样电阻阻值和反馈分压电阻比值。不要一上来就去动芯片的外围参数——很多芯片的开关频率、软启动时间由另外一个引脚的外接电容电阻决定乱调会导致振荡周期异常或者启动冲击电流过大。另外很多驱动芯片本身也支持PWM调光。方法非常简单在芯片的PWM调光引脚有些直接复用EN使能引脚输入PWM信号芯片内部的功率管以PWM频率通断LED电流要么是额定值要么是零。通过调节占空比来改变平均亮度。这种方式的好处是芯片始终工作在恒流状态不会因为调光而产生色偏LED色温一致性比直接调电流好得多。2.4 用 PWM 做出动态光效从呼吸灯到火焰模拟呼吸灯是PWM调光最经典的入门案例。原理非常简单占空比从0%逐渐增加到100%再从100%逐渐减小到0%循环往复。人眼感觉到的是灯光亮度先缓慢变亮再缓慢变暗像人在呼吸一样。这个效果的节奏快慢由占空比变化的步进时间和步长控制。我在DFRobot的火焰灯模拟方案里看到过一个更进阶的玩法用若干颗黄色和红色的LED分别用不同频率、不同占空比的PWM信号驱动然后让这些信号做随机扰动。比如有一颗LED用20Hz左右的PWM做基础闪烁另一颗用40Hz的PWM独立闪烁再把占空比加上随机数扰动就能模拟出火焰那种不规则跳动的光效。核心就是动态变化的占空比叠加随机噪声。这类动态光效实现起来有个要注意的点如果你用软件延时去改变占空比占空比的更新频率不能太高也不能太低。太高了人眼感觉不到变化觉得灯光在“抖”太低了变化又显得突兀不够柔和。我一般把占空比更新时间控制在10ms到50ms之间也就是每秒更新20到100次这样视觉效果最自然。这本质上就是在控制一个“变化的PWM”的时间尺度。3. 直流电机调速PWM 的真正硬核战场3.1 为什么占空比能控制电机转速LED的PWM调速很好理解因为人眼会做平均。但电机转速控制就完全不同了——电机可没有“视觉暂留”这种机制。那为什么给电机输出一个PWM方波就能稳定控制转速关键在于电机的电感特性和反电动势。直流电机的绕组是线圈电感很大电流不能突变。当你给电机通电的瞬间电流是缓慢上升的断电的瞬间电流也不会立刻跌到零而是通过续流回路缓慢下降。所以当PWM频率足够高时流过电机绕组的电流并不是方波而是带有一定纹波的近似直流电流。这个平均电流的大小决定了电机产生的电磁转矩大小从而决定了转速。再看电压的角度。电机的转速近似与施加在电枢两端的平均电压成正比。PWM的占空比是50%那电枢的平均电压就是电源电压的50%转速大约也是全压转速的50%。这种方式叫“斩波调压”——把连续的电能斩成一段一段用占空比控制“平均电压”比串联电阻调压或者线性调压器的效率高得多因为MOSFET在导通时压降极小截止时电流为零功率损耗都很小。但这里要强调一点电机不是纯电阻负载所以“平均电压乘以占空比”这个公式不是精确的转速计算式。电机运转时会产生反电动势EMF方向与外加电压相反实际电流是外加电压减去反电动势后除以绕组电阻。转速越高反电动势越大电流越小这就是电机在空载时转速能快速上升到一个平衡点的原因。PWM调速时占空比改变的是外加的平均电压而电机的转速会跟随变化直到反电动势差不多抵消掉外加电压的一半左右具体要看负载系统重新达到平衡。3.2 驱动电路的关键MOSFET、续流二极管和死区直接用单片机IO口驱动电机是不现实的。小电机启动电流几百毫安大电机几十安培单片机IO口最多提供几十毫安强行驱动轻则发热重则烧毁IO口。所以必须通过功率开关器件来放大驱动能力最常用的是N沟道MOSFET。N沟道MOSFET的导通条件是栅源电压Vgs超过阈值电压Vth。电机驱动的下桥臂MOSFET源极接地栅极由单片机控制控制起来比较轻松但上桥臂MOSFET源极接电机输出端电压浮动栅极需要比源极高出一个阈值电压才能导通这就麻烦了。常见的解决方案是使用专用的栅极驱动芯片它内部有自举电路能把栅极电压抬升到比电源电压还高的程度。这里还要强调续流二极管的作用。电机绕组是感性负载当PWM关断、MOSFET截止的瞬间电机电流不能突变如果没有续流回路电流会强行流过MOSFET的寄生电容或者直接产生很高的尖峰电压把管子击穿。正确做法是在每个电机绕组旁边反向并联一个快恢复二极管俗称续流二极管关断瞬间电流通过二极管继续流动把能量消耗在绕组电阻上保护MOSFET不受过压冲击。H桥是直流电机方向控制的经典拓扑我记得第一次用H桥遇到的问题是上下桥臂直通。如果同一侧的上桥和下桥同时导通电源直接被短路瞬间电流极大管子立刻烧掉。解决方法是在切换方向时先让上桥关闭等待一小段时间死区时间再让下桥导通。死区时间通常设为几百纳秒到几微秒具体取决于MOSFET的关断延迟。STM32的高级定时器在生成互补PWM输出时可以直接配置死区时间插入省去了外部的延时处理。3.3 PWM 模式 1 和模式 2 到底差在哪在STM32这类ARM单片机上配置PWM时经常会看到PWM模式1和PWM模式2这两个选项。很多新手在这里一头雾水不知道选哪个其实它们的区别就是输出极性相反。以向上计数模式为例。计数器CNT从0递增到自动重装载值ARR。PWM模式1的规则是CNT小于比较值CCR时输出有效电平CNT大于等于CCR时输出无效电平。PWM模式2正好相反CNT小于CCR时输出无效电平CNT大于等于CCR时输出有效电平。那“有效电平”是什么由另一个配置项决定——输出极性Polarity。如果你把输出极性设为高电平有效那么模式1下CNTCCR时引脚输出高电平如果你设为低电平有效那么模式1下CNTCCR时引脚输出低电平。给你一个实际例子。用STM32的TIM1_CH1PA8引脚输出PWM配置为PWM模式1极性设为高电平有效占空比设为50%。那么PA8引脚上前半个周期是高电平后半个周期是低电平。如果你改用模式2同样参数下前半个周期变成低电平后半个周期变成高电平——相当于占空比变成了100%减50%也就是50%的“互补”信号。实际应用中怎么选看你的驱动电路是“高电平驱动”还是“低电平驱动”。如果你的电机驱动芯片使能端是高电平有效比如EN接高就允许输出那你应该选PWM模式1加高电平有效保证占空比越大高电平时间越长电机转速越高。如果驱动芯片是低电平有效或者你想要的是反逻辑控制那就用模式1加低电平有效或者模式2加高电平有效。我遇到过这样一个坑用TIM1_CH1做电机PWM配上模式1、高极性然后又把输出极性配置里的“无效电平”搞反了结果占空比从0调到100%电机转速却是先快后慢再快完全非线性。后来用示波器量PA8的波形才发现原来我设置的极性让输出的高电平和预期正好相反。用示波器看波形是排查这类问题最快的方法别凭感觉猜。3.4 电机启动的“最低占空比”问题有一次我做一个小型水泵驱动用PWM控制转速占空比从0逐步往上加结果一直到15%之前电机纹丝不动过了15%突然猛转起来。原因很简单电机启动时要克服静摩擦力和自身的转动惯量如果平均电压太低产生的电磁转矩不足以让转子转动电机就“憋”在那里。而且更要命的是占空比很低时PWM脉冲宽度很窄流过电机的平均电流很小但峰值电流并不小长时间保持这种状态绕组可能过热。所以工程上处理电机低速启动的常见做法是启动瞬间先给一个较大的占空比比如80%让电机转起来然后迅速回落到目标低速占空比利用电机的惯性维持运转。如果你需要电机在极低转速下稳定运转光靠PWM调速是不够的通常需要配合减速箱降低输出转速或者用闭环控制编码器反馈转速来补偿负载波动。所以做电机控制前先想清楚你要的是变速范围还是低速稳定性这两个目标对硬件的要求差别很大。4. 单片机产生 PWM 的实操配置4.1 从定时器到引脚PWM 信号是怎么生成的绝大多数MCU的PWM功能都是由定时器Timer模块实现的原理就是一个自由运行的计数器不停计数和一个预设的比较值做大小比较然后根据比较结果驱动引脚电平翻转。理解了这个底层逻辑无论你用什么单片机STM32、HC32F460、英飞凌CCU6等配置都是通的。以STM32F103为例PWM频率的计算公式很重要你几乎天天要跟它打交道PWM频率 定时器时钟频率 / ((预分频系数 1) × (自动重装载值 1))举个例子。STM32F103的定时器TIM1挂在APB2总线上时钟72MHz。如果你设置预分频PSC为71自动重装载值ARR为999那么计数器时钟频率 72MHz / (711) 1MHzPWM频率 1MHz / (9991) 1kHz。占空比则由比较值CCR决定CCR从0改到999对应占空比从0%到100%。这里有个容易搞错的点预分频系数和自动重装载值都要加1之后再去除因为硬件寄存器里存的是0到N实际分频系数是N1。第一次用STM32CUBMX配置时我照着教程填了个预分频71看波形才发现频率不对就是因为漏了1的逻辑。输出引脚的选择也要注意。不是随便一个GPIO都能输出PWM必须是定时器的通道引脚。比如STM32F103ZET6的TIM1_CH1对应PA8如果你代码里没把PA8复用为TIM1通道而是当普通GPIO用了那引脚上永远看不到PWM波形。在CUBMX里就是选择某个引脚然后把它配置成“TIM1_CH1”这个复用功能。PA8输出PWM这个场景很典型初次配置时经常有人配完没反应一查发现引脚复用没设置。4.2 STM32CubeMX 配置 PWM 的完整思路现在ST官方推荐用STM32CubeMX做初始化代码生成。我分享一下配置PWM的关键步骤和每个步骤背后的意图。第一步在Pinout视图里点击选择PA8引脚将它设为TIM1_CH1。CUBMX会自动帮你配好GPIO复用模式这一步不需要手写寄存器。第二步在左侧Category里找到TIM1在Mode里把Channel1设置为PWM Generation CH1。然后进入Parameter Settings需要设置几个关键参数Prescaler预分频、Counter Period计数周期就是ARR、Pulse脉冲宽度就是初始CCR值、Polarity极性。理论上还有PWM模式1和模式2的选项默认都是Mode1大部分情况下保持默认就行。第三步也是新手最容易跳过的一步把PWM信号真正使能输出。CUBMX生成的初始化代码里定时器默认是关闭的。你必须在用户代码里调用HAL_TIM_PWM_Start(htim1, TIM_CHANNEL_1);PWM波形才会出现在PA8上。很多人配置了半天编译下载发现引脚没波形90%的原因就是忘了调用这个启动函数。第四步动态调节占空比。HAL库提供了宏__HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_1, new_ccr_value);把新的CCR值写进去占空比立即改变。注意CCR的取值必须在0到ARR之间超出范围的话波形行为会变得很奇怪比如占空比被钳制或者完全无效。我做呼吸灯时就遇到过这个问题CCR值不小心超过了ARRLED亮度直接跳到最亮调试了半天才反应过来。CUBMX配好之后还有一个隐藏坑引脚上电默认状态。有些板子的LED接在PA8上而PA8上电默认是浮空输入外部电路可能被拉低导致LED微亮。你在初始化用户代码里必须先配置GPIO输出信号再启动PWM否则引脚状态会在初始化和外设启动之间丢失。这个细节遇到一次就会记住了。4.3 频率与分辨率的权衡艺术前面提过频率和分辨率互相制约的关系实际项目里怎么选我给一个参考坐标系。做LED呼吸灯或者调光频率1kHz到5kHz足够分辨率要求高一些比如要把亮度细分成256级或者4096级。假设选2kHz72MHz时钟下计数器周期 72MHz / 2kHz 36000个时钟也就是ARR可以设为35999那么占空比分辨率约为1/36000远超需求。做电机调速频率尽量选20kHz左右超出人耳听觉范围。这时候计数器周期 72MHz / 20kHz 3600个时钟ARR设为3599分辨率仍然有3600级足够平滑调速。如果你的电机用霍尔传感器做速度闭环PWM频率还要和采样频率协调别让采样和PWM开关产生拍频干扰。如果你的应用需要极高的PWM频率比如一些数字电源应用要500kHz那普通定时器的位数就不够了可能要用到定时器的主模式重映射、或者直接用高级定时器的一些特殊模式。这时候就要考虑用更大位数的计时器或者更高时钟频率的MCU。优先级排序应该是先满足负载的工作需求再考虑分辨率够不够最后才反过来调整定时器参数。5. PWM 应用中的常见问题与排查实战5.1 电机抖动、异响和失控问题一电机低速时一顿一顿地转甚至有明显的“咔咔”声。这个大概率是PWM频率太低。我做过实验30Hz的PWM驱动电机你能看到电机每秒钟抖动30次几乎无法稳定控制。解决方案是把PWM频率提高到15kHz以上电机的电流纹波被电感平滑掉运转就非常顺畅了。问题二电机高速运行时发出高频啸叫。这个声音可能来自PWM频率本身如果PWM频率落在2kHz到5kHz之间恰好在人耳最敏感的频率范围听着会特别难受。对策是直接改频率到20kHz或更高。另外还要排查驱动芯片的内部振荡频率有些电源芯片的工作频率也在人耳范围附近会产生同样的异响。问题三占空比加到某一档位时电机突然速度跳变或者失控。优先怀疑电源问题——可能是PWM的开关冲击导致电源电压跌落控制电路单片机瞬间复位。用示波器探头点电机电源两端能看到巨大的纹波尖峰。处理办法在电机电源端加大容量电解电容和陶瓷电容并保证控制电路和功率电路的地线分开走单点汇接。我调试一次48V电机驱动板时就因为地线压降导致PWM信号失真输出波形上叠加了大量毛刺后来把功率地和信号地在电源输入端单点连接问题就消失了。问题四电机反电动势把单片机打死。大功率电机的电刷换向会产生高压尖峰通过地线或者信号线耦合回控制电路导致单片机复位甚至烧毁IO口。解决办法是控制信号和功率线用光耦或者数字隔离器隔开PWM信号走隔离通道电机那边再单独加TVS管吸收瞬态高压。这不是小题大做我修过好几个人为损坏的板子都是因为这一步偷懒了。5.2 LED 闪烁、频闪和拍照水波纹LED调光时出现人眼可见的闪烁一定是PWM频率太低或者占空比更新频率太低。这个好解决频率往上提就行。麻烦的是另一种情况人眼看起来不闪但用手机摄像头一拍屏幕上出现一条条滚动的暗纹。这是典型的“频闪”问题。手机摄像头的采样帧率和LED的PWM频率之间存在频率差两者相互作用在画面里产生了摩尔纹效应。比如LED的PWM频率是1kHz手机快门斩波频率与其不同步画面就会被拍出亮暗条纹。现在很多装修场景验收灯光就是用手机录像检测频闪亮暗条纹越明显频闪越严重。解决方法就是把PWM频率大幅提高一般做到5kHz以上频闪现象基本就看不出来了。另一个LED方面的坑是PWM调光和恒流驱动芯片的配合。有些恒流驱动芯片PWM调光引脚输入频率太高超过芯片规格芯片内部的响应就跟不上了亮度会出现非线性甚至芯片自己会抖动。所以LED调光要根据驱动芯片的规格书选择PWM频率不能一刀切。5.3 PWM 故障保护与安全设计在电机驱动这样的功率应用中PWM输出必须要有故障保护机制。STM32的高级定时器TIM1/TIM8自带刹车Break功能一旦刹车信号有效比如外部急停按键按下或者过流信号触发定时器的PWM输出被强制拉到无效电平而且这个过程是硬件完成的不需要CPU干预响应速度微秒级。这个设计思路很重要。你想一下如果电机堵转导致电流飙升单片机能及时检测到过流信号但CPU正在执行其他任务轮询到故障信号可能已经过去了几毫秒——对功率管来说这几毫秒足够把它烧成灰了。硬件刹车相当于给PWM输出加了一道防火墙只要有外部故障触发硬件立刻切断PWM不等CPU反应。实际项目里我习惯把电机驱动芯片的过流保护输出FAULT引脚直接接到MCU的刹车输入引脚上。比如用TIM1_BKIN引脚配置为高电平触发刹车过流时FAULT变为高电平PWM立即停止输出。这样即使单片机代码写得再烂、任务调度再慢功率管也不会因为过流而损坏。5.4 温度监控、风扇调速与硬盘散热热词里有一个“PWM怎么监控硬盘的温度”这个问题背后的实际需求是怎么根据温度自动调节风扇转速而风扇调速就是用PWM实现的。常见的做法是温度传感器比如NTC热敏电阻或数字温度传感器DS18B20采集温度单片机读取之后查表映射成PWM占空比占空比控制风扇转速。温度低时占空比给个30%风扇低速静音运行温度升高逐步提高占空比到100%风扇全速运转。这就是一个简单的开环温控逻辑。风扇本身分为两线、三线和四线制。四线制风扇里就有一根PWM控制线输入一个25kHz左右的PWM信号即可调节转速。这也是为什么你会看到“PWM怎么监控硬盘温度”这种搜索词——其实就是用PWM风扇配合软件测温实现智能调速。热敏电阻的采样精度不要求太高关键是把温度区间和占空比的映射曲线做好避免风扇转速在某个温度点上下反复跳变引起明显的噪音变化。5.5 一个真实的 PWM 调试速查表最后我把平时调PWM问题时用的自查清单整理成一张表省得每次从零开始查。现象可能原因排查方法解决建议LED不亮或亮度异常引脚复用没配好、PWM未启动示波器量引脚波形检查GPIO复用配置调用HAL_TIM_PWM_StartLED闪烁/拍照水波纹PWM频率过低手机录像观察示波器测频率提高到5kHz以上电机一顿一顿转PWM频率太低听声音看电流波形提高到15kHz~25kHz电机啸叫但转速正常PWM频率落在听觉范围用耳朵粗略判断改到20kHz以上电机不转但电流很大占空比太低启动转矩不足逐步加大占空比观察先用80%占空比启动再回落MOS管发热严重开关频率过高或驱动不足测温查看栅极波形降低频率检查栅极驱动能力上/下桥臂直通烧管死区时间不够用示波器看互补波形配置死区时间或外部加延时PWM输出上有大量毛刺地线布局不当开关噪声耦合示波器测地线压差功率地和信号地分开布线单点汇接过流烧管而程序没反应缺少硬件刹车保护查刹车输入配置将FAULT信号接到BKIN引脚做电子这行PWM属于那种“看起来很简单、用起来全是细节”的东西。我刚开始工作那会儿觉得PWM不就是翻转高低电平吗后来做电源和电机驱动项目被频率、死区、续流、刹车这些概念轮番教育过才真正把这四个字母背后的分量理解透。如果你现在正在做LED调光或者电机调速的项目建议别只盯着代码跑通多拿示波器看看真实的波形多用手摸摸功率管的温度。把波形看明白了温度摸清楚了PWM这门手艺你就已经掌握了大半。
阅读完成 · 觉得有帮助?