This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

28035正常停止电机如何将6路PWM全部拉低

Other Parts Discussed in Thread: CONTROLSUITE

你好,

我用的是28035的DSP 做电机控制,

当我需要停止电机的时候,希望将6路PWM全部拉低,但是并没有关闭PWM中断(因为正常待机时候也需要PWM中断来触发AD采样),

当我用下面这段代码强制PWM将全部拉低的时候,但是示波器测出来的结果是,只有PWM1A,PWM2A,PWM3A 这3路是被拉低,   但是PWM1B,PWM2B,PWM3B仍然是高电平,请问有什么建议吗?

如果用 EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO 来强制拉低PWM, DSP是不是会保护,不进PWM中断?

//Stop Motor

if((Motor_ON == 0)&&(Motor_ON_Previous==1))

{

EALLOW;

//CAD Action when the counter equals the active CMPA register and the counter is decrementing

//CAU Action when the counter equals the active CMPA register and the counter is incrementing

//01 =Clear: force EPWMxA output low.

EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;

EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;

EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR;

EPwm1Regs.AQCTLB.bit.CAD = AQ_CLEAR;

EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;

EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;

    EPwm2Regs.AQCTLB.bit.CAU = AQ_CLEAR;

EPwm2Regs.AQCTLB.bit.CAD = AQ_CLEAR;

EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR;

EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR;

EPwm3Regs.AQCTLB.bit.CAU = AQ_CLEAR;

EPwm3Regs.AQCTLB.bit.CAD = AQ_CLEAR;

EDIS;

}

  • 建议使用TZ来做,之后仍然会进入PWM中断。

    至于用AQCTLx之后仍有引脚置高,请看一下是不是有设置死区模块,使用了死区模块中的非门。

  • Forrest  专家你好,谢谢你的解答。

    现在我是打算用TZ来 控制 电机的开和停。

    但是用如下代码做的时候,发现我发了Motor_ON=0停止电机的时候,6路PWM确实是全部拉低了。

    但是问题是: 1. 虽然我已经做了 EPwm1Regs.TZCLR.bit.OST = 1; 但是 EPwm1Regs.TZFLG.bit.OST  仍然是 1;这是为什么呢?

    2. 我用仿真器在线仿真出现上述问题1的时候,手动将CCS4里的 View- Register 里面的 EPwm1Regs.TZCLR.bit.OST  置1,但是PWM1A,PWM1B却立刻输出了互补的PWM,其他4路PWM:PWM2A,PWM2B,PWM3A,PWM3B是正常的拉低的,我希望得到的是6路PWM都是保持拉低的。

    3. 当我需要再次把电机从停止状态切换到运转状态的时候,我会另  Motor_ON=1 指令,是不是只要将 PWM重新初始化一下就行, PWM_INIT_MACRO(pwm1) ,从Trip Zone状态切换到正常输出6路PWM,不需要做其他操作了吧?

    非常感谢你的详细解答,你的解答对我们的项目进展有重大意义。

    开始和停止电机的代码如下,请指正。

    // Stop the Motor

    if((Motor_ON == 0)&&(Motor_ON_Previous==1))

    {

         EALLOW;

         EPwm1Regs.TZFRC.bit.OST = 1;

         EPwm2Regs.TZFRC.bit.OST = 1;

         EPwm3Regs.TZFRC.bit.OST = 1;

         EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low

         EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWMxB will go low

         EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low

         EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWMxB will go low

         EPwm3Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low

         EPwm3Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWMxB will go low

         EDIS;

        // Clear any spurious OV trip

         EPwm1Regs.TZCLR.bit.OST = 1;

         EPwm2Regs.TZCLR.bit.OST = 1;

         EPwm3Regs.TZCLR.bit.OST = 1;  

    // Acknowledge this interrupt to receive more interrupts from group 2

       PieCtrlRegs.PIEACK.all = PIEACK_GROUP2;

    }

    // Run the Motor

    if((Motor_ON == 1)&&(Motor_ON_Previous==0))

    {

    // Re Initialize PWM module

        pwm1.PeriodMax = SYSTEM_FREQUENCY*1000000*T/2;  // Prescaler X1 (T1), ISR period = T x 1

    PWM_INIT_MACRO(pwm1)

    }

  • 楼主有看过epwm_trip_zone例程吗?请看看,尤其是epwm1_tzint_isr子程序的操作。

    28035的例程可以在controlsuite中找到:

    www.ti.com/.../controlsuite

  • 楼主你好。

    请注意TZCLR是受EALLOW保护的,当要清除时请按以下操作:

     EALLOW;

     EPwm1Regs.TZCLR.bit.OST = 1;

        EPwm2Regs.TZCLR.bit.OST = 1;

        EPwm3Regs.TZCLR.bit.OST = 1;  

        EDIS;

  • 已经解决问题,谢谢。

    //-----------------------------------------------------------------------------

    #define DIV_CLK_1   0

    #define DIV_CLK_10  5

    #define TRIP_ZONE_CLEAR_TRIP  1

    #define TRIP_ZONE_FORCE_TRIP  1

    #define TRIP_ZONE_OUTPUT_HIGH  1

    #define TRIP_ZONE_OUTPUT_LOW   2

    #define TRIP_ZONE_OUTPUT_FLOAT 3

    //-----------------------------------------------------------------------------

    //-----------------------------------------------------------------------------

    interrupt void IsrPwm1(void)

    {

     EPwm1Regs.TZCLR.bit.OST = TRIP_ZONE_CLEAR_TRIP;

     PieCtrlRegs.PIEACK.all = PIEACK_GROUP2;

    }//IsrPwm1

    //-----------------------------------------------------------------------------

    //-----------------------------------------------------------------------------

    void gInitPwm(void)

    {

     EALLOW;

     PieVectTable.EPWM1_TZINT = &IsrPwm1;

     EDIS;

     IER |= M_INT2;

     PieCtrlRegs.PIEIER2.bit.INTx1 = 1;

     EPwm1Regs.TBPRD = PWM_TIME_50_USEC;

     EPwm1Regs.CMPA.half.CMPA = PWM_TIME_25_USEC;

     EPwm1Regs.TBPHS.all = 0;

     EPwm1Regs.TBCTR = 0;

     EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;

     EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;

     EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;

     EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;

     EPwm1Regs.TBCTL.bit.HSPCLKDIV = DIV_CLK_1;

     EPwm1Regs.TBCTL.bit.CLKDIV = DIV_CLK_1;

     EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;

     EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_SHADOW;

     EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;

     EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;

    }//gInitPwm

    //-----------------------------------------------------------------------------

    //-----------------------------------------------------------------------------

    void gSetPwmOutput(char cPwmOutput)

    {

     EALLOW;

     EPwm1Regs.TZFRC.bit.OST = TRIP_ZONE_FORCE_TRIP;

     switch(cPwmOutput)

     {

     case gPWM_LOW_OUTPUT:

       EPwm1Regs.TZCTL.bit.TZA = TRIP_ZONE_OUTPUT_LOW;

       break;

     case gPWM_PWM_OUTPUT:

       EPwm1Regs.TZCTL.bit.TZA = TRIP_ZONE_OUTPUT_FLOAT;

       break;

     case gPWM_HIGH_OUTPUT:

       EPwm1Regs.TZCTL.bit.TZA = TRIP_ZONE_OUTPUT_HIGH;

       break;

     }

     EDIS;

    }//gSetPwmOutput

  • 你好,我现在正在学习做TZ这一块,想实现当计数器计到某一值a时,epwm1b打低电平,计数器继续计数到b(b>a)时,epwm1b恢复原来的波形,我现在参考Ti的例程,在epwm_trip_isr()中断函数中计数并判断计数值是否到a,并将其打低电平,到b时恢复,但怎么输出波形没有变化啊,GPIO我也设置了,但就是没变化,求高手指点,谢谢!

       EALLOW;

    //  EPwm1Regs.TZFRC.bit.OST = 1;                   

      if(EPwm1TZIntCount >= 20000)
         {
            EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
         }
         else
         {
            EPwm1Regs.TZCTL.bit.TZB = TZ_NO_CHANGE;
         }
         if(EPwm1TZIntCount >= 80000)
         { 
           EPwm1Regs.TZCLR.bit.OST = 1;
            EPwm1Regs.TZCLR.bit.INT = 1;
         }
         else
         {
           EPwm1TZIntCount = 0;
         }
         EDIS;

  • 受教了了,通过这种方法全部关掉pwm