#include "motor.h" /*****步进电机接口******/ static void step_motor_init(motor_t *motor, gpio_t dir, gpio_t en, float32 min_step_angle, TIM_TypeDef *pwm_timer, uint32_t pwm_channel) { DBG_ASSERT(motor != NULL __DBG_LINE); motor->handle.step_motor.gpios.dir = gpio_create(dir.port, dir.pin); motor->handle.step_motor.gpios.en = gpio_create(en.port, en.pin); motor->handle.step_motor.pwm_timer = pwm_timer; motor->handle.step_motor.pwm_channel = pwm_channel; motor->handle.step_motor.attribute.min_step_angle = min_step_angle; PWM_STOP(motor->handle.step_motor.pwm_timer, motor->handle.step_motor.pwm_channel); } static void step_motor_run(motor_t *motor, dir_e dir) { DBG_ASSERT(motor != NULL __DBG_LINE); step_motor_t *handle = &motor->handle.step_motor; DBG_ASSERT(handle != NULL __DBG_LINE); handle->attribute.dir = dir; handle->attribute.en = TRUE; dir == DIR_CCW ? handle->gpios.dir->set(*handle->gpios.dir) : handle->gpios.dir->reset(*handle->gpios.dir); LL_TIM_EnableIT_UPDATE(handle->pwm_timer); // LL_TIM_EnableIT_CC2(handle->pwm_timer); PWM_START(handle->pwm_timer, handle->pwm_channel); } static void step_motor_stop(motor_t *motor) { DBG_ASSERT(motor != NULL __DBG_LINE); step_motor_t *handle = &motor->handle.step_motor; DBG_ASSERT(handle != NULL __DBG_LINE); handle->attribute.en = FALSE; handle->attribute.angle = 0; handle->attribute.pulse_count = 0; PWM_STOP(handle->pwm_timer, handle->pwm_channel); LL_TIM_DisableIT_UPDATE(handle->pwm_timer); LL_TIM_ClearFlag_UPDATE(TIM21); if (handle->interface.stop_cb != NULL) { handle->interface.stop_cb(motor); } } static void step_motor_set_angle(motor_t *motor, float32 angle, dir_e dir) { DBG_ASSERT(motor != NULL __DBG_LINE); step_motor_t *handle = &motor->handle.step_motor; DBG_ASSERT(handle != NULL __DBG_LINE); if (TRUE == handle->attribute.en) { return; } handle->attribute.pulse_count = angle / handle->attribute.min_step_angle; handle->attribute.step_angle = 0; if (handle->attribute.pulse_count == 0) { handle->interface.stop(motor); } else { handle->interface.run(motor, dir); } } /** * @brief 步进电机中断处理函数 * @param {motor_t} *motor * @return {*} * @note */ void step_motor_update(motor_t *motor) { DBG_ASSERT(motor != NULL __DBG_LINE); step_motor_t *handle = &motor->handle.step_motor; DBG_ASSERT(handle != NULL __DBG_LINE); handle->attribute.pulse_count--; /* 每一个完整的脉冲就-- */ handle->attribute.step_angle++; /* 每一个完整的脉冲就++ */ if (handle->attribute.dir == DIR_CW) { handle->attribute.add_pulse_count++; /* 绝对位置++ */ } else { handle->attribute.add_pulse_count--; /* 绝对位置-- */ } if (handle->attribute.pulse_count <= 0) /* 当脉冲数等于0的时候 代表需要发送的脉冲个数已完成,停止定时器输出 */ { LOG_PRINT("累计旋转的角度:%d\r\n", (int)(handle->attribute.add_pulse_count * handle->attribute.min_step_angle)); /* 打印累计转动了多少角度 */ handle->interface.stop(motor); /* 停止接口一输出 */ } } motor_t *motor_create(motor_type_e motor_type) { motor_t *motor = (motor_t *)osel_mem_alloc(sizeof(motor_t)); DBG_ASSERT(motor != NULL __DBG_LINE); osel_memset((uint8_t *)motor, 0, sizeof(motor_t)); motor->type = motor_type; switch (motor_type) { case STEP_MOTOR: motor->handle.step_motor.interface.init = step_motor_init; motor->handle.step_motor.interface.run = step_motor_run; motor->handle.step_motor.interface.stop = step_motor_stop; motor->handle.step_motor.interface.set_angle = step_motor_set_angle; break; default: return NULL; } return motor; }