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.

[参考译文] LAUNCHXL-F280039C:UMCSDK v5.03/v5.04 disabe_PWM 发出 CMPSS 强制 DCAH/L 动作限定符

Guru**** 2810875 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1608015/launchxl-f280039c-umcsdk-v5-03-v5-04-disabe_pwm-issues-cmpss-force-dcah-l-action-qualifiers

器件型号: LAUNCHXL-F280039C

您好:

经过数小时评估 SDK 和后续 UMCSDK 版本后、代码似乎被错误地使用、并针对内部电流约束启用 PWM 故障控制 (hal.h)。 这是一个不!

因此、通过快速禁用和启用功能调用 (hal.h) 来导致电机控制信号门控不当、这些调用旨在为半桥电机栅极驱动器解释安全控制。 非 sys_main.c、motor_common.c、motor1_drive.c 中的内部软件控制标志。

当示例软件版本未正确使用 ePWM falut 控制时、客户会将自己的单触发和/或强制 DAC 控制添加到这两个用于外部电机故障控制的函数中、就会产生设计混淆。

请明确为 UMCSDK 内部启用/禁用标志添加不会影响外部电机 PWM 故障控制 (hal.h) 的函数、但可能清除故障功能看起来比较谨慎。 例如、当 C 代码变得不稳定时、带有紧急切断按钮的控制面板可能无法制动电机! 在这种情况下、我们可能会得到一次性中断或布尔标志、通过 EPWM 动作限定器将栅极驱动置于高阻抗状态。 BTW 清除 interrupt_all 标志对于任何添加的 ePWM 动作限定符 setup_pwmfaults 函数不会执行任何操作。  

否则、电机 ID 过程会很好地移植到 HID 器件中并正常运行。 然而、PWM 故障标志需要透明、以便工程师将其 C 代码添加到其 C 代码中、以实现与 UMCSDK 示例代码的运行没有干扰的硬件限制、从而创建 FAST、eSMO 和 GDSVM 控制信号、以便在 PWM 模块中添加客户栅极驱动器!   

当我们从 main.c 返回时、为什么当前开始循环时不受约束?disable_pwm () 电机可能会尝试启动然后立即停止、而不是实际停止、当 50%的占空比上下增加 1%左右时、电流开始自动激增。 奇怪的电流循环行为证明了永久循环正在逃逸、perhpas、因为 CPU 计时器溢出开始驱动未处理的中断?   

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    在程序启动期间运行偏移计算例程之前和之后会使用禁用和启用 PWM、否则、当用户使电机开始运行时、CMPSS 将在检测到过流条件时向 PWM 模块发出故障。 我不认为我们会出于任何其他目的使用禁用和启用、但我需要查看特定的代码、除非您可以直接指向代码的特定部分、以帮助我更好地了解您所指的内容

    此致、

    彼得

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    程序启动期间运行偏移计算例程

    您好、Peter:

    是的、我得到偏移计算代码这样做、但通过禁用 PWM 驱动器来设置 ePWM DCA1/B1 跳闸! 不过、当它应该处于低电平状态时、50%占空比仍然存在。 当标志 (motorVars_M1.flagEnableRunAndIdentify = true) 时、下面添加到 HAL_enablePWM () 和 HAL_clearMotorFaults () 中的代码会清除 DCA1/B1 一次性跳闸。此外、在紧急关闭、OVC 或紧急情况下也可以置位这些函数。

    这些 DCA1/B1 跳闸是为了在 CMPSSx 检测到 OVC 故障或用户代码强制执行 DCA1/B1 事件时保护半桥逆变器免受失控 C 代码的影响。 在 hal.h HAL_enablePWM () 中启用的 OST 跳变标志不会清除,当没有真正发生 CMPSSx 异步事件时,逆变器输出上没有 50%的占空比。 我查看了 LaunhcXL-39c CMPSS 部分中 MCU 39PZ 的勘误表文档、这似乎不是在 while 循环(代码监听下方)确保锁存器已清除时设置 DCA1/B1 锁存器的原因。

    我不清楚为什么设置 DCA1/B1 跳闸、因为 CMPSSx 不指示设置了任何锁存状态位。 使 CCS 调试 PWM1、PWM2、PWM6 寄存器生效并强制 TZ_CLEAR 位为真、DCA1/B1 标志会通过永久循环 (sys_main.c) 中的某个器件快速返回到跳闸状态 PWM DCA1/B1 故障跳闸设置为单触发事件、而不是 CBC。

    所以 runMotor1Control () 函数引起 DCA1/B1 跳闸事件、但 PWM 动作限定器子模块在 21us 中断内无法做出足够快的反应、而在循环内清除这些标志、它们只是显示为保持 CCS 调试寄存器视图!  如果我们在启用一次性 TZ 的情况下调用 HAL_disablePWM ()、则不能清除这些标志、保持设置状态、并且 PWM A1/B1 输出保持低电平状态。 我认为这是由于 runMotor1Control() 在电机运行的情况下以 166ns 的间隔在 8-28us 期间禁用和启用 PWM、CMPSS1/3 正在更新、而不是在第一个代码片段中由 CPU 计时器更新。

           systemVars.timerBase_1ms++;
           
             // 4-28us periods of 166ns SYSCLK intervals
             while(systemVars.timerBase_1ms == 20)
             {
                 // Time the loop
                 HAL_setGPIOHigh(halHandle_M1, HAL_GPIO_ISR_M1);
                 //
                 runMotorMonitor(motorHandle_M1);
                 //
                 calculateRMSData(motorHandle_M1);
    
                 // calculate motor protection value
                 calcMotorOverCurrentThreshold(motorHandle_M1);//CMPSS DACVals
                 // system control
                 systemVars.timerBase_1ms = 0;
                 //
                 systemVars.timerCnt_5ms++; // 25us interval
                 //
                 HAL_setGPIOLow(halHandle_M1, HAL_GPIO_ISR_M1);
             }

      

    static inline void HAL_enablePWM(HAL_MTR_Handle handle)
    {
        HAL_MTR_Obj *obj = (HAL_MTR_Obj *)handle;
    
    #if defined(MOTOR1_ISBLDC) || defined(MOTOR1_DCLINKSS)
    #if defined(BSXL8323RS_REVA) || defined(BSXL8320RS_REVA)
        // Clear any comparator digital filter output latch
        CMPSS_clearFilterLatchLow(obj->cmpssHandle[0]);
    
        // Clear any Trip Zone flag
        EPWM_clearTripZoneFlag(obj->pwmHandle[0], HAL_TZFLAG_INTERRUPT_ALL);
        EPWM_clearTripZoneFlag(obj->pwmHandle[1], HAL_TZFLAG_INTERRUPT_ALL);
        EPWM_clearTripZoneFlag(obj->pwmHandle[2], HAL_TZFLAG_INTERRUPT_ALL);
    #else
    #error /"This board doesn't support single shunt"/
    #endif  // BSXL8323RS_REVA || BSXL8323RH_REVB
    
    #else   // !(MOTOR1_ISBLDC || MOTOR1_DCLINKSS)
    
        EALLOW;
        // SW Reset comparator digital filter output H/L latch status
        while(HWREGH(obj->cmpssHandle[0] +  CMPSS_O_COMPSTS) &= CMPSS_COMPSTS_COMPHLATCH)
        {
            CMPSS_clearFilterLatchHigh(obj->cmpssHandle[0]);
            break;
        }
        //
        while(HWREGH(obj->cmpssHandle[0] + CMPSS_O_COMPSTS) &= CMPSS_COMPSTS_COMPLLATCH)
        {
            CMPSS_clearFilterLatchLow(obj->cmpssHandle[0]);
            break;
        }
        // SW Reset comparator digital filter output H/L latch status
        while(HWREGH(obj->cmpssHandle[1] +  CMPSS_O_COMPSTS) &= CMPSS_COMPSTS_COMPHLATCH)
        {
            CMPSS_clearFilterLatchHigh(obj->cmpssHandle[1]);
            break; 
        }
        //
        while(HWREGH(obj->cmpssHandle[1] + CMPSS_O_COMPSTS) &= CMPSS_COMPSTS_COMPLLATCH)
        {
            CMPSS_clearFilterLatchLow(obj->cmpssHandle[1]);
            break; 
        }
        // SW Reset comparator digital filter output H/L latch status
        while(HWREGH(obj->cmpssHandle[2] +  CMPSS_O_COMPSTS) &= CMPSS_COMPSTS_COMPHLATCH)
        {
            CMPSS_clearFilterLatchHigh(obj->cmpssHandle[2]);
            break; 
        }
        //
        while(HWREGH(obj->cmpssHandle[2] + CMPSS_O_COMPSTS) &= CMPSS_COMPSTS_COMPLLATCH)
        {
            CMPSS_clearFilterLatchLow(obj->cmpssHandle[2]);
            break; 
        }
     EDIS;
    
        /* Clear External Async DCAH DCBH OST Flags  */
        EPWM_clearOneShotTripZoneFlag(obj->pwmHandle[0],
        (EPWM_TZ_OST_FLAG_DCAEVT1 | EPWM_TZ_OST_FLAG_DCBEVT1));
        EPWM_clearOneShotTripZoneFlag(obj->pwmHandle[1],
        (EPWM_TZ_OST_FLAG_DCAEVT1 | EPWM_TZ_OST_FLAG_DCBEVT1));
        EPWM_clearOneShotTripZoneFlag(obj->pwmHandle[2],
        (EPWM_TZ_OST_FLAG_DCAEVT1 | EPWM_TZ_OST_FLAG_DCBEVT1));
    
    
       /* Clear DCA, DCB events, TZ-7,8,9 CBC6 OST flags */
       EPWM_clearTripZoneFlag(obj->pwmHandle[0],(EPWM_TZ_FLAG_OST | EPWM_TZ_FLAG_CBC |
               EPWM_TZ_FLAG_DCAEVT1 | EPWM_TZ_FLAG_DCBEVT1));
       EPWM_clearTripZoneFlag(obj->pwmHandle[1],(EPWM_TZ_FLAG_OST | EPWM_TZ_FLAG_CBC |
               EPWM_TZ_FLAG_DCAEVT1 | EPWM_TZ_FLAG_DCBEVT1));
       EPWM_clearTripZoneFlag(obj->pwmHandle[2],(EPWM_TZ_FLAG_OST | EPWM_TZ_FLAG_CBC |
               EPWM_TZ_FLAG_DCAEVT1 | EPWM_TZ_FLAG_DCBEVT1));
    
    
    #if defined(_SPIA_EN) || defined(_SPIB_EN)
        /* Clear ASYNC nFAULT GPIO input TZ-1 OST trip flags */
       EPWM_clearOneShotTripZoneFlag(obj->pwmHandle[0], EPWM_TZ_OST_FLAG_OST1);
       EPWM_clearOneShotTripZoneFlag(obj->pwmHandle[1], EPWM_TZ_OST_FLAG_OST1);
       EPWM_clearOneShotTripZoneFlag(obj->pwmHandle[2], EPWM_TZ_OST_FLAG_OST1);
    #endif
    
    #endif  // !(MOTOR1_ISBLDC || MOTOR1_DCLINKSS)
    
    #if defined(MOTOR1_ISBLDC)
        GPIO_writePin(MTR1_DRV_INL_A, 1);
        GPIO_writePin(MTR1_DRV_INL_B, 1);
        GPIO_writePin(MTR1_DRV_INL_C, 1);
    #endif  // MOTOR1_ISBLDC && (BSXL8323RS_REVA || SXL8323RH_REVB)
    
        obj->flagEnablePWM = true;
    
        return;
    } // end of HAL_enablePWM() function
    
       
    //! \brief      Disables the PWM device for motor control
    //! \details    Turns off the outputs of the EPWM peripherals which will put
    //!             the power switches into a high impedance state.
    //! \param[in]  handle  The hardware abstraction layer (HAL) handle
    static inline void HAL_disablePWM(HAL_MTR_Handle handle)
    {
      HAL_MTR_Obj *obj = (HAL_MTR_Obj *)handle;
    
    
      /* Enable the forced OSHT evnets   18.9.2 Fig.18-41 */
      EPWM_forceTripZoneEvent(obj->pwmHandle[0],
                              EPWM_TZ_FORCE_EVENT_DCAEVT1);
      EPWM_forceTripZoneEvent(obj->pwmHandle[0],
                              EPWM_TZ_FORCE_EVENT_DCBEVT1);
      //
      EPWM_forceTripZoneEvent(obj->pwmHandle[1],
                              EPWM_TZ_FORCE_EVENT_DCAEVT1);
      EPWM_forceTripZoneEvent(obj->pwmHandle[1],
                              EPWM_TZ_FORCE_EVENT_DCBEVT1);
      //
      EPWM_forceTripZoneEvent(obj->pwmHandle[2],
                              EPWM_TZ_FORCE_EVENT_DCAEVT1);
      EPWM_forceTripZoneEvent(obj->pwmHandle[2],
                              EPWM_TZ_FORCE_EVENT_DCBEVT1);
    
      // turns off the outputs of the EPWM peripherals which will put the power
      // switches into a high impedance state.
      //EPWM_forceTripZoneEvent(obj->pwmHandle[0], EPWM_TZ_FORCE_EVENT_OST);
      //EPWM_forceTripZoneEvent(obj->pwmHandle[1], EPWM_TZ_FORCE_EVENT_OST);
      //EPWM_forceTripZoneEvent(obj->pwmHandle[2], EPWM_TZ_FORCE_EVENT_OST);
    
    
    #if defined(MOTOR1_ISBLDC)
        GPIO_writePin(MTR1_DRV_INL_A, 0);
        GPIO_writePin(MTR1_DRV_INL_B, 0);
        GPIO_writePin(MTR1_DRV_INL_C, 0);
    #endif  // MOTOR1_ISBLDC && (BSXL8323RS_REVA || SXL8323RH_REVB)
    
      obj->flagEnablePWM = false;
    
      return;
    } // end of HAL_disablePWM() function

      

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    ]我不清楚为什么设置 DCA1/B1 跳闸、因为 CMPSSx 不指示设置了任何锁存状态位
    因此 runMotor1Control () 函数导致 DCA1/B1 跳闸事件、但 PWM 动作限定器子模块在清除这些标志的循环期间内无法在 21us 中断中做出足够快的反应、它们只是显示为保持设置的 CCS 调试寄存器视图!  [/报价]

    对于 UMCSDK 启用和禁用 PWM 导致此问题的问题、我的回答是部分正确的、也是错的。 在一次攻击中决定编写 C 代码、检查 TZOST 清除寄存器是否指示这些位实际上被清除、然后再继续执行其他启动代码。 看似一些未记录的勘误表 ePWM 跳变事件子模块时序 120MHz SYSCLK、清除位有点棘手。

    因此、当 C2000 x39c driverlib 调用清除 TZOST 寄存器位而无法按预期工作时、DCA1 和 DCB1 Event1 标志会保持启用状态。 while 循环中的(中断)指令可确保 CPU 在完成工作后不会卡住。 此代码嗅探修复了 TZOST 标志事件、使 ePWM 操作限定符能够通过 DCA1/B1 强制事件–1A/1B 来禁用(设置为低电平)PWM A1/B1 输出。  

     /* Ensure the One Shot trip flag status register BITS are clear  */
     while(HWREG(obj->pwmHandle[0] + EPWM_O_TZOSTFLG) &= EPWM_TZ_FLAG_DCAEVT1)
     {
        /* Clear External Async DCAH DCBH OST Flags  */
        EPWM_clearOneShotTripZoneFlag(obj->pwmHandle[0], EPWM_TZ_OST_FLAG_DCAEVT1);
        break;
     }
     while(HWREG(obj->pwmHandle[0] + EPWM_O_TZOSTFLG) &= EPWM_TZ_FLAG_DCBEVT1)
     {
        /* Clear External Async DCAH DCBH OST Flags  */
        EPWM_clearOneShotTripZoneFlag(obj->pwmHandle[0], EPWM_TZ_OST_FLAG_DCBEVT1);
        break;
     }
     /* Ensure the One Shot trip flag status register BITS are clear  */
     while(HWREG(obj->pwmHandle[1] + EPWM_O_TZOSTFLG) &= EPWM_TZ_FLAG_DCAEVT1)
     {
        /* Clear External Async DCAH DCBH OST Flags  */
        EPWM_clearOneShotTripZoneFlag(obj->pwmHandle[1], EPWM_TZ_OST_FLAG_DCAEVT1);
        break;
     }
     while(HWREG(obj->pwmHandle[1] + EPWM_O_TZOSTFLG) &= EPWM_TZ_FLAG_DCBEVT1)
     {
        /* Clear External Async DCAH DCBH OST Flags  */
        EPWM_clearOneShotTripZoneFlag(obj->pwmHandle[1], EPWM_TZ_OST_FLAG_DCBEVT1);
        break;
     }
     /* Ensure the One Shot trip flag status register BITS are clear  */
     while(HWREG(obj->pwmHandle[2] + EPWM_O_TZOSTFLG) &= EPWM_TZ_FLAG_DCAEVT1)
     {
        /* Clear External Async DCAH DCBH OST Flags  */
        EPWM_clearOneShotTripZoneFlag(obj->pwmHandle[2], EPWM_TZ_OST_FLAG_DCAEVT1);
        break;
     }
     while(HWREG(obj->pwmHandle[2] + EPWM_O_TZOSTFLG) &= EPWM_TZ_FLAG_DCBEVT1)
     {
        /* Clear External Async DCAH DCBH OST Flags  */
        EPWM_clearOneShotTripZoneFlag(obj->pwmHandle[2], EPWM_TZ_OST_FLAG_DCBEVT1);
        break;
     }