| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- /**
- * @file MOTOR_STEP_O_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 -
- * <a href="https://mengze.top/MZ-ATY_VCJS">
- * https://mengze.top/MZ-ATY_VCJS</a>
- * - CC 4.0 BY-NC-SA -
- * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
- * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
- * - Your use will be deemed to have accepted the terms of this statement.
- *
- * @brief functions of open loop stepper motor control for C platform
- *
- * @note Slave Mode: Disable
- * Trigger Source: Disable
- * Clock Source: Internal Clock
- * Channel2: PWM Generation CH2
- * Prescaler: 71
- * Counter Mode: Up
- * Counter Period: 999
- * Internal Clock Division: No Division
- * auto-reload preload: Disable
- * Master/Slave Mode (MSM bit): Disable
- * Trigger Event Selection: Update Event
- * PWM Generation Channel 2 Mode: PWM mode 2
- * Pulse: 499
- * Output compare preload: Enable
- * Fast Mode: Disable
- * CH Polarity: High
- * CH Idle State: Reset
- *
- * htim1.Init.Prescaler = 71;
- * htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
- * htim1.Init.Period = 999;
- * htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
- * htim1.Init.RepetitionCounter = 0;
- * htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
- * sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
- * sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
- * sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
- * sConfigOC.OCMode = TIM_OCMODE_PWM2;
- * sConfigOC.Pulse = 499;
- * sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
- * sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
- * sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
- * sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
- * sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
- * htim2.Init.Prescaler = 0;
- * htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
- * htim2.Init.Period = 65535;
- * htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
- * htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
- * sSlaveConfig.SlaveMode = TIM_SLAVEMODE_GATED;
- * sSlaveConfig.InputTrigger = TIM_TS_ITR0;
- * sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
- * sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
- *
- * @version
- * - 1_00_260109 > ATY
- * -# Preliminary version
- ********************************************************************************
- */
- #ifndef __MOTOR_STEP_O_ATY_C
- #define __MOTOR_STEP_O_ATY_C
- #include "MOTOR_STEP_O_ATY.h"
- #define MOTOR_STEP_O_ATY_TAG "\r\n[MOTOR_STEP_O_ATY] "
- /******************************* For user *************************************/
- /******************************************************************************/
- /**
- * @brief open loop stepper motor control
- *
- * @param dev
- * @param mode
- * @param enable
- * @param direction
- * @param stepCount
- * @param frequency
- * @param dutyCycle
- * @param speed
- * @return uint8_t 0: no update, 1: update, only for register update, en and dir is hardware
- * @note - Frequency and speed are mutually exclusive set, when set one, another
- * is auto calculate and update, speed has higher priority.
- * - When use speed, dutyCycle will set to 50% automatically.
- * - This function based on diff input and dev registers, so do not forget
- * update input registers back after update, like MSO_1_ValueUpdateBack().
- */
- uint8_t MSO_Cycle(struct MOTOR_STEP_O_ATY_Dev* dev,
- uint8_t mode, uint8_t enable, uint8_t direction,
- uint16_t stepCount,
- float frequency, float dutyCycle, float speed){
- uint8_t regUpdateFlag = 0;
- if(mode != dev->mode){
- dev->mode = mode;
- regUpdateFlag = 1;
- }
- if(enable != dev->enable){
- dev->enable = enable;
- dev->enSet(dev->enable);
- if(regUpdateFlag == 0) regUpdateFlag = 2;
- }
- if(direction != dev->direction){
- dev->direction = direction;
- dev->dirSet(dev->direction);
- if(regUpdateFlag == 0) regUpdateFlag = 2;
- }
- if(stepCount != dev->stepCount){
- dev->stepCount = stepCount;
- if(regUpdateFlag == 0) regUpdateFlag = 2;
- if(dev->mode == MOTOR_OPEN_MODE_COUNT)
- regUpdateFlag = 1;
- }
- if(speed != dev->speed){
- dev->speed = speed;
- dev->frequency = (dev->speed * (dev->fullSteps
- * dev->microstepping) / 60.0);
- dev->dutyCycle = 50.0;
- if(regUpdateFlag == 0) regUpdateFlag = 2;
- if(dev->mode == MOTOR_OPEN_MODE_NOCOUNT
- || (dev->mode == MOTOR_OPEN_MODE_COUNT && dev->stepCount == 1))
- regUpdateFlag = 1;
- }
- else if(frequency != dev->frequency
- || dutyCycle != dev->dutyCycle){
- dev->frequency = frequency;
- dev->dutyCycle = dutyCycle;
- if(dev->dutyCycle < 0) dev->dutyCycle = 0;
- else if(dev->dutyCycle > 100) dev->dutyCycle = 100;
- dev->speed = (dev->frequency * 60.0
- / (dev->fullSteps * dev->microstepping));
- if(regUpdateFlag == 0) regUpdateFlag = 2;
- if(dev->mode == MOTOR_OPEN_MODE_NOCOUNT
- || (dev->mode == MOTOR_OPEN_MODE_COUNT && dev->stepCount == 1))
- regUpdateFlag = 1;
- }
- if(regUpdateFlag == 1 && dev->mode == MOTOR_OPEN_MODE_COUNT){
- dev->pwmSetCount(dev->frequency, dev->dutyCycle, dev->stepCount);
- }
- else if(regUpdateFlag == 1 && dev->mode == MOTOR_OPEN_MODE_NOCOUNT){
- dev->pwmSet(dev->frequency, dev->dutyCycle);
- }
- return regUpdateFlag;
- }
- #endif /* __MOTOR_STEP_O_ATY_C */
- /************************************ etc *************************************/
- /* init
- #define MS_1_TIM htim1
- #define MS_1_TIM_CHANNEL TIM_CHANNEL_2
- #define MS_1_TIM_IT_CC TIM_IT_CC2
- #define MS_1_COUNT_TIM htim2
- // MOTOR Open ------------------------------------------------------------------
- #include "MOTOR_STEP_O_ATY.h"
- uint8_t MSO_1_EnSet(uint8_t en){
- HAL_GPIO_WritePin(MS_EN_GPIO_Port, MS_EN_Pin,
- (en == 0) ? GPIO_PIN_SET : GPIO_PIN_RESET);
- return __ATY_OK;
- }
- uint8_t MSO_1_DirSet(uint8_t dir){
- HAL_GPIO_WritePin(MS_DIRO_GPIO_Port, MS_DIRO_Pin,
- (dir == __ATY_PN_P) ? GPIO_PIN_SET : GPIO_PIN_RESET);
- return __ATY_OK;
- }
- void MSO_1_PWM_NoCount(float freq, float dutycycle){
- uint32_t ticksPeriod = 1000000U / freq;
- uint32_t ticksPulse = ticksPeriod * (100.0 - dutycycle) / 100.0;
- HAL_TIM_PWM_Stop(&MS_1_TIM, MS_1_TIM_CHANNEL);
- __HAL_TIM_SET_COUNTER(&MS_1_TIM, 0);
- __HAL_TIM_SET_AUTORELOAD(&MS_1_TIM, ticksPeriod - 1);
- __HAL_TIM_SET_COMPARE(&MS_1_TIM, MS_1_TIM_CHANNEL, ticksPulse - 1);
- HAL_TIM_PWM_Start(&MS_1_TIM, MS_1_TIM_CHANNEL);
- }
- void MSO_1_PWM_Count(float freq, float dutycycle, uint16_t step){
- uint32_t ticksPeriod = 1000000U / freq;
- uint32_t ticksPulse = ticksPeriod * (100.0 - dutycycle) / 100.0;
- HAL_TIM_PWM_Stop(&MS_1_TIM, MS_1_TIM_CHANNEL);
- HAL_TIM_Base_Stop_IT(&MS_1_COUNT_TIM);
- __HAL_TIM_SET_COUNTER(&MS_1_TIM, 0);
- // Set 1 to make sure the system can generate one pulse
- __HAL_TIM_SET_COUNTER(&MS_1_COUNT_TIM, 1);
- if(step != 0){
- // init counter 1, then do not need -1
- __HAL_TIM_SET_AUTORELOAD(&MS_1_COUNT_TIM, step);
- __HAL_TIM_SET_AUTORELOAD(&MS_1_TIM, ticksPeriod - 1);
- __HAL_TIM_SET_COMPARE(&MS_1_TIM, MS_1_TIM_CHANNEL, ticksPulse - 1);
- HAL_TIM_Base_Start_IT(&MS_1_COUNT_TIM);
- HAL_TIM_PWM_Start(&MS_1_TIM, MS_1_TIM_CHANNEL);
- }
- }
- struct MOTOR_STEP_O_ATY_Dev MOTOR_STEP_O_ATY_Dev_1 = {
- .enSet = MSO_1_EnSet,
- .dirSet = MSO_1_DirSet,
- .pwmSet = MSO_1_PWM_NoCount,
- .pwmSetCount = MSO_1_PWM_Count,
- .mode = 0xFF,
- .enable = 0xFF,
- .direction = 0xFF,
- .stepCount = 0xFFFF,
- .frequency = -1.0,
- .dutyCycle = -1.0,
- .speed = -1.0,
- .fullSteps = 200,
- .microstepping = 8,
- .lock = __ATY_UNLOCKED
- };
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim){
- if(htim == &htim4){
- UserTimerLoop_Cycle1ms(&HW_TIMER_ATY_Dev_4);
- }
- if((uint8_t)RGF_MOTOR_MODE == 0 && htim == &MS_1_COUNT_TIM){
- HAL_TIM_PWM_Stop(&MS_1_TIM, MS_1_TIM_CHANNEL);
- HAL_TIM_Base_Stop_IT(&MS_1_COUNT_TIM);
- RGF_MOTOR_STEP_COUNT = 0;
- MOTOR_STEP_O_ATY_Dev_1.stepCount = 0;
- }
- }
- void MSO_1_ValueUpdateBack(struct MOTOR_STEP_O_ATY_Dev* dev){
- RGF_MOTOR_MODE = dev->mode;
- RGF_MOTOR_ENABLE = dev->enable;
- RGF_MOTOR_DIRECTION = dev->direction;
- // RGF_MOTOR_STEP_COUNT = dev->stepCount;
- RGF_MOTOR_FREQUENCY = dev->frequency;
- RGF_MOTOR_DUTY_CYCLE = dev->dutyCycle;
- RGF_MOTOR_SPEED = dev->speed;
- }
- void MSO_1_Init(void){
- RGF_MOTOR_MODE = MOTOR_OPEN_MODE_COUNT;
- RGF_MOTOR_ENABLE = 1;
- RGF_MOTOR_DIRECTION = __ATY_PN_P;
- RGF_MOTOR_STEP_COUNT = 10000;
- RGF_MOTOR_FREQUENCY = (1600.0 / 60.0);
- RGF_MOTOR_DUTY_CYCLE = 50.0;
- RGF_MOTOR_SPEED = 200.0;
- // Prevent from getting into an interruption from the very beginning
- __HAL_TIM_CLEAR_FLAG(&MS_1_COUNT_TIM, TIM_FLAG_UPDATE);
- }
- */
- /* use
- MSO_1_Init();
- // 100ms cycle
- if(MSO_Cycle(&MOTOR_STEP_O_ATY_Dev_1,
- (uint8_t)RGF_MOTOR_MODE,
- (uint8_t)RGF_MOTOR_ENABLE,
- (uint8_t)RGF_MOTOR_DIRECTION,
- (uint16_t)RGF_MOTOR_STEP_COUNT,
- RGF_MOTOR_FREQUENCY,
- RGF_MOTOR_DUTY_CYCLE,
- RGF_MOTOR_SPEED) != 0){
- MSO_1_ValueUpdateBack(&MOTOR_STEP_O_ATY_Dev_1);
- }
- */
- /******************************************************************************/
- /******************************** End Of File *********************************/
|