找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机驱动步进电机程序 可调圈数 默认启动一次转100圈

[复制链接]
跳转到指定楼层
楼主
ID:217754 发表于 2017-7-16 22:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我也是刚学。用的资料改的。我自己用来绕线做特斯拉线圈使用。默认启动一次转100圈。需要可以自己调。

单片机源程序如下:
  1. //download by http://down.liehuo.net
  2.    
  3. #include <reg51.h>       //51芯片管脚定义头文件
  4. #include <intrins.h>  //内部包含延时函数 _nop_();

  5. #define uchar unsigned char
  6. #define uint  unsigned int
  7. #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};


  8. uchar code FFW[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9};
  9. uchar code REV[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1};

  10. sbit  K1   = P3^2;       //运行与停止
  11. sbit  K2   = P3^3;       //设定圈数
  12. sbit  K3   = P3^4;       //方向转换
  13. sbit  K4   = P3^5;       //速率调整
  14. sbit  BEEP = P3^6;       //蜂鸣器

  15. sbit  LCD_RS = P2^0;            
  16. sbit  LCD_RW = P2^1;
  17. sbit  LCD_EN = P2^2;

  18. bit  on_off=0;            //运行与停止标志
  19. bit  direction=1;         //方向标志
  20. bit  rate_dr=1;           //速率标志
  21. bit  snum_dr=1;           //圈数标志

  22. uchar code  cdis1[ ] = {" STEPPING MOTOR "};
  23. uchar code  cdis2[ ] = {"CONTROL  PROCESS"};
  24. uchar code  cdis3[ ] = {"    STOP        "};
  25. uchar code  cdis4[ ] = {"NUM:    RATE:   "};
  26. uchar code  cdis5[ ] = {"  RUNNING       "};

  27. uchar   m,v=0,q=0;

  28. uint   number=0,number1=0;
  29. uchar   snum=100,snum1=100;       //预设定圈数
  30. uchar   rate=2;               //预设定速率
  31. uchar   data_temp,data_temP1,data_temp2;   

  32. /********************************************************/
  33. /*                                                  
  34. /* 延时t毫秒
  35. /* 11.0592MHz时钟,延时约1ms                                    
  36. /*                                                      
  37. /********************************************************/
  38. void delay(uint t)
  39. {                           
  40.    uchar k;
  41.    while(t--)
  42.    {
  43.      for(k=0; k<80; k++)
  44.      { }
  45.    }
  46. }

  47. /********************************************************/
  48. void delayB(uchar x)    //x*0.14MS
  49. {
  50.    uchar i;
  51.    while(x--)
  52.    {
  53.      for (i=0; i<13; i++)
  54.      { }
  55.    }
  56. }

  57. /********************************************************/
  58. void beep()
  59. {
  60.    uchar j;
  61.    for (j=0;j<100;j++)
  62.     {
  63.      delayB(4);
  64.      BEEP=!BEEP;                 //BEEP取反
  65.     }
  66.      BEEP=1;                    //关闭蜂鸣器
  67.   delay(170);
  68. }

  69. /********************************************************/
  70. /*                                                               
  71. /*检查LCD忙状态                                                   
  72. /*lcd_busy为1时,忙,等待。为0时,闲,可写指令与数据。     
  73. /*                                                               
  74. /********************************************************/

  75. bit lcd_busy()
  76. {                          
  77.     bit result;
  78.     LCD_RS = 0;
  79.     LCD_RW = 1;
  80.     LCD_EN = 1;
  81.     delayNOP();
  82.     result = (bit)(P0&0x80);
  83.     LCD_EN = 0;
  84.     return(result);
  85. }

  86. /********************************************************/
  87. /*                                                                 
  88. /*写指令数据到LCD                                                
  89. /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                             
  90. /*                                                               
  91. /********************************************************/

  92. void lcd_wcmd(uchar cmd)

  93. {                          
  94.    while(lcd_busy());
  95.     LCD_RS = 0;
  96.     LCD_RW = 0;
  97.     LCD_EN = 0;
  98.     _nop_();
  99.     _nop_();
  100.     P0 = cmd;
  101.     delayNOP();
  102.     LCD_EN = 1;
  103.     delayNOP();
  104.     LCD_EN = 0;  
  105. }

  106. /********************************************************/
  107. /*                                                               
  108. /*写显示数据到LCD                                                  
  109. /*RS=H,RW=L,E=高脉冲,D0-D7=数据。                              
  110. /*                                                               
  111. /********************************************************/

  112. void lcd_wdat(uchar dat)
  113. {                          
  114.    while(lcd_busy());
  115.     LCD_RS = 1;
  116.     LCD_RW = 0;
  117.     LCD_EN = 0;
  118.     P0 = dat;
  119.     delayNOP();
  120.     LCD_EN = 1;
  121.     delayNOP();
  122.     LCD_EN = 0;
  123. }

  124. /********************************************************/
  125. /*                                                               
  126. /*  LCD初始化设定                                                
  127. /*                                                               
  128. /********************************************************/

  129. void lcd_init()
  130. {
  131.     delay(30);                  
  132.     lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据
  133.     delay(5);
  134.     lcd_wcmd(0x38);         
  135.     delay(5);
  136.     lcd_wcmd(0x38);         
  137.     delay(5);

  138.     lcd_wcmd(0x0c);      //显示开,关光标
  139.     delay(5);
  140.     lcd_wcmd(0x06);      //移动光标
  141.     delay(5);
  142.     lcd_wcmd(0x01);      //清除LCD的显示内容
  143.     delay(5);
  144. }

  145. /********************************************************/
  146. /*                                                                 
  147. /*  设定显示位置                                                  
  148. /*                                                               
  149. /********************************************************/

  150. void lcd_pos(uchar pos)
  151. {                          
  152.   lcd_wcmd(pos | 0x80);  //数据指针=80+地址变量
  153. }

  154. /********************************************************/
  155. /*                                                      
  156. /* LCD1602初始显示子程序                                             
  157. /*                                                      
  158. /********************************************************/
  159. void  LCD_init_DIS()
  160. {            
  161.      delay(10);                 //延时
  162.      lcd_init();                //初始化LCD            
  163.         
  164.      lcd_pos(0);                //设置显示位置为第一行的第1个字符
  165.      m = 0;
  166.      while(cdis1[m] != '\0')
  167.       {                         //显示字符
  168.         lcd_wdat(cdis1[m]);
  169.         m++;
  170.       }

  171.      lcd_pos(0x40);             //设置显示位置为第二行第1个字符
  172.      m = 0;
  173.      while(cdis2[m] != '\0')
  174.       {
  175.         lcd_wdat(cdis2[m]);      //显示字符
  176.         m++;
  177.       }

  178.       delay(3000);               //延时        
  179.         
  180.       lcd_pos(0);                //设置显示位置为第一行的第1个字符
  181.       m = 0;
  182.       while(cdis3[m] != '\0')
  183.         {                        //显示字符
  184.           lcd_wdat(cdis3[m]);
  185.           m++;
  186.         }

  187.       lcd_pos(0x40);             //设置显示位置为第二行第1个字符
  188.       m = 0;
  189.      while(cdis4[m] != '\0')
  190.         {
  191.           lcd_wdat(cdis4[m]);    //显示字符
  192.           m++;
  193.         }      

  194.         for(m=0;m<2;m++)
  195.           {
  196.        lcd_pos(0x0c+m);    //显示方向符号
  197.              lcd_wdat(0x3e);
  198.     }

  199. }
  200. /********************************************************/
  201. /*
  202. /*数据转换子程序
  203. /*
  204. /********************************************************/
  205. void  data_conv()
  206. {
  207.      data_temP1=data_temp/10;       //高位
  208.   if(data_temP1==0)
  209.   {data_temP1=0x20;}             //高位为0不显示
  210.      else
  211.   {data_temP1=data_temP1+0x30;}

  212.    data_temp2=data_temp%10;       //低位
  213.      data_temp2=data_temp2+0x30;
  214. }

  215. /********************************************************/
  216. /*
  217. /*数据显示子程序
  218. /*
  219. /********************************************************/
  220. void  data_dis()
  221. {
  222.     data_temp = snum;        //显示圈数
  223.     data_conv();
  224.        lcd_pos(0x44);
  225.        lcd_wdat(data_temP1);
  226.        lcd_pos(0x45);
  227.        lcd_wdat(data_temp2);
  228.    
  229.     data_temp = rate;         //显示速率
  230.     data_conv();
  231.        lcd_pos(0x4d);
  232.        lcd_wdat(data_temP1);
  233.        lcd_pos(0x4e);
  234.        lcd_wdat(data_temp2);
  235. }
  236. /********************************************************
  237. /*
  238. /* 显示运行方向符号
  239. /*
  240. /********************************************************/
  241. void  motor_DR()
  242.   {
  243.        if(direction==1)           //正转方向标志
  244.         { for(m=0;m<2;m++)
  245.           {
  246.       lcd_pos(0x0c+m);      //显示方向符号
  247.             lcd_wdat(0x3e);
  248.      }
  249.    }
  250.         else
  251.          { for(m=0;m<2;m++)       //反转方向标志
  252.            {
  253.           lcd_pos(0x0c+m);     //显示方向符号
  254.              lcd_wdat(0x3c);
  255.      }
  256.    }
  257.   }

  258. /********************************************************
  259. /*
  260. /* 显示运行状态
  261. /*
  262. /********************************************************/
  263. void  motor_RUN()
  264. {
  265.       if(on_off==1)
  266.     { TR0=1;
  267.       lcd_pos(0);     //设置显示位置为第一行的第1个字符
  268.          m = 0;
  269.          while(cdis5[m] != '\0')
  270.           { lcd_wdat(cdis5[m]);      //RUNNING
  271.             m++;   }
  272.             motor_DR();              //
  273.     }  
  274.       else  
  275.     { TR0=0; P1 =0x0f;
  276.    lcd_pos(0);     //设置显示位置为第一行的第1个字符
  277.          m = 0;
  278.          while(cdis3[m] != '\0')
  279.           { lcd_wdat(cdis3[m]);      //STOP
  280.             m++;   }
  281.             motor_DR();              //
  282.    snum=snum1;             //
  283.    number1=0;              //清圈数计数器
  284.          }
  285.   }

  286. /********************************************************
  287. *                                                      
  288. *  主程序                                               
  289. *                                                      
  290. *********************************************************/

  291. main()
  292. {
  293.          LCD_init_DIS();
  294.   
  295.    TMOD = 0x01;       //T0定时方式1
  296.    TL0  = 0x33;
  297.    TH0  = 0xf5;
  298.    EA   = 1;
  299.    ET0  = 1;
  300.     P1   = 0x0f;
  301.   
  302.    while(1)
  303.     {  
  304.        if(K1==0)
  305.     {
  306.          beep();
  307.       while(K1==0);       //等待键释放
  308.       on_off=~on_off;      
  309.          motor_RUN();  
  310.         }   //K1 end
  311. /********************************************************/
  312.       if(K2==0)   
  313.        {
  314.       beep();
  315.    if(snum_dr==1)
  316.     { snum++;
  317.         snum1=snum;
  318.       if(snum==0x14)
  319.             { snum_dr=~snum_dr;}
  320.     }
  321.    else  
  322.      {snum--;
  323.    snum1=snum;
  324.       if(snum==0x01)
  325.    { snum_dr=~snum_dr; }
  326.      }
  327.    
  328.     } //K2  end
  329. /********************************************************/
  330.         if(K3==0)   
  331.       {
  332.       beep();
  333.    direction=~direction;
  334.          motor_DR();
  335.       }//K3 end

  336. /********************************************************/
  337.         if(K4==0)   
  338.        {
  339.       beep();
  340.    if(rate_dr==1)
  341.     { rate++;
  342.       if(rate==0x10)
  343.             { rate_dr=~rate_dr;}
  344.     }
  345.     else  
  346.      {
  347.       rate--;
  348.       if(rate==0x01)
  349.    { rate_dr=~rate_dr; }
  350.      }
  351.   } //K4 end
  352.    
  353. /********************************************************/
  354.       if(number1==snum1)   //与设定圈数是否相等  
  355.      { number1=0;
  356.          on_off=0;
  357.          TR0=0;
  358. ……………………

  359. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
步进电机 默认100圈.zip (36.36 KB, 下载次数: 60)



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

使用道具 举报

沙发
ID:201936 发表于 2017-7-17 08:22 | 只看该作者
你好,有没有电路图?
回复

使用道具 举报

板凳
ID:231077 发表于 2020-1-16 10:10 | 只看该作者
学习了
回复

使用道具 举报

地板
ID:563570 发表于 2020-1-31 22:05 来自手机 | 只看该作者
有没有原理图
回复

使用道具 举报

5#
ID:701710 发表于 2020-3-29 23:35 | 只看该作者
我在CSDN也看过相同的代码。达到预设圈数不能正常停止
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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