/** * @file MOTOR_STEP_SPEED_T_C_ATY.c * * @param Project DEVICE_GENERAL_ATY_LIB * * @author ATY * * @copyright * - Copyright 2017 - 2026 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 Trapezoidal acceleration and deceleration control implementation for stepper motor * * @note import angle to use COMPENSATE * * @version * - 1_00_260119 > ATY * -# Initial version ******************************************************************************** */ #ifndef __MOTOR_STEP_SPEED_T_C_ATY_C #define __MOTOR_STEP_SPEED_T_C_ATY_C #include "MOTOR_STEP_SPEED_T_C_ATY.h" #include #define MOTOR_STEP_SPEED_T_C_ATY_TAG "\r\n[MOTOR_STEP_SPEED_T_C_ATY] " /******************************* For user *************************************/ /******************************************************************************/ uint8_t MSSTC_PulseToggle = 0; // pulse toggle counter (for complete pulse) int32_t MSSTC_CelCount = 0; // ac/deceleration step counter uint32_t MSSTC_FastStepDelay = 0; // minimum delay at fullSpeed int32_t MSSTC_StepDelay = 0; // current step delay (timer ticks) uint32_t MSSTC_NewStepDelay = 0; // calculated step delay for next step from last step int32_t MSSTC_Rest = 0; // Remainder for precision int32_t MSSTC_LastDelay = 0; // Last acceleration delay // for angle compensation ------------------------------------------------------ float MSSTC_StartAngle = 0; uint32_t MSSTC_CurrentTurn = 0; float MSSTC_CurrentAngle = 0; uint32_t MSSTC_TargetTurn = 0; float MSSTC_TargetAngle = 0; float MSSTC_AnglePerStep = 0; float MSSTC_TargetAngleL = 0; float MSSTC_TargetAngleH = 0; float MSSTC_AngleDiff = 0; int32_t MSSTC_StepDiff = 0; uint8_t MSSTC_CelCountErrCount = 0; float K = 0.676; /** * @brief Move motor with trapezoidal dev->fullSpeed profile * @param dev Pointer to motor device structure * @param steps Number of steps to move (positive=CW, negative=CCW) * @return 0=success, 1=busy, 2=invalid parameters */ uint8_t MSSTC_Move(struct MOTOR_STEP_SPEED_T_C_ATY_Dev* dev, uint32_t steps, float startAngle){ if(MSSTC_IsRunning(dev) == 1){ return 1; } if(steps == 0 || dev->fullSpeed == 0){ dev->stop(); return 0; } if(dev->unitDivision == 0) dev->unitDivision = 1; if(dev->powerOnlyRun == 1){ dev->enable = 1; } dev->enSet(dev->enable); dev->dirSet(dev->direction); /* Handle single step */ if(steps == 1){ dev->runState = MSSTC_STATE_DECEL; MSSTC_CelCount = -1; MSSTC_StepDelay = 1000; dev->start(); return 0; } /* Calculate motor parameters */ // alpha = 2 * PI / stepsPerRevolution [rad/step] float alpha = 2.0 * 3.14159265359 / (dev->fullSteps * dev->microstepping); /* Calculate minimum delay (maximum dev->fullSpeed) */ // wmax = fullSpeed [rad/sec] // tmin = alpha / wmax [sec/step] (t = distance / velocity) // fastStepDelay = cmin = tmin * timerFreq = alpha * timerFreq / fullSpeed MSSTC_FastStepDelay = (uint32_t)(alpha * dev->timerFreq * dev->unitDivision / dev->fullSpeed); if(MSSTC_FastStepDelay <= 1){ MSSTC_FastStepDelay = 2; } /* Calculate initial step delay (first step) */ // t0 = sqrt(2 * alpha / (acceleration / unit)) = sqrt(2 * alpha * unit / acceleration) // stepDelay = K * timerFreq * t0 if(dev->acceleration != 0){ MSSTC_StepDelay = (uint32_t)(K * dev->timerFreq * sqrt(2.0 * alpha * dev->unitDivision / dev->acceleration)); } if(dev->acceleration == 0){ // no acceleration and no deceleration MSSTC_StepDelay = MSSTC_FastStepDelay; } /* Calculate steps to reach fullSpeed */ // accelSteps = (fullSpeed / unit)^2 / (2 * alpha * (acceleration / unit)) // accelSteps = fullSpeed^2 / (2 * alpha * acceleration * unit) dev->accelSteps = 1; if(dev->acceleration != 0){ dev->accelSteps = (uint32_t)((double)dev->fullSpeed / (2.0 * alpha * dev->acceleration * dev->unitDivision) * dev->fullSpeed); } if(dev->accelSteps == 0 || dev->acceleration == 0){ dev->accelSteps = 1; } /* Calculate steps before deceleration */ dev->accelLimit = 1; if(dev->acceleration != 0 && dev->deceleration != 0){ dev->accelLimit = (uint32_t)(steps * dev->deceleration / (dev->acceleration + dev->deceleration)); } else if(dev->deceleration == 0){ dev->accelLimit = steps - 1; } if(dev->accelLimit == 0 || dev->acceleration == 0){ dev->accelLimit = 1; } /* Calculate steps deceleration */ dev->decelSteps = 1; if(dev->acceleration != 0 && dev->deceleration != 0){ if(dev->accelLimit <= dev->accelSteps){ // not to fullSpeed dev->decelSteps = steps - dev->accelLimit; dev->accelSteps = dev->accelLimit; } else{ // accelerate to fullSpeed dev->decelSteps = (uint32_t)(dev->accelSteps * dev->acceleration / dev->deceleration); } } else if(dev->acceleration == 0 && dev->deceleration != 0){ dev->decelSteps = (uint32_t)((double)dev->fullSpeed / (2.0 * alpha * dev->deceleration * dev->unitDivision) * dev->fullSpeed); if(dev->decelSteps >= steps - 1){ dev->decelSteps = steps - 1; } } if(dev->decelSteps == 0 || dev->deceleration == 0){ dev->decelSteps = 1; } /* Calculate deceleration start position */ dev->decelStart = steps - dev->decelSteps; if(dev->mode == MSSTC_MODE_SPEED_OPEN){ dev->decelSteps = (uint32_t)((double)dev->fullSpeed / (2.0 * alpha * dev->deceleration * dev->unitDivision) * dev->fullSpeed); } /* Set initial state */ if(MSSTC_StepDelay <= MSSTC_FastStepDelay){ // fullSpeed is very low, no acceleration MSSTC_StepDelay = MSSTC_FastStepDelay; dev->runState = MSSTC_STATE_FULL; } else{ dev->runState = MSSTC_STATE_ACCEL; } /* Reset counters */ dev->stepCountCurrent = 0; MSSTC_PulseToggle = 0; MSSTC_CelCount = 0; MSSTC_NewStepDelay = 0; MSSTC_Rest = 0; MSSTC_LastDelay = MSSTC_StepDelay; MSSTC_CelCountErrCount = 0; MSSTC_StartAngle = startAngle; MSSTC_CurrentTurn = 0; MSSTC_CurrentAngle = startAngle; MSSTC_TargetTurn = steps / (dev->fullSteps * dev->microstepping); MSSTC_TargetAngle = ((steps % (dev->fullSteps * dev->microstepping)) * 360.0) / (dev->fullSteps * dev->microstepping) + startAngle; while(MSSTC_TargetAngle >= 360.0){ MSSTC_TargetAngle -= 360.0; MSSTC_TargetTurn++; } MSSTC_AnglePerStep = 360.0 / (dev->fullSteps * dev->microstepping); MSSTC_TargetAngleL = MSSTC_TargetAngle - MSSTC_AnglePerStep; MSSTC_TargetAngleH = MSSTC_TargetAngle + MSSTC_AnglePerStep; MSSTC_AngleDiff = 0; MSSTC_StepDiff = 0; /* Start PWM and timer */ dev->setTimerCompare(MSSTC_StepDelay); dev->start(); return 0; } /** * @brief Timer interrupt handler - dev->fullSpeed decision algorithm * @param dev Pointer to motor device structure * @note Call this function in timer compare interrupt */ void MSSTC_IRQHandler(struct MOTOR_STEP_SPEED_T_C_ATY_Dev* dev){ /* Update timer compare value */ dev->setTimerCompare(MSSTC_StepDelay); /* Toggle counter for complete pulse generation */ MSSTC_PulseToggle++; if(MSSTC_PulseToggle >= 2){ MSSTC_PulseToggle = 0; /* State machine for dev->fullSpeed control */ switch(dev->runState){ case MSSTC_STATE_STOP: { dev->stop(); if(dev->mode == MSSTC_MODE_DISTANCE_CLOSE){ dev->runState = MSSTC_STATE_COMPENSATE; } else{ dev->runState = MSSTC_STATE_STANDBY; if(dev->powerOnlyRun == 1){ dev->enable = 0; dev->enSet(dev->enable); } } break; } case MSSTC_STATE_ACCEL: { dev->stepCountCurrent++; MSSTC_CelCount++; /* Calculate new step delay */ MSSTC_NewStepDelay = MSSTC_StepDelay - ((2 * MSSTC_StepDelay + MSSTC_Rest) / (4 * MSSTC_CelCount + 1)); MSSTC_Rest = ((2 * MSSTC_StepDelay + MSSTC_Rest) % (4 * MSSTC_CelCount + 1)); /* Check if should start deceleration */ if(dev->mode != MSSTC_MODE_SPEED_OPEN && dev->stepCountCurrent >= dev->decelStart){ MSSTC_PulseToggle = 1; MSSTC_CelCount = -1 * (int32_t)dev->decelSteps; dev->runState = MSSTC_STATE_DECEL; } /* Check if reached maximum dev->fullSpeed */ else if(MSSTC_NewStepDelay <= MSSTC_FastStepDelay){ MSSTC_LastDelay = MSSTC_NewStepDelay; MSSTC_CelCount = -1 * (int32_t)dev->decelSteps; dev->runState = MSSTC_STATE_FULL; } break; } case MSSTC_STATE_FULL: { if(dev->mode == MSSTC_MODE_SPEED_OPEN){ dev->stepCountCurrent = 0; } else{ dev->stepCountCurrent++; } MSSTC_NewStepDelay = MSSTC_FastStepDelay; // MSSTC_LastDelay = MSSTC_NewStepDelay; /* Check if should start deceleration */ if(dev->stepCountCurrent >= dev->decelStart){ MSSTC_PulseToggle = 1; MSSTC_Rest = 0; MSSTC_CelCount = -1 * (int32_t)dev->decelSteps; MSSTC_NewStepDelay = MSSTC_LastDelay; dev->runState = MSSTC_STATE_DECEL; } break; } case MSSTC_STATE_DECEL: { dev->stepCountCurrent++; MSSTC_CelCount++; /* Check if this is the last step */ if(MSSTC_CelCount >= 0){ dev->runState = MSSTC_STATE_STOP; break; } if(MSSTC_StepDiff == 0){ MSSTC_NewStepDelay = MSSTC_StepDelay - ((2 * MSSTC_StepDelay + MSSTC_Rest) / (4 * MSSTC_CelCount + 1)); MSSTC_Rest = ((2 * MSSTC_StepDelay + MSSTC_Rest) % (4 * MSSTC_CelCount + 1)); MSSTC_LastDelay = MSSTC_NewStepDelay; } break; } default: { if(dev->powerOnlyRun == 1){ dev->enable = 0; dev->enSet(dev->enable); } break; } } if(MSSTC_NewStepDelay <= 1){ MSSTC_NewStepDelay = 2; } MSSTC_StepDelay = MSSTC_NewStepDelay; } } /** * @brief Stop motor immediately but not clear params data * @param dev Pointer to motor device structure */ void MSSTC_Scram(struct MOTOR_STEP_SPEED_T_C_ATY_Dev* dev){ dev->runState = MSSTC_STATE_STANDBY; if(dev->powerOnlyRun == 1){ dev->enable = 0; dev->enSet(dev->enable); } dev->stop(); } void MSSTC_Stop(struct MOTOR_STEP_SPEED_T_C_ATY_Dev* dev){ MSSTC_CelCount = -1 * (int32_t)dev->decelSteps; dev->runState = MSSTC_STATE_DECEL; dev->start(); MSSTC_IRQHandler(dev); } void MSSTC_UpdateFullSpeed(struct MOTOR_STEP_SPEED_T_C_ATY_Dev* dev){ float alpha = 2.0 * 3.14159265359 / (dev->fullSteps * dev->microstepping); MSSTC_FastStepDelay = (uint32_t)(alpha * dev->timerFreq * dev->unitDivision / dev->fullSpeed); dev->setTimerCompare(MSSTC_FastStepDelay); } /** * @brief Check if motor is running * @param dev Pointer to motor device structure * @return 1=running, 0=stopped */ uint8_t MSSTC_IsRunning(struct MOTOR_STEP_SPEED_T_C_ATY_Dev* dev){ return (dev->runState == MSSTC_STATE_STANDBY) ? 0 : 1; } /** * @brief MSSTC_Compensate * * @param dev */ void MSSTC_Compensate(struct MOTOR_STEP_SPEED_T_C_ATY_Dev* dev){ if(dev->runState != MSSTC_STATE_COMPENSATE){ return; } uint32_t publicTurns = ((MSSTC_TargetTurn < MSSTC_CurrentTurn) ? MSSTC_TargetTurn : MSSTC_CurrentTurn); float targetAngleTotal = 360.0 * (MSSTC_TargetTurn - publicTurns) + MSSTC_TargetAngle; float currentAngleTotal = 360.0 * (MSSTC_CurrentTurn - publicTurns) + MSSTC_CurrentAngle; MSSTC_StepDiff = (int32_t)((targetAngleTotal - currentAngleTotal) / MSSTC_AnglePerStep); if(MSSTC_StepDiff > 1 || MSSTC_StepDiff < -1){ if(MSSTC_StepDiff < 0){ if(dev->turnBackAllowed == 1){ MSSTC_CelCount = MSSTC_StepDiff; dev->dirSet(dev->direction ^ 0x01); } else{ dev->runState = MSSTC_STATE_STANDBY; if(dev->powerOnlyRun == 1){ dev->enable = 0; dev->enSet(dev->enable); } } } else{ dev->dirSet(dev->direction); MSSTC_CelCount = -1 * MSSTC_StepDiff; } dev->runState = MSSTC_STATE_DECEL; MSSTC_CelCountErrCount++; if(MSSTC_CelCountErrCount > 5){ dev->runState = MSSTC_STATE_STANDBY; if(dev->powerOnlyRun == 1){ dev->enable = 0; dev->enSet(dev->enable); } } else{ dev->start(); } } else{ dev->runState = MSSTC_STATE_STANDBY; if(dev->powerOnlyRun == 1){ dev->enable = 0; dev->enSet(dev->enable); } } } /** * @brief Update current angle * @param dev Pointer to motor device structure * @param turn Turn count * @param angle Current angle */ void MSSTC_UpdateAngle(struct MOTOR_STEP_SPEED_T_C_ATY_Dev* dev, uint32_t turn, float angle){ MSSTC_CurrentTurn = turn; MSSTC_CurrentAngle = angle; MSSTC_Compensate(dev); } #endif /* __MOTOR_STEP_SPEED_T_C_ATY_C */ /************************************ etc *************************************/ /* init #define MS_1_TIM htim1 #define MS_1_TIM_CHANNEL TIM_CHANNEL_1 #define MS_1_TIM_IT_CC TIM_IT_CC1 // MSSTC ----------------------------------------------------------------------- #include "MOTOR_STEP_SPEED_T_C_ATY.h" uint8_t MSSTC_1_EnSet(uint8_t en){ HAL_GPIO_WritePin(MS_EN_GPIO_Port, MS_EN_Pin, (en == 0) ? GPIO_PIN_SET : GPIO_PIN_RESET); return 0; } uint8_t MSSTC_1_DirSet(uint8_t dir){ HAL_GPIO_WritePin(MS_DIR_GPIO_Port, MS_DIR_Pin, (dir == __ATY_PN_P) ? GPIO_PIN_SET : GPIO_PIN_RESET); return 0; } void MSSTC_1_SetTimerCompare(uint32_t value){ __HAL_TIM_SET_COMPARE(&MS_1_TIM, MS_1_TIM_CHANNEL, value); __HAL_TIM_SET_COUNTER(&MS_1_TIM, 0); } void MSSTC_1_Start(void){ HAL_TIM_OC_Start_IT(&MS_1_TIM, MS_1_TIM_CHANNEL); } void MSSTC_1_Stop(void){ HAL_TIM_OC_Stop_IT(&MS_1_TIM, MS_1_TIM_CHANNEL); } struct MOTOR_STEP_SPEED_T_C_ATY_Dev MSSTC_Dev_1 = { .enSet = MSSTC_1_EnSet, .dirSet = MSSTC_1_DirSet, .start = MSSTC_1_Start, .stop = MSSTC_1_Stop, .setTimerCompare = MSSTC_1_SetTimerCompare, .timerFreq = 1000000, .fullSteps = 200, .microstepping = 8, .enable = 0, .direction = __ATY_PN_P, .fullSpeed = 20, .unitDivision = 1, .acceleration = 100, .deceleration = 200, .mode = 0, .angleLock = 0, .powerOnlyRun = 1, .runState = MSSTC_STATE_STANDBY, .lock = __ATY_UNLOCKED }; void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef* htim){ if(htim->Instance == TIM1 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1){ if(__HAL_TIM_GET_IT_SOURCE(&MS_1_TIM, MS_1_TIM_IT_CC) != RESET){ __HAL_TIM_CLEAR_IT(&MS_1_TIM, MS_1_TIM_IT_CC); MSSTC_IRQHandler(&MSSTC_Dev_1); } } } void MSSTC_1_Init(void){ HAL_GPIO_WritePin(MS_SP_GPIO_Port, MS_SP_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(MS_MS1_GPIO_Port, MS_MS1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(MS_MS2_GPIO_Port, MS_MS2_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(MS_EN_GPIO_Port, MS_EN_Pin, GPIO_PIN_SET); RGF_MOTOR_FREQUENCY = (1600.0 / 60.0); RGF_MOTOR_DUTY_CYCLE = 50.0; RGF_MOTOR_FULL_STEPS = MSSTC_Dev_1.fullSteps; RGF_MOTOR_MICROSTEPPING = MSSTC_Dev_1.microstepping; RGF_MOTOR_ENABLE = MSSTC_Dev_1.enable; RGF_MOTOR_DIRECTION = MSSTC_Dev_1.direction; RGF_MOTOR_SPEED = MSSTC_Dev_1.fullSpeed; RGF_MOTOR_UNIT_DIVISION = MSSTC_Dev_1.unitDivision; RGF_MOTOR_ACCELERATION = MSSTC_Dev_1.acceleration; RGF_MOTOR_DECELERATION = MSSTC_Dev_1.deceleration; RGF_MOTOR_MODE = MSSTC_Dev_1.mode; RGF_MOTOR_ANGLE_LOCK_TARGET = MSSTC_Dev_1.angleLock; RGF_MOTOR_AUTO_POWER = MSSTC_Dev_1.powerOnlyRun; RGF_MOTOR_RUN_STATE = MSSTC_Dev_1.runState; RGF_MOTOR_RUN = 1; RGF_MOTOR_STEP_COUNT = 1600; } void MSSTC_1_Cycle(void){ if(MSSTC_IsRunning(&MSSTC_Dev_1) != 1){ MSSTC_Dev_1.fullSteps = (uint16_t)RGF_MOTOR_FULL_STEPS; if(MSSTC_Dev_1.microstepping != (uint16_t)RGF_MOTOR_MICROSTEPPING){ MSSTC_Dev_1.microstepping = (uint16_t)RGF_MOTOR_MICROSTEPPING; MSSTC_Dev_1.enSet(0); if(MSSTC_Dev_1.microstepping == 8){ HAL_GPIO_WritePin(MS_MS1_GPIO_Port, MS_MS1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(MS_MS2_GPIO_Port, MS_MS2_Pin, GPIO_PIN_RESET); } else if(MSSTC_Dev_1.microstepping == 16){ HAL_GPIO_WritePin(MS_MS1_GPIO_Port, MS_MS1_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(MS_MS2_GPIO_Port, MS_MS2_Pin, GPIO_PIN_SET); } else if(MSSTC_Dev_1.microstepping == 32){ HAL_GPIO_WritePin(MS_MS1_GPIO_Port, MS_MS1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(MS_MS2_GPIO_Port, MS_MS2_Pin, GPIO_PIN_SET); } else if(MSSTC_Dev_1.microstepping == 64){ HAL_GPIO_WritePin(MS_MS1_GPIO_Port, MS_MS1_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(MS_MS2_GPIO_Port, MS_MS2_Pin, GPIO_PIN_RESET); } if(MSSTC_Dev_1.powerOnlyRun == 0){ MSSTC_Dev_1.enSet(MSSTC_Dev_1.enable); } } if(MSSTC_Dev_1.enable != (uint8_t)RGF_MOTOR_ENABLE){ MSSTC_Dev_1.enable = (uint8_t)RGF_MOTOR_ENABLE; if(MSSTC_Dev_1.powerOnlyRun == 0){ MSSTC_Dev_1.enSet(MSSTC_Dev_1.enable); } } if(MSSTC_Dev_1.direction != (uint8_t)RGF_MOTOR_DIRECTION){ MSSTC_Dev_1.direction = (uint8_t)RGF_MOTOR_DIRECTION; MSSTC_Dev_1.dirSet(MSSTC_Dev_1.direction); } MSSTC_Dev_1.fullSpeed = (uint16_t)RGF_MOTOR_SPEED; MSSTC_Dev_1.unitDivision = (uint8_t)RGF_MOTOR_UNIT_DIVISION; MSSTC_Dev_1.acceleration = (uint16_t)RGF_MOTOR_ACCELERATION; MSSTC_Dev_1.deceleration = (uint16_t)RGF_MOTOR_DECELERATION; MSSTC_Dev_1.mode = (uint8_t)RGF_MOTOR_MODE; if(MSSTC_Dev_1.angleLock != (uint8_t)RGF_MOTOR_ANGLE_LOCK_TARGET){ MSSTC_Dev_1.angleLock = (uint8_t)RGF_MOTOR_ANGLE_LOCK_TARGET; if(MSSTC_Dev_1.mode == 1){ } } if(MSSTC_Dev_1.powerOnlyRun != (uint8_t)RGF_MOTOR_AUTO_POWER){ MSSTC_Dev_1.powerOnlyRun = (uint8_t)RGF_MOTOR_AUTO_POWER; if(MSSTC_Dev_1.powerOnlyRun == 0){ MSSTC_Dev_1.enSet(MSSTC_Dev_1.enable); } else{ MSSTC_Dev_1.enSet(0); } } } MT6816_1_UpdateCycle(); MSSTC_UpdateAngle(&MSSTC_Dev_1, MT6816_ATY_Dev_1.turnCount, MT6816_ATY_Dev_1.angleTotal + MT6816_ATY_Dev_1.angleStart); if((uint8_t)RGF_MOTOR_RUN == 1){ MT6816_TurnCountOffsetStart(&MT6816_ATY_Dev_1, MSSTC_Dev_1.direction); MSSTC_Move(&MSSTC_Dev_1, RGF_MOTOR_STEP_COUNT, MT6816_ATY_Dev_1.angleStart); } else if((uint8_t)RGF_MOTOR_RUN == 2){ MSSTC_Scram(&MSSTC_Dev_1); } RGF_MOTOR_RUN = 0; if(MSSTC_Dev_1.runState == MSSTC_STATE_STANDBY && MT6816_ATY_Dev_1.start == 1){ MT6816_TurnCountOffsetStop(&MT6816_ATY_Dev_1); } RGF_MOTOR_ENABLE = MSSTC_Dev_1.enable; RGF_MOTOR_DIRECTION = MSSTC_Dev_1.direction; RGF_MOTOR_RUN_STATE = MSSTC_Dev_1.runState; RGF_MOTOR_CURRENT_STEPS = MSSTC_Dev_1.stepCountCurrent; RGF_MOTOR_ACCEL_STEPS = MSSTC_Dev_1.accelSteps; RGF_MOTOR_ACCEL_LIMIT = MSSTC_Dev_1.accelLimit; RGF_MOTOR_DECEL_STEPS = MSSTC_Dev_1.decelSteps; RGF_MOTOR_DECEL_START = MSSTC_Dev_1.decelStart; } */ /* use MSSTC_1_Init(); MSSTC_1_Cycle(); // Reg ------------------------------------------------------------------------- // motor fan #define RGF_MOTOR_FAN_EN rgf[20] #define RGF_MOTOR_FAN_BASE rgf[21] #define RGF_MOTOR_FAN_LOW_T rgf[22] #define RGF_MOTOR_FAN_HIGH_T rgf[23] #define RGF_MOTOR_FAN_T_SPACE rgf[24] // motor angle base #define RGF_MOTOR_ANGLE_SET_ZERO rgf[25] #define RGF_MOTOR_ANGLE_ZERO rgf[26] #define RGF_MOTOR_ANGLE rgf[27] #define RGF_MOTOR_ANGLE_ERR rgf[28] // motor angle correction #define RGF_MOTOR_ANGLE_ANGLE_START rgf[30] #define RGF_MOTOR_ANGLE_TURN_COUNT rgf[31] #define RGF_MOTOR_ANGLE_ANGLE_TOTAL rgf[32] #define RGF_MOTOR_ANGLE_START rgf[33] // useless motor params #define RGF_MOTOR_FREQUENCY rgf[35] #define RGF_MOTOR_DUTY_CYCLE rgf[36] #define RGF_MOTOR_FULL_STEPS rgf[38] #define RGF_MOTOR_MICROSTEPPING rgf[39] // motor base #define RGF_MOTOR_ENABLE rgf[40] #define RGF_MOTOR_DIRECTION rgf[41] #define RGF_MOTOR_SPEED rgf[42] #define RGF_MOTOR_UNIT_DIVISION rgf[43] #define RGF_MOTOR_ACCELERATION rgf[44] #define RGF_MOTOR_DECELERATION rgf[45] #define RGF_MOTOR_MODE rgf[46] #define RGF_MOTOR_ANGLE_LOCK_TARGET rgf[47] #define RGF_MOTOR_AUTO_POWER rgf[48] #define RGF_MOTOR_RUN_STATE rgf[49] #define RGF_MOTOR_RUN rgf[50] #define RGF_MOTOR_STEP_COUNT rgf[51] #define RGF_MOTOR_CURRENT_STEPS rgf[52] #define RGF_MOTOR_ACCEL_STEPS rgf[53] #define RGF_MOTOR_ACCEL_LIMIT rgf[54] #define RGF_MOTOR_DECEL_STEPS rgf[55] #define RGF_MOTOR_DECEL_START rgf[56] // FAN ------------------------------------------------------------------------- uint8_t fanLastLevel = 0; void FAN_ControlCycle(void){ if((uint8_t)RGF_MOTOR_FAN_EN == 1 && RGF_BOARD_TEMP > RGF_MOTOR_FAN_LOW_T){ if((uint8_t)((RGF_BOARD_TEMP - RGF_MOTOR_FAN_LOW_T) / RGF_MOTOR_FAN_T_SPACE) + 1 != fanLastLevel){ fanLastLevel = (uint8_t)((RGF_BOARD_TEMP - RGF_MOTOR_FAN_LOW_T) / RGF_MOTOR_FAN_T_SPACE) + 1; HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1); __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, RGF_MOTOR_FAN_BASE + ((1000 - RGF_MOTOR_FAN_BASE) * fanLastLevel / ((RGF_MOTOR_FAN_HIGH_T - RGF_MOTOR_FAN_LOW_T) / RGF_MOTOR_FAN_T_SPACE))); HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); } } else{ __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0); HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1); fanLastLevel = 0; } } void FAN_Init(void){ RGF_MOTOR_FAN_EN = 1; RGF_MOTOR_FAN_BASE = 200; RGF_MOTOR_FAN_LOW_T = 50; RGF_MOTOR_FAN_HIGH_T = 80; RGF_MOTOR_FAN_T_SPACE = 5; } */ /******************************************************************************/ /******************************** End Of File *********************************/