/** * @file MOTOR_STEP_ATY.c * * @param Project DEVICE_GENERAL_ATY_LIB * * @author ATY * * @copyright * - Copyright 2017 - 2023 MZ-ATY * - This code follows: * - MZ-ATY Various Contents Joint Statement - * * https://mengze.top/MZ-ATY_VCJS * - CC 4.0 BY-NC-SA - * * https://creativecommons.org/licenses/by-nc-sa/4.0/ * - Your use will be deemed to have accepted the terms of this statement. * * @brief Familiar functions of SteppingMotor control * * @version * - 1_01_221231 > ATY * -# Preliminary version, first Release * - 1_02_230408 > ATY * -# Add State Machine and so * - 1_03_230426 > ATY * -# Change name "SteppingMotor_ATY" to "MOTOR_STEP_ATY" ******************************************************************************** */ #ifndef __MOTOR_STEP_ATY_C #define __MOTOR_STEP_ATY_C #include "MOTOR_STEP_ATY.h" /******************************* For user *************************************/ /******************************************************************************/ uint8_t motorEn = 0; uint8_t motorDir = MOTOR_DIR_OUT; uint32_t motorSoftSpeed = 0; uint32_t motorSpeed = 0; uint32_t motorSoftTime = 0; uint32_t motorTime = 0; uint32_t motorStartCounter = 0; uint32_t motorStopCounter = 0; // for stall detection or driver error(TMC2209) uint8_t motorSetState = 0; // 0: stop, 1: start hold, 2: start soft, 3: run speed, 4: change dir, 5: stop state, soft set 0 after use, 10: scram motor float speedIncreaseStep = 0.0f; float S_paramA = 0.0f; #ifdef S_PARAM_C float S_paramC = S_PARAM_C; #else float S_paramC = 0.0f; #endif /** * @brief start motor with direction set * @param dir direction to move * @param speed direction to move */ void MotorStart(uint8_t dir, uint32_t speed) { if(dir == MOTOR_DIR_IN) MOTOR_DIR_SET_IN; else if(dir == MOTOR_DIR_OUT) MOTOR_DIR_SET_OUT; MOTOR_EN_SET_ENABLE; PwmFreqSet(speed, Motor_Channel); #ifdef __DEBUG_MOTOR_STEP_ATY printf("\r\nMotor Start: %d - %d", dir, speed); #endif /* __DEBUG_MOTOR_STEP_ATY */ } /** * @brief start motor with only speed * @param speed direction to move */ void MotorStartSpeed(uint32_t speed) { MOTOR_EN_SET_ENABLE; PwmFreqSet(speed, Motor_Channel); #ifdef __DEBUG_MOTOR_STEP_ATY printf("\r\nMotor Start: %d", speed); #endif /* __DEBUG_MOTOR_STEP_ATY */ } /** * @brief stop motor */ void MotorStop(void) { // MOTOR_PARAM_SET(MOTOR_DIR_OUT, 0, 0, 0, 0, motorSetState); if(motorEn == 0) return; else{ PWM_Stop(0, Motor_Channel); MOTOR_EN_SET_DISABLE; motorStartCounter = 0; motorStopCounter = 0; #ifdef __DEBUG_MOTOR_STEP_ATY printf("\r\nMotor Stop"); #endif /* __DEBUG_MOTOR_STEP_ATY */ } } /** * @brief process motor error * @note put at 1ms cycle */ void MotorSelfCycle(void) { if(MOTOR_DIAG_GET_H) { if(motorEn == 1) MOTOR_EN_SET_DISABLE; if(motorStopCounter >= 100) MOTOR_EN_SET_ENABLE; } } /** * @brief deal step motor state * @note put at 1ms cycle; * set motorSetState = 4 to change motor dir with speed no change * set motorSetState = 3 to start motor directly, motorSoftTime need to be 0 * set motorSetState = 2 to strat motor with soft, motorDir/motorSoftSpeed/motorSpeed/motorSoftTime/motorTime need to be set * set motorSetState = 0 to stop motor * set motorSetState = 10 to scram motor * when motorSetState = 5 means last cycle finished, set others to start a new cycle * when motorSetState = 1 means motor running and state not changing */ void MotorStateMachine_Step(void) { if(motorSoftSpeed < motorSpeed) motorSoftSpeed = motorSpeed; if(motorSetState == 4){ motorStartCounter = 0; motorStopCounter = 0; motorSetState = 2; motorDir = !motorDir; } else if(motorSetState == 3){ motorStartCounter = motorSoftTime; motorSetState = 1; MotorStart(motorDir, motorSpeed); } else if(motorSetState == 2){ motorStartCounter = 0; motorSetState = 1; MotorStart(motorDir, motorSoftSpeed); } else if(motorSetState == 1){ if(motorStartCounter < motorSoftTime){ #if defined (Motor_StartLine_T) speedIncreaseStep = ((float)(motorSoftSpeed - motorSpeed) / (float)motorSoftTime); // at 1ms cycle MotorStart(motorDir, motorSpeed < (motorSoftSpeed - (speedIncreaseStep * motorStartCounter)) ? (motorSoftSpeed - (speedIncreaseStep * motorStartCounter)) : motorSpeed); #elif defined (Motor_StartLine_S) // S line: y = ax^3 + cx, a in 0-1, c >= 0, lower c cause lower increase at start or end, c for users S_paramA = (((float)(motorSoftSpeed - motorSpeed) / 2) - (S_paramC * (float)((float)motorSoftTime / 2) * (float)((float)motorSoftTime / 2) / 2)) / ((float)((float)motorSoftTime / 2) * (float)((float)motorSoftTime / 2) * (float)((float)motorSoftTime / 2) * (float)((float)motorSoftTime / 2)) * 4; // mbG[27] = S_paramA * 10000000; if(motorStartCounter < (motorSoftTime / 2)) speedIncreaseStep = ((float)(S_paramA * motorStartCounter * motorStartCounter * motorStartCounter * motorStartCounter) / 4) + ((float)(S_paramC * motorStartCounter * motorStartCounter) / 2); // (S_paramA * motorStartCounter * motorStartCounter * motorStartCounter) // + (S_paramC * motorStartCounter); else speedIncreaseStep = (float)((float)(motorSoftSpeed - motorSpeed) / 2) + ((float)(S_paramA * motorSoftTime * motorSoftTime * motorSoftTime * motorSoftTime) / 64) + ((float)(S_paramC * motorSoftTime * motorSoftTime) / 8) - ((float)(S_paramA * (motorSoftTime - motorStartCounter) * (motorSoftTime - motorStartCounter) * (motorSoftTime - motorStartCounter) * (motorSoftTime - motorStartCounter)) / 4) - ((float)(S_paramC * (motorSoftTime - motorStartCounter) * (motorSoftTime - motorStartCounter)) / 2); // 0 // - (S_paramA * (float)((float)motorStartCounter - (float)motorSoftTime) // * (float)((float)motorStartCounter - (float)motorSoftTime) // * (float)((float)motorStartCounter - (float)motorSoftTime)) // - (S_paramC * (float)((float)motorStartCounter - (float)motorSoftTime)); MotorStart(motorDir, motorSpeed < (motorSoftSpeed - speedIncreaseStep) ? (motorSoftSpeed - speedIncreaseStep) : motorSpeed); #else #endif } if(motorStartCounter == motorSoftTime) motorSetState = 3; else if(motorStartCounter == (motorSoftTime + motorTime)) motorSetState = 5; } else if(motorSetState == 10){ motorSetState = 0; MotorStop(); } else{ MotorStop(); } // 5 0 if(motorEn == 0){ motorStartCounter = 0; motorStopCounter++; } else{ motorStartCounter++; motorStopCounter = 0; } } #endif /* __MOTOR_STEP_ATY_C */ /******************************** End Of File *********************************/