28335 ePWM模块 中心移相与边沿移相代码

中心移相

最常见的中心移相示意图如下:

可以看到其中的PWM1作为主相,其余PWM2和PWM3都作为其的辅相。中心移相,顾名思义,就是移动相位参考高电平的中心,当占空比D=0.5时,其移相与我们认为的上升沿移相一致,也就是最常见的移相。

为方便理解,先给相关设置的结构体设置:

typedef struct {
    volatile struct EPWM_REGS* ePWMx;
     Uint32 Fs;
     double D;
     Uint32 td;
} ePWM_Master_Set_Struct;

typedef struct {
    volatile struct EPWM_REGS* ePWMx;
     double D;
     double Phase;
     Uint32 td;
} ePWM_Slave_Set_Struct;

其中 ePWM_Master_Set_Struct 是主相设置函数,而 ePWM_Slave_Set_Struct 辅相设置函数。

这是初始化ePWM初始化设置具体实现函数及其定义

void ePWM_Master_Set_Flush(ePWM_Master_Set_Struct* pwm);//中心对齐移相 主要
void ePWM_Slave_Set_Flush(ePWM_Master_Set_Struct* master_pwm,ePWM_Slave_Set_Struct* slave_pwm);//中心对齐移相 次要
void ePWM_Master_Set_Flush(ePWM_Master_Set_Struct* pwm)
{
    EALLOW;
    // Initialization Time(TB)
    pwm->ePWMx->TBPRD=75e6/pwm->Fs;
    pwm->ePWMx->TBPHS.half.TBPHS = 0; //不进行移相
    pwm->ePWMx->TBCTR=0; //计数器清零
    pwm->ePWMx->TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //上计数模式
    pwm->ePWMx->TBCTL.bit.PHSEN = TB_DISABLE; //主机模式
    pwm->ePWMx->TBCTL.bit.PRDLD = TB_SHADOW;
    pwm->ePWMx->TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; //减到0时发出同步信号
    pwm->ePWMx->TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
    pwm->ePWMx->TBCTL.bit.CLKDIV = TB_DIV1;
    pwm->ePWMx->CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    pwm->ePWMx->CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    pwm->ePWMx->CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = Zero
    pwm->ePWMx->CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR = Zero
    pwm->ePWMx->AQCTLA.bit.CAD = AQ_SET;  //计数比CA低时PWMA输出高
    pwm->ePWMx->AQCTLA.bit.CAU = AQ_CLEAR;  //比CA高时PWMA输出低
    pwm->ePWMx->AQCTLB.bit.CAD = AQ_CLEAR; //计数比CA低时PWMB输出低
    pwm->ePWMx->AQCTLB.bit.CAU = AQ_SET; //计数比CA高时PWMB输出高
    pwm->ePWMx->CMPA.half.CMPA = pwm->ePWMx->TBPRD *pwm->D;       // Set compare A value

    // Initialization Dead-Band(DB)
    pwm->ePWMx->DBCTL.bit.OUT_MODE=DB_FULL_ENABLE; //上升沿和下降沿都开启延迟
    pwm->ePWMx->DBCTL.bit.IN_MODE=DBA_ALL; //A作为源信号
    pwm->ePWMx->DBCTL.bit.POLSEL=DB_ACTV_HIC;//PWMA、B互补相反
    pwm->ePWMx->DBRED=pwm->td;//死区设置
    pwm->ePWMx->DBFED=pwm->td;

    // Initialization Trip-Zone(TZ)
    pwm->ePWMx->TZCTL.bit.TZA=2;    //PWM-A\B均输出低电平
    pwm->ePWMx->TZCTL.bit.TZB=2;
    pwm->ePWMx->TZCLR.bit.OST=1;    //清空OST标志位
    EDIS;
}

void ePWM_Slave_Set_Flush(ePWM_Master_Set_Struct* master_pwm,ePWM_Slave_Set_Struct* slave_pwm)
{
    EALLOW;
    // Initialization Time(TB)
    slave_pwm->ePWMx->TBPRD=75e6/master_pwm->Fs;
    slave_pwm->ePWMx->TBPHS.half.TBPHS = fabs(slave_pwm->Phase)/180*slave_pwm->ePWMx->TBPRD; //设置移相角度,相对于主pwm提前角度
    slave_pwm->ePWMx->TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
    slave_pwm->ePWMx->TBCTL.bit.PHSEN = TB_ENABLE;
    if(slave_pwm->Phase>=0)
        slave_pwm->ePWMx->TBCTL.bit.PHSDIR = TB_UP;
    else
        slave_pwm->ePWMx->TBCTL.bit.PHSDIR = TB_DOWN;
    slave_pwm->ePWMx->TBCTL.bit.PRDLD = TB_SHADOW;
    slave_pwm->ePWMx->TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
    slave_pwm->ePWMx->TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
    slave_pwm->ePWMx->TBCTL.bit.CLKDIV = TB_DIV1;
    slave_pwm->ePWMx->CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    slave_pwm->ePWMx->CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    slave_pwm->ePWMx->CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    slave_pwm->ePWMx->CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    slave_pwm->ePWMx->AQCTLA.bit.CAD = AQ_SET;  //计数比CA低时PWMA输出高
    slave_pwm->ePWMx->AQCTLA.bit.CAU = AQ_CLEAR;  //比CA高时PWMA输出低
    slave_pwm->ePWMx->AQCTLB.bit.CAD = AQ_CLEAR; //计数比CA低时PWMB输出低
    slave_pwm->ePWMx->AQCTLB.bit.CAU = AQ_SET; //计数比CA高时PWMB输出高
    slave_pwm->ePWMx->CMPA.half.CMPA = slave_pwm->ePWMx->TBPRD *slave_pwm->D;       // Set compare A value

    // Initialization Dead-Band(DB)
    slave_pwm->ePWMx->DBCTL.bit.OUT_MODE=DB_FULL_ENABLE; //上升沿和下降沿都开启延迟
    slave_pwm->ePWMx->DBCTL.bit.IN_MODE=DBA_ALL; //A作为源信号
    slave_pwm->ePWMx->DBCTL.bit.POLSEL=DB_ACTV_HIC;//PWMA、B互补相反
    slave_pwm->ePWMx->DBRED=slave_pwm->td;//死区设置
    slave_pwm->ePWMx->DBFED=slave_pwm->td;

    // Initialization Trip-Zone(TZ)
    slave_pwm->ePWMx->TZCTL.bit.TZA=2;    //PWM-A\B均输出低电平
    slave_pwm->ePWMx->TZCTL.bit.TZB=2;
    slave_pwm->ePWMx->TZCLR.bit.OST=1;    //清空OST标志位
    EDIS;
}

在程序运行中,进行调频、调宽、移相等操作就需要以下函数

void ePWM_Master_Set(ePWM_Master_Set_Struct* master_pwm);//中心对齐移相 主要
void ePWM_Slave_Set(ePWM_Slave_Set_Struct* slave_pwm,ePWM_Master_Set_Struct* master_pwm);//中心对齐移相 次要
void ePWM_Slave_Set(ePWM_Slave_Set_Struct* slave_pwm,ePWM_Master_Set_Struct* master_pwm)
{
    if(slave_pwm->Phase>=0)
        slave_pwm->ePWMx->TBCTL.bit.PHSDIR = TB_UP;
    else
        slave_pwm->ePWMx->TBCTL.bit.PHSDIR = TB_DOWN;
    slave_pwm->ePWMx->TBPRD=75e6/master_pwm->Fs;
    slave_pwm->ePWMx->TBPHS.half.TBPHS = fabs(slave_pwm->Phase)/180*slave_pwm->ePWMx->TBPRD;
    slave_pwm->ePWMx->CMPA.half.CMPA = slave_pwm->ePWMx->TBPRD *slave_pwm->D;
}

void ePWM_Master_Set(ePWM_Master_Set_Struct* master_pwm)
{
    master_pwm->ePWMx->TBPRD=75e6/master_pwm->Fs;
    master_pwm->ePWMx->CMPA.half.CMPA = master_pwm->ePWMx->TBPRD *master_pwm->D;
}

这里给个demo,实现上面3个pwm的初始化程序如下:

void Init_ePWM()
{
    InitEPwm1Gpio();    //初始化 A0-EPWM1A  A1-EPWM1B
    InitEPwm2Gpio();    //初始化 A2-EPWM2A  A3-EPWM2B
    InitEPwm3Gpio();    //初始化 A4-EPWM3A  A5-EPWM3B

    pwm1.ePWMx=&EPwm1Regs;
    pwm1.Fs=50e3; //50khz
    pwm1.D=0.25.; //0.25占空比
    pwm1.td=50; //0.5us 死区时间
    ePWM_Master_Set_Flush(&pwm1); //pwm1作为主pwm 初始化

    pwm2.ePWMx=&EPwm2Regs;
    pwm2.D=0.4; //0.4占空比
    pwm2.Phase=0; //不移相
    pwm2.td=50;
    ePWM_Slave_Set_Flush(&pwm1,&pwm2); //pwm2以pwm1作为主pwm

    pwm3.ePWMx=&EPwm3Regs;
    pwm3.D=0.4; //0.4占空比
    pwm3.Phase=-0.3*360; //滞后108°,这个参数范围为 -180°~+180°
    pwm3.td=50;
    ePWM_Slave1_Set_Flush(&pwm1,&pwm3); //pwm3以pwm1作为主pwm

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;         // Start all the timers synced
    EDIS;
}

边沿移相

边沿移相示意图如下:

结构体和上面中心移相一致,实现代码如下:

void ePWM_Master1_Set_Flush(ePWM_Master_Set_Struct* pwm);//上升沿对齐移相 主要 D<=0.5
void ePWM_Slave1_Set_Flush(ePWM_Master_Set_Struct* master_pwm,ePWM_Slave_Set_Struct* slave_pwm);//上升沿对齐移相 次要 D<=0.5
void ePWM_Master1_Set_Flush(ePWM_Master_Set_Struct* pwm)
{
    EALLOW;
    // Initialization Time(TB)
    pwm->ePWMx->TBPRD=75e6/pwm->Fs;
    pwm->ePWMx->TBPHS.half.TBPHS = 0; //不进行移相
    pwm->ePWMx->TBCTR=0; //计数器清零
    pwm->ePWMx->TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //上下计数模式
    pwm->ePWMx->TBCTL.bit.PHSEN = TB_DISABLE; //主机模式
    pwm->ePWMx->TBCTL.bit.PRDLD = TB_SHADOW;
    pwm->ePWMx->TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; //减到0时发出同步信号
    pwm->ePWMx->TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
    pwm->ePWMx->TBCTL.bit.CLKDIV = TB_DIV1;
    pwm->ePWMx->CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    pwm->ePWMx->CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    pwm->ePWMx->CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = Zero
    pwm->ePWMx->CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR = Zero
    pwm->ePWMx->AQCTLA.bit.ZRO = AQ_SET;  //计数0时PWMA输出高
    pwm->ePWMx->AQCTLA.bit.CAU = AQ_CLEAR;  //比CA高时PWMA输出低
    pwm->ePWMx->AQCTLB.bit.PRD = AQ_CLEAR; //计数PRD时输出高
    pwm->ePWMx->AQCTLB.bit.CBD = AQ_SET; //计数比CB低时PWMB输出低

    pwm->ePWMx->CMPA.half.CMPA = pwm->ePWMx->TBPRD *pwm->D*2;       // Set compare A value
    pwm->ePWMx->CMPB = pwm->ePWMx->TBPRD *(1-pwm->D*2)+1;       // Set compare B value

    // Initialization Dead-Band(DB)
    pwm->ePWMx->DBCTL.bit.OUT_MODE=DB_FULL_ENABLE; //A\B均开启死区
    pwm->ePWMx->DBCTL.bit.IN_MODE=DBA_RED_DBB_FED; //A上升沿,B下降沿源信号
    pwm->ePWMx->DBCTL.bit.POLSEL=DB_ACTV_HIC;//PWMA、B互补相反
    pwm->ePWMx->DBRED=pwm->td;//死区设置
    pwm->ePWMx->DBFED=pwm->td;

    // Initialization Trip-Zone(TZ)
    pwm->ePWMx->TZCTL.bit.TZA=2;    //PWM-A\B均输出低电平
    pwm->ePWMx->TZCTL.bit.TZB=2;
    pwm->ePWMx->TZCLR.bit.OST=1;    //清空OST标志位
    EDIS;
}

void ePWM_Slave1_Set_Flush(ePWM_Master_Set_Struct* master_pwm,ePWM_Slave_Set_Struct* slave_pwm)
{
    EALLOW;
    // Initialization Time(TB)
    slave_pwm->ePWMx->TBPRD=75e6/master_pwm->Fs;
    slave_pwm->ePWMx->TBPHS.half.TBPHS = fabs(slave_pwm->Phase)/180*slave_pwm->ePWMx->TBPRD; //设置移相角度,相对于主pwm提前角度
    slave_pwm->ePWMx->TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
    slave_pwm->ePWMx->TBCTL.bit.PHSEN = TB_ENABLE;
    if(slave_pwm->Phase>=0)
        slave_pwm->ePWMx->TBCTL.bit.PHSDIR = TB_UP;
    else
        slave_pwm->ePWMx->TBCTL.bit.PHSDIR = TB_DOWN;
    slave_pwm->ePWMx->TBCTL.bit.PRDLD = TB_SHADOW;
    slave_pwm->ePWMx->TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
    slave_pwm->ePWMx->TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
    slave_pwm->ePWMx->TBCTL.bit.CLKDIV = TB_DIV1;
    slave_pwm->ePWMx->CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    slave_pwm->ePWMx->CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    slave_pwm->ePWMx->CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    slave_pwm->ePWMx->CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    slave_pwm->ePWMx->AQCTLA.bit.ZRO = AQ_SET;  //计数0时PWMA输出高
    slave_pwm->ePWMx->AQCTLA.bit.CAU = AQ_CLEAR;  //比CA高时PWMA输出低
    slave_pwm->ePWMx->AQCTLB.bit.PRD = AQ_CLEAR; //计数PRD时输出高
    slave_pwm->ePWMx->AQCTLB.bit.CBD = AQ_SET; //计数比CB低时PWMB输出低

    slave_pwm->ePWMx->CMPA.half.CMPA = slave_pwm->ePWMx->TBPRD *slave_pwm->D*2;       // Set compare A value
    slave_pwm->ePWMx->CMPB = slave_pwm->ePWMx->TBPRD *(1-slave_pwm->D*2)+1;       // Set compare B value

    // Initialization Dead-Band(DB)
    slave_pwm->ePWMx->DBCTL.bit.OUT_MODE=DB_FULL_ENABLE; //A\B均开启死区
    slave_pwm->ePWMx->DBCTL.bit.IN_MODE=DBA_RED_DBB_FED; //A上升沿,B下降沿源信号
    slave_pwm->ePWMx->DBCTL.bit.POLSEL=DB_ACTV_HIC;//PWMA、B互补相反
    slave_pwm->ePWMx->DBRED=slave_pwm->td;//死区设置
    slave_pwm->ePWMx->DBFED=slave_pwm->td;

    // Initialization Trip-Zone(TZ)
    slave_pwm->ePWMx->TZCTL.bit.TZA=2;    //PWM-A\B均输出低电平
    slave_pwm->ePWMx->TZCTL.bit.TZB=2;
    slave_pwm->ePWMx->TZCLR.bit.OST=1;    //清空OST标志位
    EDIS;
}

同样类似的,也有程序运行中调频、调宽、调相的设置程序如下:

void ePWM_Master1_Set(ePWM_Master_Set_Struct* master_pwm);//上升沿对齐移相 主要 D<=0.5
void ePWM_Slave1_Set(ePWM_Slave_Set_Struct* slave_pwm,ePWM_Master_Set_Struct* master_pwm);//上升沿对齐移相 次要 D<=0.5
void ePWM_Slave1_Set(ePWM_Slave_Set_Struct* slave_pwm,ePWM_Master_Set_Struct* master_pwm)
{
    if(slave_pwm->Phase>=0)
        slave_pwm->ePWMx->TBCTL.bit.PHSDIR = TB_UP;
    else
        slave_pwm->ePWMx->TBCTL.bit.PHSDIR = TB_DOWN;
    slave_pwm->ePWMx->TBPRD=75e6/master_pwm->Fs;
    slave_pwm->ePWMx->TBPHS.half.TBPHS = fabs(slave_pwm->Phase)/180*slave_pwm->ePWMx->TBPRD;

    slave_pwm->ePWMx->CMPA.half.CMPA = slave_pwm->ePWMx->TBPRD *slave_pwm->D*2;       // Set compare A value
    slave_pwm->ePWMx->CMPB = slave_pwm->ePWMx->TBPRD *(1-slave_pwm->D*2)+1;       // Set compare B value
}

void ePWM_Master1_Set(ePWM_Master_Set_Struct* master_pwm)
{
    master_pwm->ePWMx->TBPRD=75e6/master_pwm->Fs;
    master_pwm->ePWMx->CMPA.half.CMPA = master_pwm->ePWMx->TBPRD *master_pwm->D*2;       // Set compare A value
    master_pwm->ePWMx->CMPB = master_pwm->ePWMx->TBPRD *(1-master_pwm->D*2)+1;       // Set compare B value
}

这里给个demo,实现上面3个pwm的初始化程序如下:

void Init_ePWM()
{
    InitEPwm1Gpio();    //初始化 A0-EPWM1A  A1-EPWM1B
    InitEPwm2Gpio();    //初始化 A2-EPWM2A  A3-EPWM2B
    InitEPwm3Gpio();    //初始化 A4-EPWM3A  A5-EPWM3B

    pwm1.ePWMx=&EPwm1Regs;
    pwm1.Fs=50e3; //50kHz
    pwm1.D=0.5; //50%占空比
    pwm1.td=50; //0.5us 死区
    ePWM_Master1_Set_Flush(&pwm1); //pwm1作为主pwm

    pwm2.ePWMx=&EPwm2Regs;
    pwm2.D=0.25; //25%占空比
    pwm2.Phase=0; //不移相
    pwm2.td=50; //注意这里死区要设置与主相一致,否则上升沿相位无法对齐
    ePWM_Slave1_Set_Flush(&pwm1,&pwm2); //pwm2以pwm1作为主pwm

    pwm3.ePWMx=&EPwm3Regs;
    pwm3.D=0.3; //30%占空比
    pwm3.Phase=-0.3*180; //滞后108° 范围-180°~+180°
    pwm3.td=50;
    ePWM_Slave1_Set_Flush(&pwm1,&pwm3); //pwm3以pwm1作为主pwm

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;         // Start all the timers synced
    EDIS;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值