如何用单片机控制舵机及程序详细

控制/MCU

1811人已加入

描述

  舵机概述

  舵机最早出现在航模运动中。在航空模型中,飞行机的飞行姿态是通过调节发动机和各个控制舵面来实现的。举个简单的四通飞机来说,飞机上有以下几个地方需要控制:

  1.发动机进气量,来控制发动机的拉力(或推力);

  2.副翼舵面(安装在飞机机翼后缘),用来控制飞机的横滚运动;

  3.水平尾舵面,用来控制飞机的俯仰角;

  4.垂直尾舵面,用来控制飞机的偏航角;

  遥控器有四个通道,分别对应四个舵机,而舵机又通过连杆等传动元件带动舵面的转动,从而改变飞机的运动状态。舵机因此得名:控制舵面的伺服电机。

  不仅在航模飞机中,在其他的模型运动中都可以看到它的应用:船模上用来控制尾舵,车模中用来转向等等。由此可见,凡是需要操作性动作时都可以用舵机来实现。

  舵机工作原理

  一般来讲,舵机主要由以下几个部分组成, 舵盘、减速齿轮组、位置反馈电位计5k、直流电机、控制电路板等。

  工作原理:控制电路板接受来自信号线的控制信号(具体信号待会再讲),控制电机转动,电机带动一系列齿轮组,减速后传动至输出舵盘。舵机的输出轴和位置反馈电位计是相连的,舵盘转动的同时,带动位置反馈电位计,电位计将输出一个电压信号到控制电路板,进行反馈,然后控制电路板根据所在位置决定电机的转动方向和速度,从而达到目标停止。

  舵机的基本结构是这样,但实现起来有很多种。例如电机就有有刷和无刷之分,齿轮有塑料和金属之分,输出轴有滑动和滚动之分,壳体有塑料和铝合金之分,速度有快速和慢速之分,体积有大中小三种之分等等,组合不同,价格也千差万别。例如,其中小舵机一般称作微舵,同种材料的条件下是中型的一倍多,金属齿轮是塑料齿轮的一倍多。需要根据需要选用不同类型。

单片机

  舵机的PWM信号

  1.PWM信号的定义

  PWM信号为脉宽调制信号,其特点在于他的上升沿与下降沿之间的时间宽度。具体的时间宽窄协议参考下列讲述。我们目前使用的舵机主要依赖于模型行业的标准协议,随着机器人行业的渐渐独立,有些厂商已经推出全新的舵机协议,这些舵机只能应用于机器人行业,已经不能够应用于传统的模型上面了。目前舵机可能是这个过渡时期的产物,它采用传统的PWM协议,优缺点一目了然。优点是已经产业化,成本低,旋转角度大(目前所生产的都可达到185度);缺点是控制比较复杂,毕竟采用PWM格式。但是它是一款数字型的舵机,其对PWM信号的要求较低:(1)不用随时接收指令,减少CPU的疲劳程度;(2)可以位置自锁、位置跟踪,这方面超越了普通的步进电机。

单片机

  其PWM格式注意的几个要点:(1)上升沿最少为0.5mS,为0.5mS---2.5mS之间;(2)HG14-M数字舵机下降沿时间没要求,目前采用0.5Ms就行;也就是说PWM波形可以是一个周期1mS的标准方波;(3)HG0680为塑料齿轮模拟舵机,其要求连续供给PWM信号;它也可以输入一个周期为1mS的标准方波,这时表现出来的跟随性能很好、很紧密。

  2.PWM信号控制精度制定

  如果采用的是8位单片机AT89C52CPU,其数据分辨率为256,那么经过舵机极限参数实验,得到应该将其划分为250份。那么0.5mS---2.5Ms的宽度为2mS=2000uS。2000uS÷250=8uS,则:PWM的控制精度为8us。我们可以以8uS为单位递增控制舵机转动与定位。舵机可以转动185度,那么185度÷250=0.74度,则:舵机的控制精度为0.74度。

单片机

  1DIV=8us;250DIV=2ms时基寄存器内的数值为:(#01H)01----(#0FAH)250。共185度,分为250个位置,每个位置叫1DIV。则:185÷250=0.74度/DIVPWM上升沿函数:0.5ms+N×DIV0us≤N×DIV≤2ms0.5ms≤0.5ms+N×DIV≤2.5ms

  单片机控制舵机及程序

  正是舵机的控制信号是一个脉宽调制信号,所以很方便和数字系统进行接口。只要能产生标准的控制信号的数字设备都可以用来控制舵机,比方PLC、单片机等。这里介绍利用51系列单片机产生舵机的控制信号来进行控制的方法,编程语言为C51。之所以介绍这种方法只是因为笔者用2051实现过,本着负责的态度,所以敢在这里写出来。程序用的是我的四足步行机器人,有删改。单片机并不是控制舵机的最好的方法,希望在此能起到抛砖引玉的作用。

  2051有两个16位的内部计数器,我们就用它来产生周期20ms的脉冲信号,根据需要,改变输出脉宽。基本思路如下(请对照下面的程序):

  我用的晶振频率为12M,2051一个时钟周期为12个晶振周期,正好是1/1000ms,计数器每隔1/1000ms计一次数。以计数器1为例,先设定脉宽的初始值,程序中初始为1.5ms,在for循环中可以随时通过改变a值来改变,然后设定计数器计数初始值为a,并置输出p12为高位。当计数结束时,触发计数器溢出中断函数,就是voidtimer0(void)interrupt1using1,在子函数中,改变输出p12为反相(此时跳为低位),在用20000(代表20ms周期)减去高位用的时间a,就是本周期中低位的时间,c=20000-a,并设定此时的计数器初值为c,直到定时器再次产生溢出中断,重复上一过程。

  #include《reg51.h》

  #defineucharunsignedchar

  #defineuintunsignedint

  uinta,b,c,d;

  sbitp12=P1^2;

  sbitp13=p1^3;

  sbitp37=P3^7;

  voidtimer0(void)interrupt1using1

  {p12=!p12;

  c=20000-c;

  TH0=-(c/256);TL0=-(c%256);

  if(c》=500&&c《=2500)c=a;

  elsec=20000-a;

  }

  voidtimer1(void)interrupt3using1

  {p13=!p13;

  d=20000-d;

  TH1=-(d/256);TL1=-(d%256);

  if(d》=500&&d《=2500)d=b;

  elsed=20000-b;

  }

  voidmain(void)

  {TMOD=0x11;

  p12=1;

  p13=1;

  a=1500;

  b=1500;

  c=a;d=b;

  TH0=-(a/256);TL0=-(a%256);

  TH1=-(b/256);TL1=-(b%256);

  EA=1;

  ET0=1;TR0=1;EX0=1;EX1=1;

  ET1=1;TR1=1;

  PX0=0;PX1=0;PT1=1;PT0=1;

  for(;;)

  {

  }

  }

  因为在脉冲信号的输出是靠定时器的溢出中断函数来处理,时间很短,因此在精度要求不高的场合可以忽略。因此如果忽略中断时间,从另一个角度来讲就是主程序和脉冲输出是并行的,因此,只需要在主程序中按你的要求改变a值,例如让a从500变化到2500,就可以让舵机从0度变化到180度。另外要记住一点,舵机的转动需要时间的,因此,程序中a值的变化不能太快,不然舵机跟不上程序。根据需要,选择合适的延时,用一个a递增循环,可以让舵机很流畅的转动,而不会产生像步进电机一样的脉动。这些还需要实践中具体体会。

  舵机的速度决定于你给它的信号脉宽的变化速度。举个例子,t=0试,脉宽为0.5ms,t=1s时,脉宽为1.0ms,那么,舵机就会从0.5ms对应的位置转到1.0ms对应的位置,那么转动速度如何呢?一般来讲,3003的最大转动速度在4.8V时为0.23s/60度,也就是说,如果你要求的速度比这个快的话,舵机就反应不过来了;如果要求速度比这个慢,可以将脉宽变化值线性到你要求的时间内,做一个循环,一点一点的增加脉宽值,就可以控制舵机的速度了。当然,具体这一点一点到底是多少,就需要做试验了,不然的话,不合适的话,舵机就会向步进电机一样一跳一跳的转动了,尝试改变这“一点”,使你的舵机运动更平滑。还有一点很重要,就是舵机在每一次脉宽值改变的时候总会有一个转速由零增加再减速为零的过程,这就是舵机会产生像步进电机一样运动的原因。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分