STM32控制舵机精准角度

目录

摘要

一、舵机原理       

二、程序介绍

三、精准角度控制原理

四、程序分享


一、舵机原理

二、程序介绍

三、精准角度控制原理

四、程序分享

摘要

        网上很多教程,都只是控制舵机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下载

你的点赞或收藏是我创作的动力~~

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YY_Share

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值