舵机(SG90)
一.实物图及接线:
1.实物图:
自带三根线(黄,红,褐)色。
2.与51单片机接线图:
Vcc(红色) ------> 单片机的5V
GND(褐色) ------> 单片机的GND
信号线(黄色) ------> 这里接P21(只要不冲突,这根随机)
二.定义和原理:
1.参数及定义:
- 舵机是一种伺服驱动器,适用于角度不断变化并可以保持的控制系统。
- 这款舵机是模拟舵机,理解为需要不断发送PWM信号控制舵机角度,例如1ms的高电平给到信号接口,他就会传输1ms的PWM信号,舵机就会转到1msPWM信号对应的45度角。
- 使用的是4.8V-6V的电压,正常接单片机的5V就行,有时候舵机出现卡顿或不转,有可能是电压不够,注意这点。精度可以控制在0.2cm。
2.原理:
占空比:就是一个周期内,高电平所占比例,舵机角度转动多少就是要看高电平占多少,理解这个很重要。
- 舵机工作的一个周期20ms,这个固定。通过给信号口输入控制信号(0.5ms-2.5ms)多少决定舵机转动的角度。
- 控制信号对应角度:(忽略上图角度)
0.5ms -----> 0度
1.0ms -----> 45度
1.5ms -----> 90度
2.0ms -----> 135度
2.5ms -----> 180度 - 这里需要用到定时器来控制舵机的一个周期及控制 控制信号的时间。
三.代码思路:
1.定时器的初始化:(以定时器0举例)
- 选择定时器0的定时模式且方式1;
- 设置初值TH0和TL0,正常情况下定时0.5ms溢出,因为刚好是角度控制信号的倍数,方便理解,也可以是0.1ms溢出,这里用0.5ms举例。
- 打开定时器启动位TR0;
- 打开总中断EA;
- 打开定时器0中断ET0;
void Time0_Init()
{
TMOD=0x01;
TH0=(65536-500)/256;
TL0=(65536-500)%256;
TR0=1;
EA=1;
ET0=1;
}
2.定时器中断函数:
- 定义一个变量,用来统计中断次数(定时器溢出申请中断次数),让它递增,直到递增到能够让舵机完成一个周期20ms,也就是40次(0.5ms*40=20ms),才让它归0,反复形成20ms的周期。
- 不能忘了重新给TH0和TL0重新赋予初值。
- 定义一个全局变量,用来控制舵机要转的角度,让它与中断次数变量对比,例如,if(中断次数<舵机角度变量){给PWM信号};理解为:一个中断次数时间0.5ms,当舵机角度变量为3时,说明将产生3个PWM信号,这个PWM信号的产生由给P21高电平产生。如果中断次数>舵机角度变量就不给PWM信号,即else{不给PWM信号}
结合下图理解:
void Time0() interrupt 1
{
count++; //定义一个变量统计中断次数
TH0=(65536-500)/256;
TL0=(65536-500)%256;
if(count==40) //一个20ms的周期
{
count=0;
}
if(count<number) //通过给number赋值决定舵机转动角度
{
SG90=1; //给P21口高电平表示传输PWM信号
}
else
{
SG90=0;
}
}
3.主函数:
- 调用定时器初始化函数。
- 可以调整舵机初始角度。
- while循环里给舵机角度变量赋值,若要让舵机在两个角度之间跳变,则用延时控制速度。还可以用按键控制想要的角度。
void main()
{
Time0_Init();
SG90=1;
while(1)
{
number=1;
count=0; //在舵机转动后清空中断次数,为下一个角度做准备
Delay1ms(1000);
number=3;
count=0;
Delay1ms(1000);
}
}
四.总代码:
现象1:从0度—>135度来回转动
#include <REGX52.H>
#include "Delay1ms.h"
sbit SG90=P2^1;
void Time0_Init();
unsigned char count=0;
unsigned char number=0;
void main()
{
Time0_Init();
SG90=1;
while(1)
{
number=1;
count=0;
Delay1ms(1000);
number=3;
count=0;
Delay1ms(1000);
}
}
void Time0_Init()
{
TMOD=0x01;
TH0=(65536-500)/256;
TL0=(65536-500)%256;
TR0=1;
EA=1;
ET0=1;
}
void Time0() interrupt 1
{
count++;
TH0=(65536-500)/256;
TL0=(65536-500)%256;
if(count==40)
{
count=0;
}
if(count<number)
{
SG90=1;
}
else
{
SG90=0;
}
}
现象2.独立按键控制0度—>90度转动
#include <REGX52.H>
#include "Delay1ms.h"
sbit SG90=P2^1;
void Time0_Init();
unsigned char count=0;
unsigned char number;
void main()
{
Time0_Init();
SG90=1;
while(1)
{
if(P3_1==0)
{
number=1;
count=0;
}
if(P3_0==0)
{
number=3;
count=0;
}
}
}
void Time0_Init()
{
TMOD=0x01;
TH0=(65536-500)/256;
TL0=(65536-500)%256;
TR0=1;
EA=1;
ET0=1;
}
void Time0() interrupt 1
{
count++;
TH0=(65536-500)/256;
TL0=(65536-500)%256;
if(count==40)
{
count=0;
}
if(count<number)
{
SG90=1;
}
else
{
SG90=0;
}
}
五.效果展示:
1.现象1:
舵机循环旋转
2.现象2:
按键控制舵机转动角度