#include "stepmotos.h" #include "inout.h" //------------------------------------------------------------------------ void DefaultMotoCoilPwm(int coil){}; void DefaultMotoCoilCtrl(void){}; #define FULL_STEP_VAL (1.0f*MOTO_PPC/FULL_STEP_PPC) // 整步电子齿轮值 #define DEF_MICO_STEP_VAL (1.0f*MOTO_PPC/MICO_STEP_PPC) // 默认微步电子齿轮值 //------------------------------------------------------------------------ //------------------------------------------------------------------------ typedef struct { POS_TYPE motoPos; // 电机位置 POS_TYPE fullStepAng; // 整步电子齿轮值 POS_TYPE micoStepAng; // 可保存电子齿轮值 int ccwdir; void (*MotoCoilAPwm)(int); void (*SetMotoACPOn)(void); void (*SetMotoACPOff)(void); void (*SetMotoACNOn)(void); void (*SetMotoACNOff)(void); void (*MotoCoilBPwm)(int); void (*SetMotoBCPOn)(void); void (*SetMotoBCPOff)(void); void (*SetMotoBCNOn)(void); void (*SetMotoBCNOff)(void); }StepMotoCtrl; StepMotoCtrl g_stepMotoCtrl[STEP_MOTOS_NUM]; //------------------------------------------------------------------------ void InitStepMotos(void) { memset(g_stepMotoCtrl, 0, sizeof(StepMotoCtrl)*STEP_MOTOS_NUM); for (int i = 0; i < STEP_MOTOS_NUM; i++) { g_stepMotoCtrl[i].motoPos = 0; // 电机位置 g_stepMotoCtrl[i].ccwdir = CCWDIR_POSI; // 电机方向 g_stepMotoCtrl[i].fullStepAng = FULL_STEP_VAL; // 整步电子齿轮值 g_stepMotoCtrl[i].micoStepAng = DEF_MICO_STEP_VAL; // 可保存电子齿轮值 g_stepMotoCtrl[i].MotoCoilAPwm = DefaultMotoCoilPwm; g_stepMotoCtrl[i].SetMotoACPOn = DefaultMotoCoilCtrl; g_stepMotoCtrl[i].SetMotoACPOff = DefaultMotoCoilCtrl; g_stepMotoCtrl[i].SetMotoACNOn = DefaultMotoCoilCtrl; g_stepMotoCtrl[i].SetMotoACNOff = DefaultMotoCoilCtrl; g_stepMotoCtrl[i].MotoCoilBPwm= DefaultMotoCoilPwm; g_stepMotoCtrl[i].SetMotoBCPOn = DefaultMotoCoilCtrl; g_stepMotoCtrl[i].SetMotoBCPOff = DefaultMotoCoilCtrl; g_stepMotoCtrl[i].SetMotoBCNOn = DefaultMotoCoilCtrl; g_stepMotoCtrl[i].SetMotoBCNOff = DefaultMotoCoilCtrl; } } //------------------------------------------------------------------------ void SetMotoCtrlFuncs(int motoIdx, MotoCoilPwm coilapwm, MotoCoilCtrl acpon, MotoCoilCtrl acpoff, MotoCoilCtrl acnon, MotoCoilCtrl acnoff, MotoCoilPwm coilbpwm, MotoCoilCtrl bcpon, MotoCoilCtrl bcpoff, MotoCoilCtrl bcnon, MotoCoilCtrl bcnoff) { StepMotoCtrl * pCtrl; if (motoIdx < 0 || motoIdx >= STEP_MOTOS_NUM) { return; } pCtrl = &(g_stepMotoCtrl[motoIdx]); pCtrl->MotoCoilAPwm = coilapwm; pCtrl->SetMotoACPOn = acpon; pCtrl->SetMotoACPOff = acpoff; pCtrl->SetMotoACNOn = acnon; pCtrl->SetMotoACNOff = acnoff; pCtrl->MotoCoilBPwm= coilbpwm; pCtrl->SetMotoBCPOn = bcpon; pCtrl->SetMotoBCPOff = bcpoff; pCtrl->SetMotoBCNOn = bcnon; pCtrl->SetMotoBCNOff = bcnoff; } void SetMotoCCWDir(int motoIdx, int dir) { StepMotoCtrl * pCtrl; if (motoIdx < 0 || motoIdx >= STEP_MOTOS_NUM) { return; } pCtrl = &(g_stepMotoCtrl[motoIdx]); if (dir >= 0) { pCtrl->ccwdir = CCWDIR_POSI; } else { pCtrl->ccwdir = CCWDIR_NEGA; } } //------------------------------------------------------------------------ // 步进电机控制输出 // theta 电机角度,每圈 200K个位置 (或 50K 个) // effort 电流 int StepMotoOut(int motoIdx, int theta, int effort) { int angleA, angleB; int coilA, coilB; int sinA, sinB; StepMotoCtrl * pCtrl; if (motoIdx < 0 || motoIdx >= STEP_MOTOS_NUM) { return 0; } pCtrl = &(g_stepMotoCtrl[motoIdx]); if (effort < 0) { effort = -effort; } if (effort > MAX_OUT_LEV) { effort = MAX_OUT_LEV; } theta *= pCtrl->ccwdir; angleA = theta % SIN_TAB_SIZE; // ((int)(theta * PHASE_MUTI)) % SIN_TAB_SIZE; angleB = angleA + (SIN_TAB_SIZE/4); // 相位角相差 90 度 sinA = GetSinValue(angleA); sinB = GetSinValue(angleB); coilA = (int)(effort * sinA / SIN_ITEM_MUTI); coilB = (int)(effort * sinB / SIN_ITEM_MUTI); if (coilA > 0) { pCtrl->MotoCoilAPwm(coilA); pCtrl->SetMotoACNOn(); pCtrl->SetMotoACPOff(); } else if (coilA < 0) { pCtrl->MotoCoilAPwm(-coilA); pCtrl->SetMotoACPOn(); pCtrl->SetMotoACNOff(); } else { pCtrl->MotoCoilAPwm(0); pCtrl->SetMotoACNOn(); pCtrl->SetMotoACPOn(); } if (coilB > 0) { pCtrl->MotoCoilBPwm(coilB); pCtrl->SetMotoBCNOn(); pCtrl->SetMotoBCPOff(); } else if (coilB < 0) { pCtrl->MotoCoilBPwm(-coilB); pCtrl->SetMotoBCPOn(); pCtrl->SetMotoBCNOff(); } else { pCtrl->MotoCoilBPwm(0); pCtrl->SetMotoBCNOn(); pCtrl->SetMotoBCPOn(); } #if (0) printf("StepMotoOut, idx=%d, theta=%d, effort=%d\r\n", motoIdx, theta, effort); printf("angleA=%d, sinA=%d, coilA=%d\r\n", angleA, sinA, coilA); printf("angleB=%d, sinB=%d, coilB=%d\r\n", angleB, sinB, coilB); #endif return 0; } //-------------------------------------------------------------- void ResetMotoPos(int motoIdx, int eff) { int pos; StepMotoCtrl * pCtrl; if (motoIdx < 0 || motoIdx >= STEP_MOTOS_NUM) { return; } pCtrl = &(g_stepMotoCtrl[motoIdx]); pCtrl->motoPos = 0; pos = (int)pCtrl->motoPos; StepMotoOut(motoIdx, pos, eff); } void SetMotoEnable(int motoIdx, int eff) { int pos; StepMotoCtrl * pCtrl; if (motoIdx < 0 || motoIdx >= STEP_MOTOS_NUM) { return; } pCtrl = &(g_stepMotoCtrl[motoIdx]); pos = (int)pCtrl->motoPos; StepMotoOut(motoIdx, pos, eff); } void SetMotoPosTo(int motoIdx, POS_TYPE pos, int eff) { StepMotoCtrl * pCtrl; if (motoIdx < 0 || motoIdx >= STEP_MOTOS_NUM) { return; } pCtrl = &(g_stepMotoCtrl[motoIdx]); pCtrl->motoPos = pos; StepMotoOut(motoIdx, pos, eff); } POS_TYPE GetMotoPos(int motoIdx) { StepMotoCtrl * pCtrl; if (motoIdx < 0 || motoIdx >= STEP_MOTOS_NUM) { return 0; } pCtrl = &(g_stepMotoCtrl[motoIdx]); return pCtrl->motoPos; } //-------------------------------------------------------------- // 电机走一整步1.8度函数 // dir 方向。 1, 正向; -1, 反向; 0 不走 // eff 电流值 int MotoOneFullStep(int motoIdx, int dir, int eff) { int pos; StepMotoCtrl * pCtrl; if (motoIdx < 0 || motoIdx >= STEP_MOTOS_NUM) { return 0; } pCtrl = &(g_stepMotoCtrl[motoIdx]); if (dir > 0) { pCtrl->motoPos += pCtrl->fullStepAng; } else if (dir < 0) { pCtrl->motoPos -= pCtrl->fullStepAng; } pos = (int)(pCtrl->motoPos + 0.5f*(pCtrl->motoPos>=0?1:-1)); if (pos > MAX_MOTO_POS) { pos -= MAX_MOTO_POS; pCtrl->motoPos -= MAX_MOTO_POS; } if (pos < -MAX_MOTO_POS) { pos += MAX_MOTO_POS; pCtrl->motoPos += MAX_MOTO_POS; } StepMotoOut(motoIdx, pos, eff); return pos; } //------------------------------------------------------------------------------------- // 电机走一个微步函数 // dir 方向。 1, 正向; -1, 反向; 0 不走 // eff 电流值 // 返回电机的位置 int MotoOneMicoStep(int motoIdx, int dir, int eff) { int pos; StepMotoCtrl * pCtrl; if (motoIdx < 0 || motoIdx >= STEP_MOTOS_NUM) { return 0; } pCtrl = &(g_stepMotoCtrl[motoIdx]); if (dir > 0) { pCtrl->motoPos += pCtrl->micoStepAng; } else if (dir < 0) { pCtrl->motoPos -= pCtrl->micoStepAng; } pos = (int)(pCtrl->motoPos + (0.5f*(pCtrl->motoPos>=0?1:-1))); if (pos > MAX_MOTO_POS) { pos -= MAX_MOTO_POS; pCtrl->motoPos -= MAX_MOTO_POS; } if (pos < -MAX_MOTO_POS) { pos += MAX_MOTO_POS; pCtrl->motoPos += MAX_MOTO_POS; } StepMotoOut(motoIdx, pos, eff); return pos; }