最近学习STM32控制SG90舵机
学习过程中发现舵机转速过快,无法平缓的转向指定角度
在网上查找资料具体了解到
舵机的转速与舵机的目标角度和舵机的当前角度的差值呈正相关
下面这张图举个例子
假设舵机在当前为90° 我们设置目标角度为180°
舵机的转速=|(180°-90°)|*k, k为比例系数
也就是舵机距离目标角度越近转速越慢,距离目标角度越远转速越快,所以我们看到舵机的起步一般非常快
现在大概知道了转速快的原因,我的目标是让舵机可以平缓的运动最好是匀速运动
思路是将目标角度与当前角度的差值分成若干块,逐步使舵机转向目标值,
例如
将90°分成四步,每步转22.5°,每转22.5°适当延时,当舵机转完22.5°后发送下一步信号,再次转动22.5° 以此类推
舵机的转速大概趋于平稳
当然每步22.5°肯定是不平滑的,我们可以分更多块每步1°或者更小
顺便写了一个函数,还有优化的空间
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "timer.h"
#include "key.h"
#include "oled.h"
unsigned int key=0,actual_pwm=100;
u32 part=0,time=0;
/**
*作用:舵机旋转
*expect_pwm:舵机目标旋转值
*s:舵机到达指定位置耗时
*最小转动角度:0.45*5
**/
void SG90(u32 expect_pwm,u32 s)
{
if(expect_pwm>actual_pwm)
time=1000000*s*5/(expect_pwm-actual_pwm);//微秒级拆分
if(expect_pwm<actual_pwm)
time=1000000*s*5/(actual_pwm-expect_pwm);//微秒级拆分
if(expect_pwm!=actual_pwm)
{
if(expect_pwm>actual_pwm)
{
while(1)
{
actual_pwm=actual_pwm+5;//一次
TIM_SetCompare1(TIM14,actual_pwm);
part++;
delay_us(time);
if(expect_pwm==actual_pwm)
{
part=0;
break;
}
}
}
if(expect_pwm<actual_pwm)
{
while(1)
{
actual_pwm=actual_pwm-5;
TIM_SetCompare1(TIM14,actual_pwm);
part++;
delay_us(time);
if(expect_pwm==actual_pwm)
{
part=0;
break;
}
}
}
}
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
TIM14_PWM_Init(4000-1,420-1); //84M/4200=200khz的计数频率,重装载值4000,所以PWM周期为0.02s(20ms)
KEY_Init();
while(1)
{
key=KEY_Scan(0);
if(key==1)
{
SG90(500,1);
}
if(key==2)
{
SG90(100,1);
}
}
}
全部程序51hei下载地址:
舵机控制(控制转速).7z
(310.21 KB, 下载次数: 92)
|