Part Number: TMS320F280039C
Other Parts Discussed in Thread: SYSBIOS
Tool/software:
The code for the BIOS system is shown below. The EPWM waveform (blue) and the interrupt waveform (yellow, toggling once each time the EPWM interrupt is entered) are shown in Figure 1. As can be seen from the figure, the toggling position of the interrupt does not occur at the midpoint of the EPWM waveform (i.e., the PRD position). Moreover, an interrupt anomaly occurs at a fixed interval (1 ms).
BIOS.cpuFreq.lo = 120000000;
Load.hwiEnabled = true;
Load.swiEnabled = true;
var task0Params = new Task.Params();
task0Params.instance.name = "task0";
task0Params.priority = 12;
task0Params.stackSize = 512;
Program.global.task0 = Task.create("&TaskParameterInit", task0Params);
var task1Params = new Task.Params();
task1Params.instance.name = "task1";
task1Params.priority = 8;
task1Params.stackSize = 512;
Program.global.task1 = Task.create("&TaskBasicControl", task1Params);
// task2
var task2Params = new Task.Params();
task2Params.instance.name = "task2";
task2Params.priority = 7;
task2Params.stackSize = 768;
Program.global.task2 = Task.create("&TaskMonitorControl", task2Params);
var ti_sysbios_hal_Hwi0Params = new ti_sysbios_hal_Hwi.Params();
ti_sysbios_hal_Hwi0Params.instance.name = "hwi_pwm";
ti_sysbios_hal_Hwi0Params.priority = 15;
ti_sysbios_hal_Hwi0Params.eventId = -1;
Program.global.hwi_pwm = ti_sysbios_hal_Hwi.create(52, "&HwiPwmISR", ti_sysbios_hal_Hwi0Params);
// hwi1
var ti_sysbios_hal_Hwi1Params = new ti_sysbios_hal_Hwi.Params();
ti_sysbios_hal_Hwi1Params.instance.name = "hwi_sciarx";
ti_sysbios_hal_Hwi1Params.priority = 9;
Program.global.hwi_sciarx = ti_sysbios_hal_Hwi.create(96, "&HwiSciaRX", ti_sysbios_hal_Hwi1Params);
// hwi2
var ti_sysbios_hal_Hwi2Params = new ti_sysbios_hal_Hwi.Params();
ti_sysbios_hal_Hwi2Params.instance.name = "hwi_sciatx";
ti_sysbios_hal_Hwi2Params.priority = 8;
Program.global.hwi_sciatx = ti_sysbios_hal_Hwi.create(97, "&HwiSciaTX", ti_sysbios_hal_Hwi2Params);
void EPWM5_Init(void)
{
EALLOW;
CpuSysRegs.PCLKCR2.bit.EPWM5 = 1; // 开启EPWM1时钟
EDIS;
//EALLOW;
//EPwm5Regs.TZSEL.bit.OSHT4 = 1; // 使能单次触发(One-Shot)保护
//EPwm5Regs.TZEINT.bit.OST = 1;
//EDIS;
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO8 = 1; // Disable pull-up on GPIO0 (EPWM1A)
GpioCtrlRegs.GPAPUD.bit.GPIO9 = 1; // Disable pull-up on GPIO1 (EPWM1B)
GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 1; // Configure GPIO0 as EPWM1A
GpioCtrlRegs.GPAMUX1.bit.GPIO9 = 1; // Configure GPIO1 as EPWM1B
EDIS;
EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE; //相位加载使能
EPwm5Regs.TBPHS.bit.TBPHS = 0; //相位值为0
EPwm5Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; //高速预分频
EPwm5Regs.TBCTL.bit.CLKDIV = TB_DIV1; //时基预分频 DIV1意思不分频
EPwm5Regs.TBPRD = 1000; // 设置周期值(决定PWM频率)
EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // 向上-向下计数模式
EPwm5Regs.TBCTL.bit.PRDLD = TB_SHADOW; // 影子寄存器模式
EPwm5Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; //CMPA使用影子寄存器
EPwm5Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; //CMPB使用影子寄存器
EPwm5Regs.CMPCTL.bit.LOADAMODE = 2; //重要,关乎合适加载占空比
EPwm5Regs.CMPCTL.bit.LOADBMODE = 2; //重要,关乎合适加载占空比
EPwm5Regs.CMPA.bit.CMPA = 0; // // 初始化CMPA值
EPwm5Regs.CMPB.bit.CMPB = 1000; // // 初始化CMPA值
EPwm5Regs.AQCTLA.bit.CAU = AQ_CLEAR; // 当计数器=比较值A且计数方向向上(UP)时,清除PWM1A(拉低)
EPwm5Regs.AQCTLA.bit.CAD = AQ_SET; // 当计数器=比较值A且计数方向向下(DOWN)时,置位PWM1A(拉高)
EPwm5Regs.AQCTLB.bit.CBU = AQ_SET; // 当计数器=比较值A且计数方向向上(UP)时,清除PWM1A(拉低)
EPwm5Regs.AQCTLB.bit.CBD = AQ_CLEAR; // 当计数器=比较值A且计数方向向下(DOWN)时,置位PWM1A(拉高)
EPwm5Regs.ETSEL.bit.INTSEL = ET_CTR_PRD;
EPwm5Regs.ETSEL.bit.INTEN = 1; // 使能ePWM1中断
EPwm5Regs.ETPS.bit.INTPRD = 1; // 每个事件都触发中断(无分频)
}
void HwiPwmISR(void)
{
LED16_TOGGLE;
LED17_TOGGLE;
EPwm5Regs.ETCLR.bit.INT = 1;
}
The code for the non-BIOS system is shown below. The EPWM (blue) waveform and the interrupt (yellow, toggling once each time the EPWM interrupt is entered) waveform are shown in Figure 2. As can be seen from the figure, the interrupt toggling occurs precisely at the midpoint of the EPWM waveform and remains stable without any anomalies.
void EPWM5_Init(void)
{
EALLOW;
CpuSysRegs.PCLKCR2.bit.EPWM5 = 1; // 开启EPWM1时钟
EDIS;
EALLOW;
PieVectTable.EPWM5_INT = &epwm1_timer_isr;//提供中断服务程序入口
EDIS;
// EALLOW;
// EPwm5Regs.TZSEL.bit.OSHT4 = 1; // 使能单次触发(One-Shot)保护
//EPwm5Regs.TZEINT.bit.OST = 1;
//EDIS;
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO8 = 1; // Disable pull-up on GPIO0 (EPWM1A)
GpioCtrlRegs.GPAPUD.bit.GPIO9 = 1; // Disable pull-up on GPIO1 (EPWM1B)
GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 1; // Configure GPIO0 as EPWM1A
GpioCtrlRegs.GPAMUX1.bit.GPIO9 = 1; // Configure GPIO1 as EPWM1B
EDIS;
EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE;//相位加载使能
EPwm5Regs.TBPHS.bit.TBPHS =0 ; //相位值为0
EPwm5Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1; //高速预分频
EPwm5Regs.TBCTL.bit.CLKDIV=TB_DIV1; //时基预分频 DIV1意思不分频
EPwm5Regs.TBPRD = 1000; // 设置周期值(决定PWM频率)
EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // 向上-向下计数模式
EPwm5Regs.TBCTL.bit.PRDLD = TB_SHADOW; // 影子寄存器模式
EPwm5Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; //CMPA使用影子寄存器
EPwm5Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; //CMPB使用影子寄存器
EPwm5Regs.CMPCTL.bit.LOADAMODE = 2; //重要,关乎合适加载占空比
EPwm5Regs.CMPCTL.bit.LOADBMODE = 2; //重要,关乎合适加载占空比
EPwm5Regs.CMPA.bit.CMPA = 500; // // 初始化CMPA值
EPwm5Regs.CMPB.bit.CMPB = 500; // // 初始化CMPA值
EPwm5Regs.AQCTLA.bit.CAU = AQ_CLEAR;// 当计数器=比较值A且计数方向向上(UP)时,清除PWM1A(拉低)
EPwm5Regs.AQCTLA.bit.CAD = AQ_SET; // 当计数器=比较值A且计数方向向下(DOWN)时,置位PWM1A(拉高)
EPwm5Regs.AQCTLB.bit.CBU = AQ_SET;// 当计数器=比较值A且计数方向向上(UP)时,清除PWM1A(拉低)
EPwm5Regs.AQCTLB.bit.CBD = AQ_CLEAR; // 当计数器=比较值A且计数方向向下(DOWN)时,置位PWM1A(拉高)
EPwm5Regs.ETSEL.bit.INTSEL =ET_CTR_PRD;
EPwm5Regs.ETSEL.bit.INTEN = 1; // 使能ePWM1中断
EPwm5Regs.ETPS.bit.INTPRD = 1; // 每个事件都触发中断(无分频)
EALLOW;
PieCtrlRegs.PIEIER3.bit.INTx5 = 1; //EPWM1中断
IER |= M_INT3; //使能CPU中断3
EDIS;
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; // 同步启动所有ePWM时基计数器
EDIS;
EINT; // 开启全局中
ERTM; // 允许实时调试中断
}
__interrupt void epwm1_timer_isr(void)
{
LED16_TOGGLE;
LED17_TOGGLE;
EPwm1Regs.ETCLR.bit.INT = 1;
PieCtrlRegs.PIEACK.bit.ACK3 = 1;
}

