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.

[参考译文] BOOSTXL-DRV8323RH:发生故障时通用电机控制实验室复位电机控制或恢复电机控制?

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

https://e2e.ti.com/support/motor-drivers-group/motor-drivers/f/motor-drivers-forum/1189718/boostxl-drv8323rh-universal_motorcontrol_lab-resetmotorcontrol-or-restartmotorcontrol-when-fault-occurred

器件型号:BOOSTXL-DRV8323RH

您好!  

将此处包含通用电机实验4中的代码段、当我跟踪代码时、如果系统遇到过流等故障、它将跳转至 第34行和第35行、并将  flagRunIdentAndOnLine 设置为 false、 然后,当  RunIdentAndOnLine = false 时 ,flagEnableRunAndIdentify= true 时,它将 调用线路184 flagMotorControl  向右吗?  

检测到故障时,您似乎无法调用 restartMotorControl?  

第34和35行

obj->flagRunIdentAndOnLine = false;
obj->motorState = motor_FAULT_stop;

线路184 resetMotorControl (handle);  

第61行:RestartMotorControl (Handle);  

void runMotor1Control(MOTOR_Handle handle)
{
    MOTOR_Vars_t *obj = (MOTOR_Vars_t *)handle;
    MOTOR_SetVars_t *objSets = (MOTOR_SetVars_t *)(obj->motorSetsHandle);
    USER_Params *objUser = (USER_Params *)(obj->userParamsHandle);

    if(HAL_getPwmEnableStatus(obj->halMtrHandle) == true)
    {
        if(HAL_getMtrTripFaults(obj->halMtrHandle) != 0)  
        {
            obj->faultMtrNow.bit.moduleOverCurrent = 1;  
        }
    }

    obj->faultMtrPrev.all |= obj->faultMtrNow.all;
    obj->faultMtrUse.all = obj->faultMtrNow.all & obj->faultMtrMask.all; 

    HAL_setMtrCMPSSDACValue(obj->halMtrHandle, objSets->dacCMPValH, objSets->dacCMPValL);

    if(obj->flagClearFaults == true)
    {
        HAL_clearMtrFaultStatus(obj->halMtrHandle); 

        obj->faultMtrNow.all &= MTR_FAULT_CLEAR;
        obj->flagClearFaults = false;
    }
    
    if(obj->flagEnableRunAndIdentify == true)
    {
        if(obj->faultMtrUse.all != 0)
        {
            if(obj->flagRunIdentAndOnLine == true)
            {
                obj->flagRunIdentAndOnLine = false;
                obj->motorState = MOTOR_FAULT_STOP;

                obj->stopWaitTimeCnt = objSets->restartWaitTimeSet; 
                obj->restartTimesCnt++;

                if(obj->flagEnableRestart == false)
                {
                    obj->flagEnableRunAndIdentify = false;			
                    obj->stopWaitTimeCnt = 0;   					
                }
            }
            
            else if(obj->stopWaitTimeCnt == 0)
            {
                if(obj->restartTimesCnt < objSets->restartTimesSet) 
                {
                    obj->flagClearFaults = 1;
                }
                else
                {
                    obj->flagEnableRunAndIdentify = false;			
                }
            }
        }
        else if((obj->flagRunIdentAndOnLine == false) && (obj->stopWaitTimeCnt == 0))  
        {
            restartMotorControl(handle); 
        }
    } 

    else if(obj->flagRunIdentAndOnLine == true) 
    {
        stopMotorControl(handle);

        if(obj->flagEnableFlyingStart == false)
        {
            obj->stopWaitTimeCnt = objSets->stopWaitTimeSet;
        }
        else
        {
            obj->stopWaitTimeCnt = 0;
        }
    }
    else
    {

    } 

    if((objUser->motor_type == MOTOR_TYPE_INDUCTION) && (obj->flagMotorIdentified == true))
    {
        EST_setFlag_bypassLockRotor(obj->estHandle, obj->flagBypassLockRotor);
    }


    if(obj->flagRunIdentAndOnLine == true)
    {
        if(HAL_getPwmEnableStatus(obj->halMtrHandle) == false)
        {
            EST_enable(obj->estHandle);

            EST_enableTraj(obj->estHandle);

            HAL_enablePWM(obj->halMtrHandle);
        }

        if(obj->flagMotorIdentified == true)
        {
            if(obj->speedRef_Hz > 0.0f)
            {
                obj->direction = 1.0f;
            }
            else
            {
                obj->direction = -1.0f;
            }

            EST_setFlag_enableForceAngle(obj->estHandle, obj->flagEnableForceAngle); // default enable

            EST_setFlag_enableRsRecalc(obj->estHandle, obj->flagEnableRsRecalc); // default false


            if(obj->motorState >= MOTOR_CL_RUNNING)
            {
                TRAJ_setTargetValue(obj->trajHandle_spd, obj->speedRef_Hz);
            }
            else
            {   
                TRAJ_setTargetValue(obj->trajHandle_spd, (obj->speedForce_Hz * obj->direction)); 
            }

            
            if((fabsf(obj->speed_Hz) > obj->speedStart_Hz) || (obj->motorState == MOTOR_CTRL_RUN))
            {
                TRAJ_setMaxDelta(obj->trajHandle_spd, (obj->accelerationMax_Hzps * objUser->ctrlPeriod_sec));

                if(obj->flagEnableLsUpdate ==  true)
                {
                    
                    objSets->Ls_d_comp_H = objUser->motor_Ls_d_H * (1.0f - obj->Is_A * objSets->Ls_d_Icomp_coef);
                    objSets->Ls_q_comp_H = objUser->motor_Ls_q_H * (1.0f - obj->Is_A * objSets->Ls_q_Icomp_coef);

                    if(objSets->Ls_d_comp_H < objSets->Ls_min_H)  	
                    {
                        objSets->Ls_d_comp_H = objSets->Ls_min_H;
                    }

                    if(objSets->Ls_q_comp_H < objSets->Ls_min_H)
                    {
                        objSets->Ls_q_comp_H = objSets->Ls_min_H;
                    }

                    EST_setLs_d_H(obj->estHandle, objSets->Ls_d_comp_H);
                    EST_setLs_q_H(obj->estHandle, objSets->Ls_q_comp_H);
                }

                PI_setMinMax(obj->piHandle_spd, -obj->maxCurrent_A, obj->maxCurrent_A);

                SVGEN_setMode(obj->svgenHandle, obj->svmMode);

                if(obj->motorState == MOTOR_CL_RUNNING)
                {
                    obj->stateRunTimeCnt++;

                    if(obj->stateRunTimeCnt == obj->fwcTimeDelay) 
                    {
                        obj->Idq_out_A.value[0] = 0.0f;
                        obj->motorState = MOTOR_CTRL_RUN;
                    }
                }
            }
            else 
            {
                TRAJ_setMaxDelta(obj->trajHandle_spd, (obj->accelerationStart_Hzps * objUser->ctrlPeriod_sec)); 

                if(obj->speed_int_Hz >= 0.0f) 
                {
                    PI_setMinMax(obj->piHandle_spd, 0.0f, obj->startCurrent_A);
                }
                else
                {
                    PI_setMinMax(obj->piHandle_spd, -obj->startCurrent_A, 0.0f);
                }

            }
        } 
    } 

    else 
    {
        resetMotorControl(handle);
    }

    
    if(EST_isTrajError(obj->estHandle) == true)
    {
        HAL_disablePWM(obj->halMtrHandle); // trajectory generator error, stop PWM
    }
    else
    {
        EST_updateTrajState(obj->estHandle);
    }

    if(EST_isError(obj->estHandle) == true)
    {
        HAL_disablePWM(obj->halMtrHandle);
    }
    else 
    {
        bool flagEstStateChanged = false;

        float32_t Id_target_A = EST_getIntValue_Id_A(obj->estHandle);

        if(obj->flagMotorIdentified == true)
        {
            flagEstStateChanged = EST_updateState(obj->estHandle, 0.0f);  
        }
        else
        {
            flagEstStateChanged = EST_updateState(obj->estHandle, Id_target_A);
        }

        if(flagEstStateChanged == true)
        {
            EST_configureTraj(obj->estHandle);

            if(obj->flagMotorIdentified == false)
            {
                EST_configureTrajState(obj->estHandle, obj->userParamsHandle, obj->piHandle_spd, obj->piHandle_Id, obj->piHandle_Iq);
            }

            if(objUser->flag_bypassMotorId == false) 
            {
                if((EST_isLockRotor(obj->estHandle) == true) || ( (EST_isMotorIdentified(obj->estHandle) == true) && (EST_isIdle(obj->estHandle) == true) ) )
                {
                    if(EST_isMotorIdentified(obj->estHandle) == true)
                    {
                        obj->flagMotorIdentified = true;

                        obj->flagRunIdentAndOnLine = false;
                        obj->flagEnableRunAndIdentify = false;  

                        EST_disable(obj->estHandle);

                        EST_disableTraj(obj->estHandle);
                    }

                    if(objUser->motor_type == MOTOR_TYPE_INDUCTION)
                    {
                        obj->flagRunIdentAndOnLine = false;
                        obj->flagEnableRunAndIdentify = false;
                    }
                }
            }   
        }
    }

    obj->flagMotorIdentified = EST_isMotorIdentified(obj->estHandle);

    if(obj->flagMotorIdentified == true)
    {
        if(obj->flagSetupController == true)
        {
            updateControllers(handle);
        }
        else
        {
            obj->flagSetupController = true;

            setupControllers(handle);
        }
    }
    runRsOnLine(handle);
    updateGlobalVariables(handle);

    return;
} 

Danny

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

    尊敬的 Danny:

    感谢您发帖到电机驱动器论坛!

    查看您共享的有关第30-62行、特别是第30和59行的函数、这设置为 if/else 方案。 这意味着、如果满足第30行中描述的条件、第32-57行将被执行、而第59-62行本质上会被忽略。 如果您希望能够实施第61行、则必须满足以下条件:

    • FAULTMtrUse.all 必须等于0
    • flagRunIdentAndOnLine  必须 为 false 并且  stopWaitTimeCnt  必须等于 0

    如果不满足上述条件、那么 您的回答是正确的、因为该 reartMotorControl (handle)将无法调用、至少在您共享的函数中是如此。

    关于 是否 调用 resetMotorControl 的问题、只要  flagRunIdentAndOnLine  等于 false、就 会调用 resetMotorControl。

    最棒的

    ~Alicia

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

    您好、Alicia、

    感谢您快速查看我的代码。

    如果该例程每1ms 调用一次

    1. flagEnableRunAndIdentify 和 flagRunIdentAndOnLine 均为 true,电机正常
    2. 所有突发过流故障、接下来的1ms 调用此函数(例程)、它跳转至第30行、并将标志 RunIdentAndOnLine 重置为 false、而第59行跳过、因为它不会同时且 stopWaitTimeCnt 仍> 0
    3. 65至81也跳过了
    4. 一直到第182行、调用 resetMotorControl


    我的问题是 、所有这些都发生在单个函数调用中、或者我没有得到它?  

    Danny

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

    尊敬的 Danny:

    如果该函数每1ms 调用一次、 则每次调用该函数时、它都会在函数内检查 if 语句中指定的条件。 如果满足条件、则执行 if 语句块中的代码。  有关 if-else if 如何工作的更详细说明、请访问以下链接。 在检查完函数中指定的所有条件并在适当时执行之后、代码将退出函数、直到下次再次调用函数时再次检查指定的条件。

    最棒的

    ~Alicia

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

    您好、Alicia、  

    感谢您 对 if else 条件的解释,但我仍然不明白...

    1. 在1ms 函数内、当检测到过流时 、flagRunIdentAndOnLine 立即 设置为 false
    2. 此时、代码仍在该函数内执行、因为没有返回以强制其退出函数
    3. 因此,它将一直持续到另一个 IF。 其他语句、说第182行(第89行至第185行)、这是对另一个 flagRunIdentAndOnLine 检查的独立检查。

    这是我的最后一个要求,希望你能帮助解释,抱歉!

    Danny

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

    尊敬的 Danny:

    举个例子,假设该函数(runMotor1Control())当前正在运行, 目前,flagRunIdentAndOnLine 为 true。 代码已将其置于第89行以评估 IF 语句、此时该语句为 true、因此该 if 语句块中的代码开始执行。 此时、假设检测到过流、因此 、由于某些中断例程、flagRunIdentAndOnLine  会立即设置 为 false。 由于第89行已经被评估为 true,  并且没有任何内容导致函数(runMotor1Control())作为一个整体在检测到标志更改时重新启动,因此第89行至180行将继续执行。 但是、下次调用此函数时、如果仍然将 flagRunIdentAndOnLine  设置 为 false、则第89行将返回 false、第182至185行将运行、而不是第89至180行。

    希望这种解释有所帮助。 如果不是,请随时告诉我在哪里可能会出现混乱,以便我能够作出澄清。

    最棒的

    ~Alicia

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

    您好、Alicia、

    再次感谢您的解释,我仍然对流程有一些疑问...

    [引用 userid="451598" URL"~/support/motor-drivers-group/motor-drivers/f/motor-drivers-forum/1189718/boostxl-drv8323rh-universal_motorcontrol_lab-resetmotorcontrol-or-restartmotorcontrol-when-fault-occurred/4485774 #4485774"]现在、假设检测到过流、因此由于某些中断例程、 flagRunIdentAndOnLine  会立即设置 为 false。 由于第89行已经被评估为 true,  并且没有任何内容导致函数(runMotor1Control())作为一个整体在检测到标志更改时重新启动,因此第89行至180行将继续执行。 但是、下次调用此函数时、如果 flagRunIdentAndOnLine  仍 设置 为 false、则第89行将返回 false、第182至185行将运行、而不是第89至180行。

    问题:

    1.这假设在第89到180行中执行代码时发生过流?  

    [引用 userid="451598" URL"~/support/motor-drivers-group/motor-drivers/f/motor-drivers-forum/1189718/boostxl-drv8323rh-universal_motorcontrol_lab-resetmotorcontrol-or-restartmotorcontrol-when-fault-occurred/4485774 #4485774"] flagRunIdentAndOnLine  会立即设置 为 false

    2. 我的理解是发生了过流, FaultMtrNow 变为  第34行,将  flagRunIdentAndOnLine 更改为 false

    基于上述流程,我的问题是,如果在 runMotor1Control()函数之前发生过流,如果发生过流,代码执行第34行并退出第28至81行,然后继续进入第89至185行,因为 现在将 flagRunIdentAndOnLine 设置为 false,以便 执行 resetMotorControl()

    这是我的理解 ,除非发生过流,否则系统调用 resetMotorControl 而不是 restartMotorControl()?  

    或者,您能告诉我何时执行了 RestartMotorControl 吗? (我的理解是过流->复位故障标志-> 重新启动电机

     

    抱歉!  

    Danny

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

    尊敬的 Danny:

    [引用 userid="544862" URL"~/support/motor-drivers-group/motor-drivers/f/motor-drivers-forum/1189718/boostxl-drv8323rh-universal_motorcontrol_lab-resetmotorcontrol-or-restartmotorcontrol-when-fault-occurred/4486379 #4486379]2.  我的理解是发生了过流、 FaultMtrNow 变为 第 34行 、将 flagRunIdentAndOnLine 更改为 false

    您是正确的、对于这种混乱感到歉意。

    [引用 userid="544862" URL"~/support/motor-drivers-group/motor-drivers/f/motor-drivers-forum/1189718/boostxl-drv8323rh-universal_motorcontrol_lab-resetmotorcontrol-or-restartmotorcontrol-when-fault-occurred/4486379 #4486379"]这是我的理解, 除非发生过流,否则系统调用 resetMotorControl 而不是 restartMotorControl()?  [/报价]

    根据  runMotor1Control()函数,如果发生过流情况,则会抛出故障,导致系统调用 resetMotorControl 函数。  直到 导致过流的故障条件以及可能发生的任何其他故障被清除并且不存在故障、才能调用 RestartMotorControl。

    最棒的

    ~Alicia  

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

    您好、Alicia、

    在2023/01/30上编辑  

    我再次查看了该功能,就像 检测到过流时一样:  

    1.跳转至第34行 设置为 flagRunIdentAndOnLine = false
    2.在该函数内的同一1ms 内、跳转至线路184 resetMotorControl 以重置电机
    3.接下来的1ms, 当 stopWaitTimeCnt 仍然大于0时,它将保持跳转至线路184复位电机  
    4. 当 stopWaitTimeCnt 为0时,跳转至第51行 清除标志 ClearFault=1  
    5.接下来的1ms、faultMtrUse.all = 0、跳转至第61行以重新启动电机  

    所有工作流程、如检测到故障时、在重新启动电机之前重置电机!!!!

    谢谢、

    Danny

    [引用 userid="451598" URL"~/support/motor-drivers-group/motor-drivers/f/motor-drivers-forum/1189718/boostxl-drv8323rh-universal_motorcontrol_lab-resetmotorcontrol-or-restartmotorcontrol-when-fault-occurred/4487257 #4487257">根据  runMotor1Control()函数,如果发生过流情况,则会引发故障,导致系统调用 resetMotorControl 函数。  除非 导致过流的故障条件以及可能发生的任何其他故障被清除并且不存在故障、否则不会调用 RestartMotorControl。[/QUERPLET]

    但是...

    [报价 userid="451598" URL"~/support/motor-drivers-group/motor-drivers/f/motor-drivers-forum/1189718/boostxl-drv8323rh-universal_motorcontrol_lab-resetmotorcontrol-or-restartmotorcontrol-when-fault-occurred/4487257 #4487257"]已清除,且不存在任何故障

    故障在51号线上清除。

    让我们重点关注第30至62行、该行用于处理故障以及是否调用了重新启动

    我的理解是:  

    • 当检测到过流时,第11行指定 faultMtrUse.all!= 0
    • 然后进入第30行,因为 faultMtrUse.all!= 0
    • flagRunIdentAndOnLine = false、为 stopWaitTimeCnt 分配2000 (以5ms 间隔减少此函数之外的计数)
    • 在第40行,如果 flagEnableRestart 为 false,则将 flagEnableRunAndIdentify 分配 为 false,使系统需要手动重新启动(不需要将 flagEnableRunAndIdentify 重置 true)
    • 接下来的1ms 将调用该函数/子例程、 faultMtrUse.all still!= 0,因为没有复位它,所以使用 flagRunIdentAndOnLine 仍然为 false,现在进入第47行并比较 stopWaitTimeCnt 值,因为 stopWaitTimeCnt 仍在5ms 间隔之外减少,所以系统仍然保持 flagRunIdAndOnLine = false,motorState = motor_FAULT_stop……
    • 此函数继续调用、这次将 stopWaitTimeCnt 减少到0、现在进入第49行、ClearFlagFosucs = 1
    • 之前的1ms 调用、flagClearFaults = 1、线路20被调用、faultMtrNow。全部被清除
    • 当 faultMtrNow.all = 0时、现在第59行被调用(否则 faultMtrUse.all!= 0)、这样才能使 restartMotorControl 恢复

    显然基于上述工作流程

    • stopWaitTimeCnt 用于控制系统调用 RestartMotor 的时间或延迟时间
    • FlagEnableRestart 标志用于确定是否可以重新启动系统
    • RESartTimesCnt 计数器用于确定可以重置多少个时间系统故障、以及可以重新启动系统

    如果您同意上述工作流程、我们可以将焦点重新调整到第182行条件、其中 一旦  RunflagIdentAndOnLine 设置为 false、resetMotorControl 就会立即调用

    感谢您的帮助 Alicia!  

    Danny