找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机带速度显示(12864液晶)步进电机程序

[复制链接]
跳转到指定楼层
楼主
ID:358930 发表于 2018-10-18 02:51 来自手机 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

  1. #include <reg51.h>
  2. #include  <intrins.h>
  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5. #define ulong  unsigned long

  6. /***************************功能定义***************************/
  7. #define LCD12864_W_COM                        0xF8        //写指令
  8. #define LCD12864_R_COM                        0xFC        //读指令
  9. #define LCD12864_W_DAT                        0xFA        //写数据
  10. #define LCD12864_R_DAT                        0xFE        //读数据
  11. #ifndef __LCD12864_H__
  12. #define __LCD12864_H__
  13. #define LCD12864_COM 0        //输入指令
  14. #define LCD12864_DAT 1        //输入数据
  15. #define LCD12864_CLEAR                        0x01        //清除显示
  16. #define LCD12864_CURSOR                        0x02        //位址归位,游标回原点
  17. #define LCD12864_CURSOR_RLF                0x04        //光标左移,整体显示不移动
  18. #define LCD12864_CURSOR_RRF                0x06        //光标右移,整体显示不移动
  19. #define LCD12864_CURSOR_RLN                0x05        //光标左移,整体显示移动
  20. #define LCD12864_CURSOR_RRN                0x07        //光标右移,整体显示移动
  21. #define LCD12864_DIS_OFF                0x08        //显示状态全关
  22. #define LCD12864_DIS_ON                        0x0E        //显示状态开
  23. #define LCD12864_DIS_CUR_ON                0x0E        //游标显示开
  24. #define LCD12864_DIS_CURS_ON        0x0F        //游标位置显示开
  25. #define LCD12864_CURSOR_RL                0x10        //游标左移
  26. #define LCD12864_CURSOR_RR                0x14        //游标右移
  27. #define LCD12864_CURDIS_RL                0x18        //整体显示左移,光标跟随
  28. #define LCD12864_CURDIS_RR                0x1C        //整体显示又移,光标跟随
  29. #define LCD12864_COM_BASIC                0x30        //基本指令集动作
  30. #define LCD12864_COM_PLOT_ON        0x36        //扩展指令集动作,绘图显示ON
  31. #define LCD12864_COM_PLOT_OFF        0x34        //扩展指令集动作,绘图显示OFF
  32. #define LCD12864_STAND_TO                0x31        //进入待命模式
  33. #define LCD12864_PLACE_ROLL                0x03        //允许输入卷动位址
  34. #define LCD12864_PLACE_IRAM                0x02        //允许输入IRAM位址
  35. #define LCD12864_REVERES_13                0x04        //选择一、三行同时作反白显示
  36. #define LCD12864_REVERES_24                0x05        //选择二、四行同时作反白显示
  37. #define LCD12864_REST_ON                0x08        //进入睡眠模式
  38. #define LCD12864_REST_OFF                0x0C        //脱离睡眠模式
  39. #define LCD12864_W_COM                        0xF8        //写指令
  40. #define LCD12864_R_COM                        0xFC        //读指令
  41. #define LCD12864_W_DAT                        0xFA        //写数据
  42. #define LCD12864_R_DAT                        0xFE        //读数据
  43. //======串口模式=======
  44. sbit LCD12864_CS = P2^7;   //片选信号输入
  45. sbit LCD12864_STD = P2^6;  //串行数据输入
  46. sbit LCD12864_SCLK = P2^5; //串行移位脉冲输入
  47. sbit LCD12864_PSB = P2^4;  //串并模式选择 0:串口,1:并口
  48. sbit LCDRST  = P2^3;
  49. unsigned char code tabe[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};//查表法//0-9数字


  50. uint r=1; //步进电机速度
  51. sbit clk=P1^0;  //步进电机速度PIN

  52. sbit cw=P1^1;  //步进电机方向PIN
  53. sbit en=P1^2;  //步进电机使能PIN

  54. sbit k1=P1^4;  //
  55. sbit k2=P1^5;  //
  56. sbit k3=P1^6;  //
  57. /*******************************延时函数**********************************************/
  58. void Delay1Ms(uint t)
  59. {
  60.          uchar i;
  61.          for (;t>0;t--)
  62.                 {
  63.                 for (i=0;i<138;i++)
  64.                         {
  65.                         _nop_();_nop_();_nop_();_nop_();_nop_();
  66.                         _nop_();_nop_();_nop_();_nop_();_nop_();
  67.                         }
  68.                 }        
  69. }
  70. void Delay1s(uchar t)
  71. {
  72.         for (;t>0;t--)
  73.                 {
  74.             Delay1Ms(250);
  75.                 Delay1Ms(250);
  76.                 Delay1Ms(250);
  77.                 Delay1Ms(250);
  78.             }        
  79. }
  80. void delayus()//us微秒延时
  81. {
  82. _nop_();
  83. _nop_();
  84. _nop_();
  85. _nop_();
  86. }
  87. void Delay1000us()                //@11.0592MHz
  88. {
  89. unsigned char i, j;

  90.         _nop_();
  91.         _nop_();
  92.         _nop_();
  93.         i = 11;
  94.         j = 190;
  95.         do
  96.         {
  97.                 while (--j);
  98.         } while (--i);
  99. }
  100. /*****************************向12864写入8位数据*************************************/
  101. void LCD12864_Wbyte(uchar byte)
  102. {
  103.         uchar i;

  104.         for(i=0;i<8;i++)
  105.                 {
  106.                 LCD12864_SCLK = 0;
  107.                 byte <<= 1;                         //左移待写入数据,使最高位移至CY
  108.                 LCD12864_STD = CY;        //写入一位数据
  109.                 LCD12864_SCLK = 1;
  110.                 LCD12864_SCLK = 0;   
  111.                 }
  112. }
  113. /***************************从12864读出8位数据***返回:sdat************************************/
  114. uchar LCD12864_Rbyte(void)
  115. {
  116.      uchar i,sdat,temp1,temp2;
  117.      temp1 = 0;
  118.      temp2 = 0;
  119. //==========12864的串行数据输出形式是D7-D6-D5-D4-0-0-0-0-D3-D2-D1-D0-0-0-0-0,故要度两个八位整合==============
  120.      for(i=0;i<8;i++)
  121.                 {
  122.                 temp1=temp1 << 1;
  123.                 LCD12864_SCLK = 0;
  124.                 LCD12864_SCLK = 1;            
  125.                 LCD12864_SCLK = 0;
  126.                 if( LCD12864_STD )        temp1|=0x01;        //tempe1:D7-D6-D5-D4-0-0-0-0
  127.                 }
  128.      for(i=0;i<8;i++)
  129.                 {
  130.                 temp2=temp2 << 1;
  131.                 LCD12864_SCLK = 0;
  132.                 LCD12864_SCLK = 1;            
  133.                 LCD12864_SCLK = 0;
  134.                 if( LCD12864_STD ) temp2|=0x01;   //tempe2:D3-D2-D1-D0-0-0-0-0
  135.                 }
  136.         sdat = ((temp1 & 0xf0)|(temp2 >> 4));  //取出D7\D6\D5\D4\D3\D2\D1\D0                    
  137.         return sdat;  //返回一个值(sdat)
  138. }
  139. /****************************读忙状态**************************************/
  140. void LCD12864_busy( void )
  141. {
  142.         do        LCD12864_Wbyte( LCD12864_R_COM );                //LCD12864_RW=11111,RW(1),RS(0),0
  143.         while( LCD12864_Rbyte() & 0x80 );         //读BF,直到BF == 0
  144. }
  145. /*************************dat_com=0写指令,dat_com=1写数据*****************************************/
  146. void LCD12864_W (bit dat_com,uchar byte)
  147. {
  148.         uchar temp;
  149.         if(dat_com == 0)         //为零,写入指令
  150.                 temp = LCD12864_W_COM;        //11111,RS(0),RW(0),0
  151.         else                            //否则,写入数据
  152.                 temp = LCD12864_W_DAT;        //11111,RS(1),RW(0),0
  153.         LCD12864_CS = 1;                //片选使能
  154.         LCD12864_busy();                //LCD忙检测
  155.         LCD12864_Wbyte(temp);        //写入模式选择,指令还是数据
  156.         LCD12864_Wbyte(byte&0xf0);        //写入字节
  157.         LCD12864_Wbyte((byte<<4)&0xf0);        //写入字节
  158.     LCD12864_CS = 0;                //片选关闭
  159. }
  160. /****************************LCD12864初始化**************************************/

  161. void LCD12864_Init(void)
  162. {
  163.         LCDRST=1;
  164.         LCD12864_PSB = 0;        //选择串口模式
  165.         LCD12864_W(LCD12864_COM,0x30);        //基本指令功能.
  166.         LCD12864_W(LCD12864_COM,0x03);        //允许输入卷动位址
  167.         LCD12864_W(LCD12864_COM,0x0c);                //脱离随眠状态,显示打开,关光标,反白关.
  168.         LCD12864_W(LCD12864_COM,0x01);                //清屏指令.
  169.         LCD12864_W(LCD12864_COM,0x06);        //AC自动加一,光标右移,整体显示不移动         
  170. }
  171. /**************************LCD12864字符位置自定义显示****************************************/
  172. void LCD12864_WPoss(uchar x,uchar y,uchar *buff)
  173. {
  174.         uchar addr,i=0;
  175.         switch (x)
  176.                 {
  177.                 case 0:addr=0x80;break;
  178.                 case 1:addr=0x90;break;
  179.                 case 2:addr=0x88;break;
  180.                 case 3:addr=0x98;break;
  181.                 }
  182.         addr=addr+y;

  183.         LCD12864_W(LCD12864_COM,LCD12864_COM_BASIC);        //8BitMCU,基本指令集合
  184.         LCD12864_W(LCD12864_COM,addr);                                        //显示在自定义位置

  185.         while(buff[i]!='\0')
  186.                 {        
  187.                 LCD12864_W(LCD12864_DAT,buff[i++]);
  188.                 if(++y==16)
  189.                         {
  190.                         y=0;
  191.                         if(++x==4) x=0;

  192.                         switch (x)
  193.                                 {
  194.                                 case 0:addr=0x80;break;
  195.                                 case 1:addr=0x90;break;
  196.                                 case 2:addr=0x88;break;
  197.                                 case 3:addr=0x98;break;
  198.                                 }
  199.                         addr=addr+y;
  200.                         LCD12864_W(LCD12864_COM,addr);
  201.                         }
  202.         
  203.                 }
  204. }
  205. /************************显示1 *********************************/
  206.                                                            
  207. void display1(long temp)
  208. {
  209.     uchar dt1,dt2,dt3,dt4,dt5,dt6,dt7,dt8;
  210.         //temp=12345678;
  211.         temp=r;
  212.               
  213.         dt1 = temp%10;//1位
  214.         dt2 = temp%100/10;//2位
  215.         dt3 = temp%1000/100;//3位
  216.         dt4 = temp%10000/1000;//4位

  217.         dt5 = temp%100000/10000;//5位
  218.         dt6 = temp%1000000/100000;//6位
  219.         dt7 = temp%10000000/1000000;//7位
  220.         dt8 = temp/10000000;//8位             最高位  
  221.         LCD12864_WPoss(0,2,"步进电机");//第1行显示表1
  222.         LCD12864_WPoss(2,0,"速度:");//第1行显示表1
  223.     // LCD12864_W(0,0x80+3);//LCD12864_W ((0或1),****)  0写指令  1写数据

  224.      //LCD12864_W(1,tabe[dt8]);//6位
  225.      //LCD12864_W(1,tabe[dt7]);//5位
  226.      //LCD12864_W(1,tabe[dt6]);//4位
  227.      //LCD12864_W(1,tabe[dt5]);//3位
  228.          LCD12864_W(1,tabe[dt4]);//4位
  229.      LCD12864_W(1,tabe[dt3]);//3位
  230.          //LCD12864_W(1,0x2e);
  231.          LCD12864_W(1,tabe[dt2]);//4位
  232.      LCD12864_W(1,tabe[dt1]);//3位
  233.     // LCD12864_WPoss(2,6,"M");//第1行显示表1
  234.    
  235. }

  236. void Disp_img(unsigned char  *img)        //图形方式12864显示字模221 横向取膜
  237. {
  238.         unsigned char i,j;
  239.         unsigned int k = 0;

  240.         LCD12864_W(0,0x36); //图形方式
  241.         for(i=0;i<32;i++)
  242.           {
  243.                 LCD12864_W(0,0x80+i);
  244.                 LCD12864_W(0,0x80);
  245.             for(j=0;j<16;j++)
  246.                 {
  247.                         LCD12864_W(1,img[k++]);
  248.                 }
  249.           }

  250.          for(i=0;i<32;i++)
  251.           {
  252.                 LCD12864_W(0,0x80+i);
  253.                 LCD12864_W(0,0x88);
  254.             for(j=0;j<16;j++)
  255.                 {
  256.                         LCD12864_W(1,img[k++]);
  257.                   }
  258.         }
  259. }
  260. void run()//步进电机运行脉冲
  261. {
  262.    uint i;

  263.    for(i=0;i<r;i++)
  264.           {
  265.           clk=0;
  266.           Delay1000us();
  267.           clk=1;
  268.           Delay1000us();
  269.          }
  270. }

  271. void keyscan() //按键扫描
  272. {
  273.    if(k1==0)               
  274.   {
  275.     delayus();               
  276.     if(k1==0)               
  277.      {
  278.       r++;if(r>1000)r=1000;
  279.           cw=0; //
  280.           en=0; //

  281.      }
  282.          }
  283.   
  284.     if(k2==0)               
  285.   {
  286.     delayus();            
  287.     if(k2==0)               
  288.      {
  289.       r--;if(r<1)r=1;
  290.           cw=1; //
  291.           en=0; //
  292.      }
  293.         }

  294.     if(k3==0)               
  295.   {
  296.     delayus();               
  297.     if(k3==0)               
  298.      {
  299.       en=1;
  300.      }

  301. }

  302.   
  303. }

  304. /*****************************main**********************************************/
  305. void main()
  306. {            
  307.         LCD12864_Init();
  308.         en=1;                                                                                                         
  309.     while(1)
  310. {               

  311.                   
  312.                   keyscan() ;
  313.                   run();//步进电机运行脉冲
  314.          
  315.                   display1();//显示//温度显示
  316.                  
  317.                                                       
  318.                  }                                                                                                                       
  319. }
复制代码

评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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