PWM
关于如何发出PWM可以参考我之前的文章。
【STM32F103】TIM定时器&PWM-CSDN博客
SG90&MG995
以这两款舵机为例是因为我手上碰巧只有这两款舵机。不过实际上舵机的操作基本上差不了多少,基本上都是给频率为50Hz的PWM,然后就可以让舵机旋转不同角度。
下面是我截取自某宝卖家给的说明书的关于舵机的介绍
1. 什么是舵机:
在机器人机电控制系统中,舵机控制效果是性能的重要影响因素。舵机可以在微机电系统和航模中作为基本的输出执行机构,其简单的控制和输出使得单片机系统非常容易与之接口。
舵机是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。目前在高档遥控玩具,如航模,包括飞机模型,潜艇模型;遥控机器人中已经使用得比较普遍。舵机是一种俗称,其实是一种伺服马达。
2. 其工作原理是:
控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。当然我们可以不用去了解它的具体工作原理,知道它的控制原理就够了。就象我们使用晶体管一样,知道可以拿它来做开关管或放大管就行了,至于管内的电子具体怎么流动是可以完全不用去考虑的。
3. 舵机的控制:
舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms~2.5ms范围内的角度控制脉冲部分。以180度角度伺服为例,那么对应的控制关系是这样的:
0.5ms--------------0度;
1.0ms------------45度;
1.5ms------------90度;
2.0ms-----------135度;
2.5ms-----------180度;
我们只需要知道我们要操作舵机,那么就给它频率为50Hz,占空比大于等于2.5%并且小于等于12.5%的PWM就可以控制舵机旋转角度了。占空比越大旋转的角度越大。
一些电气参数什么的随便找个网店,商家都会贴出来。
简单来说就是SG90和MG995都是只能旋转180度,它们之间的区别就在于MG995更贵,MG995的扭矩以及旋转速度什么的更快,总之就是性能更好一点。
没什么可说的,那就简单测评一下吧。
SG90
SG90就长得这个样子,很小巧一个玩意儿。接出来三根线,黄色红色棕色。
一般来说红色接VCC,棕色接GND,黄色接PWM(一般来说的,具体还是要看商家)。
工作电压为:4.8-7.2V。我们一般接个5V就可以了。
运行速度为:0.3秒/60度。
尺寸:23mmX12.2mmX29mm
重量:9克
扭矩:1.5kg/cm
当然,上面都是商家给的参数。
我们还是自己实测一下。
没给他通电的时候我们也是可以自己扭动它的。
SG90直接给它掰的话是可以掰差不多两百多度的。
然后不通电的时候扭动它用的力度差不多等于扭开一个已经开过的瓶盖,还是比较轻松的。
MG995
MG995长得这样样子,跟SG90相比属于是大块头了。
尺寸:40.7*19.7*42.9mm
重量 :66.2克
反应转速:无负载速度0.17秒/60度(4.8V);0.13秒/60度(6.0V)
工作电压;3.0V-7.2V。3V我试过了,基本上没有啥用,我们还是接5V即可。
工作扭矩:13KG/cm
测试发现最多可以掰差不多270度左右,但是它还是只能自己旋转180度。
掰动这个明显比掰动SG90要多费点力。差不多是扭开一瓶没开过的矿泉水瓶的程度。
STM32F103驱动代码
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void){
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //打开TIM2的外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef gitd;
gitd.GPIO_Mode=GPIO_Mode_AF_PP; //配置为复用推挽输出
gitd.GPIO_Pin=GPIO_Pin_0;
gitd.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOA,&gitd);
TIM_InternalClockConfig(TIM2); //选择内部时钟(72MHz)作为时钟源
TIM_TimeBaseInitTypeDef itd;
itd.TIM_ClockDivision=TIM_CKD_DIV1; //时钟1分频
itd.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
itd.TIM_Period=1000-1; //设置自动重装器的值
itd.TIM_Prescaler=1440-1; //设置预分频器的值
itd.TIM_RepetitionCounter=0; //重复计数器的值,但是仅高级定时器有效
TIM_TimeBaseInit(TIM2,&itd);
TIM_OCInitTypeDef itd1;
itd1.TIM_OCMode = TIM_OCMode_PWM1; //比较输出模式为PWM1
itd1.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性为高电平
itd1.TIM_OutputState=TIM_OutputState_Enable; //使能
itd1.TIM_Pulse=0; //初始化输出比较的阈值
TIM_OC1Init(TIM2,&itd1);
TIM_Cmd(TIM2,ENABLE); //使能定时器
while(1){
TIM_SetCompare1(TIM2,25); //占空比为2.5%;角度为0
Delay_s(1);
TIM_SetCompare1(TIM2,50); //占空比为5%;角度为45
Delay_s(1);
TIM_SetCompare1(TIM2,75); //占空比为7.5%;角度为90
Delay_s(1);
TIM_SetCompare1(TIM2,100); //占空比为10%;角度为135
Delay_s(1);
TIM_SetCompare1(TIM2,125); //占空比为12.5%;角度为180
Delay_s(1);
TIM_SetCompare1(TIM2,150); //占空比为15%;角度还是180,做测试是否真的只能转180度用的.
Delay_s(1);
}
}
PWM代码部分我直接复制我之前的博文。
我们主要要做的就是修改PWM的频率和占空比。频率需要为50,因此我设置的自动重装计数器的值为(1000-1),10的整数倍比较好计算占空比的比率。预分频器就设置为(1440-1),这样发出的PWM就是50Hz的了。
代码中我用的TIM2的通道1,因此对应的引脚是GPIOA的0号引脚。因此我这边接线是SG90/MG995的红线接到ST-Link的5V,棕线与STM32共地,黄线接到GPIOA的0号引脚,也就是接收PWM。
这样就可以通过PWM来操作这两个型号的舵机啦,两个舵机共用一套代码都行。
其他型号的舵机改改应该也能用。