DSP2837x PWM调试(BLDC无刷电机驱动)

PWM驱动

  • 前言
  • 一、初始化
    • 1.main()初始化
    • 2.PWM配置
  • 二、BLDC 驱动函数
    • 1.六步换向
    • 2.其他函数
  • 总结


前言

DSP28377D 的PWM调试
应用场景:直流无刷电机(BLDC)的驱动。


提示:以下是本篇文章正文内容,下面调试记录供参考

一、初始化

1.main()初始化

主程序中初始化代码如下:

     //初始化PWM
     EALLOW;
     CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =0; //关闭 pwm-时钟
     EDIS;
     InitEPwm();                          //初始化PWM
     PWM_Stop();
     EALLOW;
     CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =1; //重新打开 pwm-时钟
     EDIS;

初始化前需要关闭时钟PCLK
DSP2837x PWM调试(BLDC无刷电机驱动)_第1张图片
待初始化完成后重新开启时钟,PWM运行。

如需要开启中断,根据向量表增加如下代码:

 // Enable pwm1-3 interrupts
PieCtrlRegs.PIEIER3.bit.INTx3 = 1;

//EPWMIER
IER |= M_INT3;   
EINT;
//EPWM中断程序入口
EALLOW; 
PieVectTable.EPWM1_INT = &EPWM1_ISR;
PieVectTable.EPWM2_INT = &EPWM2_ISR;
PieVectTable.EPWM3_INT = &EPWM3_ISR;
EDIS;

2.PWM配置

void InitEPwm(void)
{
	InitEPwm1Gpio();
	InitEPwm2Gpio();
	InitEPwm3Gpio();
	InitEPwm5Gpio();
	InitEPwm1Example();
	InitEPwm2Example();
	InitEPwm3Example();
	InitEPwm5Example();
}
//初始化引脚
void InitEPwm1Gpio(void)
{
   EALLOW;
   GpioCtrlRegs.GPAPUD.bit.GPIO0 = 1;    // Disable pull-up on GPIO0 (EPWM1A)
   GpioCtrlRegs.GPAPUD.bit.GPIO1 = 1;    // Disable pull-up on GPIO1 (EPWM1B)
   GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;   // Configure GPIO0 as EPWM1A
   GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;   // Configure GPIO1 as EPWM1B
   EDIS;
}
//PWM配置
void InitEPwm1Example(void)
{
    //一个周期约等于16.7Khz
    EPwm1Regs.TBPRD = EPWM_PRD;                   // Set timer period 一个大周期有6250小周期
    EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;           // Phase is 0 关闭TBPHS功能,TBPHS决定是否使用同步信号EPWMxSYNCI
    EPwm1Regs.TBCTR = 0x0000;                     // Clear counter

    // Setup TBCLK  TBCLK = EPWMCLK/(HSPCLKDIV * CLKDIV):如果是上下计数,即需要再/2
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up 上下计数
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV2;
    //SYSCLK/HSPCLKDIV/CLKDIV

    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;    // CMPA 双缓冲操作,所有的写操作通过CPU访问影子(映射)寄存器
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;    // CMPB 双缓冲操作,所有的写操作通过CPU访问影子(映射)寄存器
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;  // 当时间基准计数器等于0(TBCTR = 0)时,CMPA 从影子寄存器中加载
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;  // 当时间基准计数器等于0(TBCTR = 0)时,CMPB 从影子寄存器中加载

    // Setup compare
    EPwm1Regs.CMPA.bit.CMPA = DutyCycle;             //用于设置占空比 3000/6000
    EPwm1Regs.CMPB.bit.CMPB = 0;                     //用于设置占空比 3000/6000
    // Set actions
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;             // When TBCTR = CMPA on Up Count,    force EPWMxA output high
    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;             // When TBCTR = CMPA on Down Count , force EPWMxA output low
    EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR;             // When TBCTR = CMPB on Up Count,    force EPWMxB output low
    EPwm1Regs.AQCTLB.bit.CAD = AQ_CLEAR;             // When TBCTR = CMPB on Down Count , force EPWMxA output high

    // Active Low PWMs - Setup Deadband
  
    EPwm1Regs.DBCTL.bit.OUT_MODE = 0;  	//DB_FULL_ENABLE:0x3 Bit 1 controls the S1 switch and bit 0 controls the S0 switch.
    EPwm1Regs.DBCTL.bit.POLSEL = 0;     //DB_ACTV_LO:0x3,Bit 3 controls the S3 switch and bit 2 controls the S2 switch
    EPwm1Regs.DBCTL.bit.IN_MODE = 0;    //DBA_ALL:0x0,Bit 5 controls the S5 switch and bit 4 controls the S4 switch shown
    
    /* 死区上升沿延时时间 */
    //EPwm1Regs.DBRED.bit.DBRED = 75;       //Rising edge delay value
    /* 死区下降沿延时时间 */
    //EPwm1Regs.DBFED.bit.DBFED = 75;       //Falling Edge Delay Count
    /* Tdb=DBRED*TBCLK*/
    // Event Trigger Selection Register Interrupt where we will change the Deadband
    //EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;    // Enable Event time-base counter equal to zero. (TBCTR = 0x00)
    //EPwm1Regs.ETSEL.bit.INTEN = 1;               // Enable ePWM Interrupt
    //  Event Trigger Pre-Scale Register
   // EPwm1Regs.ETPS.bit.INTPRD = ET_3RD;          // 0x03,Generate interrupt on ETPS[INTCNT] = 1,1 (third event),第三个事件发生时中断

    EALLOW;
    EPwm1Regs.ETSEL.bit.SOCAEN  = 1;            // Disable SOC on A group
    EPwm1Regs.ETSEL.bit.SOCASEL = 2;            // 010: Enable event time-base counter equal to period (TBCTR =TBPRD)
    EPwm1Regs.ETPS.bit.SOCAPRD = 1;             // Generate pulse on 1st event 第一次即发生SOCA事件
    EDIS;
}
  • 周期计算:
    TBCLK = EPWMCLK/(HSPCLKDIV * CLKDIV)
    如果是上下计数模式,即需要再/2,
    即 TBCLK = EPWMCLK/(HSPCLKDIV * CLKDIV) /2
  • 死区
    BLDC驱动不需要设置死区时间,故注释死区,如需设置死区,参考下图并对DBCTL寄存器进行配置,使PWM信号经过死区延时。
    DSP2837x PWM调试(BLDC无刷电机驱动)_第2张图片

二、BLDC 驱动函数

1.六步换向

霍尔与三相输出关系图如下:

DSP2837x PWM调试(BLDC无刷电机驱动)_第3张图片
驱动PWM变化一般有两种方式(2选1)

1、修改动作模式,即AQCTLA寄存器的值,改变占空比条件满足后的低电平或高电平表达,并马上改变计数值,即 EPwm1Regs.CMPA
DSP2837x PWM调试(BLDC无刷电机驱动)_第4张图片

2、强制输出 AQCSFRC,令output强制输出高/低电平。此方法输出响应会更快,但要考虑切回占空比控制输出时的电平瞬时变化问题。
DSP2837x PWM调试(BLDC无刷电机驱动)_第5张图片

附六步换向驱动代码:

void Motor_PWMChange(Motor_Sta_t *pMt)
{
    if(pMt->Dir == MT_DIR_CW )//MT_DIR_CW
    {
        switch(pMt->HallNow)
        {
            case 1://001 CB
                EPwm1Regs.AQCSFRC.bit.CSFA= 1 ; //01,强制拉低
                EPwm1Regs.AQCSFRC.bit.CSFB= 1 ; //01,强制拉低

                EPwm2Regs.AQCSFRC.bit.CSFA= 1 ; //01,强制拉低
                EPwm2Regs.AQCSFRC.bit.CSFB= 2 ; //10,强制拉高

                EPwm3Regs.AQCSFRC.bit.CSFA= 0;  //00,恢复
                EPwm3Regs.AQCTLA.all = 0x90;    //1001 0000,PWM设置
                EPwm3Regs.AQCSFRC.bit.CSFB= 1 ; //01,强制拉低
                break;

            case 2://010 BA
                EPwm1Regs.AQCSFRC.bit.CSFA= 1 ; //01,强制拉低
                EPwm1Regs.AQCSFRC.bit.CSFB= 2 ; //10,强制拉高

                EPwm2Regs.AQCSFRC.bit.CSFA= 0;  //00,恢复
                EPwm2Regs.AQCTLA.all = 0x90;    //1001 0000,PWM设置
                EPwm2Regs.AQCSFRC.bit.CSFB= 1 ; //01,强制拉低

                EPwm3Regs.AQCSFRC.bit.CSFA= 1 ; //01,强制拉低
                EPwm3Regs.AQCSFRC.bit.CSFB= 1 ; //01,强制拉低
                break;
            case 3: //011  CA
                EPwm1Regs.AQCSFRC.bit.CSFA= 1 ; //01,强制拉低
                EPwm1Regs.AQCSFRC.bit.CSFB= 2 ; //10,强制拉高

                EPwm2Regs.AQCSFRC.bit.CSFA= 1 ; //01,强制拉低
                EPwm2Regs.AQCSFRC.bit.CSFB= 1 ; //01,强制拉低

                EPwm3Regs.AQCSFRC.bit.CSFA= 0;  //00,恢复
                EPwm3Regs.AQCTLA.all = 0x90;    //1001 0000,PWM设置
                EPwm3Regs.AQCSFRC.bit.CSFB= 1 ; //01,强制拉低
                break;
            case 4: //100   AC
                EPwm1Regs.AQCSFRC.bit.CSFA= 0;  //00,恢复
                EPwm1Regs.AQCTLA.all = 0x90;    //1001 0000,PWM设置
                EPwm1Regs.AQCSFRC.bit.CSFB= 1 ; //01,强制拉低

                EPwm2Regs.AQCSFRC.bit.CSFA= 1 ; //01,强制拉低
                EPwm2Regs.AQCSFRC.bit.CSFB= 1 ; //01,强制拉低

                EPwm3Regs.AQCSFRC.bit.CSFA= 1 ; //01,强制拉低
                EPwm3Regs.AQCSFRC.bit.CSFB= 2 ; //10,强制拉高
                break;
            case 5: //101   AB
                EPwm1Regs.AQCSFRC.bit.CSFA= 0;  //00,恢复
                EPwm1Regs.AQCTLA.all = 0x90;    //1001 0000,PWM设置
                EPwm1Regs.AQCSFRC.bit.CSFB= 1 ; //01,强制拉低

                EPwm2Regs.AQCSFRC.bit.CSFA= 1 ; //01,强制拉低
                EPwm2Regs.AQCSFRC.bit.CSFB= 2 ; //10,强制拉高

                EPwm3Regs.AQCSFRC.bit.CSFA= 1 ; //01,强制拉低
                EPwm3Regs.AQCSFRC.bit.CSFB= 1 ; //01,强制拉低
                break;
            case 6: //110   BC
                  EPwm1Regs.AQCSFRC.bit.CSFA= 1 ; //01,强制拉低
                  EPwm1Regs.AQCSFRC.bit.CSFB= 1 ; //01,强制拉低

                  EPwm2Regs.AQCSFRC.bit.CSFA= 0;  //00,恢复
                  EPwm2Regs.AQCTLA.all = 0x90;    //1001 0000,PWM设置
                  EPwm2Regs.AQCSFRC.bit.CSFB= 1 ; //01,强制拉低

                  EPwm3Regs.AQCSFRC.bit.CSFA= 1 ; //01,强制拉低
                  EPwm3Regs.AQCSFRC.bit.CSFB= 2 ; //10,强制拉高
                  break;
        }

    }
}

2.其他函数

电机运行:

Result_t Motor_Run(Motor_Sta_t *pMt)
{
    if(pMt->sta == MT_STA_STOP) //当电机处于停止时可运行
    {
        pMt->HallNow = (char) (GpioDataRegs.GPBDAT.all >>26 &0x7); 	//更新当前霍尔状态
        Motor_PWMChange(&Mt1_Sta); 									//执行一次换向动作
        return RESULT_OK;
    }
    else
        return RESULT_ERROR;

}

软停机:

void PWM_Stop(void)
{
    EPwm1Regs.AQCSFRC.bit.CSFA= 1 ; //01,强制拉低
    EPwm1Regs.AQCSFRC.bit.CSFB= 1 ; //01,强制拉低
    EPwm2Regs.AQCSFRC.bit.CSFA= 1 ; //01,强制拉低
    EPwm2Regs.AQCSFRC.bit.CSFB= 1 ; //01,强制拉低
    EPwm3Regs.AQCSFRC.bit.CSFA= 1 ; //01,强制拉低
    EPwm3Regs.AQCSFRC.bit.CSFB= 1 ; //01,强制拉低
}


总结

换向前需要更新一次霍尔值,换向函数可以放在ECAP中断中进行。
ECAP的配置在另一章中记录。

你可能感兴趣的:(DSP,单片机,驱动开发,嵌入式)