124 lines
4.3 KiB
C
124 lines
4.3 KiB
C
#include "servo_motor.h"
|
|
#include "stdlib.h"
|
|
#include "memory.h"
|
|
|
|
extern TIM_HandleTypeDef htim1;
|
|
/*第二版*/
|
|
static ServoInstance *servo_motor_instance[SERVO_MOTOR_CNT] = {NULL};
|
|
static int16_t compare_value[SERVO_MOTOR_CNT] = {0};
|
|
static uint8_t servo_idx = 0; // register servo_idx,是该文件的全局舵机索引,在注册时使用
|
|
|
|
// 通过此函数注册一个舵机
|
|
ServoInstance *ServoInit(Servo_Init_Config_s *Servo_Init_Config)
|
|
{
|
|
ServoInstance *servo = (ServoInstance *)malloc(sizeof(ServoInstance));
|
|
memset(servo, 0, sizeof(ServoInstance));
|
|
|
|
servo->Servo_type = Servo_Init_Config->Servo_type;
|
|
servo->htim = Servo_Init_Config->htim;
|
|
servo->Channel = Servo_Init_Config->Channel;
|
|
|
|
HAL_TIM_PWM_Start(Servo_Init_Config->htim, Servo_Init_Config->Channel);
|
|
servo_motor_instance[servo_idx++] = servo;
|
|
return servo;
|
|
}
|
|
|
|
/**
|
|
* @brief 写入自由角度数值
|
|
*
|
|
* @param Servo_Motor 注册的舵机实例
|
|
* @param S_angle 改变自由模式设定的角度
|
|
*/
|
|
void Servo_Motor_FreeAngle_Set(ServoInstance *Servo_Motor, int16_t S_angle)
|
|
{
|
|
switch (Servo_Motor->Servo_type)
|
|
{
|
|
case Servo180:
|
|
if (S_angle > 180)
|
|
S_angle = 180;
|
|
break;
|
|
case Servo270:
|
|
if (S_angle > 270)
|
|
S_angle = 270;
|
|
break;
|
|
case Servo360:
|
|
if (S_angle > 100)
|
|
S_angle = 100;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (S_angle < 0)
|
|
S_angle = 0;
|
|
Servo_Motor->Servo_Angle.free_angle = S_angle;
|
|
}
|
|
|
|
/**
|
|
* @brief 写入起始,终止角度数值
|
|
*
|
|
* @param Servo_Motor 注册的舵机实例
|
|
* @param Start_angle 起始角度
|
|
* @param Final_angle 终止角度
|
|
*/
|
|
void Servo_Motor_StartSTOP_Angle_Set(ServoInstance *Servo_Motor, int16_t Start_angle, int16_t Final_angle)
|
|
{
|
|
Servo_Motor->Servo_Angle.Init_angle = Start_angle;
|
|
Servo_Motor->Servo_Angle.Final_angle = Final_angle;
|
|
}
|
|
/**
|
|
* @brief 舵机模式选择
|
|
*
|
|
* @param Servo_Motor 注册的舵机实例
|
|
* @param mode 需要选择的模式
|
|
*/
|
|
void Servo_Motor_Type_Select(ServoInstance *Servo_Motor, int16_t mode)
|
|
{
|
|
Servo_Motor->Servo_Angle_Type = mode;
|
|
}
|
|
|
|
/**
|
|
* @brief 舵机输出控制
|
|
*
|
|
*/
|
|
void ServeoMotorControl()
|
|
{
|
|
ServoInstance *Servo_Motor;
|
|
|
|
for (size_t i = 0; i < servo_idx; i++)
|
|
{
|
|
if (servo_motor_instance[i])
|
|
{
|
|
Servo_Motor = servo_motor_instance[i];
|
|
|
|
switch (Servo_Motor->Servo_type)
|
|
{
|
|
case Servo180:
|
|
if (Servo_Motor->Servo_Angle_Type == Start_mode)
|
|
compare_value[i] = 0.5 * 20000 / 20 + Servo_Motor->Servo_Angle.Init_angle * 20000 / 20 / 90;
|
|
if (Servo_Motor->Servo_Angle_Type == Final_mode)
|
|
compare_value[i] = 0.5 * 20000 / 20 + Servo_Motor->Servo_Angle.Final_angle * 20000 / 20 / 90;
|
|
if (Servo_Motor->Servo_Angle_Type == Free_Angle_mode)
|
|
compare_value[i] = 0.5 * 20000 / 20 + Servo_Motor->Servo_Angle.free_angle * 20000 / 20 / 90;
|
|
__HAL_TIM_SET_COMPARE(Servo_Motor->htim, Servo_Motor->Channel, compare_value[i]);
|
|
break;
|
|
case Servo270:
|
|
if (Servo_Motor->Servo_Angle_Type == Start_mode)
|
|
compare_value[i] = 0.5 * 20000 / 20 + Servo_Motor->Servo_Angle.Init_angle * 20000 / 20 / 135;
|
|
if (Servo_Motor->Servo_Angle_Type == Final_mode)
|
|
compare_value[i] = 0.5 * 20000 / 20 + Servo_Motor->Servo_Angle.Final_angle * 20000 / 20 / 135;
|
|
if (Servo_Motor->Servo_Angle_Type == Free_Angle_mode)
|
|
compare_value[i] = 0.5 * 20000 / 20 + Servo_Motor->Servo_Angle.free_angle * 20000 / 20 / 135;
|
|
__HAL_TIM_SET_COMPARE(Servo_Motor->htim, Servo_Motor->Channel, compare_value[i]);
|
|
break;
|
|
case Servo360:
|
|
/*500-2500的占空比 500-1500对应正向转速 1500-2500对于反向转速*/
|
|
compare_value[i] = 500 + 20 * Servo_Motor->Servo_Angle.servo360speed;
|
|
__HAL_TIM_SET_COMPARE(Servo_Motor->htim, Servo_Motor->Channel, compare_value[i]);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|