本帖最后由 zero949079783 于 2021-11-20 11:42 编辑
开发环境:VSCODE(gcc编译链)+STM32CubeMX(也可以使用HUAWEI-LiteOS-Studio) 。 代码:链接:https://pan.baidu.com/s/1uXfIR0GFQOBZPl1NfQP08w
提取码:6b0c
数字舵机主要由马达、减速齿轮、控制电路等组成,只需要发送一次PWM信号就能保持在规定的某个位置。
而模拟舵机是相同于传统的舵机,是需要多次发送PWM信号才能够保持在规定的位置上,实现对舵机的控制,按照规定的要求进行的速度进行转动。
数字舵机在反应速度方面与模拟舵机相比是由优势的。因为数字舵机是拥有微处理器。
下面我们介绍的SG90舵机就是模拟舵机。
控制原理及PWM配置
1)180度
模拟舵机的PWM频率为50HZ,对应的时基周期/PWM周期为20ms。我们的高电平脉宽是在0.5ms—2.5ms进行控制的。
PWM周期为20ms = (72*20000)/72000000=0.02
所以TIM_Period = 19999 //自动重装载值
TIM_Prescaler = 71 //预分频系数
占空比 = t / T 相关参数如下:
t = 0.5ms——————-舵机会转动 0 °
t = 1.0ms——————-舵机会转动 45°
t = 1.5ms——————-舵机会转动 90°
t = 2.0ms——————-舵机会转动 135°
t = 2.5ms——————-舵机会转动180°
比如说舵机旋转90度,对应高电平时间为1.5ms:
t=1.5ms=1500us
t/T =1500us/2000us=X/20000
X=1500
#include "Servo_Motor.h"
uint16_t pwm_val =500; //
void TimCH_Config(void)
{
//HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
// HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);
//HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
pwm_val =2500;
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, pwm_val); // 180
printf("\r\n舵机角度 = %d度\r\n",(pwm_val-500)/SERVODEG_NUM*9);
HAL_Delay(500);
pwm_val =500;
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, pwm_val); // 0
printf("\r\n舵机角度 = %d度\r\n",(pwm_val-500)/SERVODEG_NUM*9);
HAL_Delay(500);
HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_2);
HAL_Delay(500);
//HAL_TIM_PWM_Start_IT(&htim3,TIM_CHANNEL_2);
}
//PWM非中断输出
void Servo_Motor_OUT(void)
{
for(uint16_t i=500;i<=2500;i=i+1) //0-180度
{
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, i);
HAL_Delay(10);
}
HAL_Delay(1000);
for(uint16_t i=2500;i>=500;i=i-1) //180-0度
{
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, i);
HAL_Delay(10);
}
// __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, 500); //0
// HAL_Delay(500);
// __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, 1000); //45
// HAL_Delay(500);
// __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, 1500); //90
// HAL_Delay(500);
// __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, 2000);//135
// HAL_Delay(500);
// __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, 2500); //180
// HAL_Delay(500);
// __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, 2500); //180
// HAL_Delay(500);
// __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, 2000);//135
// HAL_Delay(500);
// __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, 1500);//90
// HAL_Delay(500);
// __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, 1000);//45
// HAL_Delay(500);
// __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, 500);//0
// HAL_Delay(500);
}
//PWM 中断回调函数
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
static uint8_t Servo_Dir_Flag = 1; //舵机方向标志 1为0-180度,0为180-0度
if(htim->Instance == TIM3)
{
HAL_TIM_PWM_Stop_IT(&htim3,TIM_CHANNEL_2); //关中断
if(Servo_Dir_Flag == 1)
{
pwm_val=pwm_val+SERVODEG_NUM; //脉冲数 一个脉冲为10US
if(pwm_val >= 2500)
{
Servo_Dir_Flag = 0;
}
}
else
{
pwm_val=pwm_val-SERVODEG_NUM; //脉冲数 一个脉冲为10US
if(pwm_val <= 500)
{
pwm_val=500; //在0度,PWM为500
Servo_Dir_Flag = 1;
}
}
//角度从为开始pwm_val-500
//显示角度 =脉冲数*9
printf("\r\n舵机角度 = %d度\r\n",(pwm_val-500)/SERVODEG_NUM*9); //显示角度 = 舵机走0.09度 = 45/脉冲数
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2,pwm_val);
}
}
HAL_TIM_PWM_Start_IT(&htim3,TIM_CHANNEL_2); //打开PWM中断
|