1. ePWM模块寄存器全景:从时间基准到故障保护
在嵌入式电机控制和数字电源领域,德州仪器(TI)的增强型脉冲宽度调制(ePWM)模块是一个功能强大且高度灵活的硬件外设。很多工程师初次接触时,面对动辄几十个寄存器、数百个配置位,往往会感到无从下手。我刚开始调电机驱动时,也曾在这些寄存器手册里“迷路”,配置出来的PWM波形要么频率不对,要么死区时间算错,甚至直接导致MOS管炸机。后来花了大量时间,把每个寄存器的功能、关联以及背后的设计逻辑都啃了一遍,才真正理解了这套精密的系统。
简单来说,你可以把ePWM模块想象成一个高度可编程的“波形发生器流水线”。它不是一个单一的功能块,而是由多个相互协作的子模块(时间基准TB、计数器比较CC、动作限定器AQ、死区发生器DB、故障保护TZ等)串联而成。每个子模块的行为,都通过其对应的寄存器来精确控制。寄存器配置的本质,就是在定义这条流水线上每个环节的“游戏规则”。比如,时间基准(TB)子模块的寄存器(TBCTL, TBPHS, TBPRD)决定了脉冲的“心跳”节拍和同步方式;计数器比较(CC)子模块的寄存器(CMPCTL, CMPA, CMPB)则决定了在心跳周期的哪个时刻“踩下开关”;而动作限定器(AQ)和死区(DB)寄存器,则负责将这个“开关动作”翻译成最终输出引脚上精准的上升沿和下降沿。
理解这些寄存器,绝不能孤立地看。它们是一个环环相扣的整体。例如,你配置了TBCTL的计数模式,就必须同步考虑CMPA/CMPB的比较值范围;你启用了死区,就必须清楚DBRED和DBFED寄存器的值是如何与TBCLK时钟关联的。本文将带你深入这条“流水线”,从最核心的时间基准控制寄存器(TBCTL)开始,一路剖析到故障保护选择寄存器(TZSEL),结合我在实际电机控制项目中的配置经验和踩过的坑,为你提供一份可直接“抄作业”的寄存器配置指南。我们会避开枯燥的位域罗列,重点讲解每个寄存器配置项的设计意图、应用场景以及配置时的关键注意事项。
2. 时间基准(TB)子模块:PWM波形的“心脏与节拍器”
时间基准子模块是整个ePWM的节奏之源。它产生一个核心的计数器TBCTR,这个计数器的计数模式、频率和相位,直接决定了PWM波形的周期和同步关系。配置好TB子模块,是生成正确PWM的第一步,也是最容易出错的一步。
2.1 TBCTL_TBSTS寄存器:定义计数行为与同步机制
这个寄存器是TB子模块的控制与状态核心。它融合了控制位(TBCTL)和状态位(TBSTS),我们主要关注控制部分。
TBCTL[CTRMODE](位1-0):计数器模式。这是第一个关键选择,决定了TBCTR计数器的计数方式。
- 00:向上计数模式(Up-Count)。计数器从0开始,每个TBCLK周期加1,直到等于周期值TBPRD,然后归零重新开始。此模式产生不对称PWM波形。在电机控制中,这常用于简单的单极性调制或某些特定的SPWM生成。
- 01:向下计数模式(Down-Count)。计数器从TBPRD值开始,每个TBCLK周期减1,直到等于0,然后重新加载TBPRD。同样产生不对称PWM,但波形相位与向上计数相反,应用相对较少。
- 10:向上-向下计数模式(Up-Down-Count)。计数器从0开始向上计数到TBPRD,然后立即向下计数回0,如此循环。此模式产生对称PWM波形,即每个PWM周期内,波形关于中心点对称。这是电机控制(如SPWM、SVPWM)和全桥/半桥电源转换中最常用的模式,因为它能有效降低谐波,且便于中心对齐的采样。
- 11:停止模式。计数器冻结,通常用于调试或紧急停止。
实操心得:模式选择背后的“为什么”为什么电机控制常用向上-向下模式?假设TBPRD=1000。在向上计数模式下,当CMPA=300时,PWM高电平时间就是计数器从0到300的时间。而在向上-向下模式下,计数器会经过300两次(一次上行,一次下行),这使得PWM脉冲在周期内对称分布。这种对称性对于驱动H桥的上下管至关重要,能确保死区时间均匀分布,减少共态导通风险,并且使电流纹波更小。新手常犯的错误是,在需要对称PWM的场合误选了向上计数模式,导致控制效果不佳甚至硬件损坏。
TBCTL[PHSEN] & TBPHS寄存器:相位同步与主从配置。这是实现多个ePWM模块同步工作的关键。在多相电机控制(如三相永磁同步电机)或交错并联电源中,需要多个PWM通道彼此保持固定的相位差。
- PHSEN(相位使能):置1后,当该模块接收到同步信号(EPWMxSYNCI)时,其计数器TBCTR会立即加载TBPHS寄存器中设定的相位值。
- TBPHS(相位值寄存器):设定加载的相位值。例如,主模块的TBPHS设为0,从模块1的TBPHS设为TBPRD/3,从模块2的TBPHS设为2*TBPRD/3,即可实现三个PWM通道互差120度电角度,这是三相逆变器的核心配置。
- TBCTL[SYNCOSEL](同步输出选择):决定本模块产生同步输出信号(EPWMxSYNCO)的条件,可以传递给下一个ePWM模块作为其输入同步信号(EPWMxSYNCI),从而形成同步链。常见设置为:主模块选择“CTR=0”,从模块选择“EPWMxSYNCI”(即直接传递输入同步信号)。
TBCTL[CLKDIV] & [HSPCLKDIV]:时钟预分频。这两个字段共同决定时间基准时钟TBCLK的频率。公式为:TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV)。SYSCLKOUT是系统时钟。例如,系统时钟150MHz,希望TBCLK为75MHz以产生高分辨率PWM,可以设置HSPCLKDIV=1,CLKDIV=2。
注意事项:频率与分辨率权衡TBCLK的频率直接决定了PWM的时间分辨率。频率越高,你能设置的最小时间步进越小(分辨率越高),但计数器的最大周期(TBPRD)受限(通常为16位,最大值65535)。PWM频率 = TBCLK / (TBPRD * 模数)。在向上-向下模式下,模数为2*TBPRD。因此,高PWM频率和高分辨率是矛盾的。你需要根据应用计算:假设需要20kHz的PWM频率(电机控制常用),TBCLK=150MHz,则在向上-向下模式下,TBPRD = TBCLK / (2 * PWM_Freq) = 150MHz / 40kHz = 3750。此时,占空比分辨率约为 1/3750 ≈ 0.027%。如果盲目追求高TBCLK,可能导致TBPRD过小,分辨率不足。
TBCTL[PRDLD]:周期寄存器加载模式。这关系到TBPRD值的更新时机。
- 0(影子模式,默认):你写入TBPRD的值先进入影子寄存器,不会立即生效。只有当计数器TBCTR等于0(在向上或向上-向下模式下)时,影子寄存器的值才会加载到活动寄存器生效。这是保证PWM周期切换时无毛刺、平滑过渡的关键机制,在需要在线调整PWM频率的应用中必须使用此模式。
- 1(立即模式):写入TBPRD的值立即生效。这可能导致当前PWM周期被突然截断或拉长,产生不可预测的脉冲,通常仅用于初始化或特殊调试。
2.2 TBCTR与TBPRD:周期与实时计数
- TBPRD(时间基准周期寄存器):这个值定义了PWM的周期。如前所述,其生效方式由PRDLD控制。在代码中,我们通常通过宏或函数来设置它,例如
EPwm1Regs.TBPRD = 3750;。 - TBCTR(时间基准计数器寄存器):这是一个只读寄存器(虽然可写,但通常不直接写),实时反映当前计数器的值。你可以读取它来了解PWM周期的进度,常用于触发ADC采样(例如在向上-向下模式下,在TBCTR=0或TBCTR=TBPRD时采样,可以实现对称采样,消除偶次谐波)。
3. 计数器比较(CC)与动作限定(AQ)子模块:波形的“雕刻刀”
时间基准产生了规律的“心跳”,而计数器比较和动作限定子模块则负责在心跳的特定时刻“雕刻”出具体的脉冲形状。CMPA和CMPB是两个比较值寄存器,它们与实时计数器TBCTR进行比较,产生比较匹配事件。
3.1 CMPCTL寄存器:比较值的加载与缓冲管理
这个寄存器控制CMPA和CMPB值的加载行为,是保证PWM占空比平滑变化的核心。
SHDWAMODE/SHDWBMODE(影子模式选择):与TBPRD的影子模式类似。
- 0(影子模式,推荐):写入CMPA/CMPB的值先进入影子寄存器。何时加载到活动寄存器由LOADAMODE/LOADBMODE决定。这是在线更新占空比(如响应速度环计算)的标准做法,可以避免在PWM周期中间改变比较值导致的脉冲宽度畸变。
- 1(立即模式):写入立即生效,可能产生毛刺,慎用。
LOADAMODE/LOADBMODE(加载事件选择):在影子模式下,决定何时将影子寄存器的值载入活动寄存器。
- 00:在TBCTR=0时加载(向上或向上-向下模式)。
- 01:在TBCTR=TBPRD时加载(向下或向上-向下模式)。
- 10:在TBCTR=0或TBCTR=TBPRD时加载(仅向上-向下模式有效,在计数反转点加载,可实现每个PWM周期更新两次,适用于需要极高动态响应的场合)。
- 11:冻结,不加载。
配置示例:实现中心对称PWM更新对于最常用的向上-向下计数模式,通常将LOADAMODE设置为
10(CTR=Zero or PRD)。这样,在每个PWM周期的开始(CTR=0)和峰值(CTR=TBPRD)都会检查并加载新的CMPA值。假设你在计数器上行过程中计算出了一个新占空比并写入CMPA影子寄存器,这个新值会在计数器到达峰值并开始下行时立即生效,从而在下一个半周期就应用新的脉宽,实现了快速且同步的更新,避免了更新点错位导致的波形不对称。SHDWAFULL/SHDWBFULL(影子寄存器满状态):这是一个重要的状态标志。当影子寄存器已满(即已有值等待加载)时,该位为1。如果你此时再次写入,会覆盖之前未加载的值。在编写占空比更新函数时,最佳实践是检查该位,确保不会丢失更新指令。更稳健的做法是使用PWM中断服务程序(在CTR=0或PRD事件触发)中进行占空比计算和更新,这样可以自然同步。
3.2 CMPA/CMPB寄存器与AQCTLA/AQCTLB:定义边沿动作
这是PWM波形生成的直接执行层。CMPA和CMPB存储比较值。当TBCTR计数到与CMPA或CMPB相等时,会产生一个“匹配事件”。但这个事件本身并不直接改变输出引脚电平,它需要被“翻译”成动作。
动作限定器寄存器(AQCTLA, AQCTLB)就是这个翻译官。它为每个输出通道(EPWMxA和EPWMxB)定义了一组规则:当特定事件发生时,输出应该做什么。
关键事件类型:
- CAU/CAD:计数器等于CMPA且正在向上/向下计数。
- CBU/CBD:计数器等于CMPB且正在向上/向下计数。
- PRD:计数器等于周期值TBPRD。
- ZRO:计数器等于0。
可执行的动作:
- 00:无操作。
- 01:清除(输出强制低)。
- 10:置位(输出强制高)。
- 11:翻转。
经典配置案例:产生一对互补的带死区PWM(用于H桥一半)假设我们使用EPWM1A和EPWM1B驱动一个半桥,需要A和B互补,且高电平有效。
- 配置AQCTLA(控制EPWM1A):
CAU = 10 (Set):当计数器向上计数到CMPA时,将EPWM1A置为高电平。CAD = 01 (Clear):当计数器向下计数到CMPA时,将EPWM1A置为低电平。- 其他事件(CBU, CBD, PRD, ZRO)设为
00 (Do nothing)。
- 配置AQCTLB(控制EPWM1B):
CBU = 01 (Clear):当计数器向上计数到CMPB时,将EPWM1B置为低电平。CBD = 10 (Set):当计数器向下计数到CMPB时,将EPWM1B置为高电平。- 其他事件设为
00。
这样,我们就得到了两个互补的PWM信号:EPWM1A在计数上行过CMPA时变高,下行过CMPA时变低;EPWM1B则相反。但此时A和B是理想互补的,没有死区,直接驱动H桥会导致上下管瞬间直通短路,必须引入死区。这就是下一个子模块的工作。
4. 死区发生器(DB)子模块:硬件实现的“安全卫士”
死区时间是插入到互补PWM信号上升沿之间的一个短暂延时,确保一个开关管完全关断后,另一个开关管才开启,防止直通短路。ePWM的DB模块在硬件层面实现了这个功能,无需软件干预,精度高且稳定。
4.1 DBCTL寄存器:死区工作模式配置
这是死区模块的核心控制寄存器。
OUT_MODE(输出模式,位17-16):决定死区如何应用到输出。
- 00:旁路模式。AQ模块的输出直接送到下一级,不产生死区。用于不需要死区的场景。
- 01:使能下降沿延时,旁路上升沿。AQ模块的EPWMxA信号直接输出为EPWMxA(最终),而EPWMxB信号经过一个下降沿延时后输出为EPWMxB(最终)。这是最常用的“高有效互补带死区”模式,通常配合AQ模块生成低有效的EPWMxB原始信号。
- 10:使能上升沿延时,旁路下降沿。与上一种相反。
- 11:完全使能。对AQ输出的两个信号都进行延时处理,适用于更复杂的场景。
配置示例:结合AQ生成带死区互补PWM延续上一节的例子,我们希望EPWM1A高有效,EPWM1B低有效,并插入死区。
- AQ配置保持不变(A高有效,B低有效)。
- 设置
DBCTL[OUT_MODE] = 0x1(01b),即对B通道(来自AQ的EPWMxB)添加下降沿延时。 - 设置
DBCTL[IN_MODE] = 0x0(默认),死区输入源都来自AQ的EPWMxA。这意味着EPWMxA的边沿作为基准,EPWMxB的下降沿相对它进行延时。 - 设置
DBCTL[POLSEL] = 0x2(10b),即“Active High Complementary (AHC)”模式。这个模式的含义是:对EPWMxB信号进行取反。这正是我们需要的!因为AQ生成的EPWMxB是低有效,经过DB模块的取反,就变成了高有效,再经过下降沿延时,最终输出的EPWM1B就是一个与EPWM1A互补、且上升沿被延迟(即死区)的高有效信号。
IN_MODE(输入模式,位21-20):选择哪个AQ输出信号作为死区延时的输入源。对于典型的互补PWM,通常两个延时都参考同一个信号(如EPWMxA),设置为
00即可。POLSEL(极性选择,位19-18):如上例所述,用于对延时后的信号进行取反,以适应不同的驱动电路逻辑(高有效或低有效驱动)。
HALFCYCLE(半周期时钟,位31):置1时,死区计数器的时钟为TBCLK/2。这可以扩展死区时间的设置范围。当需要的死区时间较长,而DBRED/DBFED寄存器(10位,最大值1023)不够用时,可以启用此模式,等效于将延时分辨率降低一倍,但范围扩大一倍。
4.2 DBRED与DBFED寄存器:设置延时时间
这两个寄存器分别控制上升沿延时和下降沿延时的具体时间长度。延时时间计算公式为:延时时间 = (DBRED_DEL 或 DBFED_DEL) * TBCLK周期 * (HALFCYCLE? 2 : 1)
例如,TBCLK = 75MHz (周期约13.33ns),需要插入500ns的死区时间(下降沿延时)。
- 若不启用半周期时钟:
DBFED_DEL = 500ns / 13.33ns ≈ 37.5,取整为38。实际死区时间 = 38 * 13.33ns ≈ 506.5ns。 - 若寄存器值算出来大于1023,就需要启用
HALFCYCLE,此时时钟周期翻倍,DBFED_DEL = 500ns / (2*13.33ns) ≈ 18.75,取整为19。
避坑指南:死区时间计算与系统影响
- 精度取舍:死区时间设置存在量化误差。你需要根据开关管的开关速度(特别是关断时间)来权衡。通常死区时间要大于管子的关断时间,并留有一定余量。计算出的理论值要向上取整。
- 最小死区:即使将DBRED/DBFED设为0,硬件也可能会有几个纳秒的固有延时。数据手册中会有这个参数,设计时需考虑。
- 对占空比的影响:插入死区会损失有效的输出电压。例如,理论上50%的占空比,插入死区后,高电平时间会略微减少。在闭环控制算法(如FOC)中,有时需要进行死区补偿。
- 双边沿延时:在某些整流或特定调制算法中,可能需要同时对上升沿和下降沿进行延时(
OUT_MODE=11),此时需要分别计算并设置DBRED和DBFED。
5. 故障保护(TZ)子模块与数字比较(DC):系统的“紧急制动”
在电机驱动和电源系统中,过流、过压、过热等故障必须在微秒级甚至更短时间内响应,否则会造成永久性硬件损坏。ePWM的Trip-Zone(TZ)子模块就是专为此设计的硬件保护电路,它可以通过外部GPIO引脚(TZ1~TZ6)或内部数字比较器(DC)事件快速强制PWM输出到安全状态(通常为高阻或强制低)。
5.1 TZSEL寄存器:选择故障源
这个寄存器用于“选通”哪些信号可以触发保护。它分为两部分:单次触发(One-Shot Trip)和周期逐波限流(Cycle-By-Cycle, CBC)触发。它们的主要区别在于响应和恢复机制。
- 单次触发(OSHT):如TZSEL_OSHT1~6, TZSEL_DCAEVT1, TZSEL_DCBEVT1。当使能的故障信号有效时,ePWM模块立即进入故障状态,所有输出被强制为预设的安全状态(通过TZCTL寄存器配置)。这种故障是“锁存”的,一旦发生,即使故障信号消失,PWM输出也不会自动恢复。必须由软件手动清除故障标志(在TZCLR寄存器中写1)后,PWM才能重新运行。适用于严重的、需要人工干预的故障,如短路、严重过温。
- 周期逐波限流(CBC):如TZSEL_CBC1~6, TZSEL_DCAEVT2, TZSEL_DCBEVT2。当使能的故障信号有效时,ePWM模块在当前PWM周期内立即将输出强制为安全状态。但是,如果在下个PWM周期开始时故障信号已经消失,则PWM输出自动恢复正常运行。这种模式是“非锁存”的。适用于需要动态限流的场景,比如电机的峰值电流限制。当电流超过阈值时,立即掐掉当前脉冲的剩余部分;下个周期如果电流恢复正常,则继续工作。这为软件实现更复杂的限流算法提供了硬件基础。
配置决策:
- 将过流保护信号连接到TZ1引脚,并在TZSEL中使能
TZSEL_CBC1和TZSEL_OSHT1。这样,轻微的、短暂的过流会触发CBC保护,自动恢复,不影响系统连续运行;而持续的重度过流则会触发OSHT保护,锁存故障,等待软件处理。 TZSEL_DCAEVT1/2和TZSEL_DCBEVT1/2则允许你将内部数字比较器(DC)模块产生的事件作为故障源。DC模块可以比较ADC结果与设定的阈值,实现纯硬件方式的模拟量(如电流)故障保护,速度极快。
5.2 TZCTL与TZFLG寄存器:定义保护动作与状态查询
TZCTL寄存器:为每个PWM输出通道(A和B)分别配置,当指定的TZ事件(OSHT或CBC)发生时,输出应该被强制为何种状态。选项通常有:
- 00:高阻(Hi-Z)。这是最安全的方式,彻底关闭驱动。
- 01:强制为低(Force to 0)。适用于低电平有效的驱动电路,或需要将桥臂下管拉低的安全状态。
- 10:强制为高(Force to 1)。适用于高电平有效的驱动电路,但需谨慎,可能不安全。
- 11:无操作。不采取任何动作,仅标志,用于调试。
安全第一原则:对于功率桥臂,最安全的做法通常是配置为高阻。同时,确保你的功率驱动电路本身有下拉电阻,在高阻状态下能自然将栅极电压拉低,关闭开关管。不要依赖TZ模块的“强制低”作为唯一安全措施,因为如果MCU彻底失效,TZ模块也可能失效。硬件层面的互锁和下拉电阻是最后的安全防线。
TZFLG寄存器:这是一个状态寄存器。当TZ事件发生时,对应的标志位(CBCFLG, OSHTFLG)会被硬件置1。软件必须定期或在中断中查询这些标志,以判断故障来源。对于OSHT故障,在采取相应处理措施(如关闭系统、报警)后,需要向TZCLR寄存器的对应位写1来清除标志,才能让PWM模块退出故障状态。
5.3 数字比较(DC)与TZDCSEL寄存器:高级故障触发
TZDCSEL寄存器用于配置数字比较器事件(DCAEVT1/2, DCBEVT1/2)的触发条件。数字比较器子模块(DC)可以实时比较来自ADC的结果寄存器(DCAH/DCAL, DCBH/DCBL)与用户设定的阈值。
例如,你可以将电流采样的ADC结果连接到DCAH,并设置一个过流阈值。在TZDCSEL中,配置DCAEVT1的触发条件为“DCAH = high”(即ADC结果大于高阈值)。然后,在TZSEL中使能TZSEL_DCAEVT1作为OSHT故障源。这样,一旦电流超过阈值,无需任何CPU干预,硬件会在几个时钟周期内直接触发PWM关断,响应速度远快于软件中断。
6. 软件强制与同步控制:调试与高级同步的利器
除了硬件自动运行,ePWM也提供了通过软件直接干预输出的能力,这对于调试和实现复杂同步序列非常有用。
6.1 AQSFRC与AQCSFRC寄存器:软件强制输出
- AQSFRC(单次软件强制):通过置位
OTSFA或OTSFB位,可以产生一个单次的软件强制事件,并根据ACTSFA或ACTSFB的配置,强制输出A或B为指定电平(清除、置位、翻转)一次。这个强制动作不受计数器方向限制,且会覆盖当前AQ模块产生的动作。常用于测试输出通路或注入特定的脉冲。 - AQCSFRC(连续软件强制):通过配置
CSFA或CSFB位,可以持续强制输出为高、低或禁用强制。这在初始化阶段或故障恢复后,需要将输出锁定在安全状态时非常有用。注意:连续强制的优先级很高,一旦启用,AQ模块的正常动作将失效。
6.2 同步链与事件触发:构建复杂PWM系统
多个ePWM模块的协同工作是实现多相系统的关键。这主要通过TB子模块的同步功能实现。
- 指定主模块:选择一个ePWM模块作为主时钟源,将其
TBCTL[SYNCOSEL]设置为CTR=ZERO。这样,每当它的计数器归零时,就会产生一个同步脉冲(EPWMSYNCO)。 - 配置从模块:将从模块的同步输入
EPWMxSYNCI连接到主模块的EPWMSYNCO。将从模块的TBCTL[SYNCOSEL]设置为SYNCI(即直接传递输入同步),并将其PHSEN置1,并设置好TBPHS相位值。 - 形成链式结构:主模块的SYNCO可以连接到第二个从模块的SYNCI,第二个从模块的SYNCO再连接到第三个,以此类推。所有从模块都会在收到同步脉冲的同一个TBCLK周期内,将自己的TBCTR加载为TBPHS值,从而实现精确的相位同步。
此外,ePWM模块产生的大量事件(CTR=PRD, CTR=ZERO, CTR=CMPA等)都可以触发ADC启动转换,实现硬件同步采样,极大提高了控制环路的速度和确定性。
7. 实战配置流程与常见问题排查
理解了各个寄存器后,我们来看一个完整的配置流程,以及如何排查常见问题。
7.1 一个完整的ePWM初始化配置示例(用于三相电机驱动的一相)
假设系统时钟SYSCLKOUT=150MHz,需要生成20kHz的中心对称PWM,死区时间500ns,使用EPWM1模块作为A相上桥臂驱动。
// 1. 配置时基子模块 (TB) EPwm1Regs.TBCTL.bit.CTRMODE = 2; // 向上-向下计数模式 EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 本例作为主模块,不使能相位加载 EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; // 周期寄存器使用影子模式 EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // 主模块,同步输出禁用(或设为CTR=ZERO给从模块) EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // 高速时钟分频 EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV2; // 时钟分频,TBCLK = 150MHz/(1*2)=75MHz EPwm1Regs.TBPRD = 3750; // PWM周期 = 2 * TBPRD / TBCLK = 2*3750/75e6 = 100us (10kHz) // 注意:这里计算的是对称PWM,一个完整周期包含上计数和下计数。 // 因此,PWM频率 = TBCLK / (2 * TBPRD) = 75MHz / (2*3750) = 10kHz。 // 若需20kHz,则TBPRD应设为1875。 // 2. 配置计数器比较子模块 (CC) EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // CMPA使用影子模式 EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // CMPB使用影子模式 EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD; // 在CTR=0或PRD时加载CMPA影子值 EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD; // 在CTR=0或PRD时加载CMPB影子值 EPwm1Regs.CMPA.half.CMPA = 1500; // 初始化占空比 50% (CMPA/TBPRD = 1500/3750 = 40%) EPwm1Regs.CMPB = 1500; // 初始化CMPB,可用于另一路PWM或作为互补信号的比较值 // 3. 配置动作限定器 (AQ) - 生成互补的原始PWM // EPWM1A: 上计数过CMPA时置高,下计数过CMPA时置低 EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // EPWM1B: 上计数过CMPB时置低,下计数过CMPB时置高 (与A互补) EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; EPwm1Regs.AQCTLB.bit.CBD = AQ_SET; // 4. 配置死区发生器 (DB) EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // 使能上升沿和下降沿延时?不,这里需要根据AQ输出选择。 // 更常见的配置:AQ生成A高有效,B低有效;DB对B添加下降沿延时并取反。 EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL; // 死区输入源为EPWMxA (来自AQ) EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active High Complementary: 对EPWMxB取反 EPwm1Regs.DBCTL.bit.OUT_MODE = DB_ENABLE_RED_FED; // 使能上升沿延时在A,下降沿延时在B // 计算死区值:500ns / (1/75MHz) = 37.5 -> 38 EPwm1Regs.DBRED = 38; // 上升沿延时 (对EPWMxA) EPwm1Regs.DBFED = 38; // 下降沿延时 (对取反前的EPWMxB,即最终EPWM1B的上升沿延时) // 5. 配置故障保护 (TZ) EPwm1Regs.TZSEL.bit.OSHT1 = 1; // 使能TZ1引脚作为单次触发源 EPwm1Regs.TZSEL.bit.CBC1 = 1; // 使能TZ1引脚作为逐波限流源 EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_HIZ; // TZ事件发生时,强制EPWM1A高阻 EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_HIZ; // TZ事件发生时,强制EPWM1B高阻 // 注意:TZ引脚需要配置为输入,并可能使能内部上拉/下拉,具体根据外部电路决定。 // 6. 使能PWM输出 (通常通过GPIO复用寄存器将引脚配置为EPWM功能) // InitGpio(); // 此函数调用TI提供的GPIO初始化代码,将对应引脚设置为EPWM模式7.2 常见问题排查速查表
| 现象 | 可能原因 | 排查步骤与解决方法 |
|---|---|---|
| 无PWM输出 | 1. 时钟未使能或分频配置错误。 2. TBCTR未启动(CTRMODE=3)。 3. GPIO引脚未正确复用为EPWM功能。 4. TZ模块强制输出为高阻或固定电平。 | 1. 检查系统时钟配置,用示波器测TBCLK引脚(如果有)或通过翻转GPIO测试时钟频率。 2. 确认 TBCTL.CTRMODE为0,1,2之一,而非3。3. 检查GPIO复用寄存器(GPxMUX, GPxGMUX)是否将引脚配置到了正确的EPWM模式。 4. 检查 TZFLG寄存器是否有故障标志,并检查TZCTL配置。临时禁用TZ功能测试。 |
| PWM频率不对 | 1. TBPRD计算或设置错误。 2. TBCLK频率计算错误(CLKDIV, HSPCLKDIV)。 3. 计数模式理解错误(向上 vs 向上-向下)。 | 1. 复核TBPRD计算公式:向上/向下模式频率=TBCLK/(TBPRD+1);向上-向下模式频率=TBCLK/(2*TBPRD)。2. 检查 SYSCLKOUT频率和两个分频字段的设置。3. 确认应用所需波形,选择正确的 CTRMODE。 |
| 占空比无法改变或变化不连续 | 1. CMPA/CMPB工作在立即模式,在错误的时间点写入。 2. 影子模式下载入点(LOADAMODE)设置不当,导致更新被跳过。 3. 写入CMPA/CMPB时未检查SHDWAFULL/SHDWBFULL,导致更新丢失。 | 1. 确保CMPCTL.SHDWAMODE设为影子模式(0)。2. 根据计数模式设置合适的 LOADAMODE。向上-向下模式推荐设为10(CTR=ZERO or PRD)。3. 在更新占空比的函数中,加入等待影子寄存器可写的逻辑(轮询SHDWxFULL位为0),或确保在CTR=0/PRD的中断中更新。 |
| 互补信号有重叠(无死区) | 1. 死区模块未使能(DBCTL.OUT_MODE=00)。2. 死区输入模式( IN_MODE)或极性选择(POLSEL)配置错误,导致延时未应用到正确边沿。3. DBRED/DBFED值设置为0。 | 1. 确认DBCTL.OUT_MODE已使能需要的延时模式(01, 10, 11)。2.仔细检查AQ和DB的联合配置逻辑。用逻辑分析仪同时抓取AQ输出后(DB输入前)和DB输出后的信号,对照手册的波形图分析。 3. 计算并设置合适的死区时间值。 |
| 插入死区后占空比不对称 | 1. 只对一路信号添加了延时(如OUT_MODE=01),但期望两路都延时。2. 在向上-向下模式下,CMPA和CMPB的值设置不对称。 | 1. 如果需要对两路都添加延时以中心对齐,需使用OUT_MODE=11,并分别设置DBRED和DBFED。2. 在互补对称PWM中,通常设置 CMPA = duty * TBPRD,CMPB = TBPRD - CMPA。确保计算正确。 |
| TZ故障保护不动作 | 1. TZ引脚未正确配置为输入,或内部上拉/下拉导致电平固定。 2. TZSEL寄存器中未使能对应的TZ引脚。3. TZCTL配置为无操作(11)。4. 外部故障信号电平与TZ动作有效电平不匹配(TZ通常是低电平有效)。 | 1. 检查TZ引脚的GPIO配置,确认其为输入,并根据外部电路配置内部上下拉。 2. 确认 TZSEL中对应位已置1。3. 确认 TZCTL已配置为强制高阻(00)或强制低(01)等安全状态。4. 用示波器测量TZ引脚电平,确认故障时是否为有效低电平。检查外部比较器或信号调理电路。 |
| 多个ePWM模块不同步 | 1. 主模块的SYNCOSEL未正确产生同步脉冲。2. 从模块的 SYNCOSEL未设置为输入同步(SYNCI)。3. 从模块的 PHSEN未使能,或TBPHS设置错误。4. 同步信号路径(通过EPWMSYNCIN/OUT引脚)未连接或配置。 | 1. 主模块SYNCOSEL建议设为CTR=ZERO。2. 从模块 SYNCOSEL必须设为SYNCI。3. 从模块 PHSEN置1,并计算好所需的相位差设置TBPHS。4. 对于片内同步,检查相关寄存器;对于片外同步,检查物理连接和引脚配置。 |
调试ePWM时,逻辑分析仪或带数字通道的示波器是必不可少的工具。同时抓取EPWMxA、EPWMxB以及关键的内部事件信号(如SYNCI/O),可以直观地验证计数方向、比较点、死区插入和同步事件是否按预期工作。先从最简单的配置开始(如单路PWM输出),逐步增加功能(互补、死区、同步),每步都验证波形,是高效排查问题的关键。