1. ePWM模块寄存器概览与设计哲学在嵌入式电机控制和数字电源领域德州仪器TI的增强型脉冲宽度调制ePWM模块是一个绕不开的核心外设。很多工程师初次接触时面对动辄几十页的数据手册和密密麻麻的寄存器位域往往会感到无从下手。我当年也是从对着手册一行行代码“翻译”开始的走了不少弯路。实际上ePWM模块的设计非常模块化和结构化其寄存器配置并非杂乱无章而是紧密围绕着一个“信号生成流水线”来组织的。理解这个流水线是掌握ePWM的关键。简单来说ePWM的工作流程可以想象成一个精密的数字信号加工厂首先一个时间基准Time-Base, TB子模块产生一个不断循环的计数器TBCTR它定义了PWM的“心跳”节拍和周期频率。然后计数器比较Counter-Compare, CC子模块将这个计数器的实时值与用户设定的比较值CMPA, CMPB进行比对在相等的时刻产生“事件”。接着动作限定器Action-Qualifier, AQ子模块接收这些事件并根据预设的规则比如“计数器等于CMPA且正在递增时”决定对输出引脚EPWMxA/B执行何种操作置高、拉低或翻转。最后死区Dead-Band, DB子模块对这两路信号进行延时处理生成带死区的互补PWM波防止桥式电路中的上下管直通。此外Trip-ZoneTZ子模块则像紧急制动系统在故障发生时能快速、安全地关断PWM输出。我们看到的TBCTL、CMPA、AQCTLA、DBCTL等一系列寄存器就是对这个流水线上各个“工位”进行参数设置和状态监控的控制面板。TBCTL负责设定计数器的“工作模式”是向上数、向下数还是先上后下和“时钟分频”决定计数器跑得多快CMPA/CMPB则相当于设定流水线上的两个“质检点”当计数器运行到这两个值时就会触发事件AQCTLA/AQCTLB规定了当“质检点”事件发生时具体要对输出A和B执行什么“动作”。因此配置ePWM的本质就是按照信号生成的逻辑顺序依次初始化这些寄存器让这个数字工厂按照我们的意愿生产出精确的PWM波形。2. 时间基准TB子模块寄存器深度解析时间基准子模块是ePWM的“心脏”它产生的周期性计数器是所有后续操作的基准。其核心寄存器包括TBCTL、TBPHS、TBCTR和TBPRD。理解它们的联动关系是精准控制PWM频率和相位同步的前提。2.1 TBCTL控制核心与状态窗口TBCTL寄存器是一个复合寄存器高16位TBSTS是状态位低16位TBCTL是控制位。这种设计节省了地址空间也方便了状态查询。TBCTL[CTRMODE]位1-0这是第一个要配置的位它决定了计数器TBCTR的计数模式。00Up-count向上计数模式。计数器从0开始递增达到周期值TBPRD后归零如此循环。这是产生非对称PWM波通常用于LED调光、简单开关控制的常用模式。其PWM频率计算公式为Fpwm TBCLK / (TBPRD 1)。例如TBCLK100MHzTBPRD999则PWM频率为100MHz / 1000 100kHz。01Down-count向下计数模式。计数器从TBPRD值开始递减到0后重新加载TBPRD。这种模式不常用。10Up-down-count上下计数模式。计数器从0递增到TBPRD然后递减回0完成一个周期。这是电机控制和数字电源中最常用的模式因为它能产生中心对称的PWM波可以有效降低谐波分量。此时PWM频率计算公式为Fpwm TBCLK / (2 * TBPRD)。同样的TBCLK和TBPRD频率是向上计数模式的一半。11Freeze计数器停止。常用于调试或紧急停止。实操心得在电机控制中为了获得更好的波形对称性和更低的电流纹波强烈推荐使用Up-down-count模式。计算TBPRD时务必注意公式的差异。我曾在一个项目中因混淆了模式导致实际PWM频率只有预期的一半调试了半天才发现是这里配置错了。TBCTL[PHSEN] TBPHS位2 相位寄存器这两个配置项共同决定了ePWM模块的相位同步能力对于多模块并联如三相逆变器至关重要。PHSEN相位使能置1后当该模块接收到同步信号EPWMxSYNCI时其计数器TBCTR会立即被加载为TBPHS寄存器中的值。TBPHS相位值寄存器一个16位寄存器存放要加载的相位值。 假设我们有ePWM1和ePWM2两个模块希望ePWM2的输出滞后于ePWM1四分之一个周期。我们可以将ePWM1的同步输出EPWM1SYNCO连接到ePWM2的同步输入EPWM2SYNCI。配置ePWM2的PHSEN1并设置其TBPHS TBPRD / 4。这样每当ePWM1的计数器归零并发出同步脉冲时ePWM2的计数器不是从0开始而是从TBPHS值开始计数从而实现了固定的相位差。TBCTL[PRDLD]位3控制周期寄存器TBPRD的加载方式。0Shadow load影子模式。这是默认且最常用的模式。你对TBPRD的写入操作实际上是写入了它的“影子寄存器”真正的“活动寄存器”会在一个安全的时刻通常是TBCTR0时自动更新。这保证了在PWM周期中间修改占空比或频率时不会产生毛刺或错误的脉冲。1Immediate load立即模式。写入TBPRD会直接更新活动寄存器立即生效。这可能会打断当前计数周期产生不可预测的输出仅在特定调试场景下使用。TBCTL[CLKDIV] [HSPCLKDIV]位12-10 位9-7这两个字段共同决定了时间基准时钟TBCLK的频率。公式为TBCLK SYSCLKOUT / (HSPCLKDIV * CLKDIV)。SYSCLKOUT是系统时钟。通过灵活的分频我们可以在不改变系统主频的情况下获得更宽的PWM频率调节范围。例如系统时钟150MHz若HSPCLKDIV/2CLKDIV/1则TBCLK75MHz。2.2 TBCTR与TBPRD计数器与周期的具象化TBCTR是一个16位的读写寄存器直接反映了计数器的当前值。你可以读取它来了解PWM周期的实时位置这在一些需要精确时间戳的应用中很有用。直接写入TBCTR会立即改变计数器值但通常不推荐在运行时这么做除非有特殊同步需求。TBPRD是16位的周期寄存器它定义了计数器的最大值向上/上下模式或初始值向下模式。如前所述它通常工作在影子模式下。计算TBPRD是配置PWM频率的第一步。例如系统时钟150MHz期望在上下计数模式下产生20kHz的PWM波。计算过程TBCLK Fpwm * 2 * TBPRDTBPRD SYSCLKOUT / (HSPCLKDIV * CLKDIV * Fpwm * 2)。假设分频器均设为1则TBPRD 150MHz / (20kHz * 2) 3750。将其写入TBPRD寄存器即可。3. 计数器比较CC与动作限定AQ子模块寄存器精讲时间基准提供了“时间轴”而比较和动作限定子模块则在这条时间轴上“雕刻”出具体的PWM波形。CMPA/CMPB定义了“雕刻点”AQCTLA/AQCTLB定义了“雕刻动作”。3.1 CMPCTL、CMPA与CMPB设定比较值与更新策略CMPA和CMPB是两个独立的16位比较寄存器。在Up-down-count模式下PWM的占空比由这两个寄存器共同决定。通常CMPA控制EPWMxA输出的第一个边沿例如从低到高的跳变CMPB控制第二个边沿从高到低的跳变。占空比的计算公式为Duty Cycle (CMPA CMPB) / (2 * TBPRD) * 100%针对对称PWM波。实际上通过灵活配置AQ模块可以实现更复杂的波形。CMPCTL寄存器的核心是控制CMPA/CMPB的更新方式这对于实现平滑的占空比变化如电机调速至关重要。SHDWAMODE/SHDWBMODE位20, 22与TBPRD的PRDLD类似选择影子模式0或立即模式1。在需要在线更新占空比的应用中必须使用影子模式以避免在PWM周期中间更新比较值导致脉冲宽度异常。LOADAMODE/LOADBMODE位16-17, 18-19在影子模式下此字段决定影子寄存器中的新值在何时加载到活动寄存器。常见选项有00在TBCTR0时加载。这是最常用的设置确保在每个PWM周期开始时更新占空比变化最平滑。01在TBCTRTBPRD时加载仅上下计数模式有意义。10在TBCTR0或TBCTRTBPRD时加载。这可以实现每个PWM周期内更新两次适用于某些特定调制算法。11冻结不加载。注意事项在配置CMP影子模式时务必注意SHDWAFULL/SHDWBFULL状态位位24, 25。在影子模式下如果你写入CMP寄存器的速度超过了其加载到活动寄存器的速度即LOAD事件发生的速度这个标志位会被置1表示影子寄存器已满下一次写入会覆盖尚未加载的值导致数据丢失。在编写占空比更新函数时一个良好的习惯是在写入前检查该位或确保你的更新频率低于PWM频率/加载事件频率。3.2 AQCTLA与AQCTLB定义输出动作的逻辑规则这是ePWM模块中最能体现其“智能”和灵活性的部分。AQ寄存器为每个输出A和B定义了一组规则规定在特定事件发生时输出引脚应该做什么。核心事件AQ模块监视六个核心事件CTR PRD计数器等于周期值。CTR ZRO计数器等于零。CTR CMPA计数器等于CMPA值且正在递增CAU或递减CAD。CTR CMPB计数器等于CMPB值且正在递增CBU或递减CBD。可用动作对于每个事件你可以为输出选择四种动作之一00无操作。01清除输出低电平。10置位输出高电平。11翻转高变低低变高。通过组合这些事件和动作可以构造出几乎任何你想要的PWM波形。例如要产生一个在Up-down-count模式下、高电平在中间的对称PWM波常用于驱动半桥的上管可以这样配置AQCTLACAUCTR上数到CMPA置位 (10)- 计数器从0上升到CMPA时输出变高。CADCTR下数到CMPA清除 (01)- 计数器从TBPRD下降到CMPA时输出变低。这样输出就会在计数器经过CMPA时产生一个对称的脉冲。而CMPB则可以用于产生另一路互补的、带死区的信号这需要结合DB模块。AQSFRC寄存器提供了软件强制事件的能力。例如OTSFA位写1可以产生一个一次性的软件强制事件并按照ACTSFA设定的动作置高、拉低、翻转改变输出A。这在某些需要精确控制单个脉冲或进行同步的场合非常有用。4. 死区生成DB与故障保护TZ子模块寄存器实战4.1 DBCTL、DBRED、DBFED生成安全的互补PWM在电机驱动或全桥/半桥电路中控制上下两个功率管的PWM信号必须是互补的且必须插入一段两者都为低电平的“死区时间”以防止上下管同时导通直通造成短路烧毁。DB模块自动化了这个过程。DBCTL[OUT_MODE]位16-17选择死区的工作模式。00旁路模式。AQ的输出直接送到最终输出不产生死区。用于不需要死区的场景。01仅使能下降沿延时。AQ的EPWMxA信号直通输出给OUTA而EPWMxB信号经过一个下降沿延时后输出给OUTB。这适用于需要将一路信号延时后作为另一路信号的场景。10仅使能上升沿延时。与01模式相反。11完全使能模式。这是最常用的桥式驱动模式。AQ输出的信号一路经过上升沿延时生成OUTA另一路经过下降沿延时生成OUTB或反之由IN_MODE决定。DBCTL[IN_MODE]位20-21选择输入到上升沿和下降沿延时模块的信号源。在典型的互补带死区输出模式下通常设置为00即AQ输出的EPWMxA同时作为上升沿和下降沿延时模块的输入。这样你只需要用AQ生成一路基础PWM波比如在EPWMxA上DB模块就能自动生成两路带死区的互补信号。DBRED 和 DBFED 寄存器这两个10位寄存器分别存储上升沿延时和下降沿延时的计数值。死区时间 延时计数值 * TBCLK周期。如果开启了半周期时钟DBCTL[HALFCYCLE]1则时间分辨率提高一倍死区时间 延时计数值 * (TBCLK周期 / 2)。例如TBCLK 100MHz (10ns)需要插入500ns的死区时间。若使用全周期时钟则DBRED DBFED 500ns / 10ns 50。配置好这两个寄存器DB模块就会自动在输出信号的边沿插入精确的延时。4.2 TZSEL配置故障触发源Trip-Zone是ePWM的硬件保护单元当外部故障信号如过流、过压、过热触发时它能以最高优先级强制PWM输出进入预设的安全状态高阻、低电平或高电平。TZSEL寄存器的作用就是“选票”决定哪些故障源可以触发保护。TZSEL_CBCx (x1~6)将这些位置1意味着对应的TZx引脚例如来自比较器的过流信号被允许作为周期循环Cycle-By-Cycle, CBC故障源。CBC故障在每个PWM周期开始时自动清除如果故障条件在下一个周期依然存在则会再次触发。适用于需要持续监控但允许每个周期重试的场景如电流限流。TZSEL_OSHTx (x1~6)将这些位置1意味着对应的TZx引脚被允许作为单次One-Shot故障源。一旦触发ePWM输出将被锁存在安全状态直到软件明确清除故障标志位。适用于严重的、需要人工干预的故障如短路、严重过热。TZDCSEL字段这部分用于配置数字比较Digital Compare, DC模块产生的事件作为故障源。DC模块可以将ADC的转换结果与设定的阈值进行比较在芯片内部产生数字故障信号无需占用外部TZ引脚。例如TZDCSEL_DCAEVT1字段用来选择什么条件下DCAEVT1事件有效如DCAH为高而TZSEL_DCAEVT1位则决定是否将这个事件作为本ePWM模块的单次故障源。避坑指南故障保护配置的常见陷阱是未正确清除故障标志位。对于OSHT故障即使外部故障信号已经消失如果TZFLG寄存器中的对应标志位没有被软件写1清除ePWM输出将一直保持安全状态。正确的流程是故障发生 - 进入中断服务程序 - 检查并处理故障 -写1清除TZCLR寄存器中对应的标志位- 重新使能PWM输出通过配置TZCTL寄存器决定故障时的输出动作通常为高阻或强制低。5. 从零构建一个带死区的互补PWM信号完整配置流程理论说了这么多我们以一个实际案例来串联所有寄存器配置在TI C2000系列DSP的ePWM1模块上产生一个频率为10kHz、占空比30%、带500ns死区的互补PWM信号EPWM1A和EPWM1B采用Up-down-count模式系统时钟150MHz。步骤1计算关键参数并配置TB子模块选择Up-down-count模式TBCTL[CTRMODE] 10b。设定时钟分频。为简化计算设HSPCLKDIV/1CLKDIV/1则TBCLK SYSCLKOUT 150MHz。计算TBPRDTBPRD SYSCLKOUT / (2 * Fpwm) 150MHz / (2 * 10kHz) 7500。设置周期加载模式为影子加载在CTR0时更新TBCTL[PRDLD] 0。暂时禁用相位加载TBCTL[PHSEN] 0。仿真模式设为自由运行TBCTL[FREE, SOFT] 11b。步骤2配置CC子模块计算比较值并设置更新方式在Up-down-count模式下对于一个简单的对称PWM通常设置CMPA CMPB即可控制占空比。占空比D (CMPA) / TBPRD。因此CMPA CMPB Duty * TBPRD 0.3 * 7500 2250。配置CMPA/CMPB为影子模式并在CTR0时加载CMPCTL[SHDWAMODE] 0,CMPCTL[SHDWBMODE] 0,CMPCTL[LOADAMODE] 00b,CMPCTL[LOADBMODE] 00b。步骤3配置AQ子模块定义波形生成逻辑我们希望EPWM1A输出一个中心对称的PWM波。配置AQCTLACAU(CTR上数到CMPA):置位 (10)- 计数器上升经过CMPA时EPWM1A变高。CAD(CTR下数到CMPA):清除 (01)- 计数器下降经过CMPA时EPWM1A变低。对于EPWM1B我们希望它输出与EPWM1A互补的波形先由DB模块添加死区。我们可以先让AQ生成一个与EPWM1A反相的基础波形或者直接让AQ生成与EPWM1A相同的波形然后依靠DB模块的极性反转功能产生互补信号。这里采用第一种方法配置AQCTLBCBU(CTR上数到CMPB):清除 (01)- 计数器上升经过CMPB时EPWM1B变低。CBD(CTR下数到CMPB):置位 (10)- 计数器下降经过CMPB时EPWM1B变高。同时为了在周期开始和结束时定义明确状态通常设置ZRO和PRD事件为“无操作”。步骤4配置DB子模块插入死区时间计算死区计数值死区时间 500ns, TBCLK周期 6.67ns。DBRED DBFED 500ns / 6.67ns ≈ 75(取整)。配置DBCTLOUT_MODE 11b完全使能上升沿和下降沿延时。IN_MODE 00b使用EPWMxA作为两路延时模块的输入源。POLSEL 10b选择Active High Complementary (AHC)模式即EPWMxB输出反相。这样DB模块将对来自AQ的EPWMxA信号进行延时处理一路延时后作为OUTA另一路延时并反相后作为OUTB自动生成带死区的互补信号。HALFCYCLE 0使用全周期时钟。将计算出的值写入DBRED和DBFED寄存器。步骤5使能计数器最后将计算好的TBPRD、CMPA、CMPB等值写入相应寄存器并确保TBCTL[CTRMODE]已设置为非冻结模式00, 01, 10。计数器将开始运行EPWM1A和EPWM1B引脚上即可测量到预期的带死区互补PWM波形。6. 高级应用与调试技巧6.1 同步链与相位控制实现多模块协作在复杂系统如三相逆变器中需要6个ePWM模块产生6路互差120度的PWM波。这时同步链Sync Chain就派上用场了。通过TBCTL[SYNCOSEL]可以配置每个模块的同步输出源如CTRZERO并将前一个模块的EPWMxSYNCO输出连接到后一个模块的EPWMxSYNCI输入。同时为后续模块使能相位加载PHSEN1并设置不同的TBPHS值如0, TBPRD/3, 2*TBPRD/3即可实现精确的相位差。关键点确保整个链路上的时钟分频CLKDIV, HSPCLKDIV一致否则相位关系会错乱。6.2 影子寄存器机制下的占空比实时更新策略在电机矢量控制FOC等应用中需要在每个PWM周期更新占空比即CMPA/CMPB的值。为了无毛刺更新必须遵循“写影子-等加载”的原则。一个稳健的更新流程通常放在PWM周期中断CTRZERO或CTRPRD中断服务程序中在中断服务程序ISR中计算新的CMPA/CMPB值。检查CMPCTL[SHDWAFULL]位如果需要可加入超时等待机制但通常在中ISR更新频率低于PWM频率时不会满。将新值写入CMPA/CMPB影子寄存器。由于LOADAMODE设置为在CTR0时加载新值将在下一个PWM周期开始时自动生效。6.3 常见配置问题与示波器调试实战问题1无PWM输出或频率不对。排查首先检查TBCTL[CTRMODE]是否被意外设为冻结模式11。用仿真器读取TBCTR寄存器的值看它是否在循环计数。如果不计数检查时钟使能和分频配置。如果计数但频率不对复核TBPRD的计算公式和CLKDIV/HSPCLKDIV的设置。问题2占空比不正确或不可调。排查确认CMPA/CMPB的值是否在0到TBPRD之间。用示波器测量波形同时用CCS的Graph工具实时绘制TBCTR和CMPA的值。观察CMPA事件点是否与波形跳变沿对齐。检查AQCTL寄存器的事件动作配置是否正确特别是CAU和CAD或CBU和CBD是否配对正确。问题3死区时间不生效或两路信号完全互补无死区。排查首先确认DBCTL[OUT_MODE]是否已使能非00模式。测量EPWMxA和EPWMxB引脚。如果两者依然是完美的互补方波边沿对齐说明DB模块可能被旁路或者DBRED/DBFED寄存器值为0。检查POLSEL配置如果设为00AH模式则两路输出同相不会互补。一个有效的调试方法是先将DBRED和DBFED设置为一个较大的值如1000用示波器应能明显看到输出边沿的延迟从而确认DB模块工作正常。问题4故障保护不动作。排查这是一个硬件关联性很强的问题。首先确认TZ输入引脚的电平是否正确低电平有效还是高电平有效需查具体芯片手册。其次检查TZSEL寄存器对应的CBC或OSHT位是否已使能。然后检查TZCTL寄存器配置了故障发生时输出应进入何种安全状态如强制高阻。最后如果使用OSHT模式故障发生后需要手动清除TZFLG标志位才能恢复输出。可以尝试在调试器中手动拉低TZ引脚观察输出是否立即进入安全状态并检查TZFLG是否置位。