找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2615|回复: 7
打印 上一主题 下一主题
收起左侧

电机控制问题困扰了我几天了,有好的办法,在文档里给我解答,谢谢

[复制链接]
跳转到指定楼层
楼主
ID:37147 发表于 2016-12-4 11:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
问题困扰了我几天了,有好的办法,在文档里给我解答,谢谢、

方案一:
1、谁能提供一个思路:用一个固定的中断时间,中断一次,变量加一次。变量每加一次,刷新的数据更新一次,这个变量的作用是:改变中断的频率的。比如说:一开始定时1ms中断一次,刷新一次数据,然后又中断一次,变量在之前的基础上加一,即2ms后数据跟着刷新一次,再中断一次,3ms后数据刷新一次,依次往下进行,即想实现匀减速。之所以用固定时间中断是因为我还需要一个脉冲(这个可以实现,但是实现不了匀减速)。
我现在这程序,你们看下,步进电机设置了3个速度,一圈一个固定速度,不是我想要的。我想要的是总共转3圈的话,速度慢慢降下来,减速的等级设多点,平滑点就好了。
方案二:
2、当然你们要说改变定时器的初值的话,这样行,我实现了电机的匀减速,我还需要一个固定的脉冲,定时的初值又是变化的,又实现不了固定脉冲了。这两个方案,问题相互交叉,很是烦恼。
方案三:
3、你们会想使用2个定时器,一个定时器给电机做匀减速运动,一个定时器做固定脉冲输出,我试了,匀减速没问题,但是固定脉冲会受影响,不是一个稳定的脉冲占空比。

  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. volatile unsigned long beats1=0;//电机1转动节拍总数
  6. void startmotor1(unsigned long angle1);//电机1函数       
  7. static unsigned char index1 =0;//节拍输出索引1
  8. unsigned char code beatcode1[8]={0x1,0x3,0x2,0x6,0x4,0xc,0x8,0x9};//步进电机1、3节拍控制码
  9. uchar temp1=0;//临时变量
  10. uchar n=0;//小电机中断频率计数变量
  11. uint k=0;//小电机刷新节拍计数
  12. void delay(unsigned char i)
  13. {
  14.         unsigned x,y;
  15.         for(x=i;x>0;x--)
  16.                 for(y=50;y>0;y--);
  17. }

  18. bit flag1=0,flag2=0,flag3=0,flag4=0;
  19. unsigned char dir=0;
  20. sbit k1=P3^5;//按键1--启动电机/正转
  21. sbit k2=P3^6;//按键2--电机反转
  22. sbit k3=P3^7;//按键3--暂停/开始
  23. sbit PWM=P2^0;//42步进电机脉冲引脚
  24. sbit buffer=P2^5;//蜂鸣器
  25. sbit fangxiang=P2^6;//电机正反转控制线
  26. sbit EN=P2^7;                //使能停止线
  27. sbit P1_0=P1^0;
  28. sbit P1_1=P1^1;
  29. sbit P1_2=P1^2;
  30. sbit P1_3=P1^3;
  31. sbit P1_4=P1^4;
  32. sbit P1_5=P1^5;
  33. sbit P1_6=P1^6;
  34. sbit P1_7=P1^7;
  35. void di()                   //蜂鸣器函数
  36. {
  37.         unsigned char a;
  38.         for(a=0;a<100;a++)
  39.         {
  40.             delay(1);
  41.                 buffer=0;
  42.                 delay(1);
  43.                 buffer=1;
  44.          }        
  45. }
  46. void keyscan()                //按键扫描程序
  47. {
  48.                 if(k1==0)
  49.                         delay(10);                                   //消抖
  50.                         if(k1==0)                                  //启动电机
  51.                         {      
  52.                                  while(!k1);                          //等待按键1松手
  53.                                 TR0=1;

  54.                         //        EN=1;
  55.                         //        fangxiang=0;
  56.                                 startmotor1(360*5);          //调用电机1函数
  57.                          }

  58. }
  59. void startmotor1(unsigned long angle1) //步进电机1启动函数,angle1为所转动角度
  60. {
  61.         EA=0;
  62.         beats1=(angle1*4076)/360;
  63.         EA=1;

  64. }

  65. void motor1()        //电机函数;固定格式,调用就行。
  66. {
  67.                         if(beats1!=0)
  68.                                 {
  69.                                         temp1=P1;
  70.                                         temp1=temp1&0xf0;                //清零P1口低4位  11110000
  71.                                         temp1=temp1|beatcode1[index1];
  72.                                         P1=temp1;
  73.                                         index1++;
  74.                                         index1=index1&0x07;
  75.                                         beats1--;
  76.                                 }
  77.                                 else
  78.                                 {                  
  79.                                     P1_0=0;
  80.                                         P1_1=0;
  81.                                         P1_2=0;
  82.                                         P1_3=0;         
  83.                                 }
  84. }

  85. void main()
  86. {  
  87.         TMOD=0x01;//设置T0为模式1
  88.         TH0=0xfc; //1ms中断一次
  89.         TL0=0x18;
  90.         ET0=1;
  91.         while(1)
  92.         {
  93.                 keyscan();        //按键扫描
  94.                 if(flag1==1)  
  95.                 {
  96.                         flag1=0;
  97.                         if(flag3==1) //进入第3圈速度;
  98.                         {
  99.                                 if(n==8) //第3圈速度,3ms刷新一次节拍;
  100.                                 {
  101.                                         n=5;
  102.                                         k++;  //第3圈节拍计数;
  103.                                         if(k==4076)         //第3圈以3ms的速度刷新4076个节拍后(即转了一圈),停止转动。
  104.                                         {
  105.                                                 k=0;
  106.                                                 beats1=0;//停止转动
  107.                                                 flag3=0;//标志3清楚,以便再次启动定时器;
  108.                                                 n=0;        //n清零
  109.                                                 TR0=0;//关定时器       
  110.                                         }
  111.                                  motor1();
  112.                                 }
  113.                         }
  114.                         if(flag2==1)  //进入第2圈速度;
  115.                         {
  116.                                 if(n==4)  //第2圈速度,2ms刷新一次节拍;
  117.                                 {
  118.                                         n=2;
  119.                                         k++;   //第2圈节拍计数;
  120.                                         if(k==4076)        //第2圈以2ms的速度刷新4076个节拍后(即转了一圈),重新设置速度n=5,进入标志3判断;
  121.                                         {
  122.                                                 k=0;
  123.                                                 n=5;
  124.                                                 flag3=1;   //速度3标志,进入速度3,3ms刷新一次;
  125.                                         }       
  126.                                 motor1();
  127.                                 }
  128.                         }  
  129.                         if(n==1)           //进入第1圈速度,1ms刷新一次节拍;
  130.                         {
  131.                                 n=0;
  132.                                 k++;           //第1圈节拍计数;
  133.                                         if(k==4076)         //第1圈以1ms的速度刷新4076个节拍后(即转了一圈),重新设置速度n=2,进入标志2判断;
  134.                                         {
  135.                                                 k=0;
  136.                                                 n=2;
  137.                                                 flag2=1;//速度2标志,进入速度2,2ms刷新一次;
  138.                                         }
  139.                                 motor1();                               
  140.                         }  
  141.                 }
  142.         }
  143. }


  144. void timer0() interrupt 1                
  145. {
  146.         TH0=0xfc; //重新赋值,1ms中断一次
  147.         TL0=0x18;
  148.         n++;         //小电机中断刷新频率计数
  149.         flag1=1;//标志的作用是跳至主函数中,以节省中断时间。
  150. }
复制代码


问题困扰了我几天了,有好的办法,在文档里给我解答,谢谢.rar

4.53 KB, 下载次数: 6, 下载积分: 黑币 -5

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2017-1-10 00:17 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

板凳
ID:37147 发表于 2017-1-10 20:45 | 只看该作者
admin 发表于 2017-1-10 00:17
好资料,51黑有你更精彩!!!

问题已经解决了。谢谢
回复

使用道具 举报

地板
ID:1 发表于 2017-1-10 20:59 | 只看该作者
怎么解决的能分享一下吗?
回复

使用道具 举报

5#
ID:37147 发表于 2017-1-10 21:40 | 只看该作者
admin 发表于 2017-1-10 20:59
怎么解决的能分享一下吗?

可以,有时间分享出来,就在这几天。
回复

使用道具 举报

6#
ID:161164 发表于 2017-1-10 23:08 | 只看该作者
虽然楼主的问题解决了,但我还是想分享一下我的想法,看看可不可行
uchar ScanTime = 0;  //创建一个全局变数,预设刷新时间
把以下代码替换 if(flag1==1) {}里的代码
if(flag1==1)  
{
                flag1=0;
                if(n>=ScanTime)           //进入第1圈速度,预设1ms刷新一次节拍;
                {
                                n=0;
                                k++;           //节拍计数;
                                if(k>=1019)         //1019 = 4076*3(圈)/12(级)
                                {
                                                k=0;
                                                ScanTime++; //延长刷新时间
                                                if(ScanTime>=12)  //12级减速
                                                {
                                                        beats1=0;//停止转动
                                                        TR0=0;//关定时器
                                                }
                                }
                                motor1();                                
                }  
}






回复

使用道具 举报

7#
ID:37147 发表于 2017-1-11 08:53 | 只看该作者
lkc8210 发表于 2017-1-10 23:08
虽然楼主的问题解决了,但我还是想分享一下我的想法,看看可不可行
uchar ScanTime = 0;  //创建一个全局 ...

对的,我也是按照这个思路写的
回复

使用道具 举报

8#
ID:37147 发表于 2017-1-11 09:08 | 只看该作者
admin 发表于 2017-1-10 20:59
怎么解决的能分享一下吗?

管理员您好,需要分享的资料,我已经分享出来了,麻烦您审核通过一下,供大家参考、学习!谢谢!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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