CANopen 某志驱动器, 撞击掉使能恢复正常状态

📅 2026/7/16 10:24:50
CANopen 某志驱动器, 撞击掉使能恢复正常状态
CANopen 某志驱动器, 撞击掉使能恢复正常状态前言数据手册介绍控制状态机 0x6040轮廓位置模式调试过程的怀点绝对位置模式下执行到指定位置相对位置模式下执行到指定位置撞击后自动复位处理函数电机清故障码清警告码个人分析AI协助分析为什么第二次必失败快速验证方法修改之后代码“完美解决-无论多少次撞击掉使能都恢复正常状态”总结一、整体流程(4 大步骤)二、逐步骤指令明细(你代码真实执行顺序)前言在自动化设备调试中,我们经常会遇到这样的场景:设备发生撞机保护后,第一次复位一切正常;但第二次撞机后,电机就再也使能不上了。最近在某志CANopen 驱动器的摆臂轴调试中就遇到了这个问题。撞击掉使能后,上位机下发恢复指令,下位机执行回原流程,但摆臂电机始终无法进入Operation Enabled状态。抓包发现状态字死死卡在0x0008。本文将完整复盘这次排查过程,重点解析CiA402 标准状态机与厂商自定义寄存器(0x200B/0x2006)混用带来的致命陷阱,并给出经过验证的非阻塞式清故障+使能代码模板。数据手册介绍控制状态机 0x6040轮廓位置模式调试过程的怀点以下为绝对位置模式和归零模式的代码,当时怀疑过有问题,但是第一次能够正常运行,为什么第二次不能正常的执行了呢?绝对位置模式下执行到指定位置/* 绝对位置模式下执行到指定位置*/voidAxis_Run_inABPositionMode(Axis_Var*Axis,uint32_tProfileVelocity,int32_tTargetPosition){switch(Axis-RunState){case0://增加这个步骤是为了Axis-RunState++;break;case1:Axis-i32TargetPosition=TargetPosition;Axis-u32ProfileVelocity=ProfileVelocity;Axis-RunState++;break;case2:Axis-i8Mode=0x01;Axis-u16ControlWord=0x1F;Axis-RunState++;break;case3:Axis-u16ControlWord=0x0F;Axis-RunState++;break;case4:/* 给电机一个状态变化的时间*/if(++Axis-RunTimes=50){Axis-RunTimes=0;Axis-RunState++;}break;case5:if(((Axis-u16DSPStatus(13))3)(abs(Axis-i32ActualPosition-Axis-i32TargetPosition)1000));/* 到位*/elseif((Axis-u16DSPStatus(19))9);/* 堵转*/elsereturn;Axis-RunState++;break;case6:Axis-RunState=RUN_FINISH;break;default:break;}}相对位置模式下执行到指定位置/* 相对位置模式下执行到指定位置*/voidAxis_Run_inRLPositionMode(Axis_Var*Axis,uint32_tProfileVelocity,int32_tTargetPosition){switch(Axis-RunState){case0:Axis-i32TargetPosition=TargetPosition;Axis-u32ProfileVelocity=ProfileVelocity;Axis-RunState++;break;case1:Axis-i8Mode=0x01;Axis-u16ControlWord=0x5F;Axis-RunState++;break;case2:Axis-u16ControlWord=0x4F;Axis-RunState++;break;case3:/* 1S间隔*/if(++Axis-RunTimes=100){Axis-RunTimes=0;Axis-RunState++;}break;case4:/* 到位判断*/if((Axis-u16DSPStatus(13))3);elsereturn;Axis-RunState++;break;case5:Axis-RunState=RUN_FINISH;break;default:break;}}撞击后自动复位处理函数voidSystem_rehome(void){staticuint8_trehome_state=0;static_Axis_ AxisID=_Axis_Y;staticuint16_ttimes=0,errtimes=0,cnt=0,rehometimes=0;//计数器if(++cnt20)return;cnt=0;switch(rehome_state){case0:if(1==Axis_ClearFault(AxisID)){rehome_state++;}break;case1:if(1==Axis_ClearWarnig(AxisID)