找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 10021|回复: 5
收起左侧

单片机8路舵机PWM控制电路和源代码 得不错!

[复制链接]
ID:130231 发表于 2017-3-11 20:57 | 显示全部楼层 |阅读模式
                                                          今天在网上发现8路舵机PWM控制电路和源代码我觉得不错!控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。以180度角度伺服为例,那么对应的控制关系是这样的:

0.5ms--------------0度;

1.0ms------------45度;

1.5ms------------90度;

2.0ms-----------135度;

2.5ms-----------180度

此电路设计51单片机控制PWM信号,输送到两个按键开关,从而来控制舵机的正转和反转,转动角度范围-90度到90度。

舵机的追随特性:

假设现在舵机稳定在A点,这时候CPU发出一个PWM信号,舵机全速由A点转向B点,在这个过程中需要一段时间,舵机才能运动到B点。图中所示。
保持时间为Tw

当Tw≥△T时,舵机能够到达目标,并有剩余时间;

当Tw≤△T时,舵机不能到达目标;

理论上:当Tw=△T时,系统最连贯,而且舵机运动的最快。

实际过程中w不尽相同,连贯运动时的极限△T比较难以计算出来。

假如我们的舵机1DIV =8us,当PWM信号以最小变化量即(1DIV=8us)依次变化时,舵机的分辨率最高,但是速度会减慢。

FnMPcQf95SjwDq9Sg0laqdTSdxfo.png 12.png

仿真:
0.png

源代码:
  1. #include<reg52.h>

  2. sbit PWM0 = P1^0;
  3. sbit PWM1 = P1^1;
  4. sbit PWM2 = P1^2;
  5. sbit PWM3 = P1^3;
  6. sbit PWM4 = P1^4;
  7. sbit PWM5 = P1^5;
  8. sbit PWM6 = P1^6;
  9. sbit PWM7 = P1^7;

  10. sbit ADD = P3^6;
  11. sbit SUB = P3^7;

  12. #define uchar unsigned char
  13. #define uint unsigned int

  14. uint t_up0 = 1500;                //舵机PWM高电平时间 1000~2000表示1ms到2ms
  15. uint t_up1 = 1500;
  16. uint t_up2 = 1500;
  17. uint t_up3 = 1500;
  18. uint t_up4 = 1500;
  19. uint t_up5 = 1500;
  20. uint t_up6 = 1500;
  21. uint t_up7 = 1500;

  22. uint t0_h;
  23. uint t0_l;


  24. void delayms(uint ms)
  25. {       
  26.         unsigned char a,b,c;
  27.         while(ms--)
  28.         {               
  29.     for(c=1;c>0;c--)
  30.         for(b=142;b>0;b--)
  31.             for(a=2;a>0;a--);
  32.         }
  33. }
  34. void timer_init()
  35. {
  36.         EA = 1;
  37.         ET0 = 1;
  38.         PT0 = 1;
  39.         TMOD = 0x11;
  40.         TH0 = (65536 - t_up0)/256;
  41.         TL0 = (65536 - t_up0)%256;
  42. }

  43. uchar t0_flag = 0;
  44. uint num_max = 65535;        //直接用65535 - t_up 不用变量 - t_up 时,误差较大,原因暂时不明 【注:65536不能存到uint类型变量中】
  45. uint t_change = 63036;//换路周期2.5ms    8路

  46. uchar error0 = 45;
  47. uchar error1 = 45;
  48. uchar error2 = 52;
  49. uchar error3 = 52;
  50. uchar error4 = 57;
  51. uchar error5 = 57;
  52. uchar error6 = 63;
  53. uchar error7 = 63;
  54. uchar error8 = 70;
  55. uchar error9 = 70;
  56. uchar error10 = 76;
  57. uchar error11 = 76;
  58. uchar error12 = 82;
  59. uchar error13 = 82;
  60. uchar error14 = 88;
  61. uchar error15 = 88;

  62. void timer0() interrupt 1
  63. {
  64.        
  65.         if(t0_flag == 0)
  66.         {
  67.                 PWM0 = 1;
  68.                 TH0 = (num_max - t_up0 + error0)/256; //+?是为了抵消执行语句花的时间
  69.                 TL0 = (num_max - t_up0 + error0)%256;
  70.                
  71.                 t0_flag = 1;
  72.         }
  73.         else if(t0_flag == 1)
  74.         {
  75.                 PWM0 = 0;
  76.                 TH0 = (t_change + t_up0 +error1)/256;
  77.                 TL0 = (t_change + t_up0 +error1)%256;
  78.                
  79.                 t0_flag = 2;
  80.         }
  81.         else if(t0_flag == 2)
  82.         {
  83.                 PWM1 = 1;
  84.                 TH0 = (num_max - t_up1 + error2)/256; //+?是为了抵消执行语句花的时间
  85.                 TL0 = (num_max - t_up1 + error2)%256;
  86.                
  87.                 t0_flag = 3;
  88.         }
  89.         else if(t0_flag == 3)
  90.         {
  91.                 PWM1 = 0;
  92.                 TH0 = (t_change + t_up1 +error3)/256;
  93.                 TL0 = (t_change + t_up1 +error3)%256;
  94.                
  95.                 t0_flag = 4;
  96.         }
  97.         else if(t0_flag == 4)
  98.         {
  99.                 PWM2 = 1;
  100.                 TH0 = (num_max - t_up2 + error4)/256; //+?是为了抵消执行语句花的时间
  101.                 TL0 = (num_max - t_up2 + error4)%256;
  102.                
  103.                 t0_flag = 5;
  104.         }
  105.         else if(t0_flag == 5)
  106.         {
  107.                 PWM2 = 0;
  108.                 TH0 = (t_change + t_up2 +error5)/256;
  109.                 TL0 = (t_change + t_up2 +error5)%256;
  110.                
  111.                 t0_flag = 6;
  112.         }
  113.         else if(t0_flag == 6)
  114.         {
  115.                 PWM3 = 1;
  116.                 TH0 = (num_max - t_up3 + error6)/256; //+?是为了抵消执行语句花的时间
  117.                 TL0 = (num_max - t_up3 + error6)%256;
  118.                
  119.                 t0_flag = 7;
  120.         }
  121.         else if(t0_flag == 7)
  122.         {
  123.                 PWM3 = 0;
  124.                 TH0 = (t_change + t_up3 +error7)/256;
  125.                 TL0 = (t_change + t_up3 +error7)%256;
  126.                
  127.                 t0_flag = 8;
  128.         }
  129.         else if(t0_flag == 8)
  130.         {
  131.                 PWM4 = 1;
  132.                 TH0 = (num_max - t_up4 + error8)/256; //+?是为了抵消执行语句花的时间
  133.                 TL0 = (num_max - t_up4 + error8)%256;
  134.                
  135.                 t0_flag = 9;
  136.         }
  137.         else if(t0_flag == 9)
  138.         {
  139.                 PWM4 = 0;
  140.                 TH0 = (t_change + t_up4 +error9)/256;
  141.                 TL0 = (t_change + t_up4 +error9)%256;
  142.                
  143.                 t0_flag = 10;
  144.         }
  145.         else if(t0_flag == 10)
  146.         {
  147.                 PWM5 = 1;
  148.                 TH0 = (num_max - t_up5 + error10)/256; //+?是为了抵消执行语句花的时间
  149.                 TL0 = (num_max - t_up5 + error10)%256;
  150.                
  151.                 t0_flag = 11;
  152.         }
  153.         else if(t0_flag == 11)
  154.         {
  155.                 PWM5 = 0;
  156.                 TH0 = (t_change + t_up5 + error11)/256;
  157.                 TL0 = (t_change + t_up5 + error11)%256;
  158.                
  159.                 t0_flag = 12;
  160.         }
  161.         else if(t0_flag == 12)
  162.         {
  163.                 PWM6 = 1;
  164.                 TH0 = (num_max - t_up6 + error12)/256; //+?是为了抵消执行语句花的时间
  165.                 TL0 = (num_max - t_up6 + error12)%256;
  166.                
  167.                 t0_flag = 13;
  168.         }
  169.         else if(t0_flag == 13)
  170.         {
  171.                 PWM6 = 0;
  172.                 TH0 = (t_change + t_up6 + error13)/256;
  173.                 TL0 = (t_change + t_up6 + error13)%256;
  174.                
  175.                 t0_flag = 14;
  176.         }
  177.         else if(t0_flag == 14)
  178.         {
  179.                 PWM7 = 1;
  180.                 TH0 = (num_max - t_up7 + error14)/256; //+?是为了抵消执行语句花的时间
  181.                 TL0 = (num_max - t_up7 + error14)%256;
  182.                
  183.                 t0_flag = 15;
  184.         }
  185.         else if(t0_flag == 15)
  186.         {
  187.                 PWM7 = 0;
  188.                 TH0 = (t_change + t_up7 + error15)/256;
  189.                 TL0 = (t_change + t_up7 + error15)%256;
  190.                
  191.                 t0_flag = 0;
  192.         }
  193.        
  194. }
  195. void main()
  196. {
  197.         uint t_while;
  198.         timer_init();
  199.         TR0 = 1;
  200.         while(1)
  201.         {
  202.                
  203.                 if(ADD == 0)
  204.                 {
  205.                         delayms(2);
  206.                         if(ADD == 0)
  207.                         {
  208.                                 if(t_up0 <= 1950)
  209.                                 {
  210.                                         t_up0 = t_up0 + 50;
  211.                                         t_up1 = t_up1 + 50;
  212.                                         t_up2 = t_up2 + 50;
  213.                                         t_up3 = t_up3 + 50;
  214.                                         t_up4 = t_up4 + 50;
  215.                                         t_up5 = t_up5 + 50;
  216.                                         t_up6 = t_up6 + 50;
  217.                                         t_up7 = t_up7 + 50;
  218.                                 }
  219.                                
  220.                                 t_while = 50000;
  221.                                 while(t_while--)
  222.                                 {
  223.                                         if(ADD == 1)
  224.                                                 break;
  225.                                 }
  226.                                

  227. …………余下代码请下载附件…………
复制代码

0.png

下载:
8路舵机PWM控制电路和源代码.zip (341.88 KB, 下载次数: 107)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:340880 发表于 2018-5-30 02:42 | 显示全部楼层
哪位大神知道这是用什么仿真的
回复

使用道具 举报

ID:344400 发表于 2018-6-4 09:29 | 显示全部楼层
渣渣新 发表于 2018-5-30 02:42
哪位大神知道这是用什么仿真的

像是KEIL软件,哪个版本不清楚
回复

使用道具 举报

ID:345120 发表于 2018-6-5 17:27 来自手机 | 显示全部楼层
渣渣新 发表于 2018-5-30 02:42
哪位大神知道这是用什么仿真的

proteus ?
回复

使用道具 举报

ID:230020 发表于 2018-6-5 18:40 | 显示全部楼层
必须顶啊!
回复

使用道具 举报

ID:229106 发表于 2018-6-8 19:02 | 显示全部楼层
渣渣新 发表于 2018-5-30 02:42
哪位大神知道这是用什么仿真的

Protues下的isis
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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