1. 项目概述与核心价值
如果你正在用TI的C2000系列DSP做电机控制、数字电源或者任何需要精确PWM(脉冲宽度调制)输出的项目,那么ePWM模块绝对是你绕不开的核心。很多人刚开始接触时,会觉得它寄存器多、概念复杂,光是时间基准、计数器模式、同步这些名词就够喝一壶了。我当年调第一个全桥逆变器时,就因为没吃透同步机制,导致上下桥臂的PWM信号没对齐,直接炸了一个MOS管,教训深刻。
所以,今天咱们不聊那些浮于表面的功能介绍,直接深入到ePWM的“心脏”——时间基准子模块(Time-Base, TB)。我会结合手册里的原理图和多年踩坑经验,把TBPRD寄存器怎么决定频率、三种计数器模式到底有什么区别、影子寄存器更新时机怎么选、以及如何让多个ePWM模块像军队一样整齐划一地工作(同步),这些关键点掰开揉碎了讲清楚。你会发现,理解了这些,你不仅能配置出正确的PWM,更能设计出高效、可靠、易于维护的驱动架构。无论是做单相逆变、三相电机FOC,还是多相交错并联的DCDC电源,这些底层机制都是你掌控全局的基石。
2. 时间基准核心:频率、周期与计数器模式解析
ePWM模块生成波形的核心是一个不断循环计数的硬件计数器,即时间基准计数器(TBCTR)。它就像一块不断走动的精密秒表,而PWM的每一个脉冲周期,都是由这块“秒表”走完一个完整循环来定义的。这个循环的“终点”或者说“满量程”,就是由时间基准周期寄存器(TBPRD)来设定的。
2.1 PWM频率与周期的计算逻辑
这里有个关键点容易混淆:PWM的周期(Tpwm)和频率(Fpwm)不仅取决于TBPRD的值,还强烈依赖于计数器的工作模式。手册里的图20-6和公式是理解这一切的钥匙。
首先,要明白时间基准时钟(TBCLK)是ePWM模块的“心跳”。它来源于系统主时钟(EPWMCLK)经过预分频(TBCTL[HSPCLKDIV, CLKDIV])得到。每个TBCLK周期,TBCTR计数器就变化一次(加1或减1)。因此,TBCLK的周期(TTBCLK)是计算一切时间的基础。
1. 递增计数模式(Up-Count)与递减计数模式(Down-Count)这两种模式产生的都是非对称PWM波形。在递增模式下,计数器从0开始,每个TBCLK加1,直到等于TBPRD值,然后瞬间归零,开始下一个周期。在递减模式下,计数器从TBPRD值开始,每个TBCLK减1,直到等于0,然后瞬间重置为TBPRD值。
- 周期公式:
Tpwm = (TBPRD + 1) * TTBCLK - 频率公式:
Fpwm = 1 / Tpwm
为什么是TBPRD + 1?这是理解计数器的关键。假设TBPRD = 4。在递增模式下,计数器序列是:0, 1, 2, 3, 4, (归零), 0, 1... 你看,从0数到4,总共经历了5个计数值(0,1,2,3,4),也就是5个TBCLK周期。同理,递减模式从4数到0,也是5个值。所以,有效计数值范围是0到TBPRD,共TBPRD+1个步长。
2. 递增-递减计数模式(Up-Down-Count)这种模式用于生成对称PWM波形,在电机控制和某些电源拓扑中非常有用,因为它能产生关于周期中心对称的脉冲,谐波特性更好。计数器从0开始递增到TBPRD,然后立即递减回0,如此循环。
- 周期公式:
Tpwm = 2 * TBPRD * TTBCLK - 频率公式:
Fpwm = 1 / Tpwm
为什么是2 * TBPRD?同样以TBPRD=4为例。一个完整周期包括:上计数段(0->1->2->3->4)和下计数段(4->3->2->1->0)。注意,峰值点4和谷底点0在每个周期只经过一次。从上计数段的0到4,需要4个TBCLK(0->1, 1->2, 2->3, 3->4)。下计数段同样需要4个TBCLK。因此,总周期是2 * 4 = 8个TBCLK周期。这里没有+1,因为计数器的转折点(TBPRD和0)是瞬时切换的,不占用额外的TBCLK周期。
实操心得:模式选择与死区插入选择哪种模式,首先看你的功率拓扑和驱动需求。对于半桥或全桥的互补PWM,通常使用递增-递减模式,因为对称波形在生成中心对齐的PWM时,天然地使上下桥臂的开关时刻关于周期中心对称,有利于减小共模噪声和开关损耗。而对于某些需要非对称PWM的场合,如单端反激变换器的初级开关管控制,则可能使用递增或递减模式。 另外,死区时间的插入逻辑也与计数模式相关。在递增-递减模式下,通常需要在计数器等于CMPA或CMPB时,结合方向信号(CTR_dir)来分别设置上升沿和下降沿的死区,逻辑上会更清晰。
2.2 影子寄存器机制:安全更新的艺术
直接操作正在控制硬件的寄存器是危险的。想象一下,你正在用TBPRD控制一个开关电源的开关频率,如果在计数器运行到一半时,软件突然改写TBPRD的值,可能会导致当前周期突然被拉长或缩短,产生一个畸变的PWM脉冲,这很可能导致桥臂直通、电流冲击等严重故障。
ePWM模块通过影子寄存器(Shadow Register)机制优雅地解决了这个问题。以TBPRD为例:
- 活动寄存器(Active Register):直接控制硬件,决定当前PWM周期的实际计数值上限。
- 影子寄存器(Shadow Register):一个缓冲器,软件平时读写的是它。它不影响当前运行。
关键在于加载时机。通过配置TBCTL[PRDLD]位,你可以选择两种模式:
- 影子模式(TBCTL[PRDLD] = 0,默认):软件写入TBPRD地址的数据,实际是写入了影子寄存器。影子寄存器的内容会在一个特定的、安全的时刻自动加载到活动寄存器。这个时刻由TBCTL2[PRDLDSYNC]位决定,通常是当计数器归零时(TBCTR = 0x00),或者当发生同步事件时。这就保证了寄存器更新只发生在周期的边界,从而避免了周期内的波形畸变。
- 立即加载模式(TBCTL[PRDLD] = 1):写入TBPRD地址的数据直接进入活动寄存器,立即生效。这种模式一般用于调试或某些需要动态、快速改变频率的特殊场景,但生产代码中需极其谨慎。
避坑指南:影子寄存器更新丢失一个常见的坑是:在影子模式下,你写入了新的TBPRD值到影子寄存器,但程序马上又去读取TBPRD,期望读到新值,结果读到的还是旧值。记住,在影子模式下,读操作也是从影子寄存器读取!只有等到加载事件(如CTR=0)发生后,活动寄存器的值才更新,但活动寄存器的值软件是不可直接读写的。因此,你的控制逻辑不应该依赖于“读取-判断-再写入”的方式去确认更新是否完成,而应该基于事件(如CTR=0中断)来触发下一次参数更新。
3. 同步机制深度剖析:从时钟对齐到相位控制
单个ePWM模块工作相对简单,但真正的挑战来自于多模块协同。比如一个三相逆变器,你需要三个ePWM模块产生六路PWM,并且这六路信号必须严格保持120度的相位差,同时它们的时钟基准必须完全一致,否则会导致三相不平衡,电机抖动、噪音大。ePWM提供了两级同步机制来解决这个问题。
3.1 时钟级同步:TBCLKSYNC
这是最底层的同步,目的是让所有ePWM模块的“心跳”(TBCLK)从第一个上升沿开始就对齐。这是通过系统控制模块中的一个全局位TBCLKSYNC实现的。
正确的使能顺序至关重要,手册里给的步骤是黄金法则:
- 使能各ePWM模块时钟:在PCLKCRx寄存器中打开你需要的ePWM模块的时钟。此时模块有电了,但计数器还没开始走。
- 停止所有时基时钟:设置
TBCLKSYNC = 0。这个操作会“冻结”所有已使能ePWM模块的TBCTR计数器,让它们都停在当前值(通常是0)。 - 配置模块参数:在这个“冻结”状态下,安全地配置各个ePWM模块的TBCTL(包括预分频器HSPCLKDIV/CLKDIV、计数模式)、TBPRD、CMPx等所有寄存器。特别注意:所有模块的预分频器设置必须相同!如果有的模块TBCLK是系统时钟的2分频,有的是4分频,那即使同步启动,它们的计数速度也不同,很快就会失步。
- 同步启动:设置
TBCLKSYNC = 1。这个上升沿信号会同时释放所有被冻结的ePWM模块的时基时钟,它们的TBCTR计数器将从下一个TBCLK的上升沿开始同步计数。
经验之谈:复位后的初始化系统上电或复位后,TBCLKSYNC默认是0。很多工程师在初始化时,先配置各个ePWM参数,最后才使能模块时钟并设置TBCLKSYNC=1,这个顺序是没问题的。但如果你在系统运行中需要动态复位或重新初始化某个ePWM模块,务必记得先将TBCLKSYNC清零,配置完再置位,否则新初始化的模块计数器可能会与其他模块错位。
3.2 计数器级同步:SYNCI, SYNCO 与相位寄存器
时钟同步保证了大家“步速一致”,但还需要让它们“起步时间”或“相对位置”可控。这就是计数器同步和相位控制的功能。
每个ePWM模块都有一个同步输入(EPWMxSYNCI)和一个同步输出(EPWMxSYNCO)。你可以将它们串联起来,形成一个同步链。例如,让ePWM1的SYNCO连接到ePWM2的SYNCI,ePWM2的SYNCO再连接到ePWM3的SYNCI。
同步事件如何起作用?当ePWM模块检测到其SYNCI输入引脚上有一个上升沿脉冲时(如果使能了同步),它会执行一个关键操作:将相位寄存器(TBPHS)的值加载到时间基准计数器(TBCTR)中。这个操作发生在下一个有效的TBCLK边沿。
这带来了巨大的灵活性:
- 主从同步:将ePWM1配置为自由运行(PHSEN=0,禁用同步),将其SYNCO输出连接到ePWM2的SYNCI。ePWM2使能同步(PHSEN=1),并设置TBPHS = 0。那么,每当ePWM1的计数器归零时,会产生一个SYNCO脉冲给ePWM2,ePWM2会立即将自己的TBCTR加载为0。这样,ePWM2就与ePWM1严格同步,且相位差为0。你可以通过配置ePWM1的SYNCO在何时产生(例如在CTR=PRD或CTR=0时),来控制同步发生的时刻。
- 相位控制:接上例,如果设置ePWM2的TBPHS = 100(假设TBPRD=1000),那么当同步事件发生时,ePWM2的TBCTR不是被清零,而是被设置为100。这意味着ePWM2的波形相对于ePWM1有了一个固定的相位偏移。这对于生成多相移相PWM至关重要。
- 方向控制(仅上下计数模式):在上下计数模式下,同步事件发生后计数器是继续向上还是向下计数?这由TBCTL[PHSDIR]位控制。PHSDIR=0表示同步后向下计数,PHSDIR=1表示同步后向上计数。图20-11和图20-12清晰地展示了这两种情况下的波形差异。这个特性在构建某些特定序列的PWM模式时非常有用。
同步源的选择同步输入SYNCI的来源非常灵活,可以通过EPWMSYNCINSEL寄存器选择,包括:
- 其他ePWM模块的SYNCO输出(用于构建同步链)。
- 其他外设如eCAP模块的SYNCO输出。
- 通过输入交叉开关(INPUTXBAR)引入的外部GPIO信号。
- 甚至是一些特殊的系统事件(如FSI的触发信号)。
这种灵活性允许你将ePWM模块的同步与系统内其他事件(如过流保护信号、ADC采样完成信号)联动,实现极其精确的事件驱动控制。
排查技巧:同步失效的常见原因
- 软件强制同步干扰:TBCTL[SWFSYNC]位可以产生一个软件同步脉冲,它与SYNCI是“或”的关系。如果你在调试时不小心置位了SWFSYNC又没清零,它可能会持续产生同步信号,干扰正常的硬件同步。检查程序中有无残留的SWFSYNC置位操作。
- 同步信号毛刺:如果SYNCI信号源是GPIO,且该GPIO受到噪声干扰,可能会产生非预期的毛刺脉冲,导致计数器被意外同步。确保硬件布线良好,必要时在软件上对同步事件进行滤波或确认。
- TBPHS值不合理:在上下计数模式下,如果你设置的TBPHS值大于TBPRD,同步加载后计数器会立即因为“溢出”而改变方向,可能产生非预期的波形。务必确保TBPHS在0到TBPRD的范围内。
4. 全局加载与高级同步控制
当系统中有多个ePWM模块,并且你需要它们在同一时刻更新多个寄存器(如TBPRD, CMPA, CMPB等)时,简单的影子寄存器按各自事件加载可能仍会引入微小的不同步。例如,模块1在CTR=0时更新了CMPA,模块2在CTR=PRD时更新了CMPA,即使它们的计数器是同步的,这两个更新事件也相差半个周期。对于高精度多相交错并联系统,这种差异是不可接受的。
4.1 全局加载机制
ePWM的全局加载(Global Load)功能就是为了解决这个问题。它允许你将多个模块的多个影子寄存器的加载动作,绑定到同一个全局事件上。
工作原理:
- 使能全局加载:在全局加载配置寄存器GLDCFG中,为你希望同步加载的寄存器(如CMPA, CMPB, TBPRD)使能全局加载模式(设置对应REGx位)。
- 选择全局加载事件:在全局加载控制寄存器GLDCTL[GLDMODE]中,选择一个事件作为全局加载触发源。这个事件可以是:
CNT_ZERO(CTR=0)PRD_EQ(CTR=PRD)CNT_ZERO or PRD_EQ- 一个同步事件(SYNCEVT)
- 数字比较事件(DCAEVT1.sync等)
- 激活全局加载:设置GLDCTL[GLD] = 1。一旦此位置位,对于所有在GLDCFG中使能了的寄存器,它们原有的、独立的影子加载事件将被忽略,转而等待上述选定的同一个全局事件。当该事件发生时,所有相关寄存器的影子寄存器内容被同时加载到各自的活动寄存器中。
这就实现了真正的“原子”更新。比如,在一个三相逆变器中,你可以将三个ePWM模块的CMPA影子寄存器都配置为全局加载,并选择CNT_ZERO作为全局事件。当你需要同时改变三个相的占空比时,只需分别更新三个模块的CMPA影子寄存器,然后等待下一个所有模块计数器同时归零的时刻,三个新的占空比值将同时生效,完美保持三相平衡。
4.2 单次加载与单次同步模式
全局加载机制还有两个高级扩展功能:
1. 单次加载模式(One-Shot Load)通过配置GLDCTL2[OSHTLD]位,可以触发一次性的全局加载。当你向OSHTLD写1时,无论当前计数器状态如何,都会立即产生一个全局加载脉冲,将所有使能了全局加载的寄存器进行一次影子->活动的传输。之后,OSHTLD位会自动清零。这个功能非常适用于初始化或非周期性的参数大切换场景。你可以先配置好所有影子寄存器,然后通过触发一次单次加载,让它们全部立即生效。
2. 单次同步模式(One-Shot Sync Mode)这个功能用于产生一个精确的同步输出脉冲。通过配置TBCTL2[OSHTSYNCMODE]选择同步源,然后向TBCTL2[OSHTSYNC]位写1,就可以在该ePWM模块的SYNCO输出端产生一个单脉冲的同步信号。这个脉冲可以用于触发其他外设(如ADC开始转换),或者作为其他ePWM模块的一次性同步源。它提供了一种软件主��发起、精确控制的同步手段。
注意事项:全局加载的配置顺序在启用全局加载(GLDCTL[GLD]=1)之前,务必先完成GLDCFG(选择哪些寄存器参与全局加载)和GLDCTL[GLDMODE](选择全局加载事件)的配置。错误的顺序可能导致寄存器���错误的时刻被更新。一个推荐的初始化流程是:配置各模块独立参数 -> 配置GLDCFG和GLDCTL[GLDMODE] -> 最后置位GLDCTL[GLD]。
5. 计数器比较模块与波形生成实战
理解了时间基准和同步,我们来看ePWM如何生成具体的PWM边沿。这离不开计数器比较(Counter-Compare, CC)子模块和动作限定(Action-Qualifier, AQ)子模块的协同工作。
5.1 比较寄存器与事件生成
CC模块的核心是四个比较寄存器:CMPA, CMPB, CMPC, CMPD。它们的作用是将时间基准计数器(TBCTR)的实时值与预设值进行比较,并在相等时产生事件。
- CTR = CMPA和CTR = CMPB事件是核心,主要用于控制EPWMxA和EPWMxB两个输出引脚的占空比。
- CTR = CMPC和CTR = CMPD事件是扩展,通常用于触发ADC转换(SOC)或产生中断,而不直接控制PWM输出。
关键点:事件发生的频率与计数模式有关。
- 在递增或递减模式下,计数器在一个周期内只会经过每个比较值一次,因此每个比较事件(如CTR=CMPA)每个PWM周期只发生一次。
- 在递增-递减模式下,情况就复杂了。计数器会先递增经过CMPA,再递减经过CMPA。因此,如果CMPA的值在0和TBPRD之间(不包含两端),那么
CTR=CMPA事件每个周期会发生两次:一次在递增段,一次在递减段。如果CMPA等于0或TBPRD,则每个周期只发生一次(因为计数器在转折点不停留)。
5.2 影子寄存器与加载时机
和TBPRD一样,CMPA和CMPB也有影子寄存器机制,由CMPCTL[SHDWAMODE]和[SHDWBMODE]控制。在影子模式下,你可以安全地在任何时刻更新CMPA/CMPB的影子寄存器,而加载到活动寄存器的时机则由CMPCTL[LOADAMODE]和[LOADBMODE]精心选择。
常见的加载时机选择策略:
- LOADAMODE = CTR=PRD:在计数器达到周期值时加载。在递增-递减模式下,这发生在波形的“峰顶”。适合在周期峰值更新占空比,用于下一个完整的对称周期。
- LOADAMODE = CTR=ZERO:在计数器归零时加载。在递增-递减模式下,这发生在波形的“谷底”。这也是一个很常见的更新点。
- LOADAMODE = CTR=PRD or CTR=ZERO:在计数器达到周期值或归零时加载。这实际上在每个PWM周期的两个边界都会尝试加载,但只有影子寄存器被写入新值后,第一次遇到的边界事件才会执行加载。这提供了更大的灵活性。
- LOADAMODE = SYNC:在同步事件发生时加载。这允许你将占空比的更新与外部同步信号对齐,在多模块系统中实现占空比的同步变化。
CMPC和CMPD也有类似的影子寄存器控制位(在CMPCTL2寄存器中),它们的加载时机配置逻辑与CMPA/B相同,通常用于同步ADC采样时刻。
5.3 动作限定器:将事件转化为边沿
CC模块产生了“时间到”的事件,但具体让输出引脚做什么(拉高、拉低、翻转),是由动作限定器(AQ)模块决定的。
AQ模块接收来自TB模块的CTR=PRD、CTR=ZERO事件,以及来自CC模块的CTR=CMPA、CTR=CMPB事件。对于每一个事件,你都可以独立地为EPWMxA和EPWMxB两个输出通道配置一个动作:
- 置高(Set High)
- 置低(Clear Low)
- 翻转(Toggle)
- 无操作(Do Nothing)
更重要的是,AQ模块会区分计数器方向。对于CTR=CMPA这样的事件,在递增-递减模式下,它会在上升沿和下降沿各发生一次。你可以通过AQCTLA和AQCTLB寄存器,分别配置在计数器递增(CAU, CBU)和递减(CAD, CBD)时,发生该事件应采取的动作。
一个典型的互补对称PWM配置示例(递增-递减模式):假设我们希望EPWMxA输出一个中心对齐的PWM,EPWMxB输出其互补信号(带死区的话需结合DB模块)。
- 设置动作:
- 当
CTR=ZERO时(计数器从0开始递增):设置EPWMxA置高(AQCTLA.ZRO = Set)。 - 当
CTR=CMPA且计数器递增时:设置EPWMxA置低(AQCTLA.CAU = Clear)。 - 当
CTR=CMPA且计数器递减时:设置EPWMxA置低(AQCTLA.CAD = Clear)。 (这样,在CMPA点,无论是上坡还是下坡,EPWMxA都变为低电平,形成一个在CMPA位置对称的下降沿?不对,这会产生一个窄脉冲。让我们重新思考。)
- 当
更正:对于中心对齐PWM,通常的配置是:
- EPWMxA:
CTR=PRD(上坡终点): AQCTLA.PRD = Clear (或Toggle,取决于初始状态)CTR=CMPA(上坡过程): AQCTLA.CAU = SetCTR=CMPA(下坡过程): AQCTLA.CAD = Clear
- EPWMxB (互补):
CTR=PRD: AQCTLB.PRD = SetCTR=CMPB(上坡): AQCTLB.CBU = ClearCTR=CMPB(下坡): AQCTLB.CBD = Set 通过设置CMPA和CMPB的值,可以控制高电平的宽度。这种配置能产生关于周期中心对称的脉冲。
实操心得:AQ配置是PWM波形的灵魂调试PWM输出时,如果波形不对,第一个要检查的就是AQ控制寄存器。务必在逻辑分析仪或示波器上,对照着TBCTR的计数波形,一个事件一个事件地核对AQ的配置。一个常见的错误是混淆了
CTR=PRD和CTR=ZERO事件在递增、递减、递增-递减模式下的行为差异。在递增-递减模式下,CTR=PRD事件只发生在计数器到达峰值时(方向由增转减),而CTR=ZERO事件只发生在计数器到达谷底时(方向由减转增)。
6. 常见问题排查与调试技巧实录
在实际项目中,ePWM的配置出错可能导致没有输出、输出频率不对、占空比失控、多路不同步等问题。下面是我总结的一些典型问题及其排查思路。
6.1 PWM无输出或输出异常
| 问题现象 | 可能原因 | 排查步骤与解决方法 |
|---|---|---|
| 完全无输出 | 1. ePWM模块时钟未使能。 2. 输出引脚未配置为ePWM功能。 3. 时基计数器未启动(TBCLKSYNC=0或TBCTL[CTRMODE]=冻结模式)。 4. 动作限定器(AQ)所有事件都配置为“无操作”。 | 1. 检查PCLKCRx寄存器中对应ePWM模块的时钟使能位。 2. 检查GPIO复用控制寄存器,将对应引脚配置为EPWMxA/EPWMxB功能。 3. 确认TBCLKSYNC已置1,且TBCTL[CTRMODE]配置为UP, DOWN, UP-DOWN之一,而非FREEZE。 4. 检查AQCTLA和AQCTLB寄存器,确保至少有一个事件(如CTR=ZERO)配置了SET或CLEAR动作。 |
| 输出恒定高电平或低电平 | 1. CMPA/CMPB值设置不当(例如,在递增模式下,CMPA=0会导致一上电就触发清零)。 2. AQ配置错误,导致输出被锁定。例如,配置了软件强制(AQCSFRC)后没有清除。 | 1. 结合计数模式检查CMPx值。在递增模式下,若CMPA=0,则计数器从0开始就满足CTR=CMPA,如果此时配置CAU=Clear,输出会立即被拉低并可能保持。 2. 检查AQSFRC和AQCSFRC寄存器,确保没有意外的软件强制动作被激活。调试时,可以尝试先禁用软件强制(CSFA/CSFB = 0)。 |
| 频率不正确 | 1. TBPRD计算错误,未考虑计数模式(+1或*2)。 2. TBCLK预分频器(HSPCLKDIV, CLKDIV)配置错误。 3. 系统时钟(SYSCLK)频率设置错误。 | 1. 根据所选计数模式,使用正确的公式复算TBPRD:TBPRD = (Fpwm * TTBCLK)^-1 - 1(递增/递减)或TBPRD = (2 * Fpwm * TTBCLK)^-1(递增-递减)。2. 核对TBCTL中的HSPCLKDIV和CLKDIV分频位设置。 3. 确认PLL配置和系统时钟频率是否符合预期。 |
| 占空比不对或不可控 | 1. CMPA/CMPB影子寄存器未成功加载到活动寄存器。 2. 在递增-递减模式下,占空比计算方式理解有误。 3. 多个事件动作冲突,优先级导致非预期结果。 | 1. 检查CMPCTL[SHDWAMODE]和[LOADAMODE]配置。在影子模式下,写入CMPA后,需要等待指定的加载事件(如CTR=PRD)发生,新值才生效。可以通过在加载事件触发中断,在中断中更新下一次的CMPA值。 2. 在递增-递减模式下,占空比D与CMPA的关系为: D = (2 * CMPA) / (2 * TBPRD) = CMPA / TBPRD(如果CMPA在半个周期内定义高电平)。务必理清AQ事件在上升段和下降段分别触发了什么动作。3. 查阅手册了解AQ事件优先级(通常ZERO和PRD事件优先于CMPA/CMPB)。确保你的动作配置没有在同一个时间点发出矛盾的指令。 |
6.2 同步功能失效
| 问题现象 | 可能原因 | 排查步骤与解决方法 |
|---|---|---|
| 多模块时钟不同步 | 1. TBCLKSYNC使能顺序错误。 2. 各模块TBCLK预分频设置不一致。 3. 在TBCLKSYNC=1后,又修改了某个模块的预分频。 | 1. 严格按照第3.1节的四步顺序操作:使能时钟 -> TBCLKSYNC=0 -> 配置参数(确保分频一致)-> TBCLKSYNC=1。 2. 检查所有需要同步的ePWM模块的TBCTL寄存器,确保HSPCLKDIV和CLKDIV字段完全相同。 3. 一旦同步启动,避免再动态修改预分频器。如需修改,必须先将TBCLKSYNC清零。 |
| 计数器相位无法对齐 | 1. 从模块的同步输入未使能(TBCTL[PHSEN]=0)。 2. 主模块的同步输出(SYNCO)未在预期事件产生。 3. TBPHS值设置错误,或未考虑计数模式。 | 1. 确认需要同步的从模块已设置TBCTL[PHSEN]=1。 2. 检查主模块的TBCTL[SYNCOSEL]位,确认SYNCO输出源配置正确(例如,配置为在CTR=ZERO时产生脉冲)。 3. 确认TBPHS值。在递增-递减模式下,如果希望从模块波形滞后主模块1/4周期,且TBPRD=1000,则应设置TBPHS=250(即1000/4)。同时注意TBCTL[PHSDIR]的设置,它决定了同步后计数方向。 |
| 同步链中后续模块不同步 | 同步脉冲在传递过程中丢失。SYNCO信号路径可能未连通。 | 使用寄存器查看工具或示波器(如果SYNCO映射到GPIO)检测同步脉冲。确保每个模块的SYNCO都正确连接到下一个模块的SYNCI。检查EPWMSYNCINSEL寄存器的配置,确认每个模块的SYNCI源选择正确。 |
6.3 高级功能调试技巧
1. 利用影子寄存器状态位CMPCTL寄存器中的[SHDWAFULL]和[SHDWBFULL]位非常有用。当软件向CMPA/CMPB影子寄存器写入新值时,这些状态位会被置1。当指定的加载事件发生,影子寄存器的值被转移到活动寄存器后,这些位会自动清零。你可以在中断服务程序中查询这些位,来判断上一次设置的参数是否已被加载生效,从而实现“双缓冲”或“乒乓操作”式的平滑参数更新,避免写入冲突。
2. 使用软件强制同步进行调试在调试同步逻辑时,可以充分利用TBCTL[SWFSYNC]位。在主循环中手动触发SWFSYNC,同时用示波器观察各个ePWM模块的输出。你可以清晰地看到,一次软件强制同步是否将所有模块的计数器都重置到了TBPHS定义的相位。这是一个验证同步链路和相位配置是否正确的快速方法。
3. 结合ET模块触发ADC采样在电机FOC控制中,需要在PWM周期的特定时刻(如中心点或下溢点)进行ADC采样。你可以配置CMPC寄存器,并设置CTR=CMPC事件来触发EPWMxSOCA或EPWMxSOCB信号,进而启动ADC转换。关键是配置CMPCTL2[LOADCMODE],确保CMPC影子寄存器的加载时机(如CTR=ZERO)与你的控制算法更新占空比的时机错开,避免在ADC采样时刻修改比较值,造成干扰。
4. 全局加载的验证验证全局加载是否工作,可以设计一个测试:让两个ePWM模块以相同的频率运行,并使能它们CMPA寄存器的全局加载,事件选为CTR=ZERO。在一个中断里,同时修改两个模块的CMPA影子寄存器为两个不同的值(比如一个变大,一个变小)。用示波器观察两个PWM输出的占空比,它们应该在同一个PWM周期内同时改变。如果发现改变不同步,相差一个或多个周期,则说明全局加载未正确配置或生效。