1、EPWM模块共有7个子模块组成:
(1)时间基准 TB、
(2)比较功能 CC、
(3)动作限定 AQ、
(4)死区产生 DB、
(5)斩波控制 PC、
(6)故障捕获 TZ、
(7)事件触发 ET、
2、具体组成如下图1、图2所示;为了完成EPWM定时中断功能,我们主要使用时间基准 TB、比较功能 CC和事件触发(ET) 这三个模块,通过设置这三个模块的寄存器,最终得到想要的结果。
(1)时基模块(TB) |
为输出的PWM产生一个时间基准TBCLK,配置PWM的时钟基准计数器TBCTR,设置计数器的计数模式,配置硬件或者软件同步时钟基准计数器,确定EPWM同步信号输出源;
|
(2)比较计数模块(CC) |
确定PWM占空比,以及EPWM输出高低电平的切换时间;
|
(3)动作模块(AQ) |
EPWM的高低电平的切换;
|
(4)死区模块(DB) |
配置输出PWM上升沿或下降沿的延时时间;
|
(5)PWM斩波模块(PC) |
产生高频PWM载波信号;
|
(6)联防模块(TZ) |
当外部有错误信号时,对PWM输出进行相应处理:例如全置高、全置低或者高阻态,也可以软件处理;
|
(7)触发模块(ET) |
使能EPWM中断,确定事件产生的触发的速度和清除相关事件标志位;
|
图-1
图-2
3、为了完成EPWM定时中断功能,主要使用时间基准模块TB、比较功能模块 CC和事件触发模块(ET) 这三个模块,通过设置这三个模块的寄存器,最终得到想要的波形结果。
4、PWM发波例程:
// Prototype statements for functions found within this file.
#define PWM1_INT_ENABLE 1
#define PWM1_TIMER_TBPRD 0x1FFF
// 这里由于只用到了EPWM的定时器功能,所以可以不用初始化GPIO
// void EpwmGpioInit(void);
//初始化EPWM寄存器
void EpwmRegInit(void);
__interrupt void Epwm1TimerISR(void); //epwm寄存器中断函数
uint16_t EPwm1TimerIntCount = 0;
void EpwmRegInit(void)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Stop all the TB clocks EPWM模块同步使用,在4中讲到了EDIS;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // 00
EPWMXSYNC EPwm1Regs.TBPRD = PWM1_TIMER_TBPRD;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
EPwm1Regs.TBCTR = 0;
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
EPwm1Regs.ETSEL.bit.INTEN = PWM1_INT_ENABLE;
EPwm1Regs.ETPS.bit.INTPRD = ET_2ND; // Generate INT on 2nd event 每两次定时中断触发一次进入中断函数 EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced
EDIS;
}
void main(void)
{
#ifdef _FLASH
memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
#endif
InitSysCtrl();
EALLOW;
// GPIO 0 作为PWM波输出端口
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;
GpioDataRegs.GPASET.bit.GPIO0 = 1;
EDIS;
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
// EpwmGpioInit();
//因为仅仅使用epwm的定时器功能,所以不需要初始化外设 EpwmRegInit();
//中断部分初始化处理
EALLOW;
//执行发波中断函数注册部分EDIS;
PieVectTable.EPWM1_INT = &Epwm1TimerISR;
IER |= M_INT3;
PieCtrlRegs.PIEIER3.bit.INTx1 = PWM1_INT_ENABLE;
EINT;
ERTM;
// Run user specific code:
while(1);
}
__interrupt void Epwm1TimerISR(void)
{
EPwm1Regs.ETCLR.bit.INT = 1; //注意此处的中断标志清除
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; //清除中断向量表中的标志位
EPwm1TimerIntCount++;
if (EPwm1TimerIntCount > 5000)
{
EPwm1TimerIntCount = 0;
GpioDataRegs.GPATOGGLE.bit.GPIO0 = 1; //TOGGLE交替
}
} |