搜索
bottom↓
回复: 43

PWM控制舵机(献丑了,不要骂我啊,俺也是新手)

[复制链接]

出0入0汤圆

发表于 2007-11-20 18:51:01 | 显示全部楼层 |阅读模式
在论坛上看见了有用这单片机作舵机控制的,下载下来,一看,头就晕了,(可能是小弟的水平太次了吧),所以,自己新潮来血,也作了这么一个舵机控制的,用的是PWM,自我感觉,代码简单,修改方便,可移植性也比较高。


    大概说明一下原理,我也是听我同事说得,舵机的脉宽值是500us到2500us,所以在产生脉宽的时候,周期至少要在400Hz以下。
如果产生PWM时,你的分频数为1时(不分频),那么产生的方波是4000Hz的,你要2500us的方波肯定是没戏了,至于500us的,我也忘了自己试没试,
                   分频数为8时,那么产生的方波是500Hz的,你要2500us的方波肯定也是没戏了,
                   所以,我用了64分频的方式,因此,TCCR1B=0x03;

    用示波器看的,当OCR1AL=0x20时,脉宽为500us,当OCR1AL=0xa0时脉宽2500us。这个值也是大概比较准确的,OCR1AL的值差那么一点点也不怎么看的出来,所以,我就用了这么两个整数值。

    单片机用的是M16,8M内部晶振,没有用到外部资源,使用的是PD5的第二功能,脉宽调制, 所以,也没有什么原理图可以画了。

下面与大家一起分享:

#include <iom16v.h>
#include <macros.h>

void delay_MS(unsigned int i)
{unsigned int j;
for (;i!=0;i--)
     {
         for (j=500;j!=0;j--)
            ;
          }
}


void main()
{
unsigned int i=0x20;


DDRD|=BIT(PD5);    //设置输出,OC1A

TCCR1A=0x83;       //10位快速PWM,且OC1A输出反向
TCCR1B=0x03;      //设置10位快速PWM,且64分频

while(1)
{
             while(160-i)    //脉宽从500uS往上加 注释(1)
              {
              OCR1AH=0;
               OCR1AL=i;
       
          delay_MS(50);
          i++;
         }
         
          while(i-32)   //脉宽从2500uS往下减  注释(2)
         {
              OCR1AH=0;
               OCR1AL=i;
       
          delay_MS(50);
          i--;
         }  
}
}

/*************************************************************       
注释(1):160的由来,此设置要产生2500ms的脉宽,OCR1AL=0xa0,OCR1AH=0x00;
        a0换算成10进制,得160

    (2):32的由来,此设置要产生500ms的脉宽,OCR1AL=0xa20,OCR1AH=0x00;
        20换算成10进制,得32


   OCR1AL=0x20;   脉宽500
   OCR1AH=0x00;
   
   OCR1AL=0xa0;
   OCR1AH=0x00;   脉宽2500  
   
用示波器测量出的结果。


还有阿,延时程序可能不准阿,这个延时程序我也不知道什么时候从哪里抄下来的,呵呵。(见谅哈)
***************************************************************/


目前就这么多啦,其他的正在改良中,呵呵,欢迎各位前来赐教,不胜感激。

出0入0汤圆

 楼主| 发表于 2007-11-20 19:24:41 | 显示全部楼层
忘了在说一点哈,用示波器看过,没有什么问题的,直接连在舵机上,也没有什么问题。

俺用的是比较古老的编译器了ICC6.31A

出0入0汤圆

 楼主| 发表于 2007-11-20 19:43:03 | 显示全部楼层
哎呀,这一年多真是荒废了,在回头看一下,都是论坛刚开始的帖子了,我的水品离大家很是久远阿

自己给自己加油!!!

努力努力在努力!!!

出0入0汤圆

发表于 2007-11-20 20:03:15 | 显示全部楼层
你可以用定时器啊,就可以不用延迟了,你那个延迟在C里面不准的

出0入0汤圆

发表于 2007-11-20 20:19:22 | 显示全部楼层
你有没试过同时驱动3个以上的舵机啊?我驱动3个以上舵机就很容易失控。。。不知是舵机质量问题还是我的电路问题。。。

出0入0汤圆

 楼主| 发表于 2007-11-20 23:00:50 | 显示全部楼层
(回三楼的话)
是啊,是啊,延时程序是不准,我不也说过了吗,这是我以前找到的,自己都忘了从哪里来的
不过这样方便与调试阿
能够看清楚脉宽的变化啊!要是觉得不妥,可以改阿,呵呵,C语言嘛,移植性好啊!!

(回四楼的话)
我该没有试过驱动这么多的舵机呢,我试试再给你答案吧!!
另外,我用的是Futaba的舵机,因为我以前是玩航空模型的,所以,还是比较相信这个牌子的。
虽然说是日本出的,但我也没有办法啊,我不能为了剩这么舵机钱,毁了我的整个飞机啊!!!
所以,后来人也别骂我了,我也是没有办法啊,不是我不爱国阿!
Futaba的舵机相对来说还是很好使的,总之,我试试再给你答案吧!!

出0入0汤圆

 楼主| 发表于 2007-11-21 19:42:49 | 显示全部楼层
今年我又对自己这些东西进行了测试,主要是回复4楼哥们的话,我今天用这段代码同时驱动了四个舵机,没有什么不正常的,希望4楼的哥们把问题说清楚,大家一起研究,一起学习。

还有,补充一点,主要是回复三楼哥们的话,我的延时程序,可能是不准,但是不影响脉宽值得变化啊。我的这段程序,脉宽值是由计数器值和比较器的值决定的,延时程序只是让某一时刻的脉宽状态保持,方便观察。

出0入0汤圆

发表于 2008-8-6 14:35:54 | 显示全部楼层
为什么脉宽要增加后又减少呢〉?楼主指点一下行吗?

出0入0汤圆

发表于 2008-8-7 08:15:42 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-8-7 09:22:04 | 显示全部楼层
学习中...
请教一个比较菜的问题,AVR程序中经常可以看到类似这样的语句
TCCR1A = (1<<COM1B1)|(0<<COM1B0)|(1<<WGM11)|(1<<WGM10);
谁能帮解释一下它的含义吗?
有其它替代的表示法吗?

出0入0汤圆

发表于 2009-3-9 09:44:02 | 显示全部楼层
有没有办法用硬件PWM控制多路舵机?好像别人都是用定时器模拟的。

出0入0汤圆

发表于 2009-3-9 12:39:32 | 显示全部楼层
11楼,硬件PWM路少就更简单了,不过要看控制器有几路PWM,一般至少3路吧

出0入0汤圆

发表于 2009-3-9 12:42:12 | 显示全部楼层
其实多路控制PWM浪费,用一个IO或PWM或WAVE输出+移位寄存器可以控制许多路,但按标准帧20ms/2=10,实际输出应当最多8路比较合理

出0入0汤圆

发表于 2009-3-9 20:39:11 | 显示全部楼层
回12楼,我是说能否用一路硬件PWM控制多路舵机?主要是我觉得用定时器模拟的话可能精度不够。
感觉软件模拟的不够先进,呵呵。

出0入0汤圆

发表于 2009-3-9 20:45:17 | 显示全部楼层
看具体控制器,比如我用ARM7的捕获外设模块的波型方式,出过宽宽窄窄的脉冲,也就是说可以出标准PPM码形,当然输出给各路舵机肯定要进行脉冲分配的,因为舵机接受信号是有标准做法的(虽然JR/FUTABA参数不一样,类型是一样的),你要驱动标准舵机就要按规则办

出0入0汤圆

发表于 2009-6-15 15:06:23 | 显示全部楼层
ddddddddd

出0入0汤圆

发表于 2009-6-15 19:44:08 | 显示全部楼层
学习了

出0入0汤圆

发表于 2009-6-17 16:30:23 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-8-21 18:43:20 | 显示全部楼层
不错,挺简单好用的

出0入0汤圆

发表于 2009-8-22 19:00:23 | 显示全部楼层
中断位不用控制吗?
这个程序能输出pwm吗

出0入0汤圆

发表于 2009-9-2 09:50:44 | 显示全部楼层
楼主 我也用你的编译器 呵呵

出0入0汤圆

发表于 2009-9-14 17:20:41 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-9-20 15:17:56 | 显示全部楼层
m

出0入0汤圆

发表于 2009-11-8 20:09:31 | 显示全部楼层
lz,注释错了,不是"10位快速PWM",应该是“10位相位修正的PWM”。

出0入0汤圆

发表于 2009-11-8 20:29:04 | 显示全部楼层
重新改写一下例程,以利于大家阅读,错误之处请大家指出。没经过lz允许,不知道可不可以??


大概说明一下原理,我也是听我同事说得,舵机的脉宽值是500us到2500us(400hz),所以在产生脉宽的时候

,周期至少要在400Hz以下。

本例用的是atmega16L,8M内部晶振,定时器1的10位相位修正PWM,OC1A引脚输出控制舵机。

如果产生PWM时,你的分频数为1时(不分频),那么产生的方波是4000Hz(由8000000/2^10/2得出)的,你要

2500us的方波肯定是没戏了,至于500us的,我也忘了自己试没试,分频数为8时,那么产生的方波是500Hz

(8000000/2^10/2/8得出)的,你要2500us的方波肯定也是没戏了,所以,我用了64分频的方式,因此,      

TCCR1B=0x03;  

    用示波器看的,当OCR1AL=0x20时,脉宽为500us(计算:32*1/(8000000/64)),当OCR1AL=0xa0时脉宽

2500us。这个值也是大概比较准确的,OCR1AL的值差那么一点点也不怎么看的出来,所以,我就用了这么两个整

数值。

     

下面与大家一起分享:

#include <iom16v.h>
#include <macros.h>

void delay_MS(unsigned int i)
{unsigned int j;
for (;i!=0;i--)
     {
for (j=500;j!=0;j--)
    ;
  }
}


void main()
{  
unsigned int i=0x20;


DDRD|=BIT(PD5);    //设置输出,OC1A
  
TCCR1A=0x83;       //10位相位修正PWM,且OC1A输出反向
TCCR1B=0x03;      //设置10位相位修正PWM,且64分频

while(1)
{
             while(160-i)    //脉宽从500uS往上加 注释(1)
       {
        OCR1AH=0;
        OCR1AL=i;  

  delay_MS(50);
  i++;
}
  
    while(i-32)   //脉宽从2500uS往下减  注释(2)
{
      OCR1AH=0;
        OCR1AL=i;  

  delay_MS(50);
  i--;
}   
}
}

/*************************************************************
注释(1):160的由来,此设置要产生2500us的脉宽,OCR1AL=0xa0,OCR1AH=0x00;
        a0换算成10进制,得160

    (2):32的由来,此设置要产生500us的脉宽,OCR1AL=0xa20,OCR1AH=0x00;
        20换算成10进制,得32


   OCR1AL=0x20;   脉宽500
   OCR1AH=0x00;
   
   OCR1AL=0xa0;
   OCR1AH=0x00;   脉宽2500   
   
用示波器测量出的结果。


还有阿,延时程序可能不准阿,这个延时程序我也不知道什么时候从哪里抄下来的,呵呵。(见谅哈)
***************************************************************/


目前就这么多啦,其他的正在改良中,呵呵,欢迎各位前来赐教,不胜感激

出0入0汤圆

发表于 2009-11-8 21:48:36 | 显示全部楼层
学习,小时候就一直想搞搞航模,以后有机会一定玩玩舵机

出0入0汤圆

发表于 2009-11-8 21:58:16 | 显示全部楼层
好贴子

出0入0汤圆

发表于 2009-11-10 20:12:31 | 显示全部楼层
学习了

出0入0汤圆

发表于 2009-12-9 17:23:08 | 显示全部楼层
mark~~~

出0入0汤圆

发表于 2009-12-9 21:17:09 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-9 22:35:03 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-10 11:27:11 | 显示全部楼层
记号

出0入0汤圆

发表于 2010-5-14 11:41:50 | 显示全部楼层

出0入0汤圆

发表于 2010-5-14 15:51:29 | 显示全部楼层
用T/C1 PWM模块产生PWM
在头文件定义servo脉冲数

//----------------------------------------------------------------------
//  SERVO DEFINES
//----------------------------------------------------------------------
#define SERVO_CENTRE_DEFLECTION_VALUE_MAX +60
#define SERVO_CENTRE_DEFLECTION_VALUE_MIN -60
#define SERVO_ELECTRICAL_CENTER_POSITION  94  //定义servo中心位置  1500/16

c文件
TCCR1A = (1<<COM1A1)|(0<<COM1A0)|(1<<COM1B1)|(0<<COM1B0)|(1<<WGM11);                //匹配时输出低电平
TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS12)|(0<<CS11)|(0<<CS10);               
//WGM13:0= 1110,快速PWM。CS12 = 1,16M/256=6250,精度16us
ICR1 = 625;                                                //625*16us = 10000us = 10ms.servo标准周期

....
void vServo1ToPosition(signed int siSrvPos){
        //move servo 1 to position
        OCR1A=(unsigned int)gucSv1CenPos+siSrvPos;
}

void vServo2ToPosition(signed int siSrvPos){
        //move servo 2 to position
        OCR1B=(unsigned int)gucSv2CenPos+siSrvPos;
}
这样只要改变偏移量siSrvPos,就可以改变servo的位置了

出0入0汤圆

发表于 2010-6-30 00:24:11 | 显示全部楼层
发现有个问题,     TCCR1A=0x83;       //10位快速PWM,且OC1A输出反向
                   TCCR1B=0x03;      //设置10位快速PWM,且64分频
    应该是10位相位修正PWM模式吧, 我用了你的程序已经试过了,FUTABA S148舵机 效果还可以,就是在我这里左右角度不一致 调整
两个循环参数,基本一致 谢谢你程序,

出0入0汤圆

发表于 2010-7-2 00:24:38 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-5 23:58:38 | 显示全部楼层
学习了,今天搞舵机控制,搞了一晚上也没想明白

出0入0汤圆

发表于 2010-7-6 08:46:29 | 显示全部楼层
偶尔也玩航模...mark

出0入0汤圆

发表于 2010-9-4 21:46:52 | 显示全部楼层
谢谢楼主的程序,硬件PWM比模拟PWM好用得多啊

出0入0汤圆

发表于 2010-9-23 15:26:02 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-29 16:56:12 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-6 08:05:06 | 显示全部楼层
回复【41楼】diziaihaozhe
-----------------------------------------------------------------------

mark

出0入0汤圆

发表于 2011-7-11 21:37:10 | 显示全部楼层
mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-8 00:43

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表