找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机步进电机控制用12864液晶显示 带proteus仿真及源程序

[复制链接]
跳转到指定楼层
楼主
一个用51单片机控制步进电机的例子,很全面,带有proteus仿真及原理图和源程序:


仿真工程文件及所有完整程序等资料下载地址:
http://www.51hei.com/bbs/dpj-56304-1.html


单片机源程序:
  1. #include <AT89X51.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #define uc unsigned char
  5. #define ui unsigned int
  6. #define LCDPAGE 0xB8                                  //设置页指令。
  7. #define LCDLINE 0x40                                  //设置列指令。
  8. sbit E=        P3^5;
  9. sbit RW=P3^4;
  10. sbit RS=P3^2;
  11. sbit L=P3^1;                                                 //左半平面
  12. sbit R=P3^0;                                                 //右半平面
  13. sbit Busy=P2^7;//                                         //忙 判断位
  14. uc scan_key1,scan_key2;                        //按键功能选择,00 停止,01 正转 10 反转
  15. uc step1;step2;
  16. static  step_index;
  17. ui count1,count2;                                   //定时
  18. uc butter;                                                        //按键
  19. static  speed;                                                //速度参数
  20.   //;本文件为16×16点阵中文字库文件,字的横向8点构成一字节,左边点在字节的高                 
  21. //位,字符点阵四角按左上角→右上角→左下角→右下角取字
  22. //;如你想在以后继续用HZDotReader打开文件,追加汉字点阵数据,请不要修改或增删所有注释         
  23. uc code JIANG[]=
  24. {
  25. //;江   CBDAD                                                               
  26. 0x10,0x60,0x01,0xC6,0x30,0x00,0x04,0x04,
  27. 0x04,0xFC,0x04,0x04,0x04,0x04,0x00,0x00,
  28. 0x04,0x04,0x7E,0x01,0x20,0x20,0x20,0x20,
  29. 0x20,0x3F,0x20,0x20,0x20,0x20,0x20,0x00,
  30. };
  31. uc code XI[]=
  32. {
  33. //;西   CCEF7                                                
  34. 0x02,0xF2,0x12,0x12,0x12,0xFE,0x12,0x12,
  35. 0x12,0xFE,0x12,0x12,0x12,0xF2,0x02,0x00,
  36. 0x00,0x7F,0x28,0x24,0x22,0x21,0x20,0x20,
  37. 0x20,0x21,0x22,0x22,0x22,0x7F,0x00,0x00,
  38. };
  39. uc code LI[]=
  40. {
  41. //;理   CC0ED
  42. 0x44,0x44,0xFC,0x44,0x44,0x00,0xFE,0x92,
  43. 0x92,0xFE,0x92,0x92,0x92,0xFE,0x00,0x00,
  44. 0x10,0x10,0x0F,0x08,0x48,0x40,0x45,0x44,
  45. 0x44,0x7F,0x44,0x44,0x44,0x45,0x40,0x00,
  46. };
  47. uc GONG[]=
  48. {
  49. //;工   CB9A4
  50. 0x00,0x00,0x02,0x02,0x02,0x02,0x02,0xFE,
  51. 0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00,
  52. 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3F,
  53. 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,
  54. };
  55. uc code DA[]=
  56. {
  57. //;大   CB4F3
  58. 0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x7F,
  59. 0xA0,0x20,0x20,0x20,0x20,0x30,0x20,0x00,
  60. 0x00,0x40,0x40,0x20,0x10,0x0C,0x03,0x00,
  61. 0x01,0x06,0x08,0x10,0x20,0x60,0x20,0x00
  62. };
  63. uc XUE[]=
  64. {
  65. //;学   CD1A7
  66. 0x40,0x30,0x10,0x12,0x5C,0x54,0x50,0x51,
  67. 0x5E,0xD4,0x50,0x18,0x57,0x32,0x10,0x00,
  68. 0x00,0x02,0x02,0x02,0x02,0x02,0x42,0x82,
  69. 0x7F,0x02,0x02,0x02,0x02,0x02,0x02,0x00,
  70. };
  71. uc code ZI[]=                                                                //自动化
  72. {  
  73. 0x00,0x00,0x00,0xF8,0x48,0x48,0x4C,0x4B,
  74. 0x4A,0x48,0x48,0x48,0xF8,0x00,0x00,0x00,
  75. 0x00,0x00,0x00,0xFF,0x44,0x44,0x44,0x44,
  76. 0x44,0x44,0x44,0x44,0xFF,0x00,0x00,0x00,
  77. };
  78. uc code DONG[]=
  79. {
  80. 0x20,0x24,0x24,0xE4,0x24,0x24,0x24,0x20,
  81. 0x10,0x10,0xFF,0x10,0x10,0xF0,0x00,0x00,
  82. 0x08,0x1C,0x0B,0x08,0x0C,0x05,0x4E,0x24,
  83. 0x10,0x0C,0x03,0x20,0x40,0x3F,0x00,0x00,
  84. };
  85. uc code HUA[]=
  86. {        
  87. 0x80,0x40,0x20,0xF8,0x07,0x02,0x00,0x00,
  88. 0xFF,0xC0,0x60,0x30,0x1C,0x08,0x00,0x00,
  89. 0x00,0x00,0x00,0x7F,0x00,0x04,0x02,0x01,
  90. 0x3F,0x40,0x40,0x40,0x40,0x78,0x00,0x00,
  91. };
  92. uc code CHANG[]=                                                 //常
  93. {
  94. 0x20,0x18,0x08,0x09,0xEE,0xAA,0xA8,0xAF,
  95. 0xA8,0xA8,0xEC,0x0B,0x2A,0x18,0x08,0x00,
  96. 0x00,0x00,0x3E,0x02,0x02,0x02,0x02,0xFF,
  97. 0x02,0x02,0x12,0x22,0x1E,0x00,0x00,0x00,
  98. };
  99. uc code YUN[]=                                                           //运
  100. {
  101. 0x40,0x41,0xCE,0x04,0x00,0x20,0x22,0xA2,
  102. 0x62,0x22,0xA2,0x22,0x22,0x22,0x20,0x00,
  103. 0x40,0x20,0x1F,0x20,0x28,0x4C,0x4A,0x49,
  104. 0x48,0x4C,0x44,0x45,0x5E,0x4C,0x40,0x00,
  105. };
  106. uc code XING[]=                                                          //行
  107. {
  108. 0x10,0x08,0x84,0xC6,0x73,0x22,0x40,0x44,
  109. 0x44,0x44,0xC4,0x44,0x44,0x44,0x40,0x00,
  110. 0x02,0x01,0x00,0xFF,0x00,0x00,0x00,0x00,
  111. 0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,
  112. };
  113. uc code ZHENG[ ] =
  114. {
  115. /*正   CD5FD */
  116. 0x00,0x02,0x02,0xC2,0x02,0x02,0x02,0x02,
  117. 0xFE,0x82,0x82,0x82,0x82,0x82,0x02,0x00,
  118. 0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,
  119. 0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x00,
  120. };
  121. uc code ZHUAN[ ] =
  122. {
  123. /*转   CD7AA */
  124. 0xC8,0xA8,0x9C,0xEB,0x88,0x88,0x88,0x40,
  125. 0x48,0xF8,0x4F,0x48,0x48,0x48,0x40,0x00,
  126. 0x08,0x08,0x04,0xFF,0x04,0x04,0x00,0x02,
  127. 0x0B,0x12,0x22,0xD2,0x0E,0x02,0x00,0x00,
  128. };
  129. uc code FAN[ ] =
  130. {
  131.         /*反   CB7B4 */

  132. 0x00,0x00,0xFE,0x12,0x72,0x92,0x12,0x12,
  133. 0x12,0x11,0x91,0x71,0x01,0x00,0x00,0x00,
  134. 0x40,0x30,0x4F,0x40,0x20,0x21,0x12,0x0C,
  135. 0x0C,0x12,0x11,0x20,0x60,0x20,0x00,0x00,
  136. };
  137. uc code TING[] =
  138. {
  139.         /*停   CCDA3 */
  140. 0x80,0x40,0x20,0xF8,0x07,0x02,0x04,0x74,
  141. 0x54,0x55,0x56,0x54,0x74,0x04,0x04,0x00,
  142. 0x00,0x00,0x00,0xFF,0x00,0x03,0x01,0x05,
  143. 0x45,0x85,0x7D,0x05,0x05,0x05,0x03,0x00,
  144. };
  145. uc code ZHI[ ] =
  146. {
  147. /*止   CD6B9 */
  148. 0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,
  149. 0xFF,0x40,0x40,0x40,0x40,0x40,0x00,0x00,
  150. 0x40,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,
  151. 0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x00,
  152. };
  153. uc code JIA[]=                                                                 //加
  154. {  
  155. 0x00,0x08,0x08,0x08,0xFF,0x08,0x08,0xF8,
  156. 0x00,0xF8,0x08,0x08,0x08,0xF8,0x00,0x00,
  157. 0x40,0x20,0x18,0x07,0x00,0x20,0x40,0x3F,
  158. 0x00,0x7F,0x10,0x10,0x10,0x3F,0x00,0x00,
  159. };
  160. uc code SU[]=                                                                //速
  161. {  
  162. 0x40,0x42,0xCC,0x00,0x04,0xE4,0x24,0x24,
  163. 0xFF,0x24,0x24,0x24,0xE4,0x04,0x00,0x00,
  164. 0x40,0x20,0x1F,0x20,0x48,0x49,0x45,0x43,
  165. 0x7F,0x41,0x43,0x45,0x4D,0x40,0x40,0x00,
  166. };
  167. uc code JIAN[]=                                                           //减
  168. {
  169. 0x00,0x02,0xEC,0x00,0xF8,0x28,0x28,0x28,
  170. 0x28,0x28,0xFF,0x08,0x8A,0xEC,0x48,0x00,
  171. 0x02,0x5F,0x20,0x18,0x07,0x00,0x1F,0x49,
  172. 0x5F,0x20,0x13,0x0C,0x13,0x20,0x78,0x00,
  173. };                                                                                   //输出空白区域
  174. uc code BAI[]=
  175. {
  176. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  177. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  178. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  179. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  180. };
  181. uc code DI[]=                                                           //低
  182. {                                 
  183. 0x40,0x20,0xF0,0x0C,0x07,0x02,0xFC,0x44,
  184. 0x44,0x42,0xFE,0x43,0x43,0x42,0x40,0x00,
  185. 0x00,0x00,0x7F,0x00,0x00,0x00,0x7F,0x20,
  186. 0x10,0x28,0x43,0x0C,0x10,0x20,0x78,0x00,
  187. };
  188. //////////////////函数声明 **************////////
  189. //************************************************
  190. void iniLCD(void);                                                           
  191. void chkbusy(void);
  192. void wcode(uc cd) ;
  193. void wdata(uc dat);
  194. void disrow(uc page,uc col,uc *temp);
  195. void display( uc page,uc col,uc *temp);
  196. void ground(step);                                     //转步
  197. void run1();                                     //正转
  198. void run2();
  199. void stop();
  200. void delay(ui time);
  201. //************************************
  202. //**************LCD初始化 ***************
  203. //*********************************
  204. void iniLCD(void)                               //初始化
  205. { L=1;R=1;
  206.   wcode(0x38);
  207.   wcode(0x0f);                                        //开显示 设置
  208.   wcode(0xc0);                                          //设置显示启动为第一行
  209.   wcode(0x01);                                            //清屏
  210.   wcode(0x06);                                                 //画面不动,光标右移。
  211. }
  212. //******************LCD判断忙的子程序**********
  213. //**********************************************8
  214. void chkbusy(void)                                 //   测LCD忙状态
  215. {
  216.   E=1;                                                               //使能LCD
  217.   RS=0;                                                               //读写指令
  218.   RW=1;                                                                  //读
  219.   P2=0xff;                                                       //读操作前先进行一次空读操作 ,接下来才能读到数据
  220.   while(!Busy);                                                 //等待,不忙退出
  221. }
  222. //*****************************************
  223. //*****************写指令代码*****************
  224. //***********************************************
  225. void wcode(uc cd)                                        //写指令 代码
  226. {
  227.   chkbusy();                                                             //写等待
  228.   P2=0xff;                                                                          //使能LCD
  229.   RW=0;                                                                             //读禁止
  230.   RS=0;                                                                              //输出 设置
  231.   P2=cd;                                                                     //写数据代码
  232.   E=1;                                                                               //以下两句产生下降沿
  233.   E=0;                                                 //
  234. }
  235. //*******************把显示数据写到内存单元中 *****************
  236. void wdata(uc dat)                                           //写显示数据
  237. {
  238.   chkbusy();                                                                //写等待
  239.   P2=0xff;                                                                             //使能LCD
  240.   RW=0;                                                                                   //读禁止
  241.   RS=1;                                                                                  //输出 设置
  242.   P2=dat;                                                                        //写数据代码
  243.   E=1;                                                                                 //以下两句产生下降沿
  244.   E=0;                                                         //
  245. }
  246. //***********************************************
  247. //****************显示LCD程序********************
  248. //*****************可以更改程序中的64变为32就可以输出数字了**********
  249. //****************************************************************
  250. //*************还可以换成生成图片的形式,具体****************
  251. ///****************************************************
  252. void  disrow(uc page,uc col,uc *temp)
  253. {
  254.   uc i;
  255.   if(col<64)                                                // 左半平面
  256.   {
  257.     L=1;R=0;
  258.         wcode(LCDPAGE+page);                               // 写指令 页
  259.         wcode(LCDLINE+col);                                       //写指令行
  260.         if((col+16)<64)                                              //如果字在左半平面显示不了,转到右半平面去
  261.         {
  262.          for(i=0;i<16;i++)                                      //写字
  263.          wdata(*(temp+i));
  264.          }
  265.          else                                                              //右半平面
  266.          {
  267.            for(i=0;i<64-col;i++)                                 //减去左边数,从右半平面第一位开始显示
  268.          wdata(*(temp+i));                                         //写字 显示
  269.          L=0;R=1;                                                         //右半平面
  270.      wcode(LCDPAGE+page);                            // 写指令 页
  271.      wcode(LCDLINE);                                       //写指令行
  272.            for(i=64-col;i<16;i++)                                 //写字 右半平面
  273.          wdata(*(temp+i));
  274.      }
  275.    }
  276.    else
  277.    {  
  278.      L=0;R=1;
  279.      wcode(LCDPAGE+page);                          // 写指令 页
  280.      wcode(LCDLINE+col-64);                              //写指令行
  281.           for(i=0;i<16;i++)                                      //写字
  282.          wdata(*(temp+i));
  283.         }
  284. }
  285. //*********************供调用 ****子程序 *************
  286. //****************************************
  287. void  display( uc page,uc col,uc *temp)
  288. {
  289.         disrow( page, col, temp);                               //显示上半字
  290.                 disrow( page+1, col, temp+16);                     //显示下半字
  291. }
  292. //***********************主***控****程********序********************
  293. //******************************************************************
  294. //***************程序完成于2008年6月 1日,儿童节********************
  295. //***************程序员:韩福伟************************************
  296. //**********江西理工大学应用科学学院机电学部自动化******************
  297. //******************************************************************
  298. //*********
  299. void main(void)
  300. {  
  301.    P2=0xff;
  302.    iniLCD();                                      //初始化 LCD
  303.    display(0,0x00,&JIANG);                         //    江
  304.    display(0,0x10,&XI);                                   //    西
  305.    display(0,0x20,&LI);                                   //   理
  306.    display(0,0x30,&GONG);                         //   工
  307.    display(0,0x40,&DA);                                   //  大
  308.    display(0,0x50,&XUE);                            //        学
  309.    step2=0;
  310.    step1=0;
  311.    P1=0xff;
  312.    P0=0;
  313.    EX1=1;
  314.    EA=1;                                               //开中断
  315.    speed=2010;
  316.    while(1)
  317.   {  
  318.      if((scan_key1==1)&(scan_key2==0))             // 正转
  319.          {  
  320.             display(6,0x00,&ZHENG);                     //  LCD显示
  321.         display(6,0x10,&ZHUAN);
  322.             ground(step_index);
  323.             delay(speed);
  324.                step_index++;                                                   //大于7,从头再来
  325.             if(step_index>7)
  326.                    step_index=0;
  327.           }
  328.          if((scan_key1==0)&(scan_key2==1))                   //反转
  329.          {                                                                    
  330.            ground(step_index);
  331.            display(6,0x00,&FAN);                      //         LCD显示
  332.        display(6,0x10,&ZHUAN);
  333.            delay(speed);
  334.               step_index--;
  335.            if(step_index<0)                                                        //小于0,从头再来。
  336.                    step_index=7;
  337.           }
  338.          if(scan_key1==0&scan_key2==0)
  339.           {
  340.            display(6,0x00,&TING);                     //        停止
  341.        display(6,0x10,&ZHI);
  342.            display(6,0x20,&BAI);
  343.            display(6,0x30,&BAI);
  344.            P0=0xff;
  345.           }
  346.          if(step1==1&step2==0)
  347.           {
  348.             speed=speed-100;
  349.                 if(speed<200|speed==200)                                   //小于话,说明电机的速度不能再提高了。
  350.                 { speed=200;                                                           //speed参数自己设定,以下遇到也是一样的。我只是一个乱写的值
  351.                   display(6,0x20,&ZHENG);                                 //正常运行
  352.                   display(6,0x30,&CHANG);
  353.                   display(6,0x40,&YUN);
  354.                   display(6,0x50,&XING);
  355.                  }
  356.                  else                                                //加速
  357.                 {
  358.                  display(6,0x20,&JIA);
  359.                  display(6,0x30,&SU);
  360.                 }
  361.           }
  362.           if(step1==0&step2==1)
  363.           {
  364.             speed=speed+100;                               //这里面的参数,论实际情况更改
  365.                 if(speed>2500|speed==2500)                          //如果 小于了,就说明到饿低速,可以用停止按键停止。
  366.                  { speed=2500;                                                   //低速运行
  367.                   display(6,0x20,&DI);
  368.                   display(6,0x30,&SU);
  369.                   display(6,0x40,&YUN);
  370.                   display(6,0x50,&XING);
  371.                  }
  372.                   else
  373.                   {
  374.                   display(6,0x20,&JIAN);                    //减速
  375.                   display(6,0x30,&SU);
  376.                   }
  377.           }
  378. }
  379. }
  380. //***************************************************
  381. //*************************        延时子程序**************
  382. //**************************************************
  383. void delay(ui time)                                    ///延时程序
  384. { for (count1=0;count1<time;count1++ )                        //此处可以用中断进行准确定时。我只是瞎定了几个参数
  385.   for(count2=0;count2<3;count2++);
  386. }
  387. //*********************************************************
  388. //******************按键处理程序****************************
  389. //************************************************************
  390. void key(void) interrupt 2
  391. {
  392.   uc i;
  393.   for(i=0;i<200;i++);                                                   //延时防抖
  394.   if(P3_3==0)                                                        
  395.    {
  396.     butter=~P1;
  397.     switch(butter)
  398.          {case 0x01:    scan_key1=1;scan_key2=0; break;        //正常运行 ,用两个数字进行选择,是不错的办法
  399.            case 0x02:    scan_key1=0;scan_key2=0;break;        //停止
  400.           case 0x04:    scan_key1=0 ;scan_key2=1; break;      //加速
  401.           case 0x08:    step1=1;step2=0;break;               //减速
  402.           case 0x10:    step1=0;step2=1;break;              //正转
  403.           default :                     ;                             //其它值返回
  404.          }
  405.    }
  406.    P1=0XFF;
  407. }
  408. //**************************************************
  409. //**********************转步************************
  410. //**************************************************
  411. void ground(step_index)         //转步
  412. {
  413. switch(step_index)
  414.    {
  415.      case 0://0            // 这里就说明了同步电机是怎么转的。我本来是用了代码的,
  416.       P0_0 = 1;                   //但是后来考虑了一些初学者不懂同步电机到底怎么转的
  417.       P0_1 = 0;                   //我就换成这个了, 知道怎么转的人,就换成代码把,一样的
  418.       P0_2 = 0;
  419.       P0_3 = 0;
  420.       break;
  421.           case 1://0,1  
  422.       P0_0 = 1;
  423.       P0_1 = 1;
  424.       P0_2 = 0;
  425.       P0_3 = 0;
  426.       break;
  427.           case 2://1
  428.       P0_0 = 0;
  429.       P0_1 = 1;
  430.       P0_2 = 0;
  431.       P0_3 = 0;
  432.       break;
  433.           case 3://1,2
  434.       P0_0 = 0;
  435.       P0_1 = 1;
  436.       P0_2 = 1;
  437.       P0_3 = 0;
  438.       break;
  439.           case 4://2
  440.       P0_0 = 0;
  441.       P0_1 = 0;
  442.       P0_2 = 1;
  443.       P0_3 = 0;
  444.       break;
  445.           case 5://2,3
  446.       P0_0 = 0;
  447.       P0_1 = 0;
  448.       P0_2 = 1;
  449.       P0_3 = 1;
  450.       break;
  451.           case 6://3
  452.       P0_0 = 0;
  453.       P0_1 = 0;
  454.       P0_2 = 0;
  455.       P0_3 = 1;
  456.       break;
  457.           case 7://3,0
  458.       P0_0 = 0;
  459.       P0_1 = 0;
  460.       P0_2 = 0;
  461.       P0_3 = 1;
  462.   }        
  463. }
复制代码



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

使用道具 举报

沙发
ID:64913 发表于 2017-8-22 23:56 | 只看该作者
楼主真是牛人。。。。。。。。。。。。。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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