1、舵机的工作原理:
舵机内部的控制电路,电位计(可变电阻器)和电机均被连接到电路板上,如内部结构图的右边部分。控制电路通过电位计可监控舵机的当前角度。
如果轴的位置与控制信号相符,那么电机就会关闭。如果控制电路发现这个角度不正确,它就会控制马达转动,直到它达到指定的角度。舵机角度根据制造商的不同而有所不同。比如,一个180度的舵机,它可以在0度至180度之间运动。由于限位装置被安装在主输出装置上,超出这个范围机械结构就不能再转动了。
舵机的输出功率与它所需要转动的距离成正比。如果输出轴需要转动很长的距离,马达就会全速运转,如果它只需要短距离转动,马达就会以较慢的速度运行,这叫做速度比例控制。
2、如何让舵机转到指定角度:
控制线用于传输角度控制信号。这个角度是由控制信号脉冲的持续时间决定的,这叫做脉冲编码调制(PCM)。舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围,总间隔为2ms。脉冲的宽度将决定马达转动的距离。例如:1.5毫秒的脉冲,电机将转向90度的位置(通常称为中立位置,对于180°舵机来说,就是90°位置)。如果脉冲宽度小于1.5毫秒,那么电机轴向朝向0度方向。如果脉冲宽度大于1.5毫秒,轴向就朝向180度方向。以180度舵机为例,对应的控制关系是这样的:
0.5ms————-0度;1.0ms————45度;1.5ms————90度;2.0ms———–135度;2.5ms———–180度;
3、舵机转动角度对应的占空比以及比较寄存器的值计算方法:
舵机配置需要满足频率为50HZ,PWM占空比是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,由于PWM周期为20ms,所以(以舵机会转动 45°为例),占空比就应该为1ms/20ms = 5%,所以TIM_SetCompare1的 TIMx 捕获比较 1 寄存器就为200-200*5% = 190
4、STM32控制舵机的代码:
控制舵机代码:
Main.cpp
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
int main(void)
{
u16 led0pwmval=185;
//u8 dir =1;
delay_init();
LED_Init();
TIM3_PWM_Init(199, 7199);//50hz
while(1)
{
led0pwmval=195;//45
TIM_SetCompare2(TIM3,led0pwmval);
delay_ms(800);
led0pwmval=190;//45
TIM_SetCompare2(TIM3,led0pwmval);
delay_ms(800);
led0pwmval=185;//90
TIM_SetCompare2(TIM3,led0pwmval);
delay_ms(800);
led0pwmval=180;//135
TIM_SetCompare2(TIM3,led0pwmval);
delay_ms(800);
led0pwmval=175;//180
TIM_SetCompare2(TIM3,led0pwmval);
delay_ms(800);
}
}
Timer.h
#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"
void TIM3_PWM_Init(u16 arr , u16 psc);
#endif
Timer.c
#include "timer.h"
void TIM3_PWM_Init(u16 arr , u16 psc)
{
GPIO_InitTypeDef GPIO_InitTypestrue;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypestrue;
TIM_OCInitTypeDef TIM_OCInitTypesture;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);//使能GPIO时钟,以及TIM3时钟使能
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//复用
GPIO_InitTypestrue.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitTypestrue.GPIO_Pin=GPIO_Pin_5;
GPIO_InitTypestrue.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitTypestrue); //GPIO初始化
TIM_TimeBaseInitTypestrue.TIM_Period=arr;
TIM_TimeBaseInitTypestrue.TIM_Prescaler=psc;
TIM_TimeBaseInitTypestrue.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitTypestrue.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3 ,&TIM_TimeBaseInitTypestrue); //定时器初始化
TIM_OCInitTypesture.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCInitTypesture.TIM_OCMode=TIM_OCMode_PWM2;
TIM_OCInitTypesture.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OC2Init(TIM3 ,&TIM_OCInitTypesture );//CH2通道初始化
TIM_OC2PreloadConfig( TIM3 ,TIM_OCPreload_Enable);//使能预装载寄存器
TIM_Cmd(TIM3,ENABLE);
}