
1. eFlexPWM从基础脉冲到复杂控制的引擎如果你在嵌入式领域尤其是电机控制或数字电源方向摸爬滚打过那么对PWM脉冲宽度调制一定不会陌生。它就像是我们手中的“数字画笔”通过调节高低电平的占空比在数字世界里精确地“绘制”出模拟信号从而控制电机的转速、LED的亮度或是开关电源的输出电压。但很多时候我们只是调用库函数设置一个频率和占空比对底层硬件如何精确地产生这个波形却知之甚少。这就好比开车只会踩油门和刹车却不懂发动机和变速箱的工作原理一旦遇到复杂的路况比如需要精确同步的多路PWM、插入死区时间防止桥臂直通、或者实现故障瞬间关断就容易束手无策。NXP的增强型FlexPWMeFlexPWM模块就是为应对这些复杂“路况”而生的高性能“动力总成”。它远不止是一个简单的定时器加比较器。我在多个无刷直流电机BLDC和永磁同步电机PMSM驱动项目中深度使用过它其设计之精巧、功能之强大让我在实现诸如磁场定向控制FOC这种对时序要求极其苛刻的算法时依然能游刃有余。它的核心秘密就藏在那一组组看似复杂的寄存器里。今天我们就抛开简单的API直接深入寄存器层面把eFlexPWM特别是其子模块Submodule的控制核心——PWM_SMnCTRL和PWM_SMnCTRL2等寄存器——掰开揉碎了讲清楚。理解这些你才能真正驾驭这头“猛兽”从实现基础的呼吸灯到构建一个稳定可靠的三相电机驱动逆变器。2. 核心架构与设计思路拆解在深入寄存器之前我们必须先建立起对eFlexPWM模块整体架构的认知。你不能拿着一堆螺丝刀就去修车得先知道发动机舱的布局。2.1 模块化与子模块协同eFlexPWM不是一个单一的PWM发生器而是一个高度模块化、可灵活配置的系统。一个典型的eFlexPWM模块包含多个独立的子模块Submodule 常缩写为SM例如SM0, SM1, SM2, SM3。每个子模块都是一个功能完整的PWM发生器拥有自己独立的16位计数器、六个比较值寄存器VAL0-VAL5以及全套控制逻辑。这种设计的美妙之处在于“独立且可联动”。每个子模块可以独立工作产生一路或两路互补对PWM波适用于控制独立的设备。更重要的是子模块之间可以通过“主-从”关系进行同步。通常SM0被设计为主模块Master它可以产生同步SYNC和重载RELOAD信号分发给其他作为从模块Slave的子模块。这就保证了多路PWM信号比如驱动三相电机的六路PWM具有完全同步的时钟基准和周期起点这对于电机控制中避免相间干扰、确保矢量合成的准确性至关重要。如果各路PWM周期稍有错位就会引入低频谐波导致电机震动和噪音我在早期调试FOC时就曾因此吃过亏。2.2 关键寄存器组概览与功能映射寄存器是软件与硬件对话的语言。eFlexPWM子模块的寄存器大致可以分为几类理解了分类配置时就不会晕头转向计数器与周期控制寄存器这是PWM的“心脏”和“节拍器”。PWM_SMnCNT只读寄存器实时反映计数器的当前值。调试时观察它可以知道计数器是否在按预期运行。PWM_SMnINIT设置计数器的初始值。计数器减到最小值或增到最大值后会重新加载这个值。PWM_SMnVAL1这是定义PWM周期的关键寄存器。计数器运行的范围通常是从INIT到VAL1。(VAL1 - INIT 1)乘以PWM时钟周期就是PWM波的周期。与之配合的PWM_SMnFRACVAL1用于实现周期的小数分频能获得更精细的频率分辨率。比较值与占空比控制寄存器这是PWM的“画笔”决定波形形状。PWM_SMnVAL2/PWM_SMnVAL3通常用于控制PWMA通道的上升沿开启和下降沿关闭时刻。VAL2 VAL3时在VAL2时刻输出变高在VAL3时刻变低从而形成正脉冲。PWM_SMnVAL4/PWM_SMnVAL5同理用于控制PWMB通道。PWM_SMnVAL0这是一个特殊的比较值它定义了“半周期”重载点并控制PWMX信号的置位和本地同步信号的复位。在中心对齐模式中它常被设置为(INITVAL1)/2即计数器计数到中点。对应的PWM_SMnFRACVAL2/3/4/5寄存器用于微调边沿位置实现高分辨率的占空比控制对于需要极细粒度调制的应用如高频数字电源非常有用。控制与配置寄存器本文核心这是PWM的“大脑”和“神经系统”。PWM_SMnCTRLPWM_SMnCTRL2全局行为控制器。它们决定了计数器如何运行时钟源、预分频、寄存器如何更新重载时机、模式、输出如何表现独立/互补、双脉冲使能等最根本的逻辑。配置错误会导致PWM无输出或行为异常。PWM_SMnOCTRL输出通道控制器。直接控制PWMA、PWMB、PWMX三个物理输出引脚的电平极性是否反向以及在故障、调试模式下的安全状态强制高、低或高阻态。这是安全性的最后一道硬件防线。PWM_SMnFRCTRL分数控制使能寄存器。用于启用或旁路上述提到的分数周期/边沿调整功能。故障与保护寄存器这是PWM的“安全气囊”。虽然输入资料未详细列出但必须提及例如PWM_FCTRL故障控制、PWM_FSTS故障状态等它们允许硬件引脚或软件快速触发故障立即将PWM输出强制切换到预设的安全状态通过OCTRL中的PWMAFS/PWMBFS设置防止功率电路损坏。在电机驱动中过流、过温保护都依赖于此。2.3 缓冲寄存器机制为什么配置不立即生效这是eFlexPWM一个非常重要且容易踩坑的设计。请注意看资料中对INIT,VAL1-5,FRACVAL1-5等寄存器的描述反复出现了“buffered”这个词。这意味着你写入这些寄存器的值并不是直接作用于当前正在运行的PWM生成硬件。它们首先被存入一个“缓冲区”Buffer。真正的“生效”需要等待一个“加载机会”Load Opportunity并在主控制寄存器PWM_MCTRL中的LDOKLoad Okay位被置位后缓冲区的内容才会一次性、同步地更新到真正的“影子寄存器”Shadow Register中由硬件使用。为什么这么设计想象一下你要同时更新PWM的周期和两路占空比。如果这些寄存器是直接生效的而你是在程序的不同时刻分别写入VAL1、VAL2、VAL3那么在写入过程中可能会产生一个畸形的PWM周期前半段是老周期新占空比后半段是新周期老占空比。这对于电机驱动是灾难性的可能导致电流冲击。缓冲机制确保了所有相关参数能在同一个PWM周期边界被原子性地切换保证了波形的连续性和一致性。如何触发加载设置PWM_SMnCTRL[LDMOD] 1那么一旦你设置MCTRL[LDOK]1立即生效。设置PWM_SMnCTRL[LDMOD] 0通常情况则需要同时满足两个条件MCTRL[LDOK]1。遇到下一个“重载点”。重载点由CTRL[FULL]全周期重载计数器等于VAL1时和/或CTRL[HALF]半周期重载计数器等于VAL0时决定。实操心得在初始化或动态调整PWM参数时标准的流程是先修改所有需要更新的缓冲寄存器VAL1,VAL2等然后设置MCTRL[LDOK]1最后根据LDMOD的模式等待或立即生效。务必在LDOK1时避免再次写入缓冲寄存器否则行为是未定义的。3. 核心控制寄存器深度解析与配置要点现在让我们聚焦于最核心的两个控制寄存器PWM_SMnCTRL2和PWM_SMnCTRL。它们定义了子模块的“性格”与“行为模式”。3.1 PWM_SMnCTRL2工作模式与同步控制这个寄存器主要管理子模块的初始化、同步、时钟源以及特殊输出模式。位域详解与配置策略DBGEN (Bit 15) / WAITEN (Bit 14)调试与等待模式使能。功能决定当芯片进入调试模式Debug或等待模式Wait时PWM输出是否继续保持。配置建议非常重要手册中给出了强烈警告。对于三相交流电机等需要持续更新PWM参数的应用必须保持默认值0即在调试/等待模式下禁用PWM输出。因为在这些模式下CPU可能停止无法更新电流环、位置环等算法所需的PWM参数维持输出会导致失控。对于简单的直流电机或LED调光可以设为1以方便调试。我的经验是在电机控制项目中除非你百分百确定安全否则永远不要开启它们。INDEP (Bit 13)独立/互补模式选择。功能这是区分普通PWM和电机驱动PWM的关键。0PWMA和PWMB构成一个互补对。这是驱动一个半桥如MOSFET的上下管的标准模式。两个输出通常相反并可以插入死区时间Deadtime防止上下管同时导通直通短路。1PWMA和PWMB作为两个完全独立的PWM通道输出。配置建议驱动全桥、三相逆变器时每个桥臂都需要一对互补PWM因此必须设为0。对于控制两个独立的设备如两个LED则设为1。INIT_SEL[1:0] (Bit 9-8)初始化信号源选择。功能决定是什么事件来触发计数器重新加载INIT值即开始一个新的PWM周期。00本地同步Local Sync。当本子模块的计数器达到VAL1时产生本地同步信号复位自身计数器。这是最常用的自运行模式每个子模块自己决定自己的周期。01主重载Master Reload。使用来自SM0的重载信号。这用于让从模块SM1, SM2...的周期与主模块SM0严格同步。注意SM0不能选这个否则逻辑冲突。10主同步Master Sync。使用来自SM0的同步信号。与主重载类似但同步点可能不同。11外部同步EXT_SYNC。由外部引脚信号触发。配置建议对于需要多路同步的应用如三相逆变器通常将SM0配置为00自身同步SM1和SM2配置为01或10跟随SM0。这样可以确保三相PWM的周期起点完全一致。CLK_SEL[1:0] (Bit 1-0)时钟源选择。功能选择子模块计数器的时钟来源。00IPBus时钟即外设总线时钟通常与内核时钟同源或分频。最常用。01外部时钟EXT_CLK。10子模块0的辅助时钟AUX_CLK。用于让从模块使用与主模块完全相同的时钟源避免时钟偏移。11保留。配置建议大多数应用使用00。在极高精度同步要求下可以考虑让从模块使用10直接采用SM0的时钟但这会增加SM0的负载。3.2 PWM_SMnCTRL计数器行为与重载机制这个寄存器控制计数器的运行细节和寄存器更新重载的时机。PRSC[2:0] (Bit 6-4)预分频器。功能对CLK_SEL选中的时钟进行分频得到最终的PWM计数时钟。分频系数为1, 2, 4, ..., 128。计算示例假设IPBus时钟fclk 100 MHz需要PWM频率f_pwm 20 kHz采用边沿对齐模式计数器从0计数到VAL1。PWM周期计数值P fclk / (f_pwm * 分频系数)。若PRSC000分频1则P 100e6 / 20e3 5000。VAL1需设置为4999如果从0开始计数。这个值在16位有符号计数器范围内-32768~32767。若PRSC001分频2则P 100e6 / (20e3*2) 2500。VAL1设置为2499。配置建议选择合适的预分频使得VAL1的值在一个合理的范围内例如几百到几千。值太小会降低占空比分辨率值太大接近65535可能溢出或降低灵活性。通常先确定频率和时钟反推预分频。HALF (Bit 11) FULL (Bit 10)半周期与全周期重载使能。功能这两个位共同决定了缓冲寄存器值更新到影子寄存器的时机。FULL1在计数器达到VAL1全周期结束时是一个重载机会。HALF1在计数器达到VAL0半周期点时是一个重载机会。可以同时使能这样每个PWM周期有两次更新机会中心对齐模式常用。与LDMOD的关系当LDMOD0时必须至少使能HALF或FULL之一重载机制才有效。当LDMOD1时重载立即发生与HALF/FULL无关。配置建议对于边沿对齐PWM计数器从0向上计数到VAL1通常只使能FULL1在周期结束时更新参数。对于中心对齐PWM计数器从0向上计数到VAL1再向下计数到0为了使波形正负半对称通常同时使能HALF1和FULL1这样在计数到VAL0中点和VAL1终点时都可以更新确保上下坡对称。中心对齐模式能显著减少谐波是电机驱动的首选。LDMOD (Bit 2)立即加载模式。功能如前所述LDMOD1时一旦设置LDOK缓冲寄存器立即加载无视HALF/FULL。配置建议谨慎使用。仅在初始化或需要极快速、非周期同步更新时使用。在正常运行中使用周期同步重载LDMOD0是更安全、更常规的做法。DBLEN (Bit 0) DBLX (Bit 1) SPLIT (Bit 3)双脉冲与分割控制。功能这是一组用于生成复杂PWM模式的高级功能。DBLEN1使能双脉冲模式。在一个PWM周期内PWMA和PWMB可以各自产生两个脉冲。这常用于某些特定的电机驱动算法或谐振变换器控制。DBLX1在DBLEN使能时此位控制PWMX输出是否为PWMA和PWMB的异或结果。SPLIT1在DBLEN使能时此位将双脉冲“分割”到PWMA和PWMB上使它们各输出一个脉冲。配置建议普通PWM应用保持为0。在需要更复杂的多脉冲调制时再深入研究。4. 从零配置一个互补PWM输出实操流程理论说了这么多我们动手配置一个最经典的应用场景产生一对带死区的互补PWM信号用于驱动一个半桥电路。假设使用SM0IPBus时钟为100MHz目标PWM频率为20kHz死区时间为1us。4.1 步骤一确定核心参数与计算PWM频率与周期f_pwm 20 kHz 周期T_pwm 1 / 20e3 50 us。时钟与预分频选择PRSC000不分频PWM计数时钟f_pwm_clk 100 MHz周期T_clk 10 ns。计算计值一个PWM周期的时钟周期数P T_pwm / T_clk 50us / 10ns 5000。采用中心对齐模式Up-Down计数计数器从0计数到VAL1再返回0。因此VAL1 P/2 - 1 2500 - 1 2499。因为计数到VAL1即反转所以峰值是VAL1。设置VAL0 0这样半周期重载点就在计数为0时中心对齐模式下0既是起点也是中点。计算占空比对应值假设需要50%占空比高电平时间占半个周期。在中心对齐模式下VAL2和VAL3分别控制高电平开始和结束的计数点。对于50%占空比高电平应从0开始在计数值为VAL1的一半时结束。VAL2 0从0开始变高VAL3 VAL1 / 2 1249计数值达到1249时变低然后继续计数到VAL1再返回在下降段对称地再产生一个高电平脉冲。计算死区时间计数值死区时间T_dead 1 us。死区时间对应的时钟周期数D T_dead / T_clk 1us / 10ns 100。eFlexPWM的死区时间通常通过硬件死区插入子模块实现其配置寄存器如PWM_SMnDTCNT0,PWM_SMnDTCNT1需要设置这个值D。注意死区时间会同时影响互补两路信号的上升沿或下降沿。4.2 步骤二寄存器配置代码示例C语言风格以下是一个简化的配置序列展示了关键寄存器的设置顺序和思路。// 假设 PWM0 是 eFlexPWM 模块 0 的基地址 SM0 是其第一个子模块 #define PWM0_SM0_CTRL2 (*(volatile uint16_t*)(PWM0_BASE 0x02)) #define PWM0_SM0_CTRL (*(volatile uint16_t*)(PWM0_BASE 0x03)) #define PWM0_SM0_INIT (*(volatile uint16_t*)(PWM0_BASE 0x01)) #define PWM0_SM0_VAL0 (*(volatile uint16_t*)(PWM0_BASE 0x05)) #define PWM0_SM0_VAL1 (*(volatile uint16_t*)(PWM0_BASE 0x07)) #define PWM0_SM0_VAL2 (*(volatile uint16_t*)(PWM0_BASE 0x09)) #define PWM0_SM0_VAL3 (*(volatile uint16_t*)(PWM0_BASE 0x0B)) #define PWM0_SM0_OCTRL (*(volatile uint16_t*)(PWM0_BASE 0x11)) #define PWM0_MCTRL (*(volatile uint16_t*)(PWM0_BASE 0xC4)) // 1. 首先停止PWM输出如果需要重新配置 // 通常通过禁用输出或设置计数器为停止状态这里简化假设从初始状态开始。 // 2. 配置控制寄存器2 (PWM_SM0CTRL2) uint16_t ctrl2_val 0; ctrl2_val | (0 15); // DBGEN 0: 调试模式禁用PWM ctrl2_val | (0 14); // WAITEN 0: 等待模式禁用PWM ctrl2_val | (0 13); // INDEP 0: PWMA和PWMB为互补对 ctrl2_val | (0 9); // INIT_SEL[1:0] 00: 本地同步自运行 ctrl2_val | (0 1); // CLK_SEL[1:0] 00: IPBus时钟 PWM0_SM0_CTRL2 ctrl2_val; // 3. 配置控制寄存器 (PWM_SM0CTRL) uint16_t ctrl_val 0; ctrl_val | (0 12); // LDFQ[3:0] 0000: 每个重载机会都加载默认 ctrl_val | (1 11); // HALF 1: 使能半周期重载中心对齐需要 ctrl_val | (1 10); // FULL 1: 使能全周期重载 ctrl_val | (0 6); // PRSC[2:0] 000: 预分频 1 (100MHz) ctrl_val | (0 3); // SPLIT 0: 不分割双脉冲 ctrl_val | (0 2); // LDMOD 0: 使用周期重载非立即加载 ctrl_val | (0 1); // DBLX 0 ctrl_val | (0 0); // DBLEN 0 PWM0_SM0_CTRL ctrl_val; // 4. 配置输出控制寄存器 (PWM_SM0OCTRL) uint16_t octrl_val 0; octrl_val | (0 10); // POLA 0: PWMA输出不反向高电平有效 octrl_val | (0 9); // POLB 0: PWMB输出不反向高电平有效 // 故障状态设置假设故障时强制输出低电平 octrl_val | (0 5) | (0 4); // PWMAFS 00: 故障时强制0 octrl_val | (0 3) | (0 2); // PWMBFS 00: 故障时强制0 PWM0_SM0_OCTRL octrl_val; // 5. 配置缓冲寄存器值先写入缓冲区 PWM0_SM0_INIT 0; // 计数器初始值 PWM0_SM0_VAL0 0; // 半周期重载点中心对齐模式设为0 PWM0_SM0_VAL1 2499; // 计数器峰值决定周期 PWM0_SM0_VAL2 0; // PWMA 高电平开始点 PWM0_SM0_VAL3 1249; // PWMA 高电平结束点 (50%占空比) // 注意在互补模式下PWMB的VAL4/VAL5通常由硬件根据VAL2/VAL3和死区时间自动生成或设置为互补值。 // 这里假设使用硬件互补和死区插入VAL4/VAL5可能不需要显式设置或设置为VAL3/VAL2。 // 6. 配置死区时间寄存器地址需参考具体手册 // PWM0_SM0_DTCNT0 100; // 死区时间计数值例如100个时钟周期(1us) // PWM0_SM0_DTCNT1 100; // 7. 触发加载设置主控制寄存器的LDOK位使所有缓冲值生效 PWM0_MCTRL | (1 0); // 设置LDOK位 (假设Bit 0是LDOK) // 8. 使能PWM输出通过OUTEN寄存器 // *(volatile uint16_t*)(PWM0_BASE 0xC0) | (1 1) | (1 0); // 使能PWMA和PWMB输出4.3 步骤三验证与调试配置完成后如何验证逻辑分析仪/示波器直接测量PWMA和PWMB引脚应看到频率20kHz占空比50%且两者反相中间有1us的死区间隔。读取计数器寄存器在调试器中实时读取PWM_SMnCNT应能看到其值在0到2499之间往复变化中心对齐。检查标志位有些状态寄存器可以指示重载事件、比较匹配事件是否发生。注意以上代码是概念性示例寄存器偏移地址、位域位置必须严格参照你所使用的具体NXP MCU型号的参考手册。不同型号的eFlexPWM模块寄存器地址和位定义可能有细微差别。5. 高级应用与故障排查实录掌握了基础配置就可以挑战更复杂的应用了。这里分享几个高级场景和常见坑点。5.1 实现三相六步BLDC驱动对于三相无刷直流电机你需要三个子模块SM0, SM1, SM2每个模块产生一对互补PWM对应一个桥臂的上下管。关键配置点同步将SM1和SM2的INIT_SEL设置为01主重载或10主同步让它们的周期起始点与SM0同步。中心对齐所有子模块的CTRL寄存器都应设置HALF1和FULL1以实现中心对齐PWM降低谐波和噪声。死区时间每个子模块必须配置合适的死区时间这是硬件安全的关键。输出控制根据电机换相表在特定时刻改变VAL2/VAL3和VAL4/VAL5的值或者更高效地使用eFlexPWM的“输出掩码”PWM_MASK和“软件控制输出”PWM_SWCOUT寄存器在换相点直接控制输出使能实现“堵转”或“续流”状态。5.2 分数周期与高分辨率PWM当需要的PWM频率不是系统时钟的整数分频时或者需要极其精细的占空比调节比如0.01%步进就需要用到分数寄存器FRACVAL1~5。原理通过FRACVAL1累加小数周期每累加满一个整数周期就在对应的VAL1周期上临时增加一个时钟周期。FRACVAL2/3/4/5则用于微调边沿位置。配置流程使能分数功能设置FRCTRL寄存器中的FRAC1_EN、FRAC23_EN、FRAC45_EN。设置FRAC_PU1给分数延迟模拟电路上电需等待至少25us。计算并设置分数值。例如需要PWM频率为19.9876 kHz系统时钟100MHz整数分频无法精确得到。可以计算出一个接近的整数周期值VAL1然后用FRACVAL1来补偿误差。避坑指南手册明确警告当VAL2和VAL3或VAL4和VAL5的差值小于等于3个时钟周期时应禁用对应的分数使能位FRAC23_EN或FRAC45_EN否则可能导致输出错误。因为分数调整电路需要最小脉冲宽度来工作。5.3 常见问题排查速查表在实际调试中你可能会遇到以下问题现象可能原因排查步骤与解决方案无PWM输出1. 输出未使能 (PWM_OUTEN)。2. 计数未运行时钟源错误或未使能。3. 故障输入有效输出被强制到安全状态。1. 检查PWM_OUTEN寄存器对应位是否置1。2. 检查CTRL2[CLK_SEL]和CTRL[PRSC]用调试器读CNT寄存器看是否变化。3. 检查故障输入引脚状态和PWM_FSTS寄存器确认是否进入故障状态。检查OCTRL中故障状态位的设置。PWM频率不对1.VAL1或INIT计算错误。2. 预分频器PRSC配置错误。3. 时钟源CLK_SEL选择错误。1. 重新计算周期计数值。确认是边沿对齐还是中心对齐模式。2. 核对PRSC分频系数。3. 确认IPBus时钟频率是否正确CLK_SEL是否选对源。占空比无法调节或不对1.VAL2/VAL3或VAL4/VAL5的值设置不合理如VAL2 VAL3。2. 缓冲寄存器未成功加载LDOK机制问题。3. 输出极性POLA/POLB设置反了。1. 确保比较值在计数器运行范围内且逻辑正确对于正脉冲通常VAL2 VAL3。2. 确保在修改缓冲寄存器后正确设置了MCTRL[LDOK]并确认LDMOD和HALF/FULL配置使得重载能发生。3. 检查OCTRL中的极性位或用示波器观察实际电平。互补输出没有死区或直通1. 死区时间寄存器未配置或配置为0。2. 死区插入模块未使能如果存在独立使能位。3.INDEP位错误地设为1独立模式。1. 确认死区时间寄存器如DTCNT0/1已写入正确的计数值。2. 查阅手册确认是否有额外的死区使能控制位。3. 确认CTRL2[INDEP]0。多路子模块不同步1. 从模块的INIT_SEL未设置为跟随主模块。2. 主模块未产生同步/重载信号。3. 各子模块时钟源不一致。1. 检查SM1, SM2等的CTRL2[INIT_SEL]应设置为01或10。2. 确认主模块SM0的VAL1已设置且计数器在运行。3. 检查所有子模块的CTRL2[CLK_SEL]建议都设为00IPBus时钟或从模块设为10主模块时钟。动态更新参数导致波形抖动1. 在错误的时机非重载点写入了缓冲寄存器。2. 未使用缓冲机制直接写入了可能正在使用的寄存器。1.务必遵循“写缓冲-置LDOK-等待硬件加载”的流程。可以在置LDOK前一次性更新所有需要改动的缓冲寄存器。2. 可以考虑在中断服务程序中于周期开始或结束时进行参数更新。调试eFlexPWM示波器和逻辑分析仪是你的最佳伙伴。同时充分利用MCU的寄存器查看和内存查看功能确保你写入的值和硬件实际使用的值是一致的。理解“缓冲-影子”机制是避免很多灵异问题的关键。最后电机控制无小事任何PWM的异常都可能导致硬件损坏在给功率板通电前务必先用低压或电阻负载验证PWM波形完全正确。