8.DSP学习记录之ePWM
ePWM
- 一、ePWM简介
- 1. DSP28335的ePWM资源
- 2. ePWM实现原理
- 二、ePWM内部模块解释
- 1.时基模块(TB)
- (1)计数时钟频率的配置
- (2)计数模式和PWM周期
- (3)影子(映射)寄存器
- (4)时钟同步和相位控制
- (5)软件同步多个ePWM模块的基准时钟
- 2.比较计数模块(CC)
- (1)CC相关寄存器及其作用概述
- (2)同步操作下比较事件情况
- 3.动作限定子模块(AQ)
- (1)输入阶段
- (2)输出阶段
- (3)触发事件的优先级
- (4)三种计数方式的PWM产生
- (5)总结
- 4.死区控制模块(DB)
- (1)DBCTL死区控制寄存器操作
- (2)常用的一种死区设置方案
- 5.斩波控制模块(PC)
- 6.故障捕获模块(TZ)
- 7.事件触发触发模块(ET)
- (a)中断功能
- (b)产生ADC启动信号
- 三、相关寄存器与位功能解释汇总
- 1.时基模块相应寄存器汇总
- 2.计数比较相应寄存器汇总
- 3.动作模块寄存器汇总
- 4.死区模块寄存器汇总
- 5.斩波模块寄存器汇总
- 6.错误联防(故障捕获)模块寄存器汇总
- 7.事件触发模块寄存器汇总
- 四、PWM输出配置步骤
- (1)使能ePWM外设时钟及失能时基模块时钟
- (2)开启ePWM对应GPIO时钟及初始化配置
- (3)初始化时基模块,即配置TB相关寄存器值
- (4)初始化比较模块,即配置CC相关寄存器值
- (5)初始化动作限定模块,即配置AQ相关寄存器值
- (6)初始化事件触发模块,即配置ET相关寄存器值
- (7)初始化死区模块、斩波模块,即配置DB、PC相关寄存器值
- (8)使能时基计数器时钟
- 五、ePwm呼吸灯实验
ePWM模块是TI DSP最重要的模块
DSP之所以能够在电源、电机控制应用广泛与DSP的ePWM模块密不可分
本文大量参考《手把手叫你学DSP》这本书,有条件直接看课本效果更好
一、ePWM简介
PWM(脉冲宽度调制)通过控制调节脉冲宽度控制功率输出的模式,主要由三部分组成:占空比Tpn/T、脉冲宽度Ton、脉冲周期T
单周期的PWM波形很简单,主要就是控制脉冲的周期,脉冲的宽度,脉冲起落的时间,一个周期内的脉冲个数,但事实是产生PWM波形时,要结合实际应用,每个要素都要顾及,需要灵活配置。
1. DSP28335的ePWM资源
F28335中每个ePWM模块都是一个独立的小模块,每个ePWM模块由两路ePWM输出组成,分别为ePWMxA和ePWMxB,这一对PWM输出,可以配置成两路独立的单边沿PWM输出,或者两路独立的但互相相对称的双边沿PWM输出,或者一对双边沿非对称的PWM输出,共有6对这样的ePWM模
块,因为每对PWM模块中的两个PWM输出均可以单独使用,所以也可以认为有12 路单路ePWM,除此之外还有6个APWM,这6个APWM通过CAP模块扩展配置,可以独立使用,所以F28335最多可以有18路PWM输出。
每一组ePWM模块都包含以下7个模块:时基模块TB、计数比较模块CC、动作模块AQ、死区产生模块DB、PWM 斩波模块PC、错误联防模块TZ、事件触发模块ET。

上图中,ePWM通过ePWMxA和ePWMxB输出PWM波,PIE是中断管理
TZ1~TZ6是故障触发,用于告知ePWM出现了故障,需要立即停机,从而实现保护功能。每个ePWM模块都可以使用或屏蔽掉故障触发信号。
时钟基准同步信号输入EPWMxSYNCI及输出EPWMxSYNCO可以将所有的ePWM模块连接成一个整体,当然,每个ePWM模块都可以通过设置,使用或者忽略同步信号;
ADC启动信号EPWMxSOCA和EPWMxSOCB。
28335的整体内部结构如下图所示:

2. ePWM实现原理

与STM32的PWM实现原理类似,从图看出,需要有3个寄存器:周期寄存器TPR、计数器寄存器TCNT和比较寄存器CMPR。
产生PWM原理如下:
周期寄存器TPR决定了一个周期计数的最大值,也就决定了PWM的周期。计数器寄存器TCNT按照时钟信号来进行计数,图中为增减计数模式, 即从0增计数到TPR,然后再从TPR减计数到0,不断重复。当计数器寄存器TCNT的值与比较寄存器的值CMPR相等时,PWM的电平发生变化,由低电平变为高电平,或者由高电平变为低电平,从而产生周期性的PWM波形 。改变周期寄存器TPR,就可以改变PWM的周期,即可以改变PWM的频率;改变比较寄存器CMPR,就可以改变PWM的占空比。
二、ePWM内部模块解释
由上解释,PWM模块内部主要包括以下模块:
时基模块(TB)
比较计数模块(CC)
动作模块(AQ)
死区模块(DB)
PWM斩波模块(PC)
事件触发模块(ET)
联防模块(TZ)
下面对其进行详细解释。
1.时基模块(TB)
通过时间基准子模块TB可以实现计数时钟的配置、计数模式的选择、同步信号的选择、相位的控制等功能,下面会分别进行介绍。其内部结构如下图

相对应的寄存器有:

(1)计数时钟频率的配置
计数器计数需要一个计数的节拍来进行计数,也就是它需要按照一定的时间来进行一次计数。时间基准子模块TB的计数时钟TBCLK是由系统时钟 SYSCLKOUT分频而来。
计数器和控制寄存器TBCTL的两个位有关:HDSPCLKDIV和CLKDIV。
HSPCLKDIV 的值为x,则如果x为0,则分频系数为1,如果x不为0,则分频系数为2x;如果CLKDIV的值为y,则分频系数为2。计数时钟TBCLK的计算公式为:
举例:主频SYSCLK150Mhz,若HDSPCLKDIV为0,CLKDIV为2,则TBCLK为37.5Mhz
(2)计数模式和PWM周期
主要有三种计数方式,增计数、减计数、增减计数
周期寄存器TBPRD决定了PWM的周期
增计数模式:计数器TBCTR从0开始增计数,每次加1,计数到TBPRD时,TBCTR变为0,然后重新开始增计数至TBPRD,不断重复。
减计数模式:计数器TBCTR从TBPRD开始减计数,每次减1,计数到0时,TBCTR又变为TBPRD,然后重新开始减计数至0,不断重复。
增减计数模式:计数器TBCTR从0开始增计数,每次加1,计数到TBPRD时,进行减计数,每次减1,计数到0时再开始增计数,不断重复。
计数器工作在增计数模式或者减计数模式时,PWM的计数周期 脉冲个数 为:Tpwm=TBPRD+1
当计数器工作于增减计数模式时,PWM的计数周期 脉冲个数为:Tpwm=2* TBPRD
而每计一次数所需要的时间是由计数时钟来决定对的,计数时钟为TBCLK,即一次计时时间为1/TBCLK纳秒
故而PWM的周期为:
T=Tpwm∗1/TBCLK∗10t−6T = Tpwm *1/TBCLK *10t^{-6}T=Tpwm∗1/TBCLK∗10t−6
得到PWM的周期,PWM的频率也就得到了,取倒数就可以。
(3)影子(映射)寄存器
影子寄存器可以使得硬件的更新和寄存器同步。当前寄存器可以用来控制系统硬件的运行,并反映硬件的当前状态。映射寄存器可以用来临时存放数据,并在某个特定的时刻将数据传送给当前寄存器,可见映射寄存器对硬件没有任何直接作用。
映射寄存器和当前寄存器拥有相同的地址,TBCTL[PRDLD] 位决定了是否使用TBPRD的映射寄存器功能,从而决定了CPU读写操作作用于当前寄存器还是映射寄存器。
(1)TBPRD映射模式。
当TBCTL[PRDLD]=0时,TBPRD使用映射模式,此时CPU读写TBPRD的地址单元将直接作用于映射寄存器。当计数器TBCTR的值等于0时,映射寄存器中的内容直接装载到当前寄存器。默认情况TBPRD采用映射模式。
(2)TBPRD立即模式。当TBCTL[PRDLD]=1时,TBPRD使用立即模式,此时CPU读写TBPRD的地址单元时将绕开映射寄存器,而直接作用于当前寄存器。
(4)时钟同步和相位控制
前面讲过,如果只有一个ePWM单元,就不会存在同步问题,自顾自地计数就可以了,但是当多个ePWM模块一起工作时,往往会涉及输出PWM的同步问题,即如何让多个ePWM模块同步进行计数,换句话说,通过同步可以将器件内所有的ePWM模块连在一起。如下图:

TMS320F28335的每个ePWM都有一个同步信号输入EPWMxSYNCI和一个同步信号输出EPWMxSYNCO。
ePWM1模块的同步信号输入来自于外部引脚,然后ePWM1将同步信号输出给ePWM2和ePWM4,其他模块的同步信号输入/输出关系见图。每个ePWM模块都可以使用或者忽略同步信号。
在实际使用时,PWM信号之间往往会有相位的差别,ePWM的时间基准子模块可以通过TBCTL[PHSEN]位来实现相位控制功能。如果TBCTL[PHSEN]=1,那么相应的ePWM模块的时间基准计数器TBCTR将在以下情况发生时自动装载相位寄存器 TBPHS中的值。
(1)同步脉冲EPWMxSYNCI输入时,即当同步脉冲信号EPWMxSYNCI被检测到时,相位寄存器TBPHS中的值将被装载到时间基准计数器TBCTR中,装载过程发生在下一个时间基准时钟 TBCLK的上升沿。如果TBCLK=SYSCLKOUT,那么将产生两个TBCLK周期的延时;如果TBCLK != SYSCLKOUT,那么将产生一个TBCLK周期的延时。
(2)软件强制同步脉冲产生时,即当向**TBCTL[SWFSYNC]**位中写1时,相当于使用软件强制的方式产生一个同步脉冲,而软件产生的同步脉冲与EPWMxSYNCI具有相同的作用。
相位控制功能可以方便地控制各个ePWM模块所产生的PWM脉冲之间的相位关系,可控制一路PWM脉冲的相位超前、滞后或与另一路PWM脉冲同步。在增减计数模式下,TBCTL[PSHDIR]位控制同步事件发生后时间基准计数器TBCTR的计数方向,新的计数方向与同步事件之前的计数方向无关。在增计数或减计数模式下,PHSDIR位被忽略。
图示如下:增计数(减计数同理)

增减计数:
(5)软件同步多个ePWM模块的基准时钟
如果有多个ePWM模块的基准时钟被使能,那么时间基准控制寄存器TBCTL[TBCLKSYNC]位可以用来同步这些基准时钟。当TBCTL[TBCLKSYNC]=0时,所有ePWM模块的时钟停止(默认);当TBCTL[TBCLKSYNC]=1时,所有ePWM模块的时钟在TBCLK的上升沿启动。
在初始化ePWM模块时,需要按照以下步骤进行操作:
(1)使能各个ePWM模块的时钟;
(2)将TBCLKSYNC清零,从而停止所有ePWM模块的时钟;
(3)对ePWM模块进行配置;
(4)将TBCLKSYNC置位,同时启动所有ePWM模块的时钟。
2.比较计数模块(CC)
计数器比较功能(Counter Compare,CC)子模块有两个比较寄存器CMPA和CMPB,其功能就是将计数器寄存器TBCTR的值和这两个比较寄存器的值进行比较,由此产生比较事件,从而产生PWM波。
需要注意的是:
不要以为EPWMxA引脚使用比较寄存器CMPA,EPWMxB引脚使用比较寄存器B,在这里,EPWMxA可以使用CMPA或CMPB,EPWMxB也可以使用CMPA或CMPB,具体配置下面在下一步的AQ子模块中进行介绍。
(1)CC相关寄存器及其作用概述
该模块在ePWM中的位置在如图:
该模块主要包括如下四个寄存器:
比较事件出现时间:
当计数器寄存器TBCTR的值与比较寄存器A的值相等时,会产生CTR=CMPA事件;当计数器寄存器TBCTR的值与比较寄存器B的值相等时,会产生CTR=CMPB事件。
比较事件出现次数:
对于增计数和减计数模式,比较事件在一个计数周期内出现一次。对于增减计数模式,如果比较值为0~TBPRD,则比较事件在一个计数周期内出现两次;如果比较值等于0或者TBPRD,则比较事件在一个计数周期内只出现一次。
比较寄存器的映射以及装载时间:
比较寄存器CMPA和CMPB都有相应的映射寄存器,CMPA是否启用映射寄存器由 CMPCTL[SHDWAMODE] 决定,CMPB是否启用映射寄存器由 CMPCTL[SHDWBMODE] 决定。
如果启用了映射寄存器,CMPA和CMPB工作于映射模式,可以通过CMPCTL
[LOADAMODE]和CMPCTL[LOADBMODE]选择何时将映射寄存器中的内容装载进当
前寄存器中,可以有3种选择:
(1)TBCTR=0时,也就是当计数器寄存器计数到0时,将映射寄存器中的值装载进当前寄存器中。
(2)TBCTR=TBPRD时,也就是当计数器寄存器计数到TBPRD时,将映射寄存器中的值装载进当前寄存器中。
(3)TBCTR=0或TBCTR=TBPRD时,也就是当计数器寄存器计数到0或TBPRD时,将映射寄存器中的值装载进当前寄存器中。
当然,如果选择CMPA和CMPB工作于立即模式,则只要值有更新,就会将CMPA和
CMPB的值直接写进当前寄存器中,比较值立即发生更新。
(2)同步操作下比较事件情况
增计数举例:
在画圈时刻产生同步信号,使得计数器装载TBPHS的值,进而使得CMPB重复触发
增减计数的TBCTL[PHSDIR] = 0(同步信号计数方向为减计数)举例:

在画圈时刻产生同步信号,使得计数器装载TBPHS的值,因TBCTL[PHSDIR] = 0,故技术方向为减计数,不改变CMPA/B的触发,TBCTL[PHSDIR] = 1时同理
3.动作限定子模块(AQ)
动作限定模块主要用于对计数器到达事件值进行处理,其主要寄存器如下表:

(1)输入阶段
该模块内部构成如下图:
送入AQ有四种情况,分别为:
(1)CTR=PRD,也就是当计数器寄存器TBCTR的值与周期寄存器TBPRD相等时
(2)CTR=Zero,也就是当计数器寄存器TBCTR的值等于0时
(3)CTR=CMPA,也就是当计数器寄存器TBCTR的值等于比较寄存器CMPA时
(4)CTR=CMPB,也就是当计数器寄存器TBCTR的值等于比较寄存器CMPB时
图中CTR_dir为计数方向,将计数方向输入给动作限定子模块,能够让AQ对计数器的计数
方向进行识别,从而使得AQ对引脚输出状态的控制变得更加灵活。
加上计数方向后,能够送入动作限定子模块的事件有:

(2)输出阶段
每个ePWM模块有两个输出引脚:EPWMxA和EPWMxB,对这两个引脚输出动作的设定是完全独立的,任何一个事件都可以对EPWMxA或EPWMxB产生任何动作。EPWMxA可以通过寄存器AQCTLA进行设置,EPWMxB可以通过寄存器AQCTLB进行设置。在寄存器AQCTLA和AQCTLB中,每个事件都可以被设置为以下4种动作中的一种:
(1)无动作,即保持EPWMxA或EPWMxB的输出状态不变
这种情况使得PWM引脚的输出状态不发生变化
但是这个事件仍然可以触发中断,也可以产生启动ADC转换的信号 SOC
(2)置高,使EPWMxA或EPWMxB输出高电平;
(3)置低,使EPWMxA或EPWMxB输出低电平;
(4)翻转,翻转EPWMxA或EPWMxB的状态,之前是高电平则变为低电平,之前是低电平则变为高电平。
在动作限定子模块中,除了计数器的各种事件能够限定PWM引脚动作外,还可以通过软件强制的功能来限定PWM引脚动作
软件强制可以通过寄存器AQSFRC和AQCSFRC来控制,比如当AQSFRC[OTSFA]=1时,就对EPWMxA引脚输出一次强制事件,此时引脚如何动作由AQSFRC[ACTSFA]来决定,可选的动作也是上面介绍的4种。
AQSFRC 是控制产生单次软件强制事件,而AQCSFRC是控制产生连续软件强制事件。
(3)触发事件的优先级
ePWM的动作限定子模块AQ在同一时刻可以接收多个发事件,在这种情况下,动作限定子模块如何响应呢?和中断优先级类似,AQ在硬件上也设计有事件的优先级。在众多事件中,软件强制的优先级始终是最高的,因为软件强制肯定是人为干预的,所以明显要优先响应。表12-5为增减计数模式下事件的优先级。
优先级具体高低定义如下:
增减计数:

增计数:
减计数:

(4)三种计数方式的PWM产生
在实际应用中,增计数和减计数通常用来产生不对称的PWM波,而中央对齐计数通常用来产生对称PWM波(常用于三相桥臂的通断)
a.增计数:

上图EPWMxA使用CMPA寄存器,EPWMxB使用CMPB寄存器,各自独立产生不对称的PWM波形,EPWMxA和EPWMxB虽然可以生成不同的PWM,但是频率是一样的,因为它们使用的是同一个周期寄存器TBPRD。
EPWMxA在TBCTR=CMPA时,变为高电平,在TBCTR=TBPRD时,变为低电平。如果CMPA=0,则EPWMxA始终输出高电平,占空比为100%;如果CMPA=TBPRD,则EPWMxA始终输出低电平,占空比为0%。
EPWMxA的占空比计算公式为: Duty=(TBPRD−CMPA)/TBPRDDuty = (TBPRD-CMPA)/TBPRDDuty=(TBPRD−CMPA)/TBPRD
EPWMxB的占空比计算公式为: Duty=CMPB/TBPRDDuty = CMPB/TBPRDDuty=CMPB/TBPRD
b.减计数:

上图EPWMxA使用CMPB寄存器,EPWMxB使用CMPA寄存器,其余均与增计数一致
注意:此处也说明了EPWMxA和CMPA并不是严格绑定,是可以与B通用的
c.中央对齐计数:

上图中,EPWMxA和EPWMxB都是用CMPA寄存器,输出对称互补的PWM波形。所谓互补是指当EPWMxA为高电平时,EPWMxB为低电平;当EPWMxA为低电平时,EPWMxB为高电平。
这种情况在实际应用中是最常见的,当驱动一个桥电路时,就需要一对互补的PWM。
EPWMxA在增计数时,如果TBCTR=CMPA,则变为高电平;在减计数时,如果TBCTR=CMPA,则变为低电平。如果CMPA=0,则EPWMxA始终输出高电平,占空比为100%;如果CMPA=TBPRD,则EPWMxA始终输出低电平,占空比为0%。
EPWMxA的占空比计算公式为:Duty=(TBPRD−CMPA)/TBPRDDuty = (TBPRD-CMPA)/TBPRDDuty=(TBPRD−CMPA)/TBPRD
EPWMxB在增计数时,如果TBCTR=CMPA,则变为低电平;在减计数时,如果TBCTR=CMPA,则变为高电平。如果CMPA=0,则EPWMxB始终输出低电平,占空比为0%;如果CMPA=TBPRD,则EPWMxB始终输出高电平,占空比为100%。
EPWMxB的占空比计算公式为: Duty=CMPA/TBPRDDuty = CMPA/TBPRDDuty=CMPA/TBPRD
(5)总结
简单总结一下,PWM产生需要周期寄存器TBPRD,计数器寄存器TBCTR,还有比较寄存器CMPx,TBPRD决定了PWM的周期,也就是PWM的频率,计数方式;CMPx、动作限定共同决定了PWM的占空比。
在使用时,改变TBPRD的值可以改变PWM的频率;改变CMPx的值可以改变PWM的占空比。
4.死区控制模块(DB)
常用于避免一侧桥臂两个开关管同时导通的情况
简单讲,死区就是在两个互补对称PWM中间插入短暂的延时,使得同一桥臂的上下开关管总是上管关闭后下管再导通,如下图:
相应的寄存器:
内部结构:

(1)DBCTL死区控制寄存器操作
死区控制子模块DB的内部结构主要包含了3个部分,分别是输入信号源选择、极性控制和输出模式选择,这3个部分均可以通过寄存器DBCTL来设置。
(a)输入信号源选择DBCTL[IN_MODE],对需要边沿控制的信号源进行选择:
DBCTL[IN_MODE]=0x00,EPWMxA作为上升沿及下降沿延时的信号源;
DBCTL[IN_MODE]=0x01,EPWMxB作为上升沿的信号源,EPWMxA作为下降沿的信号源;
DBCTL[IN_MODE]=0x10,EPWMxA作为上升沿的信号源,EPWMxB作为下降沿的信号源;
DBCTL[IN_MODE]=0x11,EPWMxB作为上升沿及下降沿延时的信号源。
(b)极性控制DBCTL[POLSEL],决定是否在信号输出前,对经过上升沿或下降沿延时控制的信号进行取反操作:
DBCTL[POSEL]=0x00,EPWMxA和EPWMxB均不反转极性,也就是都不用取反,直接输出;
DBCTL[POSEL]=0x01,EPWMxA反转极性,EPWMxB直接输出;
DBCTL[POSEL]=0x10,EPWMxB反转极性,EPWMxA直接输出;
DBCTL[POSEL]=0x11,EPWMxA和EPWMxB均反转极性,信号取反后再输出。
( c)输出模式选择DBCTL[OUT_MODE],决定是否需要对输入信号进行边沿控制:
DBCTL[OUT_MODE]=0x00,禁用延时,EPWMxA和EPWMxB直接通过DB子模块; DBCTL[OUT_MODE]=0x01,禁用上升沿延时,EPWMxA直接通过DB子模块;
DBCTL[OUT_MODE]=0x10,禁用下降沿延时,EPWMxB直接通过DB子模块;
DBCTL[OUT_MODE]=0x11,使能上升沿和下降沿延时。
(2)常用的一种死区设置方案
EPWMxA和EPWMxB互补输出分别驱动一个桥臂的上下管,死区控制子模块DB的输出模式设定为
EPWMxA和EPWMxB均需要延时,都会送进DB子模块进行延时控制。选择EPWMxA的上升沿进行延时控制,EPWMxB的下降沿进行延时控制。
DB的输入信号EPWMxA_in和EPWMxB_in为两个相同的信号。EPWMxA_in的上升沿经过延时控制后,直接输出。EPWMxB_in的下降沿经过延时控制后,先取反,然后再输出。
具有死区的互补输出的一对PWM – EPWMxA和EPWMxB。
死区控制子模块DB的上升沿延时时间由寄存器DBRED决定,下降沿延时时间由DBFED决定,两个时间可以独立设置。通常,死区时间设置在几μs。
DBRED 和 DBFED延时时间计算式公式如下:
TRED=DBRED∗TBCLKTRED=DBRED* TBCLKTRED=DBRED∗TBCLK
TFED=DBFED∗TBCLKTFED=DBFED * TBCLKTFED=DBFED∗TBCLK
具体实现如下图:
5.斩波控制模块(PC)
该模块作用的个人理解:用高频载波使得原PWM的高电平供电时间再进行一次PWM调制
斩波控制(PWM Chopper,PC)子模块可以通过高频载波信号对由AQ或者DB子模块输出的PWM波形进行调制,这项功能在控制高开关频率的功率器件时非常有用。

斩波控制模块寄存器:

PCCTL[CHPEN]=0:信号不需要通过斩波控制子模块而直接输出
PCCTL[CHPEN]=1:斩波功能使能,PWM信号将经过高频载波信号调制后再输出
PCCTL[CHPFREQ]:控制频率(CHPFREQ取值范围0~7)
PCCTL[CHDUTY]:控制占空比(CHDUTY取值范围0~6)
PCCTL[OSHTWTH]:设置首次脉冲(取值范围为0~15)
内部结构:
高频载波信号是由系统时钟SYSCLKOUT分频而来,其频率和占空比由**PCCTL[CHPFREQ]和PCCTL[CHDUTY]**控制,其频率和占空比计算公式如下:
fpwm−chopper=SYSCLKOUT8×(CHPFREQ+1)\ f_{pwm-chopper} = \frac{SYSCLKOUT}{8×(CHPFREQ+1)} fpwm−chopper=8×(CHPFREQ+1)SYSCLKOUT
Dutypwm−chopper=1+CHPDUTY8×∗100%。\ Duty_{pwm-chopper} = \frac{1+CHPDUTY}{8×}*100 \%。 Dutypwm−chopper=8×1+CHPDUTY∗100%。
过程如下图:
原先PWM高电平的地方变成了高频载波信号,把每一个周期内的第一个载波脉冲称为首次脉冲(one shot)。首次脉冲的宽度是可编程的,可以使得第一个脉冲携带较大的能量,从而保证功率器件能够可靠开通,而其余脉冲用来维持功率器件的持续开通与关断。
首次脉冲宽度可以通过PCCTL[OSHTWTH]来设置,取值范围为0~15,其计算公式如下:
Tfirst−pulse=Tfirst−pulse∗8∗(1+OSHTWTH)\ T_{first-pulse} = T_{first-pulse} *8*(1+OSHTWTH) Tfirst−pulse=Tfirst−pulse∗8∗(1+OSHTWTH)
上式中,Tfirst−pulseT_{first-pulse}Tfirst−pulse 为系统时钟SYSCLKOUT的周期
首次脉冲斩波如下图:
6.故障捕获模块(TZ)
其故障保护作用,它有6个输入引脚TZn,外部信号可以通过这几个引脚接入故障捕获子模块,用来表示发生了外部故障或者其他事件,从而ePWM模块对此作出相应的动作,比如将所有的PWM信号置为低电平。
寄存器主要有下面几个 :
选择寄存器TZSEL,每个ePWM模块都可以使用或者忽略6路故障触发信号中的任何一路若禁用则这个ePWM模块的PWM信号不受故障保护,将直接输出。
如果为某个ePWM模块选择了故障触发信号输入引脚,该引脚平时是高电平状态,如果通过电路的设计,在外部出现故障时,将该故障触发信号输入引脚的电平置为低电平,则故障捕获子模块捕获到故障信
号,然后根据控制寄存器TZCTL的设置来完成相应的动作,可以将相应的EPWMxA引脚和EPWMxB引脚强制为低电平、高电平或者高阻态输出。
每个TZn输入可以配置成单次触发(one shot trip)或周期性触发(cycle-by-cycletrip),这由寄存器TZSEL[OSHTn]位和TZSEL[CBCn]位决定,其定义如下:
(1)单次触发。
单次触发是指故障捕获模块一旦被故障信号触发,就会根据TZCTL寄存器里设定的情形来强制EPWMxA和EPWMxB的输出,这种输出状态会一直保持下去,除非人为清除故障信号并复位ePWM。
另外,单次触发事件标志位**TZFLG[OST]**置位。如果通过TZEINT寄存器使能了外设中断和相应的PIE中断,将产生 EPWMx_TZINT中断。
注意:TZFLG[OST]标志位必须通过写TZCLR[OST]位手动清除。
(2)周期性触发。
周期性触发是以计数器TBCTR的计数周期为单位的,在每一个周期内,如果捕获到故障信号,则EPWMxA和EPWMxB的输出立即由TZCTL寄存器中所设定的状态决定,但是当PWM模块的计数器寄存器TBCTR计数到0时并且故障信号已经不存在时,EPWMxA和EPWMxB的强制状态就会被清除。因此,在该模式下触发事件在每个ePWM周期内被清除。
另外,周期性故障触发事件标志位TZFLG[CBC]置位。如果通过TZEINT寄存器使能了外设中断和相应的PIE中断,则将产生EPWMx_TZINT中断。TZFLG[CBC]标志位将一直保持不变,直到通过写 ** TZCLR[CBC] **位可将其清零。如果周期性触发事件仍然存在,那么即使手动清除TZFLG[CBC],也会立即再次被置位。
7.事件触发触发模块(ET)
事件触发(Event Trigger,ET)子模块用来处理时间基准计数器、比较功能子模块所产生的各种事件,然后向CPU发出中断请求或产生ADC启动信号SOCA或SOCB。

如上图:每个ePWM模块都有一条连接到PIE上的中断请求信号线和连接到ADC模块上的两路ADC启动信号SOCA及SOCB,所有ADC启动信号都通过“或门”连接到了一起,如果同时有两路ADC启动信号出现,则只有一路启动信号能被识别。
相关的寄存器如下:
事件触发模块内部如下图:

可以得到,以下情况会产生事件:

上述这些事件中的任何一个都可以产生中断,也都可以产生ADC的启动信号,究竟是哪种事件可以产生中断或者ADC启动信号则可以通过ETSEL寄存器进行设置。从事件产生的结果来看,事件触发子模块只有3种情况:触发中断、ADCSOCA、ADCSOB,这3种情况寄存器设置的内容是相同的。
比如ETSEL寄存器,每种情况都有一个位用来使能或者禁止该信号,还有3位来选择具体的事件触发源。下面按中断功能和产生ADC启动信号来分别进行介绍
(a)中断功能
内部结构如下:

ET的中断逻辑里有一个计数器ETPS[INTCNT],它是用来统计中断事件发生的次数的,当寄存器ETSEL[INTSEL]中设定的中断事件发生时,计数器ETPS[INTCNT]会加1,此时是不会产生中断请求的,只有当 ETPS[INTCNT] = ETPS[INTPRD] 时,ET才会向PIE发出中断请求。ETPS[INTPRD]用来表明每发生多少次中断事件,会产生中断信号EPWMx_INT。
当ETPS[INTCNT]=ETPS[INTPRD]时,计数器停止计数,接下来可能发生的情况有下面3种:
(1)如果外设中断没有被使能ETSEL[INTEN]=0,或中断标志位已经被置位ETFLG[INT]=1,则不会产生中断请求,中断事件计数器ETPS[INTCNT]停止计数,保持当前值不变。
(2)如果外设中断被使能ETSEL[INTEN]=1,且中断标志位尚未置位ETFLG[INT]=0,则会将中断标志位置位,即ETFLG[INT]=1,还会产生中断请求,当中断请求送达PIE后,计数器ETPS[INTCNT]被清零并重新开始计数。
(3)如果外设中断被使能ETSEL[INTEN]=1,且中断标志位已经被置位ETFLG[INT]=1,也就是说,前面已经产生了中断而且中断还没有被响应,则这个状态会保持,然后等CPU响应中断,等到ENTFLG[INT]被清零,计数器重新开始计数。
向ETPS[INTPRD]中写数据将直接对ETPS[INTCNT]清零,并将ETPS[INTCNT]的输出信号复位,但不产生中断请求。每次向强制中断寄存器ETFRC[INT]中写1,会使ETFLG[INTCNT]增加1,直到ETPS[INTCNT]=ETPS[INTPRD]。如果ETPS[INTPRD]=0,则中断事件计数器被禁止,不检测任何中断事件,ETFRC[INT]也被忽略,这时候也不会产生中断请求。
(b)产生ADC启动信号

产生ADC启动信号和产生中断的方式是类似的,也由事件计数器 ETPS[SOCACNT] 用来统计事件发生的数量,用 ETPS[SOCAPRD] 来表明每发生多少次事件产生ADC启动信号。如果ETPS[SOCAPRD]=0,则禁止事件计数器工作,也就不会产生ADC启动信号。
和产生中断不同的是,启动信号ADCSOCA是连续的脉冲信号,也就是说,即使ETFLG[SOCA]被置位,也不会影响接下来脉冲的产生。通过寄存器ETSEL[SOCA]和ETSEL[SOCB]可以分别独立设置ADC启动信号ADCSOCA 和 ADCSOCB的触发事件。倘若禁止ETSEL[SOCAEN]或者 ETSEL[SOCBEN],则可立即停止启动信号的产生,但是事件计数器仍然计数,直到计数器的值等于其周期寄存器的值。
三、相关寄存器与位功能解释汇总
不需要全记住,用到那个查哪个即可


1.时基模块相应寄存器汇总
时基周期寄存器TBPRD:

时基相位寄存器TBPHS:

时基计数寄存器TBCTR:

时基控制寄存器TBCTL:




时基状态寄存器TBSTS:

2.计数比较相应寄存器汇总
计数比较寄存器A CMPA:
计数比较寄存器B CMPB:
计数比较控制寄存器CMPCTL:

3.动作模块寄存器汇总
动作控制寄存器A AQCTLA:


动作控制寄存器B AQCTLB:

动作软件强制寄存器AQSFRC:
动作连续软件强制寄存器AQCSFRC:
4.死区模块寄存器汇总
死区控制寄存器DBCTL:
死区上升沿延时寄存器DBRED:
死区下降沿延时寄存器DBFED:
5.斩波模块寄存器汇总
斩波控制寄存器PCCTL:

6.错误联防(故障捕获)模块寄存器汇总
错误联防选择寄存器TZSEL:


错误联防控制寄存器TZCTL:
错误联防中断使能寄存器TZEINT:
错误联防中断标志寄存器TZFLG:
错误联防中断清除寄存器TZCLR:
错误联防中断强制寄存器TZFRC:
7.事件触发模块寄存器汇总
事件触发选择寄存器ETSEL:


事件触发分频寄存器ETPS:

事件触发标志寄存器ETFLG:

事件触发清除寄存器ETCLR:

事件触发强制寄存器ETFRC:
四、PWM输出配置步骤
(1)使能ePWM外设时钟及失能时基模块时钟
要使用ePWM外设则需开启相应时钟,在对ePWM相关寄存器配置时得先关闭时基模块时钟,待配置好后在开启,可以保证同步。
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC=0;//失能时钟同步
SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK=1;//开启时钟源
EDIS;
(2)开启ePWM对应GPIO时钟及初始化配置
由于PWM输出通道是对应着F28335芯片的IO口,所以需要使能对应的端口时钟,并将对应IO口配置为ePWM输出功能。初始化ePWMGPIO的函数TI已经提供给我们了,直接调用即可。本章使用的是ePWM6,调用的函数如下:
InitEPwm6Gpio();
其内部定义为:
void InitEPwm6Gpio(void)
{EALLOW;/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.GpioCtrlRegs.GPAPUD.bit.GPIO10 = 0; // Enable pull-up on GPIO10 (EPWM6A)GpioCtrlRegs.GPAPUD.bit.GPIO11 = 0; // Enable pull-up on GPIO11 (EPWM6B)/* Configure ePWM-6 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be ePWM6 functional pins.
// Comment out other unwanted lines.GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 1; // Configure GPIO10 as EPWM6AGpioCtrlRegs.GPAMUX1.bit.GPIO11 = 1; // Configure GPIO11 as EPWM6BEDIS;
}
#endif // endif DSP28_EPWM6
就是简单的使能GPIO10和11的内部上拉和复用功能1(查原理图知该两引脚的复用功能为ePWM6A和ePWM6B)
(3)初始化时基模块,即配置TB相关寄存器值
要产生PWM波,时基模块是必不可少的,通过配置它可以确定计数器的计数方式、周期频率、是否同步等。
比如我们要设置ePWM6计数方式为向上计数,不使用相位同步功能,计数器计数频率为系统时钟频率,计数器初值为0等,如下:
//(3)初始化时基模块,即配置TB相关寄存器值EPwm6Regs.TBCTL.bit.SYNCOSEL=TB_SYNC_DISABLE; //当时基寄存器的值等于比较寄存器CMPA时发生事件EPwm6Regs.TBCTL.bit.PHSEN=TB_DISABLE; //禁止装载同步EPwm6Regs.TBPHS.half.TBPHS=0; //自动装载相位寄存器设置为0,这一步不设置也行EPwm6Regs.TBCTR=0x0000; //清除ClearcounterEPwm6Regs.TBPRD= tbprd; //TB周期寄存器EPwm6Regs.TBCTL.bit.CTRMODE=TB_COUNT_UP; //CountupEPwm6Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1; //一分频EPwm6Regs.TBCTL.bit.CLKDIV=TB_DIV1; //TBCLK = SYSCLKOUT//HDSPCLKDIV为0时,TBCLK = SYSCLKOUT/(2^CLKDIV)
(4)初始化比较模块,即配置CC相关寄存器值
要产生可调的PWM波,除了需要时基模块外,CC模块也是必不可少的,通过配置它可以确定比较寄存器值的加载模式,比较器值、占空比等。比如我们要设置ePWM6加载方式为计数器为0加载、比较器值为0等,具体配置代码如下:
//(4)初始化比较模块,即配置CC相关寄存器值EPwm6Regs.CMPCTL.bit.SHDWAMODE=CC_SHADOW;//影子寄存器装载EPwm6Regs.CMPCTL.bit.SHDWBMODE=CC_SHADOW;EPwm6Regs.CMPCTL.bit.LOADAMODE=CC_CTR_ZERO;//CTR = 0时装载EPwm6Regs.CMPCTL.bit.LOADBMODE=CC_CTR_ZERO;//SetComparevaluesEPwm6Regs.CMPA.half.CMPA=0; //SetcompareAvalueEPwm6Regs.CMPB=0;
(5)初始化动作限定模块,即配置AQ相关寄存器值
要产生可调PWM波,除了需要TB、CC模块外,AQ模块也是必不可少的,通过配置它可以确定PWM输出波形方式等。比如我们要设置ePWM6输出,当ePWMA计数器计数到0时输出低电平,ePWMA计数器向上计数到CMPA时输出高电平,当ePWMB计数器计数到0时输出低电平,当ePWMB计数器向上计数到CMPB时输出高电平,具体配置代码如下:
//(5)初始化动作限定模块,即配置AQ相关寄存器值EPwm6Regs.AQCTLA.bit.ZRO=AQ_CLEAR; //低于比较值输出低EPwm6Regs.AQCTLA.bit.CAU=AQ_SET; //高于比较值输出高EPwm6Regs.AQCTLB.bit.ZRO=AQ_CLEAR; //SetPWM1BonZeroEPwm6Regs.AQCTLB.bit.CBU=AQ_SET; //ClearPWM1Bonevent
(6)初始化事件触发模块,即配置ET相关寄存器值
当需要事件触发输出控制,就需要对ET相关寄存器配置。比如计数器计数到0时,同时使能事件触发中断,每发生一次触发事件就输出PWM。
EPwm6Regs.ETSEL.bit.INTSEL=ET_CTR_ZERO; //TBCTR = 0时发生触发事件
EPwm6Regs.ETSEL.bit.INTEN=1; //使能中断
EPwm6Regs.ETPS.bit.INTPRD=ET_1ST; //一次就触发
(7)初始化死区模块、斩波模块,即配置DB、PC相关寄存器值
如果不是特殊应用的话,一般不对死区模块和斩波模块配置,它们的应用方法在前面各小节也介绍过,所以这里我们不作介绍
(8)使能时基计数器时钟
将各模块寄存器配置好后,最后开启时基计数器时钟,完成这步操作,对应的IO口即可输出PWM波。开启时基计数器时钟代码如下:
ELLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
timers synced// Start all the
EDIS;
五、ePwm呼吸灯实验
实验效果:两个灯交替暗灭(设定PRD为500,ARRA、ARRB不断增大减小)
代码:ePWM.c
#include "ePWM.h"void ePWM_Init(unsigned char tbprd)
{//(1)使能ePWM外设时钟及失能时基模块时钟EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC=0;//失能时钟同步SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK=1;//开启时钟源EDIS;//(2)开启ePWM对应GPIO时钟及初始化配置InitEPwm6Gpio();//(3)初始化时基模块,即配置TB相关寄存器值EPwm6Regs.TBCTL.bit.SYNCOSEL=TB_SYNC_DISABLE; //当时基寄存器的值等于比较寄存器CMPA时发生事件EPwm6Regs.TBCTL.bit.PHSEN=TB_DISABLE; //禁止装载同步EPwm6Regs.TBPHS.half.TBPHS=0; //自动装载相位寄存器设置为0,这一步不设置也行EPwm6Regs.TBCTR=0x0000; //清除ClearcounterEPwm6Regs.TBPRD= tbprd; //TB周期寄存器EPwm6Regs.TBCTL.bit.CTRMODE=TB_COUNT_UP; //CountupEPwm6Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1; //一分频EPwm6Regs.TBCTL.bit.CLKDIV=TB_DIV1; //TBCLK = SYSCLKOUT//HDSPCLKDIV为0时,TBCLK = SYSCLKOUT/(2^CLKDIV)//(4)初始化比较模块,即配置CC相关寄存器值EPwm6Regs.CMPCTL.bit.SHDWAMODE=CC_SHADOW;//影子寄存器装载EPwm6Regs.CMPCTL.bit.SHDWBMODE=CC_SHADOW;EPwm6Regs.CMPCTL.bit.LOADAMODE=CC_CTR_ZERO;//CTR = 0时装载EPwm6Regs.CMPCTL.bit.LOADBMODE=CC_CTR_ZERO;//SetComparevaluesEPwm6Regs.CMPA.half.CMPA=0; //SetcompareAvalueEPwm6Regs.CMPB=0;//(5)初始化动作限定模块,即配置AQ相关寄存器值EPwm6Regs.AQCTLA.bit.ZRO=AQ_CLEAR; //低于比较值输出低EPwm6Regs.AQCTLA.bit.CAU=AQ_SET; //高于比较值输出高EPwm6Regs.AQCTLB.bit.ZRO=AQ_CLEAR; //SetPWM1BonZeroEPwm6Regs.AQCTLB.bit.CBU=AQ_SET; //ClearPWM1Bonevent//(6)初始化事件触发模块,即配置ET相关寄存器EPwm6Regs.ETSEL.bit.INTSEL=ET_CTR_ZERO; //TBCTR = 0时发生触发事件EPwm6Regs.ETSEL.bit.INTEN=1; //使能中断EPwm6Regs.ETPS.bit.INTPRD=ET_1ST; //一次就触发//(7)初始化死区模块、斩波模块,即配置DB、PC相关寄存器值//(8)使能时基计数器时钟EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;EDIS;}void EPwm6A_SetCompare(unsigned char ARRA)
{EALLOW; // 允许写入受保护的寄存器EPwm6Regs.CMPA.half.CMPA=ARRA;EDIS; // 禁止写入受保护的寄存器
}void EPwm6B_SetCompare(unsigned char ARRB)
{EALLOW; // 允许写入受保护的寄存器EPwm6Regs.CMPB = ARRB;EDIS; // 禁止写入受保护的寄存器
}
上述代码中,CAU = 0x2;ZRO = 0x0;即在上升时刻,CTR等于CMPA时,输出高电平,当计数器为0时刻,输出低电平,PWM方式如下图:
若考虑用中央对齐计数的互补PWM方式实现,(注意:中央对齐计数只考虑CMPA)也能实现同样的效果,则可以将第五步代码改为:
//(5)初始化动作限定模块,即配置AQ相关寄存器值EPwm6Regs.AQCTLA.bit.ZRO=0x1;//CTR为0时置低EPwm6Regs.AQCTLA.bit.CAU=0x2;//向上计数CTR=CMPA时置高EPwm6Regs.AQCTLA.bit.CAD=0x1;//向下计数CTR=CMPA时置低EPwm6Regs.AQCTLB.bit.ZRO=0x2;//CTR为0时置高EPwm6Regs.AQCTLB.bit.CBU=0x1;//向上计数CTR=CMPA时置低EPwm6Regs.AQCTLB.bit.CBD=0x2;//向下计数CTR=CMPA时置高
且将主函数的发波代码改为:
EPwm6A_SetCompare(i);
EPwm6B_SetCompare(i);
此时波形为:
main.c:
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "led.h"
#include "Interrupt.h"
#include "ePWM.h"void main()
{int i=0;unsigned char j=0;InitSysCtrl();InitPieCtrl();IER=0x0000;IFR=0x0000;InitPieVectTable();LED_Init();ePWM_Init(500);while(1){if(j==0){i++;if(i==300){j=1;}}else{i--;if(i==0){j=0;}}EPwm6A_SetCompare(i);EPwm6B_SetCompare(300-i);DELAY_US(10*1000);}
}
