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-F28379D:在 FCL 中更改 PWM 频率

Guru**** 2545610 points
Other Parts Discussed in Thread: SFRA, LAUNCHXL-F28379D, BOOSTXL-3PHGANINV, C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1206988/launchxl-f28379d-change-pwm-frequency-in-fcl

器件型号:LAUNCHXL-F28379D
主题中讨论的其他器件:SFRABOOSTXL-3PHGANINVC2000WARE

您好!

对于一个项目、我尝试按照"在单个 C2000 MCU 上使用 FCL 和 SFRA 的双轴电机控制"手册中所述的步骤进行操作。 为此、我将 LAUNCHXL-F28379D 与 BOOSTXL-3PhGaNInv 和演示项目"Dual_axis_servo_drive_FCL_QEP_f2837x"结合使用。 我使用的是"C2000Ware_MotorControl_SDK_4_02_00_00"。  

当我尝试在"Dual_axis_servo_drive_user.h"中将 PWM 频率从10kHz 更改为20kHz 时、项目构建并加载到微控制器上的调试器。 但是、当启动程序时、它会卡在文件"ePWM.h"的以下行:

仅电机1会发生这种情况。 它已在编译级别1-3中进行了测试、并且始终显示错误。

我已经试着增加电机2的 PWM 频率、这个方法运行没有任何问题。

问题可能在哪里?

此致

Pavel Müller ć

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

    两个 ISR 需要更多的 CPU 周期、并且 ISR 的执行时间要高于20kHz 的周期、因此您需要将 PWM 频率限制在15kHz 以下、甚至要低得多。

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

    您好,延明

    感谢您的回答。

    我知道 ISR 可以使用10kHz 以上的整个 CPU 时间。 但为什么问题只发生在电机1上? 对于电机2、可以正常生成频率为100kHz 的 PWM。 我认为这也可能是您的代码中的一个错误。 有没有办法可以解决这个问题?

    此致

    Pavel Müller ć

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    使用电机2时,生成100kHz
    的 PWM 没问题

    适合100kHz 吗?

    我认为这也可能是您代码中的一个错误。 有没有办法可以解决这个问题?

    您可以尝试10~15kHz 来查看会发生什么情况?

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

    是的、我能够为构建级别1生成电机2的 PWM、最大频率为500kHz。 对于构建级别2、最大频率为100kHz。

    您可以尝试10~15kHz 来查看发生了什么?

    对于电机1、没有问题的最大频率为13kHz。 高于该13kHz 时、程序卡在上述行中。

    感谢您的帮助!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [报价 userid="555540" url="~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1206988/launchxl-f28379d-change-pwm-frequency-in-fcl/4556960 #455696"]是的,我能够为电动机2生成 PWM,用于构建级别1,最大频率为500kHz。 对于构建级别2、最大值为100kHz。

    是的、您可以将 PWM 频率设定为任一值、但是控制 ISR 必须是一个正确的值、这样才能及时执行针对两个电机的 ISR 代码而不会发生溢出。

    对于电机1、没有问题的最大频率为13kHz。 高于该13kHz 时、程序卡在上述行中。

    感谢您的帮助!

    [/报价]

    如上所述。 需要通过选择正确的控制 ISR 频率来避免两个 ISR 中的溢出。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的,您可以将 PWM 频率设置为任意值,但控制 ISR 必须是正确的值,这样才能及时为两个电机执行 ISR 代码而不会溢出。

    我认为电机 ISR 频率由 PWM 的频率设置、因为每次计数器达到其最高值时都会执行 FCL。 我在文件"dual_axis_servo_drive_user.h"中调整了 PWM 频率。 因此应在整个项目中将其应用于电机1。

    如上所述。 需要通过选择正确的控制 ISR 频率来避免两个 ISR 中的溢出。

    经过一些调试、我能够找到误差。 该错误显示在文件"dual_axis_servo_drive.c"中的以下函数:

    // current feedback offset calibration for motor_1
        runOffsetsCalculation(&motorVars[0]);

    此函数在文件"Dual_axis_servo_drive_user.c"中定义:

    void runOffsetsCalculation(MOTOR_Vars_t *pMotor)
    {
        // Feedbacks OFFSET Calibration
        pMotor->offset_currentAs = 0;
        pMotor->offset_currentBs = 0;
        pMotor->offset_currentCs = 0;
    
        if(pMotor == &motorVars[0])
        {
            for(offsetCalCounter = 0; offsetCalCounter < 20000; offsetCalCounter++)
            {
                EPWM_clearEventTriggerInterruptFlag(halMtr[0].pwmHandle[0]);
    
                while(EPWM_getEventTriggerInterruptStatus(halMtr[0].pwmHandle[0]) == false);
    

    在上面的函数中、函数"EPWM_getEventTriggerInterruptStatus"被调用:

    static inline bool
    EPWM_getEventTriggerInterruptStatus(uint32_t base)
    {
    
    
        //
        // Check the arguments
        //
        ASSERT(EPWM_isBaseValid(base));
    
        //
        // Return INT bit of ETFLG register
        //
        return(((HWREGH(base + EPWM_O_ETFLG) & 0x1U) == 0x1U) ? true : false);
    }

    问题是、如果为 PWM 设置了高于13kHz 的频率、该函数返回"false"。

    该函数评估 ePWM1的事件中断标志是否被清除。 如果我在调试器中检查寄存器、就可以看到对于 低于13kHz 的频率、PWM1的"ETFLG"已正确设置为0。 对于更高的频率、中断标志不会被清除、这就是该函数返回"false"的原因。程序滞留在 while 循环中。

    为什么电机1只发生这种情况? 我该如何以清除标志的方式来修复它呢?

    感谢您的帮助!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [报价 userid="555540" url="~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1206988/launchxl-f28379d-change-pwm-frequency-in-fcl/4561099 #4561099"]为什么电机1只发生这种情况? 如何以清除标志的方式解决此问题?

    如果电机1的中断优先级高于电机2的中断优先级同时被触发。

    您可能必须首先限制 PWM/控制频率。 我们将了解如何在 ISR 中优化代码以减少执行时间。

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

    在进一步调试后、我解决了某些情况下的错误。

    我尝试从闪存而不是 RAM 运行程序、中断标志错误不再出现。 测试显示、来自闪存的电机 ISR 的时间为3.6us。 我能够同时为两个电机以高达40kHz 的 PWM 频率运行程序。 使用 PI 电流控制器和构建级别3时、单次采样和双次采样的限制条件是此40kHz。

    为了从频率高于13kHz 的 RAM 运行、我必须对您的代码进行以下修改:

    void runOffsetsCalculation(MOTOR_Vars_t *pMotor)
    {
        // Feedbacks OFFSET Calibration
        pMotor->offset_currentAs = 0;
        pMotor->offset_currentBs = 0;
        pMotor->offset_currentCs = 0;
    
        if(pMotor == &motorVars[0])
        {
            for(offsetCalCounter = 0; offsetCalCounter < 20000; offsetCalCounter++)
            {
                EPWM_clearEventTriggerInterruptFlag(halMtr[0].pwmHandle[0]);
    
                while(EPWM_getEventTriggerInterruptStatus(halMtr[0].pwmHandle[0]) == false){
                    EPWM_clearEventTriggerInterruptFlag(halMtr[0].pwmHandle[0]);
                }

    正如您所看到的、我添加了第15行、以便在复位不成功时再次复位标志。 我还必须为另一个电机添加这条线。

    进行此修改后、电机 ISR 时间为5.6us。 测试显示从 RAM 运行的最大频率只有25kHz。

    当我再次尝试使用闪存的这个小变化来运行程序时、校准函数再次卡住。 为什么需要从 RAM 和闪存运行不同的代码? 我可以对这两者使用相同的代码吗?

    由于我想在我的项目中使用50kHz 的 PWM 频率、我想知道是否有办法改进电机 ISR。 为什么我要测量3.6us、而不是 FCL 文档中描述的1us?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当我想在我的项目中使用50kHz PWM 频率时,我想知道是否有办法改进电机 ISR。 为什么我测量3.6us 而不是 FCL 文档中描述的1us?

    是的、您应该在 RAM 内运行所有 ISR 代码、并且确保 ISR 执行时间远远低于中断周期。 如果可能、您可以尝试使用较高的 PWM 频率和较低的控制 ISR 频率。