EPWM模块中很多寄存器都分为活动寄存器和影子寄存器。典型的,比如计数周期寄存器PRD,平时在中断里面更新PRD的值来改变PWM波的频率时,并不是立即生效,而是等到计数器计到0后在下一个计数周期中生效。
(资料图)
在早期的ePWM模块设计中,PRD寄存器的加载与以下配置有关:
该位的解释如下:
Active Period Register Load From Shadow Register Select
0:The period register (TBPRD) is loaded from its shadow register when the time-base counter,TBCTR, is equal to zero.
A write or read to the TBPRD register accesses the shadow register.
1:Load the TBPRD register immediately without using a shadow register.
A write or read to the TBPRD register directly accesses the active register.
注:复位后PRDLD的值为0,即默认情况下使能了影子寄存器。
此设计可以解决TBPRD与比较值CMPA/CMPB之间的同步问题。
试想一下,如果没有影子寄存器的机制,在哪些应用场景下会出现问题?
在变频应用中,比如只改变频率,不改变占比空(比如维持在50%)的情况下,要想改变频率,必须在中断服务函数中同时更改PRD和CMP值。但是,软件给寄存器赋值和硬件计数器之间是不同步的,有可能刚好将PRD和CMP中的某一个寄存器更新了而另一个还没有来得及更新的时候,CC模块得出的比较信号出错了。
上述影子寄存器的机制只解决了单个EPWM模块内部的同步加载。在移相应用中,涉及到多个EPWM模块之间的同步,需要考虑TBPRD和TBPHS的同步。
比如,下面这种情况,PWM1和PWM2的频率相同,PRD都是600,但是相位差了120度,PWM2的TBPHS等于PRD/3。但是,在某一个时刻,ISR程序中更新了频率,把TBPRD由600改为了1200,同时将PWM2的相位寄存器TBPHS由200改为了400.。接下来,PWM1的计数器归零,发出同步信号SYNCO。此时PWM2的计数值更新为400,但是PRD的值还没有从影子寄存器更新的活动寄存器,仍然是600。(要等到计数器归零时才更新)。等到PWM2的计数器计满归零后,TBPRD才从600更新为1200。此时时刻,PWM2和PWM1之间失去了同步。
为了解决这个问题,为PRD的加载新增加了一个同步机制。
上述风险已在 2 型 ePWM 中得到解决,后者会额外启用同步事件,由 TBCTL2[PRDLDSYNC] 位确定,以使影子 到活动加载对 TBPRD 和 CMP 寄存器有效。这样就可以得到正确的相移,如下图所示。
当PWM2收到PWM1的同步信号时,PWM2的PRD也会同步加载。关于PRDLDSYNC的说明如下:
首先,当PRDLD位为0时(使能影子寄存器),TBPRD的加载不是简单地看TBCTR是否等于0,还要看PRDLDSYNC位。
Active Period Reg Load from Shadow Select
0: The period register (TBPRD) is loaded from its shadow register when the time-base counter, TBCTR, is equal to zero and/or a sync event as determined by the TBCTL2 PRDLDSYNC bit.
A write/read to the TBPRD register accesses the shadow register.
1: Immediate Mode (Shadow register bypassed): A write or read to the TBPRD register accesses the active register.
再来看TBCTL2寄存器中的PRDLDSYNC位:
当PRDLDSYNC配置为01时,当TBCTR=0或者SYNC信号发生时,都会触发TBPRD的加载。
这么多影子寄存器,每个都受到一堆条件的限制,这时就需要一个动作将影子寄存器进行加载,这个就是“全局加载”。
When this feature is enabled, the transfer of contents from the shadow register to the active register, for all registers that have this mode enabled, occurs at the same event as defined by the configuration bits in Global Shadow to Active Load Control Register (GLDCTL[GLDMODE]). When GLDCTL[GLD] = ’1’, shadow to active load event selection bits for individual shadowed registers are ignored and global load mode takes effect for the corresponding registers enabled by GLDCFG[REGx].
首先,可以选择加载触发的条件:CTR=0/CTR=PRD及同步信号等。
其次,可以选择是否单次模式。在单次模式下,软件每向GLDCTL2[OSHTLD]中写入一个“1”,就触发一次加载。连续模式下,可配置触发条件满足N次才加载一次。
在 LLC 等变频应用中,控制 ISR 将会更新周期和比较寄存器,该操作以固定频率运行,此频率与 PWM 开关频率异步。因此,可能会在切换周期即将结束的某一时间点触发执行 ISR。如果是这种情况,用于更新 ePWM 寄存器 的 ISR 代码的某些部分有可能在周期结束之前执行,而该代码的其余部分在下一个开关周期中执行。如图所示,ePWM1 的周期寄存器在开关周期结束前更新,而 ePWM2 的周期寄存器并未及时更新。因此,ePWM2 以旧 的 PWM 频率运行,而 ePWM1 以新频率运行。
为了解决这个问题,引入寄存器链接方案。
For variable frequency applications, there is a need for simultaneous writes of TBPRD and CMPx registers between ePWM modules. This prevents situations where a CTR = 0 or CTR = PRD pulse forces a shadow to active load of these registers before all registers are updated between ePWM modules (resulting in some registers being loaded from new shadow values while others are loaded from old shadow values). To support this, an ePWM register linking scheme for TBPRD:TBPRDHR, CMPA:CMPAHR, CMPB:CMPBHR, CMPC, and CMPD registers between PWM modules has been added.
对于变频应用,需要在ePWM模块之间同时写入TBPRD和CMPx寄存器。这可以防止在ePWM模块之间更新所有寄存器之前,CTR = 0或CTR = PRD脉冲强制影子对这些寄存器进行活动负载(导致某些寄存器从新的阴影值加载,而其他寄存器则从旧的阴影值加载)。为了支持这一点,在PWM模块之间添加了TBPRD:TBPRDHR,CMPA:CMPAHR,CMPB:CMPBHR,CMPC和CMPD寄存器的ePWM寄存器链接方案。
For a particular ePWM module # A , user code writes “B+1”, to the linked register bit-field in EPWMXLINK. “B” is the ePWM module # being linked to (that is, writes to the ePWM module “B” TBPRD:TBPRDHR, CMPA:CMPAHR, CMPB:CMPBHR, or CMPC will simultaneously be written to corresponding register in ePWM module “A”). For instance if ePWM3 EPWMXLINK register is configured so that CMPA:CMPAHR are linked to ePWM1, then a write to CMPA:CMPAHR in ePWM 1 will simultaneously write the same value to CMPA:CMPAHR in ePWM3. If ePWM4 also has its CMPA:CMPAHR registers linked to ePWM1, then a write to ePWM 1 will write the same value to the CMPA:CMPAHR registers in both ePWM3 and ePWM4.
对于特定的 ePWM 模块 # A,用户代码将"B+1"写入 EPWMXLINK 中链接的寄存器位字段。"B"是链接到的 ePWM 模块 # (即写入 ePWM 模块 "B" TBPRD:TBPRDHR、CMPA:CMPAHR、CMPB:CMPBHR 或 CMPC 将同时写入 ePWM 模块 "A" 中的相应寄存器)。例如,如果将 ePWM3 EPWMXLINK 寄存器配置为将 CMPA:CMPAHR 链接到 ePWM1,则在 ePWM 1 中写入 CMPA:CMPAHR 将同时向 ePWM3 中的 CMPA:CMPAHR 写入相同的值。如果 ePWM4 还具有链接到 ePWM1 的 CMPA:CMPAHR 寄存器,则写入 ePWM 1 将向 ePWM3 和 ePWM4 中的 CMPA:CMPAHR 寄存器写入相同的值。
The register description for EPWMXLINK clearly explains the linked register bit-field values for corresponding ePWM. An example of using the EPWMXLINK is linking ePWM2 CMPA with CMPA of ePWM1. In this case, a write to CMPA of ePWM1 will also change the CMPA value for ePWM2.
EPWMXLINK的寄存器描述清楚地解释了相应ePWM的链接寄存器位字段值。使用EPWMXLINK的一个例子是将ePWM2 CMPA与ePWM1的CMPA联系起来。在这种情况下,写入 ePWM1 的 CMPA 也会更改 ePWM2 的 CMPA 值。
如果控制 ISR 与 PWM 开关频率异步,则还需要使用一次性加载模式和全局加载模式,以确保多个 PWM 模块中 的所有寄存器在所选事件中都是最新的。 使用一次性加载模式,用户可在全局加载机制下设置 GLDCTL2[OSHTLD] =‘1’,以确保影子寄存器到活动寄存 器的传输只发生一次。换而言之,所有全局加载事件都被阻止,除非 GLDCTL2[OSHTLD] =‘1’。此外,也可以 跨多个 PWM 模块使用 EPWMXLINK[GLDCTL2LINK] 链接 GLDCTL2 寄存器。因此,借助 ePWM 链接方案,当 在所有寄存器更新后启用一次性加载模式时,一个或多个 PWM 模块中的多个 PWM 寄存器只会在第一次全局加 载事件中生效,后续事件将被忽略。
1. 在初始化期间
// Sync source ePWM1 settings
EPWM_enableGlobalLoadRegisters(base1, EPWM_GL_REGISTER_CMPA_CMPAHR| EPWM_GL_REGISTER_TBPRD_TBPRDHR|EPWM_GL_REGISTER_DBRED_DBREDHR| EPWM_GL_REGISTER_DBFED_DBFEDHR|EPWM_GL_REGISTER_CMPC);
EPWM_setGlobalLoadTrigger(base1, EPWM_GL_LOAD_PULSE_CNTR_PERIOD);
EPWM_enableGlobalLoadOneShotMode(base1);
EPWM_enableGlobalLoad(base1);
// Sync receiver ePWM2 settings
EPWM_enableGlobalLoadRegisters(base2, EPWM_GL_REGISTER_CMPA_CMPAHR| PWM_GL_REGISTER_TBPRD_TBPRDHR|EPWM_GL_REGISTER_DBRED_DBREDHR| EPWM_GL_REGISTER_DBFED_DBFEDHR);
EPWM_setGlobalLoadTrigger(base2, EPWM_GL_LOAD_PULSE_SYNC);
EPWM_enableGlobalLoadOneShotMode(base2);
EPWM_enableGlobalLoad(base2);
EPWM_setupEPWMLinks(base2, EPWM_LINK_WITH_EPWM_2, EPWM_LINK_GLDCTL2);
2. 在执行控制 ISR 期间
EPWM_setGlobalLoadOneShotLatch(HIGH_FREQ_PWM1_BASE);
标签: