一、配置步骤
1.关闭时基模块时钟、开启epwm模块时钟
EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; EDIS;
关闭时基模块时钟是为了在配置epwm模块时确保配置的正确性和安全性,防止误触发;提前开启epwm模块的时钟是为了后续配置步骤中开启时基时钟后epwm能正确运行。
2.配置对应epwm模块的GPIO管脚
InitEPwm6Gpio();
void InitEPwm6Gpio(void)
{EALLOW;GpioCtrlRegs.GPAPUD.bit.GPIO10 = 0; // Enable pull-up on GPIO10 (EPWM6A)GpioCtrlRegs.GPAPUD.bit.GPIO11 = 0; // Enable pull-up on GPIO11 (EPWM6B)GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 1; // Configure GPIO10 as EPWM6AGpioCtrlRegs.GPAMUX1.bit.GPIO11 = 1; // Configure GPIO11 as EPWM6BEDIS;
}
这里可以直接调用EPwm.c源文件中的配置对应epwm模块的GPIO管脚的函数。
3.根据所需要的epwm模块数量以及是否需要同步处理来配置同步信号
3.1 只用到一个epwm模块
只用到一个epwm时,需要禁用同步输出和相位同步:
EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
//禁用epwm6的同步输出信号,这意味着EPWM6模块不会产生同步输出信号,用于其他EPWM模块的同步操作。EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;
//禁用相位同步功能。禁用相位同步意味着当有同步信号输入时,定时器不会加载相位寄存器(TBPHS)的值。因此,EPWM6模块的计数器不会被同步信号影响,保持独立运行。EPwm6Regs.TBPHS.half.TBPHS = 0;
//TBPHS(时基相位寄存器)用于存储相位偏移值,当启用相位同步时,计数器会加载这个值以实现同步。设置为0意味着如果相位同步功能被启用,定时器的计数器将从0开始计数。
3.2 用到多个epwm模块且需要让他们保持同步
主模块配置产生同步信号:
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
//当计数器CTR达到0时,epwm1模块会产生同步输出信号。此信号可以用于同步其他EPWM模块,使它们的计数器在同一时刻开始计数。
从模块配置接受同步信号进行相位同步:
EPwm6Regs.TBCTL.bit.PHSEN = TB_ENABLE; // 使能相位同步EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // 使用同步输入信号EPwm6Regs.TBPHS.half.TBPHS = 0; // 设置相位偏移为0
4.配置时基模块从而设定PWM波周期
EPwm6Regs.TBCTR = 0x0000; // 清除CTR计数器EPwm6Regs.TBPRD = tbprd; //计数周期EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 设置计数模式为向上计数EPwm6Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1; //分频系数xEPwm6Regs.TBCTL.bit.CLKDIV=TB_DIV1; //分频系数y
PWM波周期T由以下公式得到:
5.配置比较模块和动作模块从而设定PWM波占空比
根据TBCTR是否达到CMPA、CPMB、TBPRD、0的值,可以产生以下六种事件:
TBCTR=0 | ZRO |
TBCTR=TBPRD | PRD |
TBTCR=CMPA,且正在增计数 | CAU |
TBTCR=CMPA,且正在减计数 | CAD |
TBTCR=CMPB,且正在增计数 | CBU |
TBTCR=CMPB,且正在减计数 | CBD |
每种事件可以触发以下四种动作:
无动作 | AQ_NO_ACTION |
使EPWMxA/EPWMxB置高 | AQ_SET |
使EPWMxA/EPWMxB置低 | AQ_CLEAR |
使EPWMxA/EPWMxB翻转 | AQ_TOGGLE |
下面以CAU=AQ_SET、,CBU=AQ_CLEAR为例配置CC、AQ模块:
EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
//开启CMPA的阴影模式在阴影模式下,CMPA寄存器的值会首先写入阴影寄存器,然后在特定的事件(例如计数器到达零点)发生时,阴影寄存器的值才会被复制到实际的CMPA寄存器。这可以避免在修改CMPA值时,PWM信号出现突变。EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
//当计数器达到零点时,阴影寄存器的值会被加载到实际的CMPA寄存器中。这种加载模式确保CMPA值的更新在计数器归零时进行,从而保持PWM信号的同步和一致性。EPwm6Regs.CMPA.half.CMPA = CMPA; EPwm6Regs.CMPB = CMPB; EPwm6Regs.AQCTLA.bit.PRD = AQ_CLEAR; EPwm6Regs.AQCTLA.bit.CAU = AQ_SET; EPwm6Regs.AQCTLB.bit.PRD = AQ_SET; EPwm6Regs.AQCTLB.bit.CBU = AQ_CLEAR;
此模式下EPWM6A的占空比计算公式为:
此模式下EPWM6B的占空比计算公式为:
6.配置中断事件和定义中断服务函数
可选择以上六种事件来作为触发中断的事件,当中断事件到来后,PIE模块会向CPU发送一次中断请求,CPU响应后则进入中断服务函数。
EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // TBPCR=0时触发中断申请EPwm6Regs.ETSEL.bit.INTEN = 1; // Enable INT //使能EPWM6模块的中断功能EPwm6Regs.ETPS.bit.INTPRD = ET_1ST; // 每次计数器达到0时都会触发中断事件IER |= M_INT3; //使能第3组中断PieCtrlRegs.PIEIER3.bit.INTx6 = 1; //使能INT3.6 epwm6中断EINT; ERTM;
中断服务函数:
interrupt void epwm6_timer_isr(void)
{EPwm6Regs.ETCLR.bit.INT = 1; 清除标志位PieCtrlRegs.PIEACK.bit.ACK3 = 1; 运行第3组中断能接受其他中断
}
二、配置模板
以epwm6产生一定占空比和一定周期的PWM波且按PWM周期进入中断函数为例,以下为完整的配置模板:
void EPWM6_Init(Unit16 tbprd,Unit16 cmpa,Unit cmpb)
{EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; EDIS;EALLOW; PieVectTable.EPWM1_INT = &epwm6_timer_isr;EDIS; EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;EPwm6Regs.TBPHS.half.TBPHS = 0;EPwm6Regs.TBCTR = 0x0000; EPwm6Regs.TBPRD = tbprd;EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; EPwm6Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1; EPwm6Regs.TBCTL.bit.CLKDIV=TB_DIV1; EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;EPwm6Regs.CMPA.half.CMPA = cmpa; EPwm6Regs.CMPB = cmpb; EPwm6Regs.AQCTLA.bit.PRD = AQ_CLEAR; EPwm6Regs.AQCTLA.bit.CAU = AQ_SET; EPwm6Regs.AQCTLB.bit.PRD = AQ_SET; EPwm6Regs.AQCTLB.bit.CBU = AQ_CLEAR; EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; EPwm6Regs.ETSEL.bit.INTEN = 1; EPwm6Regs.ETPS.bit.INTPRD = ET_1ST; EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS; IER |= M_INT3; PieCtrlRegs.PIEIER3.bit.INTx6 = 1; EINT; ERTM;
}
interrupt void epwm6_timer_isr(void)
{EPwm6Regs.ETCLR.bit.INT = 1; 清除标志位PieCtrlRegs.PIEACK.bit.ACK3 = 1; 运行第3组中断能接受其他中断
}