一、舵机原理
二、程序介绍
三、精准角度控制原理
四、程序分享
网上很多教程,都只是控制舵机0°,45°,90°等特定的角度,比如1°,很多程序都做不到,即使有也少得可怜,更不会详解介绍是怎么实现精准控制每一度的,因此,这篇文章的意义就在这里。
一、舵机原理
我们以SG90、MG90等舵机为例,舵机有三个PIN,分别是VCC,GND,PWM,PWM引脚需要一个20ms周期信号,通过不同的占空比来控制不同角度,具体参数如下:
0.5ms--------------0度;
1.0ms------------45度;
1.5ms------------90度;
2.0ms-----------135度;
2.5ms-----------180度;
动态原理如下,源自网上。
二、程序介绍
产生PMW的方法很多,典型的就是用单片机,这里以STM32F1举例
PWM配置:这个配置没有什么特别,大同小异,直接使用经典的配置就可以,重点在后面的主函数。
void TIM3_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler =psc;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_Cmd(TIM3, ENABLE);
}
主函数:
void Servo_Control(float angle)
{
float temp;
u16 led0pwmval=0;
// temp = 195- 0.11*(float)angle;
// TIM_SetCompare2(TIM3, (float)temp);
pwmval = (int)(2000*(1-((0.5+angle/90.0)/20.0))) -5;
TIM_SetCompare2(TIM3, pwmval);//
}
int main(void)
{
float i;
Servo_Control(0);
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
LED_Init();
//TIM3_PWM_Init(199,7199); //(199+1)*(7199+1)/72*10^6 0.02S 20MS
TIM3_PWM_Init(1999,719);
while(1)
{
Servo_Control(0);
/*
for(i=0;i<=179;i++)
{
Servo_Control(i);
delay_ms(2);
}
delay_ms(2);
for(i=180;i>=1;i--)
{
Servo_Control(i);
delay_ms(2);
}
delay_ms(2);
*/
}
}
这里分为两部分:
//TIM3_PWM_Init(199,7199); //(199+1)*(7199+1)/72*10^6 0.02S 20MS
TIM3_PWM_Init(1999,719);
首先两个定时器都能产生20ms周期的脉冲,但是网上很多网友使用的都是第一种方式:TIM3_PWM_Init(199,7199),这个的弊端是,由于计数的数量太少了,才199,导致在控制舵机角度的时候,即使我最小修改一个单位的数值,表现出来的变化脉冲宽度都比较大,导致舵机旋转了大于一个度数,换句话说,这个代码调节的精度太差。
因此,我们需要想办法让计数器计数得尽量多,在我们修改前期的数值时,后面的脉宽变化很小很小,小于舵机旋转1°所需的变化脉宽,我们就成功了。
因此,我们使用:TIM3_PWM_Init(1999,719);
三、精准角度控制原理
精准角度控制,主要在下面这两行代码
pwmval = (int)(2000*(1-((0.5+angle/90.0)/20.0))) -5;
TIM_SetCompare2(TIM3, pwmval);
假设我们需要舵机旋转45°,则占空比为1ms/20ms=5%,则TIM_SetCompare2TIMx 捕获比较 1 寄存器值就是2000-2000*5%=1900;
那这个数值跟角度有什么关系呢,就来到了这个代码:
pwmval = (int)(2000*(1-((0.5+angle/90.0)/20.0))) -5;
占空比从0.5开始为0°,因此需要以0.5开始相加,我们假设把45°为angle带进去,则最里面的括号为1,正好对标舵机45°时候的1ms。
那为什么我后面要减5呢,这个是我舵机的误差,因为在我设定为0°的时候,我发现舵机的角度并不是完完全全的水平,因此这个相当于一个校准系数,根据实际情况而定,如果舵机质量很好,没有误差,那不需要-5,就是这个意思。
我这里还写了一个for循环,供大家参考,作用是使得舵机以1°的步进正反旋转。
for(i=0;i<=179;i++)
{
Servo_Control(i);
delay_ms(2);
}
delay_ms(2);
for(i=180;i>=1;i--)
{
Servo_Control(i);
delay_ms(2);
}
delay_ms(2);
四、程序分享
这里附上下载链接,或者去我的主页
STM32控制舵机精准角度程序,精确到某一度-嵌入式文档类资源-CSDN下载文章来源:https://www.toymoban.com/news/detail-616336.html
你的点赞或收藏是我创作的动力~~文章来源地址https://www.toymoban.com/news/detail-616336.html
到了这里,关于STM32控制舵机精准角度的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!