This repository has been archived on 2025-01-02. You can view files and clone it, but cannot push or open issues or pull requests.
torsion/User/board/motor.c

120 lines
3.9 KiB
C

#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);
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);
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);
}
}
static void step_motor_set_speed(motor_t *motor, uint32_t psc)
{
}
/**
* @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;
motor->handle.step_motor.interface.set_speed = step_motor_set_speed;
break;
default:
return NULL;
}
return motor;
}