
六路互补PWM这六个字凡是做过电机驱动、三相逆变或者开关电源的人应该都不陌生。它本质上是给三相全桥或半桥电路的六个开关管生成驱动信号上桥臂三路PWM下桥臂三路PWM上下桥臂一一互补中间还必须隔出一段死区时间防止瞬间直通。这个实验项目就是要把这六路信号完整地拉出来在示波器上确认波形、死区、相位和故障保护逻辑都正确。做这个实验的动机很直接——我见过不止一次程序烧进去电机不转或者一通电驱动板直接冒烟最后查下来都是六路PWM配置问题不是相位不对就是死区没生效再不就是极性搞反。六路互补PWM这一关不过后面什么FOC、速度闭环、电流环都无从谈起。这篇内容适合刚入门电机驱动的开发者也适合从单路PWM转向三相PWM的老手核心目标只有一个把六路互补PWM看明白、配正确、测清楚。1. 实验背景与整体思路1.1 六路互补PWM到底解决什么问题先看最典型的三相全桥拓扑。三相电机需要三个绕组通电通常由六个开关管组成三个半桥每个半桥的上管和下管交替导通。上管导通时电机相线接到母线正极下管导通时接到母线负极。如果上下管同时导通母线电源直接短路电流瞬间飙升轻则炸管子重则连驱动板和控制器一起带走。PWM信号的任务是控制每个开关管的导通时间从而控制相电压和相电流。单路PWM只能控制一个开关而三相电机需要六个开关协同工作因此必须生成六路PWM。每一路上桥和下桥必须严格互补也就是上管导通的时候下管必须关断下管导通的时候上管必须关断。理想情况是这样但实际功率管存在开通延迟、关断延迟如果不能保证两者之间有一个明确的“双关断”时间窗口就会出现瞬间直通。这个“双关断”窗口就是死区。六路互补PWM的核心不仅仅是输出六路信号而是输出“带死区的互补信号”。死区时间设置是否合理直接决定驱动器能不能可靠工作。1.2 为什么要把验证单独拎出来做很多人的习惯是直接写完整个电机控制工程然后把程序烧进去试运行。这种做法风险很大。要知道六路PWM出问题的概率远高于单路PWM原因在于通道多、关联项多、时序要求高。比如这几个典型问题六路信号的相位顺序不对电机会抖动甚至反转死区寄存器或死区配置没生效上下桥瞬时直通上下桥极性配置错误导致上管和下管同时为有效电平输出引脚复用配置错误波形出现在完全不同的引脚上故障输入没配置好紧急刹车信号来了PWM照样输出。如果把这些变量混在完整的电机驱动代码里排查问题会被无数信号淹没。单独做一个验证实验把六路互补PWM当作唯一的研究对象配置和观测范围一下子缩小很多排错效率会高得多。我这次实验的思路很简单先用带高级定时器的MCU生成六路互补PWM接一个低压小功率三相全桥驱动板不加电机或者只接一个很小的电阻负载在示波器上逐项验证波形参数同时测试故障刹车功能。全部通过之后再进行下一步电机开环控制实验。1.3 实验验收标准没有验收标准的实验等于没做。这次实验我定了几个可量化的指标每一项都必须独立确认PWM频率符合设计值比如25kHz六路输出中任意一组上下桥波形互补死区时间满足设计值误差在可接受范围三路上桥信号相位互差120度占空比能够动态调整且更新时机可控刹车信号触发后六路PWM全部输出无效电平清除刹车信号后PWM能恢复正常输出。这些指标里前面几条是基础波形指标后面几条是工程可靠性指标。很多时候大家只测前三条觉得波形看起来对就行结果接到真实驱动板上才发现上电一瞬间PWM输出混乱或者故障恢复逻辑没处理。所以我把故障刹车也放在验收标准里这点在电机驱动里极其重要。2. 硬件平台与测量工具准备2.1 主控板、驱动板与最小外围这个实验不需要特别贵的设备核心是MCU选型。必须选带高级定时器的Cortex-M内核芯片普通定时器虽然也能输出PWM但通常不支持互补输出、死区插入、刹车保护这些硬件特性。用普通定时器加外部逻辑搭死区确实也可以但调试复杂度高实时性和可靠性远不如芯片原生支持。主控板我用的是自己做的一块小控制板上面有一颗Cortex-M内核MCU工作电压3.3V高级定时器通道分布在固定引脚上。这个实验对主控板的要求就是引脚引出完整、供电稳定、调试接口可用。开发板也完全可以但最好把PWM引脚单独引出来方便夹示波器探头。驱动板选择上有一个原则第一轮验证先不用大功率驱动尽量选母线电压在12V到24V的小功率三相全桥驱动板或者用三个半桥驱动芯片搭出来的评估板。大功率驱动板一旦配置错误放烟花概率很高而且实验成本大。用低压小功率板即使直通了炸管概率也会小很多排查起来更从容。2.2 测量工具与探头接法示波器是必备工具。建议至少2通道带宽50MHz以上就够用。四个通道更好可以同时观察上管、下管、母线电压和故障信号。逻辑分析仪也建议准备一个通道多适合看六路信号的相位关系但注意逻辑分析仪只能看数字电平不能看真实的开关波形。示波器探头接地是个很容易被忽略的点。测量上下桥臂PWM波形时如果使用普通的探头接地夹子要尽量短直接夹在信号参考地附近。长接地线会形成环路引入高频噪声波形会多出一堆振铃误判为驱动问题。还有一个关键是如果母线电压比较高最好使用隔离探头或差分探头。低压实验普通探头还能顶一顶但养成好习惯很重要。2.3 接线清单和上电顺序这次实验我整理了一个接线表和上电顺序表。接线表的作用不是记流水账而是减少低级错误。每个PWM通道接到哪里驱动板电源怎么供电母线电容怎么连接都必须清清楚楚。信号来源去向说明PWM_UHMCU引脚A驱动板上桥U输入高有效或低有效取决于驱动板PWM_ULMCU引脚B驱动板下桥U输入必须与UH互补PWM_VHMCU引脚C驱动板上桥V输入V相上管PWM_VLMCU引脚D驱动板下桥V输入V相下管PWM_WHMCU引脚E驱动板上桥W输入W相上管PWM_WLMCU引脚F驱动板下桥W输入W相下管BRK_IN外部按键或信号MCU刹车输入低电平或高电平触发母线正极直流电源正极驱动板母线正极第一轮用12V低压母线负极直流电源负极驱动板母线负极与MCU共地上电顺序方面我的习惯是第一先给MCU上电不接驱动板第二用示波器或逻辑分析仪测量六个PWM引脚确认波形正确第三断电接驱动板信号线但仍然不接母线电第四上电MCU再次量驱动板输入端的波形第五最后才给驱动板接低压母线电。这个顺序虽然麻烦但每一步都在验证前一步的正确性避免问题一次性爆发。3. 互补PWM核心机制拆解3.1 从单路PWM到六路互补单路PWM很好理解就是一个定时器通道输出连续的方法占空比由比较寄存器控制。到了六路互补PWM情况变成了三个相互独立、但又有固定相位关系的PWM对。每一对上下桥的PWM信号除了占空比一致或按需求调整之外上桥和下桥必须形成互补关系。芯片实现互补输出时通常做法是定时器通道输出主波形硬件自动在另一个引脚输出反相波形并在上升沿和下降沿插入死区。硬件插入死区有一个好处即使程序跑飞或者寄存器配置出错只要初始化时死区参数写对了PWM输出本身不会出现长时间直通安全性远高于纯软件翻转。相位关系上电机的三相电压在电角度上互差120度对应到U、V、W三组PWM上桥信号必须依次滞后120度。这个120度不是绝对的时间值而是相对PWM周期而言的。比如25kHz对应周期40微秒120度就差约13.33微秒。实现上有两种方法一种是用定时器的多个通道配置事件偏移另一种是在更新中断里调整占空比和相位。硬件条件允许时优先用定时器主从模式和捕获比较通道让硬件自动维护相位关系CPU只负责改变幅值。3.2 死区时间怎么计算死区时间的本质是等待功率管完全关断后再开通另一个管子。IGBT和MOSFET都有开通延迟、关断延迟、上升时间和下降时间。如果上管还没完全关断下管就开始导通就会形成直通短路。死区时间的最小值不能小于“最大关断延迟减去最小开通延迟再加上一点安全裕量”。这个值直接看功率管的datasheet取最差工况下的参数。举个例子某个MOSFET的关断延迟最大是120ns开通延迟最小是50ns那理论死区至少要大于70ns。但实际使用还要考虑温度、驱动电阻、PCB寄生参数所以一般会乘以2到3倍的安全系数。在交流电机驱动里常见死区时间在500ns到3us之间。我做这次实验时设置PWM频率25kHz死区时间取2us。2us相对于40us周期来说占5%加入死区后实际输出电压会有一定损失但这是保证安全必须付出的代价。要注意的是死区不是越短越好也不是越长越好。太短容易直通太长会导致波形畸变加剧电流谐波变大甚至电机发热。3.3 极性与对齐方式的取舍极性配置是一个特别容易踩坑的地方。同一个PWM信号驱动芯片可能是高电平有效也可能是低电平有效。有些集成驱动模块内部还有反相逻辑。如果MCU输出的是高有效而驱动板输入期望低有效结果就是上管常开或者上下管同时导通。我建议实验前先把驱动板的输入逻辑查清楚再设计MCU的输出极性。如果驱动板的输入是高有效那MCU的PWM输出极性也配成高有效通过硬件寄存器设置输出极性。不要用软件取反原因很简单软件取反在单路PWM时看着没问题但一旦加了死区很容易把死区逻辑搞乱而且更新不及时会产生毛刺。对齐方式同样重要。边沿对齐模式实现简单比较值只在周期开始更新适合对纹波要求不高的场景。中心对齐模式是把PWM计数器的值先增后减比较值在两边触发上下桥脉冲对称谐波含量较低是电机控制里更常用的方式。中心对齐的代价是计算频率时要多乘一个2很多人在这里算错。3.4 刹车保护与输出安全高级定时器一般都有专门刹车功能也叫故障保护输入。外部信号触发后PWM输出可以立即切到规定电平不需要CPU介入延迟极短。这个功能在电机驱动中必须用起来。刹车输入接一个外部急停按钮或者接驱动板故障输出。触发后六路PWM全部输出无效电平。所谓无效电平就是上桥和下桥都关断电机进入自由停转状态。刹车触发后定时器主输出被硬件封锁即使软件继续修改占空比也不会影响引脚。清除刹车状态之后需要软件重新使能主输出PWM才恢复正常。这个恢复逻辑一定要在代码里显式处理不能写一个死循环在那空等。4. 实验过程与关键配置4.1 初始化步骤与时钟选择初始化步骤我拆成四块时钟和引脚、定时器参数、互补输出和死区、刹车配置。顺序不能乱尤其不能让PWM先跑起来再配置死区那样在配置窗口期内会有一段无死区输出非常危险。时钟选择上我这次用的是从外部晶振倍频到很高的系统时钟具体频率以手头MCU为准。实验里把高级定时器的时钟设为时钟树上的定时器时钟不额外分频或分频系数很小。这样死区时间的分辨率最高死区寄存器可以配置出很精确的延迟。PWM频率的设计公式也要想清楚。边沿对齐模式下频率等于定时器时钟除以预分频系数和自动重装载值的乘积。中心对齐模式下计数器需要来回计数实际频率要再除以2。我这次用中心对齐模式预分频设为0自动重装载值根据频率反推。如果定时器时钟是168MHz想要25kHz波形自动重装载值大约就是3359实现出来频率非常接近25kHz。4.2 六路互补PWM配置参考代码下面这段代码是参考写法芯片不同寄存器名字会有差异但流程不变。我刻意保留了完整结构实际使用时按自己的MCU手册对应修改寄存器即可。void pwm_gpio_init(void) { // 使能GPIO和定时器时钟 // 高级定时器通道1、2、3各自对应一组互补引脚 // 配置为复用推挽输出 // 同时配置刹车输入引脚为输入模式 } void pwm_timer_init(void) { // 基本计数参数 timer.prescaler 0; timer.period 3359; // 中心对齐模式下约25kHz timer.repetitionCounter 1; // 每两次更新事件后触发 timer.counterMode CENTER_ALIGNED; // 中心对齐模式 // 配置通道1、2、3为PWM输出高有效 timer.channel[0].mode PWM; timer.channel[0].polarity ACTIVE_HIGH; timer.channel[0].ccr 840; timer.channel[1].mode PWM; timer.channel[1].polarity ACTIVE_HIGH; timer.channel[1].ccr 840; timer.channel[2].mode PWM; timer.channel[2].polarity ACTIVE_HIGH; timer.channel[2].ccr 840; // 配置互补输出使能和死区 timer.output[0].complementaryEnable 1; timer.output[1].complementaryEnable 1; timer.output[2].complementaryEnable 1; timer.deadTime 2000; // 死区2us具体换算见3.3节 timer.breakPolarity ACTIVE_LOW; timer.breakEnable 1; timer.autoRecovery 1; // 主输出使能 timer.mainOutputEnable 1; }这段代码不是能在所有芯片上直接编译但思路完整。关键点是输出模式设为PWM互补输出单独使能死区单独配置刹车先使能主输出最后使能。这个“最后使能”的目的就是避免初始化中途引脚输出不受控的波形造成直通风险。4.3 死区寄存器换算示例死区寄存器通常不是直接写2us而是写一个字段值由定时器时钟和内部时间基准单元决定。以某款常见MCU的DeadTime寄存器为例假设只有一个8位字段其单位由tDTS决定。tDTS通常是定时器时钟周期也可能使用额外的分频器。若tDTS为1/168MHz约等于5.95ns那2us的死区大约需要336个tDTS。但8位字段最大255所以必须提前配置一个额外的“长死区”模式让每个单位变成tDTS的倍数比如乘以16。这样2us就只需要336除以16等于21个单位。这样写寄存器值21就能得到约2us死区。实际调试时不要只凭计算就认为配置正确。我会在死区寄存器写入后立刻用示波器测量观察实际死区值和设计值的偏差。不同芯片手册对死区字段的定义差异很大可能有3位、8位、还有分高低两个字段的务必以手册为准。最可靠的验证方法始终是示波器实测。4.4 实测波形验证步骤第一步先测任意一组上下桥波形。示波器通道1接UH通道2接UL同时显示。正常情况下看到的是互补波形在高电平到低电平切换之间有一小段两个信号都是低电平的间隙这个间隙就是死区。第二步测三路上桥的相位。把通道1接UH通道2接VH或者用逻辑分析仪看三根线确认V相和W相上桥相对于U相分别滞后120度。相位不对的话后面接电机大概率转不动或者反转。第三步动态调整占空比。通过上位机或者调试器修改三个通道的比较值观察波形脉宽同步变化。注意修改比较值时要在更新事件之后生效否则波形会突然跳变。我建议打开预装载能力这样比较值在更新事件时才被加载避免边沿抖动。第四步验证刹车。让PWM正常运行触发刹车输入示波器看到六路全部变成无效电平。清除刹车信号之后主输出恢复波形正常。这个验证我在实际项目中反复做每次都有效。第五步接低压驱动板和空载电机。母线电压先用12V不接电机的情况下用手转动电机轴确认磁阻感均匀。再接电机输出占空比从5%开始缓慢增加观察母线电流不要异常上升。这一步通过后才算实验真正完成。5. 常见问题排查实录5.1 六路波形乱序、相位错位这个问题的表现是逻辑分析仪上六路都有波形但三个上桥之间的顺序不是互差120度有时甚至出现同一组上下桥同时导通的情况。排查方向首先看引脚映射。MCU的定时器通道和引脚复用不是随便定义的同一个通道可能能映射到不同引脚。如果初始化时把通道1接到了原来应该接通道2的引脚上就会出现相位错乱。建议把每个PIN脚和定时器通道的对应关系整理成表格对照初始化代码逐一确认。其次看计数器和比较值的相对关系。如果三个通道使用同一个计数器但CCR值设置成不同的相位偏置相位差就是由CCR差值决定的。我见过有人把CCR值设置了三个不同数字但三个通道用的都是同一个CCR寄存器结果相位完全一致。确认每个通道独立使用自己的比较寄存器是这类型问题的重要突破口。5.2 死区缺失导致上下管直通这个问题的表现很直接母线电流异常大驱动板发烫甚至烧毁。示波器看上下桥波形中间没有低电平间隙两个信号在切换沿几乎贴在一起。原因多半是死区配置没有真正生效。有些MCU的死区字段需要在使能PWM输出之前写入写入之后再改不会生效或者需要更新事件后才加载。我调试时遇到过一次原因是仿真器直接修改了死区寄存器但定时器已经运行导致寄存器没有真正加载。解决办法关闭定时器重新初始化死区寄存器再开启输出。同时在代码里加一个自检函数在PWM开始输出前读回死区寄存器和设计值比较不一致就报错停机。这个自检虽然很简单但能省掉不少现场排查时间。5.3 占空比设置不对称三个通道的占空比都设置为50%但示波器看下来U相是50%V相不是W相又有偏差。这种问题在高精度控制里非常致命会导致电流不平衡。常见原因有两个第一比较值寄存器位宽和ARR位宽不同如果CCR接近ARR边界可能出现溢出或截断第二没有开启预装载修改CCR后不同通道在各自比较事件瞬时生效导致波形不对称。我的建议是三个通道的CCR更新放在同一个更新事件里并且周期性同步更新。如果芯片支持多通道同时更新就配置为同一个更新事件再更新。如果硬件不支持同时更新至少要保证CPU在同一个中断里写三个寄存器减小时间窗口。5.4 上电瞬间误开通这个问题很隐蔽。程序正常运行时波形完全正确但每次上电一瞬间电机都会轻微抖动一下或者驱动板有电流冲击。原因是MCU引脚在上电复位阶段处于未定义状态如果这个状态下PWM引脚输出高电平且驱动板输入恰好是高有效那功率管就会瞬间导通。解决办法有几层硬件上在PWM引脚到驱动板输入端之间加下拉电阻保证未配置阶段引脚稳定在无效电平软件上初始化顺序要“先配置引脚后配置定时器”并且主输出使能放在最后。如果芯片支持引脚默认输出安全电平的功能也一并打开。我在这次实验中还做了一层保护MCU PWR引脚和驱动板使能引脚连接MCU完成自检后再给驱动板发送允许信号。这个逻辑虽然简单但上电瞬间的安全确实需要多级保障。5.5 示波器测量引入的假波形有时候看到的波形像振铃一样上下桥切换时出现连续振荡第一反应是驱动电路有严重问题。但实际上可能是探头地线过长或者参考地接触不良。我排查过一次换了一根很短的接地弹簧波形立刻干净很多。这不是玄学探头的接地环路相当于一个电感高频开关信号在这个电感上会产生压降示波器看到的就是真实信号叠加了噪声。测量高频PWM时尽量用弹簧地线不要用长鳄鱼夹线。还有一个容易遇到的问题示波器带宽不足或采样率设置太低把窄的死区间隙滤掉了导致看不出死区是否存在。此时要调整示波器时基把死区那段波形放大看确认间隙确实存在。6. 几个容易被忽略的经验6.1 先空载再带载先低压再高压这个顺序看上去很保守但它能救下不少电路板。六路PWM验证通过之后不要直接上高压大功率电机。我建议按这样的阶梯递进纯逻辑测量空载驱动板带低压电机带中压电机最后再根据项目需求上额定电压。每一步如果发现异常都回到上一步去排查。尤其要注意的是空载电机和带载电机对死区的敏感度完全不同。空载时电流小直通损伤有限带载时电流大直通很容易烧管子。所以即使前几步顺利带载测试时也不能掉以轻心第一次通电最好用限流电源把最大电流限制在几百毫安到一安培之间。看到母线电流异常就别犹豫直接断电。6.2 死区补偿别一上来就做很多人知道死区会导致波形畸变和电流谐波于是马上研究死区补偿算法。我的建议是实验阶段先不做死区补偿甚至先忘记这件事。补偿算法本身牵涉电流极性判断、相电压重构和软件延迟补偿任何一个地方出错都会让调试工作像滚雪球一样越来越大。把基础波形验证好、让系统在无补偿情况下稳定转起来再逐步引入死区补偿这样才能评估补偿前后的效果差异。直接一起上线出了问题你根本不知道是方向判断错了还是补偿系数算错了还是相位估计算法的问题。6.3 软件刹车与硬件刹车配合很多MCU支持软件产生刹车事件也支持外部输入触发硬件刹车。两者的区别是软件刹车依赖CPU执行如果程序跑飞或者卡在死循环软件刹车可能不会生效硬件刹车不依赖CPU外部信号直接作用于定时器输出即使内核异常也能切断PWM。所以实验里我同时配置了软件刹车和硬件刹车。硬件刹车接急停按钮这是最后一道保险软件刹车用于正常停机流程比如收到上位机停机指令后先停机再进入待机模式。主输出在刹车恢复后需要重新使能这个恢复逻辑一定要在正常流程里显式写好不能依赖仿真器或调试器手动操作。最后再分享一个我个人的操作习惯完成六路互补PWM验证之后把示波器截图、寄存器配置、接线表、异常记录一起归档。不要觉得这是多此一举实际项目维护时这堆记录能帮你很快恢复现场。特别是寄存器配置隔三个月再回头看的代码你未必能立刻想起来当时为什么这么配。这个实验看似基础但它把PWM发生、死区、相位、刹车这些最关键的底层逻辑全部摸了一遍后面做再复杂的控制算法这份底子都用得上。