optical/EMBOS/Users/EmbFunc/movectrl/movectrl.c
2025-09-04 09:45:08 +08:00

1884 lines
44 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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/CCWPULSE/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/CCWPULSE/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/CCWPULSE/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/CCWPULSE/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/CCWPULSE/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;
}