搜索
bottom↓
回复: 91

【酷】 自写-多路舵机控制程序,舵机控制不明白的进来看!

  [复制链接]

出0入0汤圆

发表于 2012-3-30 10:27:55 | 显示全部楼层 |阅读模式
呵呵,第一次发帖。一直潜水来着,发现这里高手如云的。好吧,讲讲今天讨论呢的。

舵机控制信号  PWM  周期为20MS  高电平范围0.5ms-2.5ms  对应 0-180°  当多路舵机控制时候,目前这个方法最多只能8路控制   8*2.5(最大高电平时长)=20MS 刚好等于总周期。

下面贴上程序,本人小菜鸟,高手多多包涵。如果写的不好,请大家指点。多多学习,进步。

新论坛号码给封了,阿莫说一定要发帖,才能解锁。以后还想在论坛潜水呢, 大家帮帮忙啊。





/*-------------------------------------------------------------------------
* 文 件 名:舵机控制程序  实现任意角度变化 0.5MS-2.5MS 范围 周期20MS
* 芯    片:STC89C52RC
* 晶    振:12MHz
* 创 建 者:小强
* 创建日期:2011.10.25
* 修 改 者:
* 修改日期:
* 联系作者:lyg407@126.com   QQ:516380635

* 功能描述:两个按键控制 舵机从0-180°变化。。。
遇到问题: 如果使用平常方法给TH0 TL0 赋值 ,那样定时误差比较大。。

平常方法:        TH0=(65536-500)/256;
                        TL0=(65536-500)%256;
而如果使用这种方法:
                TH0=-num/256; //高电平时间
                TL0=-num%256;
误差就比较小。 所以。。任何事情理论和实际都有可能会有区别。
所以都要实践得出结果。。  
第一次INIT 初始化用平常方法可以,无所谓第一次中断。 。
但是后来定时 时间设置就不能就用平常方法了。而要用这个新颖的方法。
我也是看到别人是这么用的。。所以改了下,果然 效果很好。值得学习。
在KEIL仿真了一下。。然后观察寄存器 和平常方法是一致的。
-------------------------------------------------------------------------*/

#include<reg51.h>
#include<math.h>

#define uchar unsigned char
#define uint unsigned int

#define Cycle 20000  //定义周期
uint PWM_Value[8];

uchar order=0; //中断步长


sbit key1=P2^0;
sbit key2=P2^1;

//PWM的输出端口
sbit PWM_OUT0=P0^0;
sbit PWM_OUT1=P0^1;
sbit PWM_OUT2=P0^2;
sbit PWM_OUT3=P0^3;



void Init_Timer0()         //定时器0 初始化
{
        TMOD=0x01;

        TH0=(65536-500)/256;
        TL0=(65536-500)%256;

        EA = 1;//打开总中断
    ET0 = 1;//打开定时器0中断
    TR0 = 1;//启动定时器0
       
        PT0=1;  //定时器0 设置为最高优先中断
        PX0=0; // 外部中断0 设置最低中断
}
//延时
void delay(void)
{
  uint i=100;

  while(i--);

}

//按键检测
void keyscan()
{
        if(key1==0)                 //高电平加
        {
                if(PWM_Value[0]<2000)
                        PWM_Value[0]+=2;
                if(PWM_Value[1]<2000)
                        PWM_Value[1]+=2;
                if(PWM_Value[2]<2000)
                        PWM_Value[2]+=2;
                if(PWM_Value[3]<2000)
                        PWM_Value[3]+=2;
        }
        if(key2==0)           //高电平减
        {
                if(PWM_Value[0]>1000)
                        PWM_Value[0]-=2;
                if(PWM_Value[1]>1000)
                        PWM_Value[1]-=2;
                if(PWM_Value[2]>1000)
                        PWM_Value[2]-=2;
                if(PWM_Value[3]>1000)
                        PWM_Value[3]-=2;
        }

        delay();
}
//主函数
void main(void)
{
        PWM_Value[0]=1500;
        PWM_Value[1]=1500;
        PWM_Value[2]=1500;
        PWM_Value[3]=1500;
        Init_Timer0();

        while(1)
        {
                keyscan();       
        }
}
//定时器0 中断子函数
//这里输出几路波形 就应该为 20MS/N =X 那么X 就是N路平分时间
//在用N-高电平时间  就为该路低电平时间咯。 就这么简单。。。
void timer0(void) interrupt 1
{         
        switch(order)
        {
                case 1:PWM_OUT0=1;
                           TH0=-PWM_Value[0]/256;     //第一路输出高电平时长
                           TL0=-PWM_Value[0]%256;
                           break;
                case 2:PWM_OUT0=0;
                           TH0=-(5000-PWM_Value[0])/256;   //第一路 输出低电平时长
                           TL0=-(5000-PWM_Value[0])%256;
                           break;
                case 3:PWM_OUT1=1;
                           TH0=-PWM_Value[1]/256;
                           TL0=-PWM_Value[1]%256;
                           break;
                case 4:PWM_OUT1=0;
                           TH0=-(5000-PWM_Value[1])/256;
                           TL0=-(5000-PWM_Value[1])%256;
                           break;
                case 5:PWM_OUT2=1;
                           TH0=-PWM_Value[2]/256;
                           TL0=-PWM_Value[2]%256;
                           break;
                case 6:PWM_OUT2=0;
                           TH0=-(5000-PWM_Value[2])/256;
                           TL0=-(5000-PWM_Value[2])%256;
                           break;
                case 7:PWM_OUT3=1;
                           TH0=-PWM_Value[3]/256;
                           TL0=-PWM_Value[3]%256;
                           break;
                case 8:PWM_OUT3=0;
                           TH0=-(5000-PWM_Value[3])/256;
                           TL0=-(5000-PWM_Value[3])%256;
                          
                           order=0;
                           break;

                           default: order=0;
                }
                order++;
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2012-3-30 10:28:28 | 显示全部楼层
    先顶一个。

出0入0汤圆

发表于 2012-3-30 13:30:30 | 显示全部楼层
平常方法:        TH0=(65536-500)/256;
                        TL0=(65536-500)%256;
而如果使用这种方法:
                TH0=-num/256; //高电平时间
                TL0=-num%256;
请问楼主,这两种方法有什么不同的呢?

出0入0汤圆

 楼主| 发表于 2012-3-31 09:39:10 | 显示全部楼层
51yyaayya 发表于 2012-3-30 13:30
平常方法:        TH0=(65536-500)/256;
                        TL0=(65536-500)%256;
而如果使用这种方 ...

哈哈,这个问题我也奇怪, 我开始 是用第一种 方法 写的, 但是发现这样 出来的PWM 波形, 周期和高电平时长,都有大的误差,所以我就找了相关的参考,发现 都是用的第二种方法, 我做了试验, 第二种方法和第一种结果是一样的。可能是因为 单片机 处理两种语句  周期 时间 有区别吧。 个人理解,待高手指点吧。

出0入0汤圆

发表于 2012-4-2 21:21:25 | 显示全部楼层
菜鸟表示飘过~

出0入0汤圆

发表于 2012-4-2 22:15:13 | 显示全部楼层
LZ比我强,学习了

出0入0汤圆

发表于 2012-4-26 20:32:08 | 显示全部楼层
我也在研究呢

出0入0汤圆

发表于 2012-4-26 21:42:05 | 显示全部楼层
看得不是很明白,我以前做多路PWM输出时用以下这种方法,不知效果如何。

void tim0_ISR() interrupt 1   //﹚T0中断
{

  TH0=0xA3;    //0.1ms
  TL0=0Xa3;
  cout1++;    //计数
  if(cout1==t0_max)pwm1=1;//PWM_H   
  if(cout1==(t0_max+pwm_set1)) pwm1=0;//第一路PWM低电平时间   
  if(cout1==t0_max)pwm2=1;//PWM_H      
  if(cout1==(t0_max+pwm_set2)) pwm2=0;//第二路PWM低电平时间   
  if(cout1==t0_max)pwm3=1;//PWM_H      
  if(cout1==(t0_max+pwm_set3)) pwm3=0;//第三路PWM低电平时间   
if(cout1==212)cout1=0;//计数结束,这里为整个PWM周期

}
以上为3路PWM输出,调整pwm_set1/2/3娈量可以单独调节PWM脉宽。

出0入0汤圆

发表于 2012-4-26 21:54:26 | 显示全部楼层
D:\Work\舵机

出0入0汤圆

发表于 2012-6-7 19:24:43 | 显示全部楼层
#define Cycle 20000  //定义周期
这个是什么意识,是怎么定义的

出0入0汤圆

 楼主| 发表于 2012-6-9 23:10:49 | 显示全部楼层
嘿嘿H2 发表于 2012-6-7 19:24
#define Cycle 20000  //定义周期
这个是什么意识,是怎么定义的

这个是定义 PWM 输出的周期啊。  舵机周期一般是20MS   50HZ.

出0入0汤圆

发表于 2012-6-13 17:26:49 | 显示全部楼层
我的舵机没反应,不知道大家测试的怎么样?

出0入0汤圆

发表于 2012-6-13 17:29:21 | 显示全部楼层
好想看你的图

出0入0汤圆

发表于 2012-6-14 00:46:03 | 显示全部楼层
正在学pwm

出0入0汤圆

发表于 2012-6-14 08:53:15 | 显示全部楼层
lyg407 发表于 2012-6-9 23:10
这个是定义 PWM 输出的周期啊。  舵机周期一般是20MS   50HZ.

哦,谢谢,对c还是很了解,以前写汇编的,

出0入0汤圆

发表于 2012-6-14 08:54:29 | 显示全部楼层
lyg407 发表于 2012-6-9 23:10
这个是定义 PWM 输出的周期啊。  舵机周期一般是20MS   50HZ.

漏字了,是不了解

出0入0汤圆

发表于 2012-6-15 22:43:56 | 显示全部楼层
学习了

出0入0汤圆

发表于 2012-7-2 09:37:16 | 显示全部楼层
mark 路过,注意学习了!

出0入0汤圆

发表于 2012-7-2 15:14:39 | 显示全部楼层
谢谢楼主,写得不错

出0入0汤圆

 楼主| 发表于 2012-7-4 12:36:26 | 显示全部楼层
dingdingri 发表于 2012-7-2 15:14
谢谢楼主,写得不错

呵呵, 谢谢。  希望资料对大家有用。

出0入54汤圆

发表于 2012-7-19 20:30:41 | 显示全部楼层
频率是50hz的?

出0入0汤圆

 楼主| 发表于 2012-7-20 22:13:14 | 显示全部楼层
unifax001 发表于 2012-7-19 20:30
频率是50hz的?

of course.

出0入0汤圆

发表于 2012-7-21 10:41:33 | 显示全部楼层
程序很好啊,虽然弄了好久才用上,主要是是我太笨,按键扫描没注意

出0入0汤圆

 楼主| 发表于 2012-7-21 17:11:19 | 显示全部楼层
困境堂主 发表于 2012-7-21 10:41
程序很好啊,虽然弄了好久才用上,主要是是我太笨,按键扫描没注意

出0入0汤圆

发表于 2012-7-22 01:34:32 | 显示全部楼层
MARK 记录下

出0入0汤圆

 楼主| 发表于 2012-7-30 11:51:26 | 显示全部楼层
looklgb 发表于 2012-7-30 11:09
不知道LZ测试了没,proteus示波器可是没有波形的哦

      我一直用的很好哦。 可以根据自己要求适当更改。。如果有什么问题,可以找我。 一直不是太喜欢用仿真软件。。。喜欢实战,真实的。

出0入0汤圆

发表于 2012-7-30 14:12:28 | 显示全部楼层
非常好啊

出0入0汤圆

发表于 2012-7-30 15:47:40 | 显示全部楼层
lyg407 发表于 2012-3-31 09:39
哈哈,这个问题我也奇怪, 我开始 是用第一种 方法 写的, 但是发现这样 出来的PWM 波形, 周期和高电平 ...

你去看下汇编之后的代码就知道了第一种要多很多行!呵呵

出0入0汤圆

 楼主| 发表于 2012-7-30 16:05:49 | 显示全部楼层
sdyaojingwen 发表于 2012-7-30 15:47
你去看下汇编之后的代码就知道了第一种要多很多行!呵呵

恩。。 这个肯定是和单片机本身执行的速度有关。 谢谢你的指点,学习了。

出0入0汤圆

 楼主| 发表于 2012-7-30 16:06:55 | 显示全部楼层
dingdingri 发表于 2012-7-30 14:12
非常好啊

   谢谢支持。 我也想了好久,  还可以驱动多个舵机哦。

出0入0汤圆

发表于 2012-8-11 13:24:33 | 显示全部楼层
下进去程序  怎么舵机始终在0°啊

出0入0汤圆

发表于 2012-8-13 12:22:24 | 显示全部楼层
刚刚好在做舵机,,学习啊

出0入0汤圆

发表于 2012-8-13 12:22:39 | 显示全部楼层
刚刚好在做舵机,,学习啊

出0入0汤圆

发表于 2012-8-13 15:53:49 | 显示全部楼层
再做成遥控   

出0入0汤圆

发表于 2012-8-13 16:32:47 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2012-8-13 16:34:47 | 显示全部楼层
谢谢分享                     

出0入0汤圆

发表于 2012-8-13 19:26:36 | 显示全部楼层
楼主真的强悍

出0入0汤圆

发表于 2012-8-20 22:19:10 | 显示全部楼层
学习学习学习

出0入0汤圆

发表于 2012-9-3 17:31:27 | 显示全部楼层
正在学pwm

出0入0汤圆

发表于 2012-10-25 10:20:34 | 显示全部楼层
liweiqiang668 发表于 2012-4-26 21:42
看得不是很明白,我以前做多路PWM输出时用以下这种方法,不知效果如何。

void tim0_ISR() interrupt 1   / ...

一般的舵机中间值是1520us,你这样子,那个20us怎么出来呢?

出0入0汤圆

发表于 2012-10-28 22:25:32 | 显示全部楼层
如果要限制时间的话,是不是得另开一个定时器?

出0入0汤圆

 楼主| 发表于 2012-10-29 10:57:50 | 显示全部楼层
568581185 发表于 2012-10-28 22:25
如果要限制时间的话,是不是得另开一个定时器?



什么是时间限制?   周期20MS  那么所有的信号,必须20MS 在给一次型号。 如果是1-2MS范围 那么 2MS *10=20MS     最多分10分,驱动10路舵机。 如果是0.5-2.5MS  那么2.5MS*8=20MS  最多分8路。驱动8路舵机。  这是一个定时器驱动这么多路,  如果2个定时器,那么可以驱动更多路了哦。

出5入8汤圆

发表于 2012-10-29 11:03:41 | 显示全部楼层
菜鸟飘过,好好学习,天天向上。。。。

出0入0汤圆

 楼主| 发表于 2012-10-29 11:08:36 | 显示全部楼层
diyeyuye 发表于 2012-10-29 11:03
菜鸟飘过,好好学习,天天向上。。。。



出0入0汤圆

发表于 2012-10-29 20:04:05 | 显示全部楼层
我想问下LZ用PWM一直稳定地控制电机减速行么?

出0入0汤圆

发表于 2012-10-30 09:29:48 | 显示全部楼层
lyg407 发表于 2012-10-29 10:57
什么是时间限制?   周期20MS  那么所有的信号,必须20MS 在给一次型号。 如果是1-2MS范围 那 ...

因为舵机改造了,舵机能像电机一样一直转动,然后舵机得转一会儿停一会儿,那不是得开另外一个定时器定时么?

出0入0汤圆

 楼主| 发表于 2012-10-30 10:13:41 | 显示全部楼层
568581185 发表于 2012-10-30 09:29
因为舵机改造了,舵机能像电机一样一直转动,然后舵机得转一会儿停一会儿,那不是得开另 ...

阿是改成360°连续旋转舵机了?  一直正转,或者一直反转。。那你给个1.5MS 就停止, 小于1.5MS 就反转,大于1.5MS 就正转。

出0入0汤圆

 楼主| 发表于 2012-10-30 10:15:21 | 显示全部楼层
stm师弟 发表于 2012-10-29 20:04
我想问下LZ用PWM一直稳定地控制电机减速行么?

这个是控制舵机的程序。  如果控制普通低压直流电机,也和这个差不多。 加个驱动电路,然后用PWM 就能调速了。只不过占空比时间为0-100% 。

出0入0汤圆

发表于 2012-10-31 12:42:45 | 显示全部楼层
lyg407 发表于 2012-10-30 10:13
阿是改成360°连续旋转舵机了?  一直正转,或者一直反转。。那你给个1.5MS 就停止, 小于1.5MS 就反转, ...

额,反馈电路去掉了,呵呵

出0入0汤圆

发表于 2012-11-1 13:17:18 | 显示全部楼层
mark!mark,谢谢楼主分享

出0入0汤圆

 楼主| 发表于 2012-11-1 13:36:25 | 显示全部楼层
nullyb 发表于 2012-11-1 13:17
mark!mark,谢谢楼主分享

    新会员喔,第一次嘛。。给了我。哈哈。3Q。

出0入0汤圆

发表于 2012-11-1 17:18:05 | 显示全部楼层
嗯,新会员!以前在别的论坛了。

出0入0汤圆

发表于 2012-11-8 08:57:54 | 显示全部楼层
测试一下

出0入0汤圆

发表于 2012-11-12 00:13:56 | 显示全部楼层
留个记号

出0入0汤圆

发表于 2012-11-18 14:00:50 | 显示全部楼层
第一种方法有 求差运算,所以速度要慢于后者,个人观点,呵呵。

出0入0汤圆

发表于 2012-11-18 17:20:09 | 显示全部楼层
很有用的东西  不错啊

出0入0汤圆

发表于 2012-11-19 01:46:54 来自手机 | 显示全部楼层
记号,学习~~~

出0入0汤圆

发表于 2012-12-5 16:57:07 | 显示全部楼层
请问lz,有没检测过0.5--2.5ms变化是不是随着按键PWM_Value[xx]的值递增而线性变化呢?不过这可能不适用与更高场合的精度要求,我有个要求舵机1us精度变化的,用avr,lz有建议吗?

出0入0汤圆

发表于 2012-12-6 14:07:47 | 显示全部楼层
还有些东西看不是很明白,继续努力

出0入0汤圆

 楼主| 发表于 2012-12-6 14:28:33 | 显示全部楼层
时代还怪 发表于 2012-12-5 16:57
请问lz,有没检测过0.5--2.5ms变化是不是随着按键PWM_Value[xx]的值递增而线性变化呢?不过这可能不适用与 ...

舵机本身的话,我觉得精度不算太高。可能我用的普通的,而且本身用的地方,没有那么高的要求。 如果高精度的,可以试试步进电机呢?

出0入0汤圆

发表于 2012-12-6 15:24:02 | 显示全部楼层
楼主定时器用的不错。

出0入0汤圆

发表于 2012-12-6 15:39:42 | 显示全部楼层
mark            

出0入0汤圆

发表于 2013-1-4 13:12:01 | 显示全部楼层
一般的舵机中间值是1520us,

出0入0汤圆

发表于 2013-1-4 13:28:46 | 显示全部楼层
mark! 记住了

出0入0汤圆

发表于 2013-1-8 22:30:16 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2013-1-10 09:58:38 | 显示全部楼层
留爪待用

出0入0汤圆

发表于 2013-1-16 22:54:38 | 显示全部楼层
好东西,得分享一下!!!!

出0入0汤圆

发表于 2013-2-26 16:42:41 来自手机 | 显示全部楼层
学习一下....

出0入0汤圆

发表于 2013-2-26 16:45:25 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2013-4-22 23:45:53 | 显示全部楼层
学习了........

出0入0汤圆

发表于 2013-7-3 13:43:36 | 显示全部楼层
正在学习,谢谢分享

出0入0汤圆

发表于 2013-7-4 18:15:11 | 显示全部楼层
刚好要用到。谢谢LZ啦。遇到什么的,大家一起讨论下。

出0入0汤圆

发表于 2013-7-22 20:35:40 | 显示全部楼层
向lz学习下

出0入0汤圆

发表于 2013-7-22 22:26:05 | 显示全部楼层
楼主,程序只要将最精彩的部分拿出来共同分享,思想强调下,其他的部分打包就行了。。。

出10入95汤圆

发表于 2013-11-21 09:52:17 | 显示全部楼层
谢谢!

出0入0汤圆

 楼主| 发表于 2013-11-21 14:45:40 | 显示全部楼层
ddcour 发表于 2013-11-21 09:52
谢谢!

不谢。

出0入0汤圆

发表于 2013-11-21 15:34:50 | 显示全部楼层

出0入0汤圆

发表于 2013-11-22 16:56:18 | 显示全部楼层
是否有个电路图可以贴上来欣赏呢?

出0入0汤圆

发表于 2013-11-22 20:44:50 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2013-11-22 21:36:07 | 显示全部楼层
学习了,~

出0入0汤圆

发表于 2014-6-4 22:13:36 | 显示全部楼层
写得非常好,赞一个

出0入0汤圆

发表于 2014-8-10 14:42:19 | 显示全部楼层
楼主很棒,改天实践一下!!

出0入0汤圆

发表于 2014-9-15 07:21:22 | 显示全部楼层
老大厉害。长期潜水员要加油了 ,努力升级

出0入0汤圆

发表于 2015-6-4 16:15:10 | 显示全部楼层
今天无聊找了个舵机试了下,好像只能调90度角,示波器测了信号都正常。舵机是futaba的,不知道什么原因?

出0入0汤圆

发表于 2015-6-4 22:31:06 | 显示全部楼层
哈哈   谢谢楼主,

出0入0汤圆

发表于 2015-6-5 00:17:45 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2015-6-9 22:16:01 | 显示全部楼层
这个好,谢谢

出0入0汤圆

发表于 2015-7-20 07:33:43 | 显示全部楼层
谢谢分享学习了,~

出0入0汤圆

发表于 2015-7-20 13:12:03 | 显示全部楼层
4路pwm输出吗?

出0入0汤圆

发表于 2015-7-20 13:28:35 | 显示全部楼层
顶一下,顶一下

出0入0汤圆

发表于 2019-4-21 01:38:18 | 显示全部楼层
用到了,写的不错

出0入4汤圆

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

本版积分规则

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

GMT+8, 2024-7-24 06:23

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

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