#define _IN_MOVECTRL_C #include "movectrl.h" //---------------------------------------------------------------------------------------------------- #include "delay.h" #include "trigger.h" #include "inout.h" #include "shell.h" #include "error.h" #include "workctrl.h" #ifndef IsStopButton #define IsStopButton GetInputNullOff #endif //---------------------------------------------------------------------------------------------------- __weak void NormalRefPosition(u32 para, s32 * posilist) { } //---------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------- // 紧急停止 int GetCommonEms(void) { int err = ERR_NONE; TasksWhenDelay(); return err; } // 快速停止 int GetCommonQStop(void) { int err = ERR_NONE; return err; } // 普通停止 int GetCommonNStop(void) { int err = ERR_NONE; #if (0) if (err == ERR_NONE && IsConsoleCancel() != 0 && // 终端输入停止 1 ) { printf("get console cancel\r\n"); err = STA_NORMAL_STOP; } #endif #if (1) if (err == ERR_NONE && IsStopButton() == SENSOR_ON && // 检测暂停按钮按下 1 ) { printf("get stop button down\r\n"); err = STA_NORMAL_STOP; } #endif return err; } //---------------------------------------------------------------------------------------------------- // 周期性运动的零位检测(归零) #if (1) #define ADJ_RUN_MVMT(cm) ((cm)*3) #define ADJ_FAN_MVMT(cm) ((cm)*36/360) #define CANC_MVMT(cm) ((cm)*288/360) #define ADJ_WAVE_MVMT(cm) ((cm)*10/360) #define ADJ_WVC_MVMT(cm) ((cm)*1/360) // 急停控制 int RSensorEmsScan(u32 para1, u32 para2) { int rslt = GetCommonEms(); return rslt; } // 快速停止控制 int RSensorQStopScan(u32 para1, u32 para2) { int rslt; RSenserCheck * pchk; rslt = GetCommonQStop(); if (rslt != ERR_NONE) { return rslt; } pchk = (RSenserCheck *)para1; if (pchk == NULL) { return STA_NORMAL_STOP; } if (pchk->zeroflag == 0) // 如果没有经过传感器位置 { pchk->cansflag = 0; if (pchk->sensorscan != NULL) { if (pchk->sensorscan() == pchk->val) // 检测到传感器位置 { // printf("1. first in sensor area when run\r\n"); pchk->zeroflag = 1; // 设置经过传感器标志 pchk->canscount = g_motosPara.motosPos[pchk->axisIdx]; } } } else { if (pchk->cansflag == 0) // 如果没有跳过传感器位置 { if (pchk->sensorscan != NULL) { if (pchk->sensorscan() != pchk->val) // 检测非传感器位置 { if (abs(g_motosPara.motosPos[pchk->axisIdx] - pchk->canscount) > pchk->cansmvmt) { // printf("1. first out zero area when run\r\n"); pchk->cansflag = 1; } } } } else { if (pchk->sensorscan != NULL) { if (pchk->sensorscan() == pchk->val) // 检测传感器位置 { // printf("1. in sensor area when run\r\n"); rslt = STA_NORMAL_STOP; } } } } return rslt; } // 普通停止控制 int RSensorNStopScan(u32 para1, u32 para2) { int rslt; rslt = GetCommonNStop(); if (rslt != ERR_NONE) { return rslt; } return rslt; } //------------------------------------------------------------------ // 控制流程,运动到传感器 int RoundRunToSensor(RSenserCheck * pck) { return RoundRunToSensorBase(pck, 0); } // 运动到传感器边缘 int RoundRunToSensorEdge(RSenserCheck * pck) { return RoundRunToSensorBase(pck, 1); } // 运动到传感器中心 int RoundRunToSensorCenter(RSenserCheck * pck) { return RoundRunToSensorBase(pck, 2); } // 控制流程 // flag,找零成功后转动到哪个位置 0,无动作 1,转动到边缘位置 2,转动到中心位置 int RoundRunToSensorBase(RSenserCheck * pck, int flag) { int rslt, err, i; InterMoveCtrl lmctrl; u16 axisIdx; u32 interLong; if (pck == NULL) { return -1; } axisIdx = pck->axisIdx; assert_param(axisIdx < AXIS_NUM); memset(&lmctrl, 0, sizeof(InterMoveCtrl)); lmctrl.vAxisId = pck->vAxisId; // 使用虚轴 lmctrl.motosConfig.newConfig = pck->newCfg; // 需要更新电机配置 pck->cansmvmt = CANC_MVMT(pck->circleNum); if (1 && pck->newCfg == 0 && pck->syncflag != 0 && 1 ) { for (i = 0; i < AXIS_NUM; i++) { if (pck->syncList[i] != 0) { lmctrl.mvmtPara.movement[i] = ADJ_RUN_MVMT(pck->circleNum); } } } else { lmctrl.motosConfig.axisConfig[axisIdx].axisConfig = pck->axisCfg; // 实轴输出配置 lmctrl.motosConfig.axisConfig[axisIdx].poutType = pck->axisOtp; // 脉冲输出模式(CW/CCW,PULSE/DIR) lmctrl.motosConfig.axisConfig[axisIdx].spdSource = MAKE_POUT_CMD(lmctrl.vAxisId); // 实轴速度控制模式(虚轴1,虚轴2,虚轴3,编码器) lmctrl.motosConfig.axisConfig[axisIdx].datSource = DATI_INTERPOLATION; // 实轴数据获取模式(硬件插补,编码器随动,编码器映射) lmctrl.mvmtPara.movement[axisIdx] = ADJ_RUN_MVMT(pck->circleNum); // 各个轴的运动量,0,无运动;其他,运动长度,单位p } interLong = abs(ADJ_RUN_MVMT(pck->circleNum)); lmctrl.mvmtPara.extraRepeat = 0; // 延续重复次数 lmctrl.mvmtPara.interLong = interLong; // 插补长轴位移,必须大于或等于movement分量中的最大值 lmctrl.mvmtPara.pulsePerSegment = abs(pck->circleNum); // 每段脉冲数 // 速度控制参数 lmctrl.spdPara.startPPS = pck->rspd.stspSpd; // 启动速度 lmctrl.spdPara.stopPPS = pck->rspd.stspSpd; // 停止速度 lmctrl.spdPara.runPPS = pck->rspd.runSpd; // 运行速度 lmctrl.spdPara.slowPPS = pck->rspd.runSpd; // 降速速度 lmctrl.spdPara.addPPSG = pck->rspd.spdAdd; // 升速加速度 lmctrl.spdPara.decPPSG = pck->rspd.spdAdd; // 降速加速度 lmctrl.spdPara.brkPPSG = pck->rspd.brkAdd; // 刹车加速度 lmctrl.stopMode = STOP_MODE_SPD; // 停止运动方式 // 回调函数及参数 lmctrl.Delay = DelayRef; // 延时回调函数 lmctrl.RefreshPosition = NormalRefPosition; // 坐标刷新回调函数 lmctrl.refPosPara = 0; // 坐标刷新参数 lmctrl.WorkBeforeRun = NULL; // 运行前工作回调函数 lmctrl.WorkAfterRun = NULL; // 运行后工作回调函数 lmctrl.workPara1 = 0; lmctrl.workPara2 = 0; // 工作参数 lmctrl.GetSlowDown = NULL; // 慢速运动条件函数,当为空时,不检测降速条件; 不为空时,条件满足,速度降低,条件消失,速度恢复 lmctrl.GetNormalStop = RSensorNStopScan; // 一般停止条件函数,当为空时,不检测停止条件; 不为空时,条件满足,降速到停止(按降速加速度) lmctrl.GetQuickStop = RSensorQStopScan; // 快速停止条件函数,当为空时,不检测停止条件; 不为空时,条件满足,降速到停止(按刹车加速度) lmctrl.GetEmergencyStop = RSensorEmsScan; // 紧急停止条件函数,当为空时,不检测急停条件; 不为空时,条件满足,立刻停止发送脉冲(无需降速) lmctrl.condPara1 = (u32)(pck);; lmctrl.condPara2 = 0; // 条件函数参数 rslt = InterpolationMotion(&lmctrl); // 运动控制 if (rslt == 3) // 条件停车 { DelayRef(100); // 等待机械稳定 // 重新检查传感器位置 if (pck->sensorscan != NULL) { if (pck->sensorscan() != pck->val) // 如果传感器不在位置,那么反向慢速转动到位置 { printf("not at sensor\r\n"); if ( pck->newCfg == 0 && pck->syncflag != 0 ) { for (i = 0; i < AXIS_NUM; i++) { if (pck->syncList[i] != 0) { lmctrl.mvmtPara.movement[i] = ADJ_FAN_MVMT(pck->circleNum)*(-1); } } } else { lmctrl.mvmtPara.movement[axisIdx] = ADJ_FAN_MVMT(pck->circleNum)*(-1); } lmctrl.motosConfig.newConfig = 0; rslt = InterpolationMotion(&lmctrl); // 运动控制 } } } err = GetMoveResultError(rslt, lmctrl.errInfo); #if (1) if (flag != 0) { // 摆动找到中心位置 if ((err == STA_NORMAL_STOP || err == ERR_NONE) && pck->sensorscan() == pck->val && // 在传感器位置 1 ) { // printf("move to edge\r\n"); int gapcount, pcount; // 取反 if (pck->val == SENSOR_ON) { pck->val = SENSOR_OFF; } else { pck->val = SENSOR_ON; } // 速度控制参数,使用慢速速度 lmctrl.spdPara.startPPS = pck->rspd.stspSpd/2; // 启动速度 lmctrl.spdPara.stopPPS = pck->rspd.stspSpd/2; // 停止速度 lmctrl.spdPara.runPPS = pck->rspd.runSpd/2; // 运行速度 lmctrl.spdPara.slowPPS = pck->rspd.runSpd/2; // 降速速度 lmctrl.spdPara.addPPSG = pck->rspd.spdAdd; // 升速加速度 lmctrl.spdPara.decPPSG = pck->rspd.spdAdd; // 降速加速度 lmctrl.spdPara.brkPPSG = pck->rspd.brkAdd; // 刹车加速度 if ( pck->newCfg == 0 && pck->syncflag != 0 ) { for (i = 0; i < AXIS_NUM; i++) { if (pck->syncList[i] != 0) { lmctrl.mvmtPara.movement[i] = ADJ_FAN_MVMT(pck->circleNum)*(-1); } } } else { lmctrl.mvmtPara.movement[axisIdx] = ADJ_FAN_MVMT(pck->circleNum)*(-1); } pck->cansflag = 0; pck->cansmvmt = ADJ_WVC_MVMT(pck->circleNum); lmctrl.motosConfig.newConfig = 0; rslt = InterpolationMotion(&lmctrl); // 运动控制, 运动到边缘 err = GetMoveResultError(rslt, lmctrl.errInfo); #if (1) if (flag == 2) { if ((err == STA_NORMAL_STOP || err == ERR_NONE) && pck->sensorscan() == pck->val && 1 ) { pcount = GetMotoCounter(axisIdx); // 读取位置 // 正向 if ( pck->newCfg == 0 && pck->syncflag != 0) { for (i = 0; i < AXIS_NUM; i++) { if (pck->syncList[i] != 0) { lmctrl.mvmtPara.movement[i] = ADJ_FAN_MVMT(pck->circleNum); } } } else { lmctrl.mvmtPara.movement[axisIdx] = ADJ_FAN_MVMT(pck->circleNum); } pck->cansflag = 0; pck->cansmvmt = ADJ_WVC_MVMT(pck->circleNum); rslt = InterpolationMotion(&lmctrl); // 运动控制, 运动到另外的边缘 err = GetMoveResultError(rslt, lmctrl.errInfo); if ((err == STA_NORMAL_STOP || err == ERR_NONE) && pck->sensorscan() == pck->val && 1 ) { gapcount = abs(GetMotoCounter(axisIdx) - pcount); // 读取位置 gapcount /= 2; if (gapcount != 0) { if ( pck->newCfg == 0 && pck->syncflag != 0 ) { for (i = 0; i < AXIS_NUM; i++) { if (pck->syncList[i] != 0) { lmctrl.mvmtPara.movement[i] = gapcount*(-1); } } } else { lmctrl.mvmtPara.movement[axisIdx] = gapcount*(-1); } lmctrl.GetNormalStop = NULL; // 一般停止条件函数,当为空时,不检测停止条件; 不为空时,条件满足,降速到停止(按降速加速度) lmctrl.GetQuickStop = NULL; // 快速停止条件函数,当为空时,不检测停止条件; 不为空时,条件满足,降速到停止(按刹车加速度) lmctrl.stopMode = STOP_MODE_TAB; // 停止运动方式 lmctrl.spdPara.startPPS = pck->rspd.runSpd; // 启动速度 lmctrl.spdPara.stopPPS = pck->rspd.runSpd; // 停止速度 lmctrl.spdPara.runPPS = pck->rspd.runSpd; // 运行速度 rslt = InterpolationMotion(&lmctrl); // 运动控制 err = GetMoveResultError(rslt, lmctrl.errInfo); } } } } #endif } } #endif return err; } //------------------------------------------------------------------ // 急停控制 int RMotoRunEmsScan(u32 para1, u32 para2) { RMotoRun * pmr; int rslt = GetCommonEms(); pmr = (RMotoRun *)para1; if (pmr->RRunProc != NULL) { pmr->RRunProc(); } return rslt; } // 快速停止控制 int RMotoRunQStopScan(u32 para1, u32 para2) { int rslt; rslt = GetCommonQStop(); if (rslt != ERR_NONE) { return rslt; } return rslt; } // 普通停止控制 int RMotoRunNStopScan(u32 para1, u32 para2) { int rslt; rslt = GetCommonNStop(); if (rslt != ERR_NONE) { return rslt; } return rslt; } // 按偏移量运动 int RoundRunAsOffset(RMotoRun * pmr) { int rslt, err, i; InterMoveCtrl lmctrl; int axisIdx; int movmt; if (pmr == NULL) { return ERR_MV_PARA; } movmt = 0; memset(&lmctrl, 0, sizeof(InterMoveCtrl)); lmctrl.vAxisId = pmr->vAxisId; // 使用虚轴 lmctrl.motosConfig.newConfig = pmr->newCfg; // 需要更新电机配置 for (i = 0; i < AXIS_NUM; i++) { axisIdx = pmr->config[i].axisIdx; if (axisIdx >= 0) { assert_param(axisIdx < AXIS_NUM); lmctrl.motosConfig.axisConfig[axisIdx].axisConfig = pmr->config[i].axisCfg; // 实轴输出配置 lmctrl.motosConfig.axisConfig[axisIdx].poutType = pmr->config[i].poutType; // 脉冲输出模式(CW/CCW,PULSE/DIR) lmctrl.motosConfig.axisConfig[axisIdx].spdSource = MAKE_POUT_CMD(lmctrl.vAxisId); // 实轴速度控制模式(虚轴1,虚轴2,虚轴3,编码器) lmctrl.motosConfig.axisConfig[axisIdx].datSource = DATI_INTERPOLATION; // 实轴数据获取模式(硬件插补,编码器随动,编码器映射) lmctrl.mvmtPara.movement[axisIdx] = pmr->config[i].movement; // 各个轴的运动量,0,无运动;其他,运动长度,单位p if (pmr->config[i].movement != 0) { movmt = pmr->config[i].movement; } } } // printf("round run as offset, movmt=%d\r\n", movmt); if (movmt == 0) // 无运动量 { return ERR_NONE; } lmctrl.mvmtPara.extraRepeat = pmr->mrepeat; // 延续重复次数 lmctrl.mvmtPara.interLong = pmr->interLong; // 插补长轴位移,必须大于或等于movement分量中的最大值 lmctrl.mvmtPara.pulsePerSegment = pmr->segmentNum; // 每段脉冲数 // 速度控制参数 lmctrl.spdPara.startPPS = pmr->rspd.stspSpd; lmctrl.spdPara.stopPPS = pmr->rspd.stspSpd; lmctrl.spdPara.slowPPS = pmr->rspd.stspSpd; lmctrl.spdPara.runPPS = pmr->rspd.runSpd; lmctrl.spdPara.addPPSG = pmr->rspd.spdAdd; lmctrl.spdPara.decPPSG = pmr->rspd.spdAdd; lmctrl.spdPara.brkPPSG = pmr->rspd.brkAdd; // 停止加速度 lmctrl.stopMode = STOP_MODE_TAB; // 停止运动方式 // 回调函数及参数 lmctrl.Delay = DelayRef; // 延时回调函数 lmctrl.RefreshPosition = NormalRefPosition; // 坐标刷新回调函数 lmctrl.refPosPara = 0; // 坐标刷新参数 lmctrl.WorkBeforeRun = NULL; // 运行前工作回调函数 lmctrl.WorkAfterRun = NULL; // 运行后工作回调函数 lmctrl.workPara1 = 0; lmctrl.workPara2 = 0; // 工作参数 lmctrl.GetSlowDown = NULL; // 慢速运动条件函数,当为空时,不检测降速条件; 不为空时,条件满足,速度降低,条件消失,速度恢复 if (pmr->escStop != 0) { // printf("stop condition is null\r\n"); lmctrl.GetNormalStop = NULL; lmctrl.GetQuickStop = NULL; } else { // printf("stop condition is r move stop\r\n"); lmctrl.GetNormalStop = RMotoRunNStopScan; // 一般停止条件函数,当为空时,不检测停止条件; 不为空时,条件满足,降速到停止(按降速加速度) lmctrl.GetQuickStop = RMotoRunQStopScan; // 快速停止条件函数,当为空时,不检测停止条件; 不为空时,条件满足,降速到停止(按刹车加速度) } lmctrl.GetEmergencyStop = RMotoRunEmsScan; // 紧急停止条件函数,当为空时,不检测急停条件; 不为空时,条件满足,立刻停止发送脉冲(无需降速) lmctrl.condPara1 = (u32)(pmr);; lmctrl.condPara2 = 0; // 条件函数参数 rslt = InterpolationMotion(&lmctrl); // 运动控制 err = GetMoveResultError(rslt, lmctrl.errInfo); return err; } #endif //---------------------------------------------------------------------------------------------------- #if (1) // 急停检测 int MoveToSensorEmsScan(u32 para1, u32 para2) { int rslt; MTSCtrl * pmts; pmts = (MTSCtrl*)(para1); rslt = GetCommonEms(); if (rslt != ERR_NONE || pmts == NULL) { return rslt; } if (pmts->emcstopscan != NULL) { rslt = pmts->emcstopscan(); } if (rslt != ERR_NONE) { return rslt; } if (pmts->movement > 0) { if (pmts->limitpsensor != NULL) // 检测正向限位 { if (pmts->limitpsensor() == SENSOR_ON) { rslt = ERR_LMT_POSITIVE; // 正向限位 } } } else if (pmts->movement < 0) { if (pmts->limitnsensor != NULL) // 检测反向限位 { if (pmts->limitnsensor() == SENSOR_ON) { rslt = ERR_LMT_NEGATIVE; // 反向限位 } } } else { rslt = ERR_MTZ_ERROR; // 归零错误 } return rslt; } // 普通停止检测 int MoveToSensorNStopScan(u32 para1, u32 para2) { int rslt; MTSCtrl * pmts; pmts = (MTSCtrl*)(para1); rslt = GetCommonNStop(); if (rslt != ERR_NONE || pmts == NULL) { return rslt; } return rslt; } // 快速停止检测 int MoveToSensorQStopScan(u32 para1, u32 para2) { int rslt; MTSCtrl * pmts; pmts = (MTSCtrl*)(para1); rslt = GetCommonQStop(); if (rslt != ERR_NONE || pmts == NULL) { return rslt; } if (rslt == ERR_NONE) { if (pmts->zerosensor != NULL) // 检测零位 { if (pmts->zerosensor() == pmts->zeroval) { rslt = STA_MTZ_SUCCESS; // 归零成功 } } } return rslt; } // 降速检测 int MoveToSensorSlowScan(u32 para1, u32 para2) { int rslt; MTSCtrl * pmts; pmts = (MTSCtrl*)(para1); rslt = 0; if (pmts != NULL) { if (pmts->slowsensor != NULL) // 检测降速 { if (pmts->slowsensor() == SENSOR_ON) { pmts->slowsta = 1; } } } rslt = pmts->slowsta; // 降速状态 return rslt; } //------------------------------------------------ // 直线运动到传感器 int LineRunToSensorCtrl(MTSCtrl * pmtsc) { int rslt, err, poismv; InterMoveCtrl lmctrl; u16 axisIdx; int i; if (pmtsc == NULL) { return -1; } axisIdx = pmtsc->axisIdx; assert_param(axisIdx < AXIS_NUM); memset(&lmctrl, 0, sizeof(InterMoveCtrl)); lmctrl.vAxisId = pmtsc->vAxisId; // 使用虚轴 lmctrl.motosConfig.newConfig = pmtsc->newCfg; // 需要更新电机配置 if ( pmtsc->newCfg == 0 && pmtsc->syncflag != 0) { for (i = 0; i < AXIS_NUM; i++) { if (pmtsc->syncList[i] != 0) { lmctrl.mvmtPara.movement[i] = pmtsc->movement; // 各个轴的运动量,0,无运动;其他,运动长度,单位p } } } else { lmctrl.motosConfig.axisConfig[axisIdx].axisConfig = pmtsc->axisCfg; // 实轴输出配置 lmctrl.motosConfig.axisConfig[axisIdx].poutType = pmtsc->poutType; // 脉冲输出模式(CW/CCW,PULSE/DIR) lmctrl.motosConfig.axisConfig[axisIdx].spdSource = MAKE_POUT_CMD(lmctrl.vAxisId); // 实轴速度控制模式(虚轴1,虚轴2,虚轴3,编码器) lmctrl.motosConfig.axisConfig[axisIdx].datSource = DATI_INTERPOLATION; // 实轴数据获取模式(硬件插补,编码器随动,编码器映射) lmctrl.mvmtPara.movement[axisIdx] = pmtsc->movement; // 各个轴的运动量,0,无运动;其他,运动长度,单位p } lmctrl.mvmtPara.extraRepeat = 0; // 延续重复次数 lmctrl.mvmtPara.interLong = abs(pmtsc->movement); // 插补长轴位移,必须大于或等于movement分量中的最大值 lmctrl.mvmtPara.pulsePerSegment = PULSE_PER_SEGMENT; // 每段脉冲数 // 速度控制参数 lmctrl.spdPara.startPPS = pmtsc->lspd.stspSpd; // 启动速度 lmctrl.spdPara.stopPPS = pmtsc->lspd.stspSpd; // 停止速度 lmctrl.spdPara.runPPS = pmtsc->lspd.runSpd; // 运行速度 lmctrl.spdPara.slowPPS = pmtsc->lspd.stspSpd; // 降速速度 lmctrl.spdPara.addPPSG = pmtsc->lspd.spdAdd; // 升速加速度 lmctrl.spdPara.decPPSG = pmtsc->lspd.spdAdd/2; // 降速加速度 lmctrl.spdPara.brkPPSG = pmtsc->lspd.brkAdd; // 刹车加速度 lmctrl.stopMode = STOP_MODE_SPD; // 停止运动方式 // 回调函数及参数 lmctrl.Delay = DelayRef; // 延时回调函数 lmctrl.RefreshPosition = NormalRefPosition; // 坐标刷新回调函数 lmctrl.refPosPara = 0; // 坐标刷新参数 lmctrl.WorkBeforeRun = NULL; // 运行工作回调函数 lmctrl.WorkAfterRun = NULL; // 运行后工作回调函数 lmctrl.workPara1 = 0; lmctrl.workPara2 = 0; // 工作参数 lmctrl.GetSlowDown = MoveToSensorSlowScan; // 慢速运动条件函数,当为空时,不检测降速条件; 不为空时,条件满足,速度降低,条件消失,速度恢复 lmctrl.GetNormalStop = MoveToSensorNStopScan; // 一般停止条件函数,当为空时,不检测停止条件; 不为空时,条件满足,降速到停止(按降速加速度) lmctrl.GetQuickStop = MoveToSensorQStopScan; // 快速停止条件函数,当为空时,不检测停止条件; 不为空时,条件满足,降速到停止(按刹车加速度) lmctrl.GetEmergencyStop = MoveToSensorEmsScan; // 紧急停止条件函数,当为空时,不检测急停条件; 不为空时,条件满足,立刻停止发送脉冲(无需降速) lmctrl.condPara1 = (u32)(pmtsc); lmctrl.condPara2 = 0; // 条件函数参数 // 检测条件 err = ERR_NONE; poismv = 0; #if (1) if (pmtsc->syncflag == 0) { err = MoveToSensorEmsScan(lmctrl.condPara1, lmctrl.condPara2); // 检测急停条件 if ((pmtsc->movement < 0 && err == ERR_LMT_NEGATIVE) || (pmtsc->movement > 0 && err == ERR_LMT_POSITIVE) ) // 在限位 { poismv = pmtsc->mvposi; // 反向运动 } err = MoveToSensorQStopScan(lmctrl.condPara1, lmctrl.condPara2); // 检测停止条件 if (err == STA_MTZ_SUCCESS) // 在零位位置 { poismv = pmtsc->mvposi; // 反向运动 } else if (err == ERR_NONE) { rslt = MoveToSensorSlowScan(lmctrl.condPara1, lmctrl.condPara2); // 在降速区域 if (rslt != ERR_NONE) { poismv = pmtsc->mvposi; // 反向运动 } } else { } } #endif do { // 运动 if (poismv != 0) { if (pmtsc->moveasoffset != NULL) { err = pmtsc->moveasoffset(poismv, &(pmtsc->lspd)); // 运动一段距离 } if (err == ERR_NONE) { // 重新检测 err = MoveToSensorEmsScan(lmctrl.condPara1, lmctrl.condPara2); // 检测急停条件 if (err == ERR_NONE) { err = MoveToSensorQStopScan(lmctrl.condPara1, lmctrl.condPara2); // 检测停止条件 if (err == ERR_NONE) { pmtsc->slowsta = 0; } } } } if (err == ERR_NONE) { s32 temp, val; temp = GetMotoCounter(axisIdx); // 电机位置 rslt = InterpolationMotion(&lmctrl); // 运动控制 if (poismv == 0 && (rslt == 3 || rslt == 2)) { if (rslt == 3) { err = MoveToSensorQStopScan(lmctrl.condPara1, lmctrl.condPara2); // 检测停止条件 if (err == STA_MTZ_SUCCESS && pmtsc->mvposi != 0) { val = GetMotoCounter(axisIdx); if (abs(val-temp) < abs(pmtsc->mvposi/2)) // 如果归零行走位移太小 { poismv = pmtsc->mvposi; // 反向运动 continue; // 重新执行一次归零 } } } else if (rslt == 2) { err = MoveToSensorEmsScan(lmctrl.condPara1, lmctrl.condPara2); // 检测急停条件 if ((pmtsc->movement < 0 && err == ERR_LMT_NEGATIVE) || (pmtsc->movement > 0 && err == ERR_LMT_POSITIVE) ) // 在限位 { poismv = pmtsc->mvposi; // 反向运动 continue; // 重新执行一次归零 } } } err = GetMoveResultError(rslt, lmctrl.errInfo); } break; }while(1); return err; } //------------------------------------------------ #endif //---------------------------------------------------------------------------------------------------- #if (1) // 急停检测 int MoveBHEmsScan(u32 para1, u32 para2) { int rslt; MVByHandCtrl * pmbhc; pmbhc = (MVByHandCtrl*)(para1); rslt = GetCommonEms(); if (rslt != ERR_NONE || pmbhc == NULL) { return rslt; } if (pmbhc->movement > 0) { if (pmbhc->limitpsensor != NULL) // 检测正向限位 { if (pmbhc->limitpsensor(pmbhc->para) == SENSOR_ON) { rslt = ERR_LMT_POSITIVE; // 正向限位 } } } else if (pmbhc->movement < 0) { if (pmbhc->limitnsensor != NULL) // 检测反向限位 { if (pmbhc->limitnsensor(pmbhc->para) == SENSOR_ON) { rslt = ERR_LMT_NEGATIVE; // 反向限位 } } } else { rslt = ERR_MTZ_ERROR; // 归零错误 } return rslt; } // 普通停止检测 int MoveBHNStopScan(u32 para1, u32 para2) { int rslt; MVByHandCtrl * pmbhc; pmbhc = (MVByHandCtrl*)(para1); rslt = GetCommonNStop(); if (rslt != ERR_NONE || pmbhc == NULL) { return rslt; } if (rslt == ERR_NONE && pmbhc->stopscan != NULL) { rslt = pmbhc->stopscan(pmbhc->para); } return rslt; } // 慢速检测 int MoveBHNSlowScan(u32 para1, u32 para2) { int rslt; MVByHandCtrl * pmbhc; pmbhc = (MVByHandCtrl*)(para1); rslt = ERR_NONE; if (pmbhc->slowscan != NULL) { rslt = pmbhc->slowscan(para2); } return rslt; } // 快速停止检测 int MoveBHQStopScan(u32 para1, u32 para2) { int rslt; MVByHandCtrl * pmbhc; pmbhc = (MVByHandCtrl*)(para1); rslt = GetCommonQStop(); if (rslt != ERR_NONE || pmbhc == NULL) { return rslt; } return rslt; } // 手动移动控制 int MoveByHandCtrl(MVByHandCtrl * pmbhc) { int rslt, err, i; u16 axisIdx; InterMoveCtrl lmctrl; if (pmbhc == NULL) { return ERR_NONE; } if (pmbhc->movement == 0) { return ERR_NONE; } // 先决条件和准备工作 if (pmbhc->precondition != NULL) { err = pmbhc->precondition(pmbhc->para); if (err != ERR_NONE) { return err; } } axisIdx = pmbhc->axisIdx; assert_param(axisIdx < AXIS_NUM); memset(&lmctrl, 0, sizeof(InterMoveCtrl)); lmctrl.vAxisId = pmbhc->vAxisId; // 使用虚轴 lmctrl.motosConfig.newConfig = pmbhc->newCfg; // 需要更新电机配置 if ( pmbhc->newCfg == 0 && pmbhc->syncflag != 0) { for (i = 0; i < AXIS_NUM; i++) { if (pmbhc->syncList[i] != 0) { lmctrl.mvmtPara.movement[i] = pmbhc->movement; // 各个轴的运动量,0,无运动;其他,运动长度,单位p } } } else { lmctrl.motosConfig.axisConfig[axisIdx].axisConfig = pmbhc->axisCfg; // 实轴输出配置 lmctrl.motosConfig.axisConfig[axisIdx].poutType = pmbhc->poutType; // 脉冲输出模式(CW/CCW,PULSE/DIR) lmctrl.motosConfig.axisConfig[axisIdx].spdSource = MAKE_POUT_CMD(lmctrl.vAxisId); // 实轴速度控制模式(虚轴1,虚轴2,虚轴3,编码器) lmctrl.motosConfig.axisConfig[axisIdx].datSource = DATI_INTERPOLATION; // 实轴数据获取模式(硬件插补,编码器随动,编码器映射) lmctrl.mvmtPara.movement[axisIdx] = pmbhc->movement; // 各个轴的运动量,0,无运动;其他,运动长度,单位p } lmctrl.mvmtPara.extraRepeat = 0; // 延续重复次数 lmctrl.mvmtPara.interLong = abs(pmbhc->movement); // 插补长轴位移,必须大于或等于movement分量中的最大值 lmctrl.mvmtPara.pulsePerSegment = pmbhc->ppSegment; // 每段脉冲数 // 速度控制参数 lmctrl.spdPara.startPPS = pmbhc->hspd.stspSpd; // 启动速度 lmctrl.spdPara.stopPPS = pmbhc->hspd.stspSpd; // 停止速度 lmctrl.spdPara.runPPS = pmbhc->hspd.runSpd; // 运行速度 lmctrl.spdPara.slowPPS = pmbhc->hspd.stspSpd; // 降速速度 lmctrl.spdPara.addPPSG = pmbhc->hspd.spdAdd; // 升速加速度 lmctrl.spdPara.decPPSG = pmbhc->hspd.spdAdd/2; // 降速加速度 lmctrl.spdPara.brkPPSG = pmbhc->hspd.brkAdd; // 刹车加速度 lmctrl.stopMode = STOP_MODE_SPD; // 停止运动方式 // 回调函数及参数 lmctrl.Delay = DelayRef; // 延时回调函数 lmctrl.RefreshPosition = NormalRefPosition; // 坐标刷新回调函数 lmctrl.refPosPara = 0; // 坐标刷新参数 lmctrl.WorkBeforeRun = NULL; // 运行前工作回调函数 lmctrl.WorkAfterRun = NULL; // 运行后工作回调函数 lmctrl.workPara1 = 0; lmctrl.workPara2 = 0; // 工作参数 lmctrl.GetSlowDown = MoveBHNSlowScan; // 慢速运动条件函数,当为空时,不检测降速条件; 不为空时,条件满足,速度降低,条件消失,速度恢复 lmctrl.GetNormalStop = MoveBHNStopScan; // 一般停止条件函数,当为空时,不检测停止条件; 不为空时,条件满足,降速到停止(按降速加速度) lmctrl.GetQuickStop = MoveBHQStopScan; // 快速停止条件函数,当为空时,不检测停止条件; 不为空时,条件满足,降速到停止(按刹车加速度) lmctrl.GetEmergencyStop = MoveBHEmsScan; // 紧急停止条件函数,当为空时,不检测急停条件; 不为空时,条件满足,立刻停止发送脉冲(无需降速) lmctrl.condPara1 = (u32)(pmbhc);; lmctrl.condPara2 = (u32)(pmbhc->movement<0?-1:1); // 条件函数参数 rslt = InterpolationMotion(&lmctrl); // 运动控制 err = GetMoveResultError(rslt, lmctrl.errInfo); return err; } #endif //------------------------------------------------ //------------------------------------------------------------------------------- // 单轴异步运动 // 使用STM32计算速度&发送脉冲 int SeparateExerStart(SepMoveCtrl * pCtrl) // 单轴异步运动 启动 { int rslt; MotoCtrl lmctrl; u16 axisIdx; u16 axisID; int i; if (pCtrl == NULL) { return -1; } axisIdx = pCtrl->axisIdx; assert_param(axisIdx < AXIS_NUM); memset(&lmctrl, 0, sizeof(MotoCtrl)); lmctrl.movement = pCtrl->movement; // 位移量 lmctrl.startPPS = pCtrl->startPPS; // 启动速度 lmctrl.runPPS = pCtrl->runPPS; // 运动速度 lmctrl.addPPSG = pCtrl->addPPSG; // 启停加速度 lmctrl.brkPPSG = pCtrl->brkPPSG; // 刹车加速度 lmctrl.funTestTime = pCtrl->funTestTime; // 运行过程中外部函数检测间隔时间 for (i = 0; i < 6; i++) { lmctrl.syncList[i] = pCtrl->syncList[i]; // 同步移动选择 } lmctrl.GetNormalStop = pCtrl->GetNormalStop; // 一般停止条件函数 lmctrl.GetQuickStop = pCtrl->GetQuickStop; // 快速停止条件函数 lmctrl.condPara1 = pCtrl->condPara1; // 条件函数参数 lmctrl.condPara2 = pCtrl->condPara2; // 条件函数参数 lmctrl.blockRunflag = pCtrl->blockRunflag; // 阻塞运行标志 lmctrl.ExecWhenRun = pCtrl->ExecWhenRun; // 电机运行过程中执行的函数 lmctrl.ExecWhenStart = pCtrl->ExecWhenStart; // 电机启动前执行的函数 lmctrl.ExecWhenStop = pCtrl->ExecWhenStop; // 电机停止后执行的函数 axisID = axisIdx + 1; if (pCtrl->newCfg != 0) {// 重新配置 if ((pCtrl->axisCfg & CONFIG_EN) != 0) // 配置允许 { if ((pCtrl->axisCfg & POA_EN) != 0) // A允许输出 { SetAxisConfig(axisID, POUTA_EN); } else { SetAxisConfig(axisID, POUTA_DIS); } if ((pCtrl->axisCfg & POB_EN) != 0) // B允许输出 { SetAxisConfig(axisID, POUTB_EN); } else { SetAxisConfig(axisID, POUTB_DIS); } if ((pCtrl->axisCfg & SON_EN) != 0) // 伺服ON允许 { SetAxisConfig(axisID, SERVO_ON); } else { SetAxisConfig(axisID, SERVO_OFF); } if ((pCtrl->axisCfg & ALM_LEVH) != 0) // 报警电平为高 { SetAxisAlarmConfig(axisID, ALM_LEV_HIGH); } else { SetAxisAlarmConfig(axisID, ALM_LEV_LOW); } if ((pCtrl->axisCfg & ALM_EN) != 0) // 报警停车允许 { SetAxisAlarmConfig(axisID, ALM_STOP_EN); } else { SetAxisAlarmConfig(axisID, ALM_STOP_DIS); } if ((pCtrl->axisCfg & POUT_EN) != 0) // 输出允许 { SetAxisConfig(axisID, pCtrl->poutType); // 脉冲输出模式 脉冲方式输出 } else { SetAxisConfig(axisID, POUT_DISABLE); // 禁止脉冲输出 } } } #if (STM32_MOTOS_NUM >= 1) if (((axisID == 1) || (lmctrl.syncList[1-1] == 1)) && (pCtrl->useOutPort == 0)) { SetAxisConfig(1, POUT_ENABLE_BUSIO); // 脉冲输出允许:输入为内部总线直接控制模式 SetAxisConfig(1, DATI_BUS_IO); // 内部总线直接控制模式 SetSTM32Moto1Mode(MODE_STEPDIR); // 脉冲模式为方向/脉冲形式 } #endif #if (STM32_MOTOS_NUM >= 2) if (((axisID == 2) || (lmctrl.syncList[2-1] == 1)) && (pCtrl->useOutPort == 0)) { SetAxisConfig(2, POUT_ENABLE_BUSIO); // 脉冲输出允许:输入为内部总线直接控制模式 SetAxisConfig(2, DATI_BUS_IO); // 内部总线直接控制模式 SetSTM32Moto2Mode(MODE_STEPDIR); // 脉冲模式为方向/脉冲形式 } #endif #if (STM32_MOTOS_NUM >= 3) if (((axisID == 3) || (lmctrl.syncList[3-1] == 1)) && (pCtrl->useOutPort == 0)) { SetAxisConfig(3, POUT_ENABLE_BUSIO); // 脉冲输出允许:输入为内部总线直接控制模式 SetAxisConfig(3, DATI_BUS_IO); // 内部总线直接控制模式 SetSTM32Moto3Mode(MODE_STEPDIR); // 脉冲模式为方向/脉冲形式 } #endif #if (STM32_MOTOS_NUM >= 4) if (((axisID == 4) || (lmctrl.syncList[4-1] == 1)) && (pCtrl->useOutPort == 0)) { SetAxisConfig(4, POUT_ENABLE_BUSIO); // 脉冲输出允许:输入为内部总线直接控制模式 SetAxisConfig(4, DATI_BUS_IO); // 内部总线直接控制模式 SetSTM32Moto4Mode(MODE_STEPDIR); // 脉冲模式为方向/脉冲形式 } #endif #if (STM32_MOTOS_NUM >= 5) if (((axisID == 5) || (lmctrl.syncList[5-1] == 1)) && (pCtrl->useOutPort == 0)) { SetAxisConfig(5, POUT_ENABLE_BUSIO); // 脉冲输出允许:输入为内部总线直接控制模式 SetAxisConfig(5, DATI_BUS_IO); // 内部总线直接控制模式 SetSTM32Moto5Mode(MODE_STEPDIR); // 脉冲模式为方向/脉冲形式 } #endif #if (STM32_MOTOS_NUM >= 6) if (((axisID == 6) || (lmctrl.syncList[6-1] == 1)) && (pCtrl->useOutPort == 0)) { SetAxisConfig(6, POUT_ENABLE_BUSIO); // 脉冲输出允许:输入为内部总线直接控制模式 SetAxisConfig(6, DATI_BUS_IO); // 内部总线直接控制模式 SetSTM32Moto6Mode(MODE_STEPDIR); // 脉冲模式为方向/脉冲形式 } #endif switch (axisIdx) { #if (STM32_MOTOS_NUM >= 1) case 0: rslt = STM32Moto1Start(&lmctrl); break; #endif #if (STM32_MOTOS_NUM >= 2) case 1: rslt = STM32Moto2Start(&lmctrl); break; #endif #if (STM32_MOTOS_NUM >= 3) case 2: rslt = STM32Moto3Start(&lmctrl); break; #endif #if (STM32_MOTOS_NUM >= 4) case 3: rslt = STM32Moto4Start(&lmctrl); break; #endif #if (STM32_MOTOS_NUM >= 5) case 4: rslt = STM32Moto5Start(&lmctrl); break; #endif #if (STM32_MOTOS_NUM >= 6) case 5: rslt = STM32Moto6Start(&lmctrl); break; #endif default: rslt = ERR_MV_PARA; // 参数错误 break; } return rslt; } //------------------------------------------------ // 单轴异步运动 停止 int SeparateExerStop(u16 axisIdx) { int rslt; assert_param(axisIdx < AXIS_NUM); rslt = ERR_NONE; switch (axisIdx) { case 0: #if (STM32_MOTOS_NUM >= 1) STM32Moto1Stop(); break; #endif #if (STM32_MOTOS_NUM >= 2) case 1: STM32Moto2Stop(); break; #endif #if (STM32_MOTOS_NUM >= 3) case 2: STM32Moto3Stop(); break; #endif #if (STM32_MOTOS_NUM >= 4) case 3: STM32Moto4Stop(); break; #endif #if (STM32_MOTOS_NUM >= 5) case 4: STM32Moto5Stop(); break; #endif #if (STM32_MOTOS_NUM >= 6) case 5: STM32Moto6Stop(); break; #endif default: rslt = ERR_MV_PARA; // 参数错误 break; } return rslt; } //------------------------------------------------ int GetSeparateExerState(u16 axisIdx) // 单轴异步运动 得到当前状态 { int rslt,err; assert_param(axisIdx < AXIS_NUM); rslt = ERR_NONE; switch (axisIdx) { #if (STM32_MOTOS_NUM >= 1) case 0: rslt = GetSTM32Moto1State(); break; #endif #if (STM32_MOTOS_NUM >= 2) case 1: rslt = GetSTM32Moto2State(); break; #endif #if (STM32_MOTOS_NUM >= 3) case 2: rslt = GetSTM32Moto3State(); break; #endif #if (STM32_MOTOS_NUM >= 4) case 3: rslt = GetSTM32Moto4State(); break; #endif #if (STM32_MOTOS_NUM >= 5) case 4: rslt = GetSTM32Moto5State(); break; #endif #if (STM32_MOTOS_NUM >= 6) case 5: rslt = GetSTM32Moto6State(); break; #endif default: rslt = ERR_MV_PARA; // 参数错误 break; } if (rslt == STM32MOTO_STOP) { err = STA_PROCESS_FINISH; // 执行完成 } else { //err = STA_PROCESS_RUNNING; // 执行过程中 err = rslt; // 返回运行状态 } return err; } //------------------------------------------------ //------------------------------------------------------------------------------- // 转化为 -180--180度之间的数 void ChangeRotToNP180(s32 * pval) { while (*pval > (ROT_PULSE_PER_CIRCLE/2)) { *pval -= (s32)(ROT_PULSE_PER_CIRCLE); } while (*pval < ((s32)(ROT_PULSE_PER_CIRCLE/2) * -1)) { *pval += (s32)(ROT_PULSE_PER_CIRCLE); } } // 转化为 -360--360度之间的数 void ChangeRotToNP360(s32 * pval) { while (*pval < ((s32)(ROT_PULSE_PER_CIRCLE) * -1)) { *pval += (s32)(ROT_PULSE_PER_CIRCLE); } while(*pval > ((s32)(ROT_PULSE_PER_CIRCLE))) { *pval -= (s32)(ROT_PULSE_PER_CIRCLE); } } // 转化为 0--360度之间的数 void ChangeRotTo0To360(s32 * pval) { while (*pval < 0) { *pval += (s32)(ROT_PULSE_PER_CIRCLE); } while(*pval > ((s32)(ROT_PULSE_PER_CIRCLE))) { *pval -= (s32)(ROT_PULSE_PER_CIRCLE); } } // 转化为 -360--0度之间的数 void ChangeRotToN360To0(s32 * pval) { while (*pval > 0) { *pval -= (s32)(ROT_PULSE_PER_CIRCLE); } while (*pval < ((s32)(ROT_PULSE_PER_CIRCLE) * -1)) { *pval += (s32)(ROT_PULSE_PER_CIRCLE); } } // int GetMoveResultError(int rslt, int errinfo) { int err; switch (rslt) { case -1: // 参数错误 err = ERR_MV_PARA; break; case -2: // 填充数据错误 err = ERR_FILL_DATA; break; case -3: // FPGA读写错误 err = ERR_FPGA_RESET; // FPGA复位错误 break; case -4: // FPGA版本错误 err = ERR_FPGA_ERR; // 运动控制芯片版本错误 break; case 1: // 驱动器报警 err = ERR_DRIVER; break; case 0: // 运动执行完成 case 2: // 紧急停止条件触发停车 case 3: // 快速停止条件触发停车 case 4: // 普通停车条件触发停车 err = errinfo; break; case 5: err = ERR_FPGA_RESET; break; default: // 正常结束或其他 err = ERR_NONE; break; } return err; } //--------------------------------------------------- // 主轴角度转化 // 如果pdir == 0, 转化为 -180--180度之间的数, // 如果pdir != 0 那么转化为 0-- 360之间的数 void ChangeMsToNP180(s32 * pval, int pdir) { while (*pval < ((s32)(MS_PULSE_PER_CIRCLE/2) * -1)) { *pval += (s32)(MS_PULSE_PER_CIRCLE); } while (*pval > ((s32)(MS_PULSE_PER_CIRCLE/2))) { *pval -= (s32)(MS_PULSE_PER_CIRCLE); } if (pdir != 0) // 正向转动 { if (*pval < 0) { *pval += MS_PULSE_PER_CIRCLE; } } } void ChangeMsToNP360(s32 * pval) { *pval %= MS_PULSE_PER_CIRCLE; while (*pval < ((s32)(MS_PULSE_PER_CIRCLE) * -1)) { *pval += (s32)(MS_PULSE_PER_CIRCLE); } while(*pval > ((s32)(MS_PULSE_PER_CIRCLE))) { *pval -= (s32)(MS_PULSE_PER_CIRCLE); } } void ChangeMsTo0To360(s32 * pval) { *pval %= MS_PULSE_PER_CIRCLE; while (*pval < 0) { *pval += (s32)(MS_PULSE_PER_CIRCLE); } while(*pval > ((s32)(MS_PULSE_PER_CIRCLE))) { *pval -= (s32)(MS_PULSE_PER_CIRCLE); } } //-------------------------------------------------------------------------------- // 普通停止检测 int MoveToSensorAsMidPosNStopScan(u32 para1, u32 para2) { int rslt; MTSAMPCtrl * pmts; pmts = (MTSAMPCtrl*)(para1); rslt = GetCommonNStop(); if (rslt != ERR_NONE || pmts == NULL) { return rslt; } return rslt; } // 快速停止检测 int MoveToSensorAsMidPosQStopScan(u32 para1, u32 para2) { int rslt; MTSAMPCtrl * pmts; pmts = (MTSAMPCtrl*)(para1); rslt = GetCommonQStop(); if (rslt != ERR_NONE || pmts == NULL) { return rslt; } if (rslt == ERR_NONE) { if (pmts->zerosensor != NULL) // 检测零位 { if (pmts->zerosensor() == pmts->zeroval) { rslt = STA_MTZ_SUCCESS; // 归零成功 } } } return rslt; } // 急停检测 int MoveToSensorAsMidPosEmsScan(u32 para1, u32 para2) { int rslt; MTSAMPCtrl * pmts; pmts = (MTSAMPCtrl*)(para1); rslt = GetCommonEms(); if (rslt != ERR_NONE || pmts == NULL) { return rslt; } if (pmts->emcstopscan != NULL) { rslt = pmts->emcstopscan(); } if (rslt != ERR_NONE) { return rslt; } if (pmts->movement > 0) { if (pmts->limitpsensor != NULL) // 检测正向限位 { if (pmts->limitpsensor() == SENSOR_ON) { rslt = ERR_LMT_POSITIVE; // 正向限位 } } } else if (pmts->movement < 0) { if (pmts->limitnsensor != NULL) // 检测反向限位 { if (pmts->limitnsensor() == SENSOR_ON) { rslt = ERR_LMT_NEGATIVE; // 反向限位 } } } else { rslt = ERR_MTZ_ERROR; // 归零错误 } return rslt; } // 找挡片中心位置停止检测 int MoveToMidPosQStopScan(u32 para1, u32 para2) { static int isckzero = 0; int rslt = 0; MTSAMPCtrl * pmts; pmts = (MTSAMPCtrl*)(para1); rslt = GetCommonQStop(); if (rslt != ERR_NONE || pmts == NULL) { return rslt; } if (rslt == ERR_NONE) { if (pmts->zerosensor != NULL) // 检测零位 { if (isckzero == 1) { if (pmts->zerosensor() != pmts->zeroval) { isckzero = 0; rslt = 1; } } else { if (pmts->zerosensor() == pmts->zeroval) { isckzero = 1; } } } } return rslt; } // 直线运动到零位传感器且挡片在中心位置,特别说明,此种归零方式不能使用带有豁口的挡片,尤其是豁口不在中心位置 // return -1:参数错误 int LineRunToSensorAsMidPosCtrl(MTSAMPCtrl * pmtsampc) { int rslt, err; InterMoveCtrl lmctrl; u16 axisIdx; int mvnum = 0; // 运动次数,最多运动两次,即正反限位各一次,若运动到正反限位还没有找到零位传感器,则归零失败 if (pmtsampc == NULL) { return -1; } axisIdx = pmtsampc->axisIdx; assert_param(axisIdx < AXIS_NUM); memset(&lmctrl, 0, sizeof(InterMoveCtrl)); lmctrl.vAxisId = pmtsampc->vAxisId; // 使用虚轴 lmctrl.motosConfig.newConfig = pmtsampc->newCfg; // 需要更新电机配置 err = ERR_NONE; #if (1) //if (pmtsampc->syncflag == 0) { err = MoveToSensorAsMidPosEmsScan(lmctrl.condPara1, lmctrl.condPara2); // 检测急停条件 if ((pmtsampc->movement < 0 && err == ERR_LMT_NEGATIVE) || (pmtsampc->movement > 0 && err == ERR_LMT_POSITIVE) ) // 在限位 { mvnum++; pmtsampc->movement = pmtsampc->movement * (-1); // 在限位则向反向运动找零 } err = MoveToSensorAsMidPosQStopScan(lmctrl.condPara1, lmctrl.condPara2); // 检测停止条件 if (err == STA_MTZ_SUCCESS) // 在零位位置 { pmtsampc->movement = 0; // 在零位则跳过找零位传感器过程,直接慢速移动找挡片中心位置 } } #endif if (pmtsampc->newCfg == 0 && pmtsampc->syncflag != 0) { for (int i = 0; i < AXIS_NUM; i++) { if (pmtsampc->syncList[i] != 0) { lmctrl.mvmtPara.movement[i] = pmtsampc->movement; // 各个轴的运动量,0,无运动;其他,运动长度,单位p } } } else { lmctrl.motosConfig.axisConfig[axisIdx].axisConfig = pmtsampc->axisCfg; // 实轴输出配置 lmctrl.motosConfig.axisConfig[axisIdx].poutType = pmtsampc->poutType; // 脉冲输出模式(CW/CCW,PULSE/DIR) lmctrl.motosConfig.axisConfig[axisIdx].spdSource = MAKE_POUT_CMD(lmctrl.vAxisId); // 实轴速度控制模式(虚轴1,虚轴2,虚轴3,编码器) lmctrl.motosConfig.axisConfig[axisIdx].datSource = DATI_INTERPOLATION; // 实轴数据获取模式(硬件插补,编码器随动,编码器映射) lmctrl.mvmtPara.movement[axisIdx] = pmtsampc->movement; // 各个轴的运动量,0,无运动;其他,运动长度,单位p } lmctrl.mvmtPara.extraRepeat = 0; // 延续重复次数 lmctrl.mvmtPara.interLong = abs(pmtsampc->movement); // 插补长轴位移,必须大于或等于movement分量中的最大值 lmctrl.mvmtPara.pulsePerSegment = PULSE_PER_SEGMENT; // 每段脉冲数 // 速度控制参数 lmctrl.spdPara.startPPS = pmtsampc->lspd.stspSpd; // 启动速度 lmctrl.spdPara.stopPPS = pmtsampc->lspd.stspSpd; // 停止速度 lmctrl.spdPara.runPPS = pmtsampc->lspd.runSpd; // 运行速度 lmctrl.spdPara.slowPPS = pmtsampc->lspd.stspSpd; // 降速速度 lmctrl.spdPara.addPPSG = pmtsampc->lspd.spdAdd; // 升速加速度 lmctrl.spdPara.decPPSG = pmtsampc->lspd.spdAdd/2; // 降速加速度 lmctrl.spdPara.brkPPSG = pmtsampc->lspd.brkAdd; // 刹车加速度 lmctrl.stopMode = STOP_MODE_SPD; // 停止运动方式 // 回调函数及参数 lmctrl.Delay = DelayRef; // 延时回调函数 lmctrl.RefreshPosition = NormalRefPosition; // 坐标刷新回调函数 lmctrl.refPosPara = 0; // 坐标刷新参数 lmctrl.WorkBeforeRun = NULL; // 运行工作回调函数 lmctrl.WorkAfterRun = NULL; // 运行后工作回调函数 lmctrl.workPara1 = 0; lmctrl.workPara2 = 0; // 工作参数 lmctrl.GetSlowDown = NULL; // 慢速运动条件函数,当为空时,不检测降速条件; 不为空时,条件满足,速度降低,条件消失,速度恢复 lmctrl.GetNormalStop = MoveToSensorAsMidPosNStopScan; // 一般停止条件函数,当为空时,不检测停止条件; 不为空时,条件满足,降速到停止(按降速加速度) lmctrl.GetQuickStop = MoveToSensorAsMidPosQStopScan; // 快速停止条件函数,当为空时,不检测停止条件; 不为空时,条件满足,降速到停止(按刹车加速度) lmctrl.GetEmergencyStop = MoveToSensorAsMidPosEmsScan; // 紧急停止条件函数,当为空时,不检测急停条件; 不为空时,条件满足,立刻停止发送脉冲(无需降速) lmctrl.condPara1 = (u32)(pmtsampc);; lmctrl.condPara2 = 0; // 条件函数参数 // 运动到零位传感器 while(mvnum < 2 && pmtsampc->movement != 0) { rslt = InterpolationMotion(&lmctrl); // 运动控制 if (rslt == 3) { err = MoveToSensorAsMidPosQStopScan(lmctrl.condPara1, lmctrl.condPara2); // 检测停止条件 break; } else if (rslt == 2) { err = MoveToSensorAsMidPosEmsScan(lmctrl.condPara1, lmctrl.condPara2); // 检测急停条件 if ( (pmtsampc->movement < 0 && err == ERR_LMT_NEGATIVE) || (pmtsampc->movement > 0 && err == ERR_LMT_POSITIVE) || // 在限位 0 ) { mvnum++; pmtsampc->movement = pmtsampc->movement * (-1); // 反向运动 lmctrl.mvmtPara.movement[axisIdx] = pmtsampc->movement; } else { break; } } else { break; } } if (mvnum >= 2) // 正负限位都运动还未找到零位,归零错误 { err = ERR_MTZ_ERROR; return err; } if (err == STA_MTZ_SUCCESS) // 找零成功,开始移动到挡片中心位置 { s32 pos1, pos2; // 挡片两侧位置记录 pmtsampc->movement = pmtsampc->bafflewidth + 1000; lmctrl.mvmtPara.movement[axisIdx] = pmtsampc->movement; lmctrl.mvmtPara.interLong = abs(pmtsampc->movement); // 插补长轴位移,必须大于或等于movement分量中的最大值 lmctrl.spdPara.startPPS = pmtsampc->mposspd.stspSpd; // 启动速度 lmctrl.spdPara.stopPPS = pmtsampc->mposspd.stspSpd; // 停止速度 lmctrl.spdPara.runPPS = pmtsampc->mposspd.runSpd; // 运行速度 lmctrl.spdPara.slowPPS = pmtsampc->mposspd.stspSpd; // 降速速度 lmctrl.spdPara.addPPSG = pmtsampc->mposspd.spdAdd; // 升速加速度 lmctrl.spdPara.decPPSG = pmtsampc->mposspd.spdAdd/2; // 降速加速度 lmctrl.spdPara.brkPPSG = pmtsampc->mposspd.brkAdd; // 刹车加速度 lmctrl.GetQuickStop = MoveToMidPosQStopScan; // 快速停止条件函数,当为空时,不检测停止条件; 不为空时,条件满足,降速到停止(按刹车加速度) err = ERR_NONE; rslt = InterpolationMotion(&lmctrl); // 运动控制 err = GetMoveResultError(rslt, lmctrl.errInfo); if (err == 1) { pos1 = GetMotoCounter(axisIdx); pmtsampc->movement = pmtsampc->movement * (-1); lmctrl.mvmtPara.movement[axisIdx] = pmtsampc->movement; err = ERR_NONE; rslt = InterpolationMotion(&lmctrl); // 运动控制 err = GetMoveResultError(rslt, lmctrl.errInfo); if (err == 1) { int dir; pos2 = GetMotoCounter(axisIdx); if (pmtsampc->movement > 0) { dir = -1; // 跟前一次运动方向相反 } else { dir = 1; } pmtsampc->movement = abs(pos1-pos2)/2; // 20220317 BUG修复,单纯取绝对值电机只会单向运动,不会根据实际运动方向自切换 pmtsampc->movement *= dir; lmctrl.mvmtPara.movement[axisIdx] = pmtsampc->movement; lmctrl.mvmtPara.interLong = abs(pmtsampc->movement); lmctrl.GetQuickStop = NULL; // 20210812 因有些挡片带有豁口(带降速传感器时,实际此种归零方式完全不需要降速传感器) // 当找零运动到豁口时,个别情况下会存在传感器响应不正常的情况 // 故此处移动到挡片中心位置时不再检测此停止条件 err = ERR_NONE; rslt = InterpolationMotion(&lmctrl); // 运动控制 err = GetMoveResultError(rslt, lmctrl.errInfo); if (err == ERR_NONE) { err = STA_MTZ_SUCCESS; } } } } return err; }