概述

F28335共有六祖ePWM,每组都有两个独立的输出,每组都如下图所示,有7个子模块:时基,计数比较,动作确认,死区设置,PWM斩波设置,事件触发,故障捕获。
在这里插入图片描述
从下边这张图可以比较清晰的看出PWM信号在芯片内部的信号走向:时间基准模块产生时钟基准;计数器根据时间基准进行计数,当计数器过零、到达PRD,到达CMPA、CPMB都会给动作限定子模块发出信号;动作子模块根据设定打出对应的PWM信号给到死区控制模块;再经由PWM斩波模块和故障捕获模块后再从对应的GPIO打出。
在这里插入图片描述

实列

下边以从EPWMxA和EPWMxB打出互补的频率为10KHz,占空比为50%,死区上升沿和下降沿均为3us为例具体介总结下。(SYSCLKOUT为150MHz)

1. 设置GPIO复用功能:

void 
InitEPwm1Gpio(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.GPIO0 = 0;    // Enable pull-up on GPIO0 (EPWM1A)
    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;    // Enable pull-up on GPIO1 (EPWM1B)   

    //
    // Configure ePWM-1 pins using GPIO regs
    // This specifies which of the possible GPIO pins will be ePWM1 functional 
    // pins. Comment out other unwanted lines.
    //
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;   // Configure GPIO0 as EPWM1A
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;   // Configure GPIO1 as EPWM1B

    EDIS;
}

2. 时间基准子模块初始化:

由下图可以看出,定时器的时间基准TBCLK为SYSCLKOUT经过TBCTL[HSPCLKDIV]和TBCTL[CLKDIV]进行分频后给出。
他们的关系是:TBCLK = SYSCLKOUT / (HSPCLKDIV × CLKDIV)
T B C L K = S Y S C L K O U T 2 C L K D I V ( H S P C L K D I V = 0 ) TBCLK=\frac{SYSCLKOUT}{2^{CLKDIV}} (HSPCLKDIV = 0) TBCLK=2CLKDIVSYSCLKOUT(HSPCLKDIV=0)
T B C L K = S Y S C L K O U T 2 ∗ H S P C L K D I V ∗ 2 C L K D I V ( H S P C L K D I V ≠ 0 ) TBCLK=\frac{SYSCLKOUT}{2*HSPCLKDIV*2^{CLKDIV}} (HSPCLKDIV ≠ 0) TBCLK=2HSPCLKDIV2CLKDIVSYSCLKOUT(HSPCLKDIV=0)
其中HSPCLKDIV的默认值是1,CLKDIV的默认值是0,按默认值配置,TBCLK = 150/2 = 75MHz
在这里插入图片描述
若希望TBCLK = 37.5MHz,可以按如下代码配置:

    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;
    EPwm1Regs.TBCTL.bit.CLKDIV = 2;

3. 计数模式配置:

确定好计数时间基准后,还需要确定计数模式和计数周期数才能决定输出PWM的频率。F28335有如下图三种计数模式,增计数模式,减计数模式,增减计数模式:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
其中,增计数模式和减计数模式的PWM频率和TBPRD的关系为:
F p w m = T B C L K ( T B P R D + 1 ) Fpwm=\frac{TBCLK}{(TBPRD+1)} Fpwm=(TBPRD+1)TBCLK
增减计数模式PWM频率和TBPRD的关系为:
F p w m = T B C L K 2 ∗ T B P R D Fpwm=\frac{TBCLK}{2*TBPRD} Fpwm=2TBPRDTBCLK
本例时间基准频率设置为75MHz,增减计数模式,则 TBPRD设置为3750时,PWM频率为10KHz,对应代码为:

EPwm1Regs.TBCTL.bit.CTRMODE = 2;
EPwm1Regs.TBPRD = 3750;

其中,CTRMODE有两位,对应的模式如下:
在这里插入图片描述
另外,TBCTL寄存器中还有同步输出设置位(SYNCOSEL),影子寄存器启动控制位(PRDLD),相位控制使能位(PHSEN)。SYNCOSEL得默认值为0,同步输出为EPWMxSYNC;PRDLD默认值为0,表示使用影子寄存器;PHSEN默认值为0,表似关闭相位控制。具体介绍以后有用到再说。

4. 占空比设置:

每个ePWM模块都有两个比较器值可以设定,分别CMPA和CMPB。值得一提的是,这里得尾缀A和B与每一组PWM输出的A和B没有直接关系,也就是说CMPA的值即可以控制PWMA也可以控制PWMB。
实际正空比设置除了CMPx的值之外,还和动作子模块有关系,以本例为里,我们可以设置CMPA = TBPRD/2,并设定PWMA在CMPA = TBPRD/2且再递增计数时置高,在CMPA = TBPRD/2且再递减计数时置低,PWMB的动作与PWMA一致:

	EPwm1Regs.CMPA.half.CMPA =  EPwm1Regs.TBPRD * 0.5;
    EPwm1Regs.AQCTLA.bit.CAU = 2;
    EPwm1Regs.AQCTLA.bit.CAD = 1;
    EPwm1Regs.AQCTLB.bit.CAU = 2;
    EPwm1Regs.AQCTLB.bit.CAD = 1;

动作寄存器的各位,默认都是0,也就是都不执行动作。对应位赋值为1则到达计数值时输出清零;对应位赋值为2则到达计数值时输出置1;对应位赋值为3则到达计数值时输出翻转;
在这里插入图片描述
另外,CMPx也有对应的影子寄存器,由CMPCTL寄存器控制,其中SHDWxMODE(x为A或B)默认为0,默认为启用影子寄存器,LOADxMODE (x为A或B)为赋值节点设置,默认为0,默认当计数器CTR=0时载入新的比较值,LOADxMODE其他值的动作见下图:
在这里插入图片描述
本实例中只是初始化设定一个固定的占空比,这个寄存器设不设置都行,实际数字电源的应用中,影子寄存器的设置对开关电源环路的相位有一定的影响。

5. 死区以及输出极性设置:

开关电源应用中,PWM经常要控制桥式结构的对管开关,为了防止对管穿通,实际PWM做互补输出时都需要预留一定的死区时间。
要设置死区,首先要先配置死区控制寄存器DBCTR:
在这里插入图片描述
IN_MODE决定了上升沿和下降沿死区以哪一路(A、B)的信号为参考,具体如下:
在这里插入图片描述
本实例可以相将PWMA的上升和PWMB的下降沿设置为参考源,即DBCTR.IN_MODE = 2;
POLSEL为极性控制位,默认不翻转,01为PWMA反转,10为PWMB反转,11为PWMA和PWMB同时反转。本实例输出需要做互补,因此可先把PMWA和PWMB设置为一样的状态,再将DBCTR.POLSEL配置为10。
最后还要根据死区时间要求配置DBRED和DBFED寄存器,这两个寄存器都是10位有效,单位为uS,计算公式为:
T r d = D B R E D ∗ T b c l k Trd=DBRED*Tbclk Trd=DBREDTbclk
T r d = D B F E D ∗ T b c l k Trd=DBFED*Tbclk Trd=DBFEDTbclk
本实例,Tbclk为1/75uS,3uS的死区时间需要可以把DBFED和DBRED都设置位3*75。
最终代码如下:

    //死区设置
    EPwm1Regs.DBCTL.bit.OUT_MODE = 3;//使能上升沿下降沿延时
    EPwm1Regs.DBCTL.bit.POLSEL = 2;
    EPwm1Regs.DBCTL.bit.IN_MODE = 2;
    EPwm1Regs.DBRED = 75 * 3;
    EPwm1Regs.DBFED = 75 * 3;

6. 其他子模块配置:

斩波和故障捕获后边有用到再提,简单说下事件触发子模块,如下图所以,F28335可以根据CTR的值以及CTR_Dir的方向,产生总共8种事件,每种事件都可以配置产生中断事件,还可以触发ADC采样。
在开关电源的应用种,要严格控制ADC的采样时间点,不同的采样时间点,都开关电源的环路影响较大,这个时间节点的配置较为关键。后边会再单独出一篇,单独总结这个问题。

初始化参考代码:

void 
InitEPwm(void)
{
    //
    // Initialize ePWM1/2/3/4/5/6
    //
    InitEPwm1Gpio();

    EALLOW;
    //时基子模块设置
    EPwm1Regs.TBCTL.bit.CTRMODE = 2;
    EPwm1Regs.TBCTL.bit.PHSEN = 0;
    EPwm1Regs.TBCTL.bit.PRDLD = 0;
    EPwm1Regs.TBCTL.bit.SYNCOSEL = 1;
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1;
    EPwm1Regs.TBCTL.bit.CLKDIV = 0;

    //比较功能子模块设置
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0;
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0;
    EPwm1Regs.CMPCTL.bit.LOADAMODE = 0;
    EPwm1Regs.CMPCTL.bit.LOADBMODE = 0;

    //动作子模块设置
    EPwm1Regs.AQCTLA.all = 0;
    EPwm1Regs.AQCTLB.all = 0;
    EPwm1Regs.AQCTLA.bit.CAU = 2;//计数上升方向到达A比较器设置值,PWMA动作:0无动作,1置低,2置高,3翻转
    EPwm1Regs.AQCTLA.bit.CAD = 1;//计数下降方向到达A比较器设置值,PWMA动作:0无动作,1置低,2置高,3翻转
    EPwm1Regs.AQCTLB.bit.CAU = 2;//计数上升方向到达A比较器设置值,PWMB动作:0无动作,1置低,2置高,3翻转
    EPwm1Regs.AQCTLB.bit.CAD = 1;//计数下降方向到达A比较器设置值,PWMB动作:0无动作,1置低,2置高,3翻转

    //死区设置
    EPwm1Regs.DBCTL.bit.OUT_MODE = 3;//使能上升沿下降沿延时
    EPwm1Regs.DBCTL.bit.POLSEL = 2;
    EPwm1Regs.DBCTL.bit.IN_MODE = 2;

    //事件中断设置
    EPwm1Regs.ETSEL.bit.INTSEL = 1;
    EPwm1Regs.ETSEL.bit.INTEN = 1;
    EPwm1Regs.ETPS.bit.INTPRD = 1;
    EPwm1Regs.ETCLR.bit.INT = 1;

    //PWM频率,死区时间,占空比设置
    EPwm1Regs.TBPRD = 3750;
    EPwm1Regs.TBPHS.half.TBPHS = 0;
    EPwm1Regs.DBRED = 75 * 3;
    EPwm1Regs.DBFED = 75 * 3;
    EPwm1Regs.CMPA.half.CMPA =  EPwm1Regs.TBPRD * 0.5;

    EDIS;
}
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐