电子说
舵机的控制方式
舵机的种类有很多,下面我所展示的是非常常见的SG90舵机(下面简称“舵机”),也是我们这次实验室考核所使用的舵机。
篇幅有限,这里只简单介绍了SG90舵机,想深入研究的同学可以自己去查阅资料。
我们先来了解一下SG90舵机
SG90舵机有三根线:GND、VCC和信号线:
GND(负极)和VCC(正极)都是电源线,可以接在开发板相同标识的排针或与开发板相同的电源上,注意GND要与单片机共地(接在同一个负极上)。
信号线接在单片机的IO口上,我们使用IO口输出PWM来控制舵机。
在对舵机进行控制时,像控制LED灯直接对信号线输出1和0是不能够正常控制的,要使用PWM进行控制:
↑不正确的控制方法,可能是酱紫的
↑使用PWM控制,能随意改变角度
那么下面我们进入正题:使用PWM对舵机进行控制。
舵机能在其旋转范围内(0°~180°)旋转至任意角度,但注意,这不是指能够连续转圈圈,而是像一把量角器,假设设置了30°,那么舵机就会旋转至30°的位置并停下,而不是在原来的位置叠加上30°。
舵机的旋转角度是通过PWM的占空比来调节的,PWM的周期一般为20ms,它们的关系如下表所示:
可以发现,要舵机停在0°的位置并不能将IO口直接置0,180°也不能直接置1。
示例程序
舵机的控制程序其实和LED亮度调节、呼吸灯的程序基本一致,都是使用PWM控制,只不过占空比有范围而已。
下面的程序是在我之前发的PWM的程序上稍作修改得到的,PWM部分就不再解释了,只解释舵机的控制部分。
#include < reg52.h >
#define PWM_T 200 //产生中断的时间,因为是24MHz,200即100微妙(0.1毫秒)
int PWM_count0 = 0; //进入中断的次数
int PWM_count1 = 0; //与上面的类似,用于计数
int PWM_F = 0; //一个用于计时的标志,作用类似定时器的TF0、TF1
sbit servo = P2^0; //舵机信号线所连接的IO口
void PWM_Start() //PWM初始化函数,打开了定时器0
{
EA = 1;
ET0 = 1;
TMOD |= 0x01;
TR0 = 1;
TH0 = (65536-PWM_T)/256;
TL0 = (65536-PWM_T)%256;
}
int PWM(int PWM_value) //控制PWM输出的子函数
{
if(PWM_count0 <= PWM_value)
{
return 1;
}
else
{
return 0;
}
}
void main()
{
PWM_Start(); //PWM开始运行
while(1)
{
while(1)
{
servo = PWM(5); //旋转至0°
if(PWM_F == 1) //判断标志是否为1,是则代表着过了1秒
{
PWM_F = 0; //将标志归零
break; //过了1秒,退出循环
}
}
while(1)
{
servo = PWM(10); //旋转至45°
if(PWM_F == 1)
{
PWM_F = 0;
break;
}
}
while(1)
{
servo = PWM(15); //旋转至90°
if(PWM_F == 1)
{
PWM_F = 0;
break;
}
}
while(1)
{
servo = PWM(20); //旋转至135°
if(PWM_F == 1)
{
PWM_F = 0;
break;
}
}
while(1)
{
servo = PWM(25); //旋转至180°
if(PWM_F == 1)
{
PWM_F = 0;
break;
}
}
}
}
void Timer0() interrupt 1
{
TH0 = (65536-PWM_T)/256;
TL0 = (65536-PWM_T)%256;
PWM_count0++;
if(PWM_count0 == 200) //过了20ms,完成了一个PWM周期
{
PWM_count0 = 0; //清零,重新开始计数
PWM_count1++;
if(PWM_count1 == 50) //PWM_count0清零了50次,也就是说过了20ms*50=1000ms=1s
{
PWM_count1 = 0; //清零,重新开始计数
PWM_F = 1; //标志置1,说明已经过了2s
}
}
}
我在程序中并没有使用软件延时(delay()函数),这在PWM那篇文章中也说过了,软件延时期间无法改变IO口的高低电平输出,PWM也就失效了。
我的做法是设置一个标志PWM_F(也可以直接判断PWM_count1的值),当达到设定的时间就退出循环,否则就回到循环进行PWM输出。
如果你觉得这样做比较麻烦,也可以调用另一个定时器来计时,不过定时器的数量是有限的(51只有两个,52、STC15F2K60S2有三个)。
在写PWM的程序时,可以参考我上面的做法,每0.1ms进入一次中断,进入200次(20ms)就完成一次PWM中断,对应着舵机所要求的PWM周期长度,控制起来也会方便很多。
另外,头文件建议使用与单片机型号所匹配的,上面例程中包含reg52.h是为了有较高的兼容性,但这样就有一些资源无法调用。例如STC15F2K60S2,P4引脚(如P47)只有在包含STC15F2K60S2.h时才能被调用。
假如你的舵机不能正常运行,可能是下面的原因:
1.单片机晶振或定时器没有设置正确,例如上面例程对应的是24MHz的频率,下载时选择了默认的11.0592MHz;
2.电源供电不足,可以使用充电宝供电试试。
总结
学会PWM后,舵机的控制其实非常容易,稍作一下改动就行。对舵机感兴趣的同学可以去了解一下其他类型的舵机,使用PWM控制的只是其中一种。
全部0条评论
快来发表一下你的评论吧 !