找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4719|回复: 7
收起左侧

51单片机步进电机正反转调速1602显示 代码

[复制链接]
ID:200201 发表于 2017-5-13 10:35 | 显示全部楼层 |阅读模式
步进电机正反转调速 51单片机源程序

  1. //51单片机步进电机正反转调速1602显示 - C51源代码
  2. #include <reg51.h>       //51芯片管脚定义头文件
  3. #include <intrins.h>  //内部包含延时函数 _nop_();

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


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

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

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

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

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

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

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

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

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

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

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

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

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

  91. void lcd_wcmd(uchar cmd)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  364. /********************************************************/
  365. /*
  366. /*  定时器 0 中断
  367. /*
  368. /********************************************************/

  369. void  motor_onoff()  interrupt  1  
  370. {     
  371.        TL0  = 0x33;
  372.        TH0  = 0xf5;
  373.        q++;
  374.     if(q < rate)
  375.         { return; }
  376.     else
  377.        {  q=0;   
  378.        number++;                  //脉冲计数
  379.         
  380.       if(number==4096)              //64个脉冲电机转一圈
  381.        { snum--;
  382.       number=0;
  383.             number1++; }          //电机转动圈数
  384.    

  385.          if(direction==1)            //方向标志
  386.        { if(v<8)  
  387.          {P1 = FFW[v];v++;}       //取数据,正转
  388.         if(v==8)
  389.         { v=0; }
  390.           }
  391.    
  392.       else
  393.        { if(v<8)  
  394.          
  395. …………限于本文篇幅 余下代码请从51黑下载附件…………

复制代码

下载:
51单片机步进电机正反转调速1602显示.docx (23.08 KB, 下载次数: 119)
回复

使用道具 举报

ID:130231 发表于 2017-5-19 11:15 | 显示全部楼层
楼主!辛苦了,我刚好需要,又省了半天编写时间了。
回复

使用道具 举报

ID:79544 发表于 2017-6-13 11:31 | 显示全部楼层
显示不是很正常,楼主哪里的原因
回复

使用道具 举报

ID:188115 发表于 2017-7-12 13:05 | 显示全部楼层
楼主!辛苦了
回复

使用道具 举报

ID:217754 发表于 2017-7-14 23:17 | 显示全部楼层
辛苦了。。谢谢分享
回复

使用道具 举报

ID:63317 发表于 2017-7-15 10:04 | 显示全部楼层
楼主!辛苦了
回复

使用道具 举报

ID:150982 发表于 2018-5-24 07:12 | 显示全部楼层

楼主!辛苦了
回复

使用道具 举报

ID:812760 发表于 2020-12-2 22:34 来自手机 | 显示全部楼层
楼主,能把电机加进去吗,我看程序里没有电机
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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