找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机步进电机正反转控制仿真及说明 程序有详细注释

[复制链接]
ID:753618 发表于 2020-5-27 22:04 | 显示全部楼层 |阅读模式
步进电机是机电设计中的一个关键,很多人不能理解电机控制中程序设置1100的原理,我专门画了一个六个场效应管的仿真图,另外,对于中断的开启和关闭也做了注释,希望能够帮助到个位黑友。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.png 51hei.png

如图,有6个场效应管,当Q1、Q4打开时,AB相导通,电流经正极---Q1---线圈A---线圈B---Q4---负极,六种相位导通模式依次为:AB、AC、BC、BA、CA、CB,场效应管导通顺序:Q1Q4、Q1Q2、Q3Q2、Q3Q6、Q5Q6、Q5Q4按照Q6Q5Q4Q3Q2Q1顺序排列,如令Q1、Q4 = 1时,场效应管导通。如线圈A、B通电,有排列0 0 0 0 0 1 1,其余类推。以上是用六个场效应管控制线圈通电情况的分析,对于仿真模拟中1 1 0 0 的情况可以类似理解。

单片机源程序如下:
  1. #include<reg51.h>       //包含51单片机寄存器定义的头文件
  2. typedef unsigned char uchar;
  3. typedef unsigned int uint;
  4. sbit S1=P1^4;           //将S1位定义为P1.4引脚
  5. sbit S2=P1^5;           //将S2位定义为P1.5引脚
  6. sbit S3=P1^6;           //将S3位定义为P1.6引脚
  7. uchar keyval;   //储存按键值
  8. uchar ID;       //储存功能标号
  9. /*************************************************
  10. 函数功能:软件延时(约50ms)
  11. **************************************************/
  12. void delay(uint num)     //延迟函数用了两个参数,如num=10,则循环1100次
  13. {
  14.    uint x,y;
  15.    for (x=num;x>0;x--)
  16.    for (y=110;y>0;y--);
  17. }
  18. /************************************************
  19. 函数功能:步进电机转动延时,延时越长,转速越慢
  20. *************************************************/
  21. void motor_delay(void)     
  22. {
  23.    uint i;
  24.      for(i=0;i<2000;i++)   // 马达延时函数只用了一个参数,共循环2000,
  25.         ;                  // 与延迟函数差不多

  26. }
  27. /************************************************
  28. 函数功能:步进电机正转(利用motor_delay()函数实现延时)
  29. *************************************************/
  30. void forward( )
  31.   {
  32.       P0=0xfc;           //P0口低四位脉冲1100
  33.       motor_delay();     //在1100状态停留2000次循环
  34.       P0=0xf6;           //P0口低四位脉冲0110
  35.       motor_delay();     //在0110状态停留2000次循环
  36.       P0=0xf3;           //P0口低四位脉冲0011
  37.       motor_delay();     //在0011状态停留2000次循环
  38.       P0=0xf9;           //P0口低四位脉冲1001
  39.       motor_delay();     //在1001状态停留2000次循环
  40.   }
  41. /************************************************
  42. 函数功能:步进电机反转
  43. *************************************************/
  44. void backward()
  45.   {
  46.       P0=0xfc;            //P0口低四位脉冲1100
  47.       motor_delay();
  48.       P0=0xf9;           //P0口低四位脉冲1001
  49.       motor_delay();
  50.       P0=0xf3;           //P0口低四位脉冲0011
  51.       motor_delay();
  52.       P0=0xf6;           //P0口低四位脉冲0110
  53.       motor_delay();
  54.   }
  55. /************************************************
  56. 函数功能:步进电机停转
  57. *************************************************/
  58. void stop(void)
  59. {
  60.       P0=0xff ;          //停止输出脉冲
  61. }
  62. /*************************************************
  63. 函数功能:主函数
  64. **************************************************/
  65. void main(void)           
  66. {
  67.    TMOD=0x01;               //使用定时器T0的模式1
  68.    TR0=0;                   //给定时器T0赋初值并关闭T0
  69.    TH0=(65536-500)/256;     //定时器TH0赋初值为500
  70.    TL0=(65536-500)%256;     //定时器TL0赋初值为500
  71.    keyval=0;                //按键值初始化为0
  72.    ID=0;
  73.    EA=1;                    //开总中断
  74.    ET0=1;                   //定时器T0中断允许
  75.    TR0=1;                   //启动定时器T0,这里必须要启动,因为大循环里                  
  76.    while(1)                 //要给keyval赋值,而赋值语句在中断服务函数里
  77.    {                  
  78.        switch(keyval)           //根据按键值keyval选择待执行的功能
  79.        {
  80.             case 1:forward();  break;  //按键S1按下,正转
  81.                                           
  82.             case 2:backward(); break;  //按键S2按下,反转
  83.                                           
  84.             case 3:stop();     break;  //按键S3按下,停转                                                                                   
  85.        }                        
  86.    }
  87. }
  88. /*************************************************
  89. 函数功能:定时器T0的中断服务子程序
  90. **************************************************/
  91. void Time0_serve(void) interrupt 1  
  92. {
  93.    TH0=(65536-200)/256;         //定时器T0的高8位赋初值
  94.    TL0=(65536-200)%256;         //定时器T0的低8位赋初值
  95.    if((P1&0xff)!=0xff)          //检测是否有按键按下
  96.        {
  97.             delay(50);            //延时一段时间再去检测
  98.             if((P1&0xff)!=0xff)   //再次检测是否确实有按键按下
  99.             {
  100.                 if(S1==0)        //按键S1被按下
  101.                 keyval=1;        //给keyval赋值
  102.                 if(S2==0)        //按键S2被按下
  103.                 keyval=2;        //给keyval赋值
  104.                 if(S3==0)        //按键S3被按下
  105.                 keyval=3;        //给keyval赋值                                    
  106.             }//注:有些作者喜欢在中断程序里设置定时器开、关,
  107.        }     //其实没有必要。因为主程序调用时必须进行定时器设置
  108. }
复制代码

所有资料51hei提供下载(仿真工程报错的,参考回帖中的解决办法):
电机正反转控制及说明.zip (74.52 KB, 下载次数: 101)

评分

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

查看全部评分

回复

使用道具 举报

ID:328014 发表于 2021-6-20 18:20 | 显示全部楼层
我叫小大打 发表于 2021-6-20 11:20
仿真不行,打开报错,大家有无解决办法

我研究一下,终于成功打开了这个仿真工程大家打不开的原因应该是作者是用的之前很老的Proteus版本画的,应该低于7.1版,所以工程对咱们现在用的高版不兼容
我研究出了2个解决办法:http://www.51hei.com/bbs/dpj-208859-1.html  成功搞定了,如图(我是用的Proteus8.8版本成功打开的,其他版本未测试,7.5与7.8均报错):

51hei.gif



用7.5与7.8直接打开确实会报错:
51hei.png

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:652598 发表于 2020-6-4 13:43 | 显示全部楼层
电机不转,难受
回复

使用道具 举报

ID:429631 发表于 2020-6-5 03:40 来自手机 | 显示全部楼层
好帖子,有空研究研究!
回复

使用道具 举报

ID:737390 发表于 2020-6-5 09:20 | 显示全部楼层

好帖子,程序书写规范值得学习!
回复

使用道具 举报

ID:699194 发表于 2021-6-20 11:20 | 显示全部楼层
仿真不行,打开报错,大家有无解决办法
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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