找回密码
 立即注册

QQ登录

只需一步,快速开始

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

步进电机正反转调速LCD显示实验程序

[复制链接]
跳转到指定楼层
楼主
ID:71259 发表于 2014-12-30 01:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include <reg52.h>       //51芯片管脚定义头文件
  2. #include <intrins.h>  //内部包含延时函数 _nop_();

  3. #define uchar unsigned char
  4. #define uint  unsigned int

  5. uchar code FFW[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9};   //正转相序
  6. uchar code REV[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1};   //反转相序

  7. sbit  K1   = P3^2;       //运行与停止
  8. sbit  K2   = P3^3;       //速率调整
  9. sbit  K3   = P3^4;       //方向转换
  10.   
  11. sbit  BEEP = P3^6;       //蜂鸣器

  12. sbit  RS = P2^0;     //液晶管脚定义      
  13. sbit  RW = P2^1;
  14. sbit  E = P2^2;
  15. sbit  BF=P0^7;    //忙碌标志位

  16. bit  on_off=0;            //运行与停止标志
  17. bit  direction=1;         //方向标志


  18. uchar   rate=2;               //预设定速率
  19. uchar   data_temp;  

  20. uchar u=0,v=0;



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

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

  41. /********************************************************/
  42. void delayB(uchar x)    //x*0.14MS
  43. {
  44.    uchar i;
  45.    while(x--)
  46.    {
  47.      for (i=0; i<13; i++)
  48.      { }
  49.    }
  50. }

  51. /********************************************************/
  52. void beep()
  53. {
  54.    uchar j;
  55.    for (j=0;j<100;j++)
  56.     {
  57.      delayB(4);
  58.      BEEP=!BEEP;                 //BEEP取反
  59.     }
  60.      BEEP=1;                    //关闭蜂鸣器
  61.   delay(170);
  62. }

  63. /********************************************************/
  64. /*                                                               
  65. /*检查LCD忙状态                                                  
  66. /*BF为1时,忙,等待。为0时,闲,可写指令与数据。   
  67. /*                                                              
  68. /********************************************************/

  69. bit BusyTest()
  70. {                        
  71.     bit result;
  72.     RS = 0;
  73.     RW = 1;
  74.     E= 1;
  75.   _nop_();
  76.   _nop_();
  77.     result = BF;
  78.     E = 0;
  79.     return(result);
  80. }

  81. /*****************************************************
  82. 函数功能:将模式设置指令或显示地址写入液晶模块
  83. 入口参数:dictate
  84. ***************************************************/
  85. void WriteInstruction (unsigned char dictate)
  86. {  
  87.     while(BusyTest()==1); //如果忙就等待
  88.   RS=0;                  //根据规定,RS和R/W同时为低电平时,可以写入指令
  89.   RW=0;  
  90.   E=0;                   //E置低电平(写指令时,
  91.                              // 就是让E从0到1发生正跳变,所以应先置"0"
  92.   _nop_();
  93.   _nop_();             //空操作两个机器周期,给硬件反应时间
  94.   P0=dictate;            //将数据送入P0口,即写入指令或地址
  95.   _nop_();
  96.   _nop_();
  97.   _nop_();
  98.   _nop_();               //空操作四个机器周期,给硬件反应时间
  99.   E=1;                   //E置高电平
  100.   _nop_();
  101.   _nop_();
  102.   _nop_();
  103.   _nop_();               //空操作四个机器周期,给硬件反应时间
  104.    E=0;                  //当E由高电平跳变成低电平时,液晶模块开始执行命令
  105. }

  106. /*****************************************************
  107. 函数功能:指定字符显示的实际地址
  108. 入口参数:x
  109. ***************************************************/
  110. void WriteAddress(unsigned char x)
  111. {
  112.      WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x"
  113. }

  114. /*****************************************************
  115. 函数功能:将数据(字符的标准ASCII码)写入液晶模块
  116. 入口参数:y(为字符常量)
  117. ***************************************************/
  118. void WriteData(unsigned char y)
  119. {
  120.     while(BusyTest()==1);
  121.    RS=1;           //RS为高电平,RW为低电平时,可以写入数据
  122.    RW=0;
  123.    E=0;            //E置低电平(写指令时,,
  124.                        // 就是让E从0到1发生正跳变,所以应先置"0"
  125.    P0=y;           //将数据送入P0口,即将数据写入液晶模块
  126.    _nop_();
  127.    _nop_();
  128.     _nop_();
  129.     _nop_();       //空操作四个机器周期,给硬件反应时间
  130.    E=1;          //E置高电平
  131.    _nop_();
  132.    _nop_();
  133.    _nop_();
  134.    _nop_();        //空操作四个机器周期,给硬件反应时间
  135.    E=0;            //当E由高电平跳变成低电平时,液晶模块开始执行命令
  136. }

  137. /*****************************************************
  138. 函数功能:对LCD的显示模式进行初始化设置
  139. ***************************************************/
  140. void LcdInt(void)
  141. {
  142.     delay(15);             //延时15ms,首次写指令时应给LCD一段较长的反应时间
  143.     WriteInstruction (0x38);  //显示模式设置:16×2显示,5×7点阵,8位数据接口
  144. delay(5);   //延时5ms 
  145. WriteInstruction (0x38);
  146. delay(5);
  147. WriteInstruction (0x38); //3次写 设置模式
  148. delay(5);
  149. WriteInstruction (0x0c);  //显示模式设置:显示开,无
  150. delay(5);
  151. WriteInstruction (0x06);  //显示模式设置:光标右移,字符不移
  152. delay(5);            
  153. WriteInstruction (0x01);  //清屏幕指令,将以前的显示内容清除
  154. delay(5);
  155. }
  156. /********************************************************/
  157. /*                                                      
  158. /* LCD1602初始显示子程序                                            
  159. /*                                                     
  160. /********************************************************/
  161. void LcdInt_Dis()
  162. {
  163. uchar i=0;
  164. LcdInt();
  165. delay(15);
  166. WriteInstruction(0x01);
  167. delay(5);
  168. WriteAddress(0x00);
  169. delay(5);
  170. while(cdis1[i]!='\0'){
  171.   WriteData(cdis1[i]);
  172.   delay(5);
  173.   i++;
  174. }
  175. WriteAddress(0x40);
  176. delay(5);
  177. i=0;
  178.     while(cdis2[i]!='\0'){
  179.   WriteData(cdis2[i]);
  180.   delay(5);
  181.   i++;
  182. }

  183. delay(3000);
  184. WriteInstruction(0x01);   //清屏
  185. delay(5);
  186. i=0;
  187. WriteAddress(0x00);
  188. delay(5);
  189. while(cdis3[i]!='\0'){
  190.   WriteData(cdis3[i]);
  191.   delay(5);
  192.   i++;
  193. }
  194. WriteAddress(0x40);
  195. delay(5);
  196. i=0;
  197.     while(cdis4[i]!='\0'){
  198.   WriteData(cdis4[i]);
  199.   delay(5);
  200.   i++;
  201. }
  202. WriteAddress(0x0c);
  203. delay(5);
  204. for(i=0;i<2;i++)    //显示方向符号
  205.        WriteData(0x3e);

  206. }



  207. /********************************************************/
  208. /*
  209. /*数据显示子程序
  210. /*
  211. /********************************************************/
  212. void  data_dis()
  213. {   
  214.     data_temp = rate;         //显示速率

  215.     WriteAddress(0x4c);
  216.     WriteData(data_temp+0x30);
  217.     delay(5);

  218. }

  219. /********************************************************
  220. /*
  221. /* 显示运行方向符号
  222. /*
  223. /********************************************************/
  224. void  dr_dis()
  225. {
  226.    uchar i=0;
  227. WriteAddress(0x0c);      //显示方向符号
  228.     if(direction==1)           //正转方向标
  229. {
  230.   
  231.   for(i=0;i<2;i++){
  232.             WriteData(0x3e);
  233.    delay(5);
  234.   }
  235.    
  236.     }
  237.     else
  238.     {
  239.   for(i=0;i<2;i++){      //反转方向标志   
  240.            WriteData(0x3c);
  241.      delay(5);
  242.   }
  243.    
  244.     }
  245. }

  246. /********************************************************
  247. /*
  248. /* 显示运行状态
  249. /*
  250. /********************************************************/
  251. void run_dis()
  252. {
  253. uchar i=0;
  254. if(on_off==1){
  255.   WriteAddress(0x00);
  256.   delay(5);
  257.   for(i=0;cdis5[i]!='\0';i++){
  258.    WriteData(cdis5[i]);
  259.    delay(5);
  260.   }
  261. }
  262. else{
  263.     WriteAddress(0x00);
  264.   delay(5);
  265.   for(i=0;cdis3[i]!='\0';i++){
  266.    WriteData(cdis3[i]);
  267.    delay(5);
  268.   }
  269. }
  270. }

  271. /********************************************************/
  272. /*
  273. /*步进电机正转
  274. /*
  275. /********************************************************/
  276. void  motor_ffw()
  277. {
  278.    unsigned char i;
  279.    unsigned char  j;

  280.    for (j=0; j<8; j++)        
  281.     {              
  282.       for (i=0; i<8; i++)       //一个周期转45度
  283.         {
  284.           P1 = FFW[i];          //取数据
  285.           delay(rate);            //调节转速
  286.         }
  287.     }

  288. }

  289. /********************************************************/
  290. /*
  291. /*步进电机反转
  292. /*
  293. /********************************************************/
  294. void  motor_rev()
  295. {
  296.      unsigned char i=0;
  297.   unsigned int  j=0;
  298.   for (j=0; j<8; j++)     
  299.       {

  300.         for (i=0; i<8; i++)     //一个周期转45度
  301.         {
  302.           P1 = REV[i];          //取数据
  303.           delay(rate);            //调节转速
  304.         }
  305.       }
  306. }  






  307. /********************************************************
  308. *                                                      
  309. *  主程序                                             
  310. *                                                     
  311. *********************************************************/

  312. void main()
  313. {
  314. LcdInt_Dis();  //液晶初始化
  315. TMOD=0X01;   //定时器T0工作方式1
  316. EA=1;      //开总中断
  317. ET0=1;     //开T0中断
  318. TH0=(65536-1000)/256;
  319. TL0=(65536-1000)%256; //定时1ms;
  320. TR0=1;     //启动T0
  321. P1=0X0F;    //关闭电机
  322. while(1){
  323. /**************************************/
  324.   if(K1==0){
  325.    delay(15);   //延时消陡
  326.    if(K1==0){
  327.     on_off=~on_off;   //取反
  328.     beep();
  329.     while(K1==0);  //等待按键释放
  330.       }
  331.    
  332.      }
  333.    
  334. /**************************************/
  335.   if(K2==0){
  336.    delay(15);
  337.    if(K2==0){
  338.     rate++;
  339.     if(rate==0x0a)    //若rate=10,则回到2重新开始
  340.      rate=2;
  341.     beep();
  342.     while(K2==0);
  343.    }
  344.   }

  345. /**************************************/  
  346.   if(K3==0){
  347.    delay(15);
  348.    if(K3==0){
  349.     direction=~direction;
  350.     beep();
  351.     while(K3==0);
  352.    }
  353.   }

  354. /**************************************/
  355.      data_dis();
  356.         run_dis();
  357.   dr_dis();  
  358. };

  359. }



  360. /***************************************
  361. 定时器0中断
  362. ***************************************/
  363. void t0()   interrupt 1
  364. {
  365.     TH0=(65536-1000)/256;
  366. TL0=(65536-1000)%256;
  367. v++;
  368. if(v<rate)    //每个脉冲间隔v*1ms
  369.   return;
  370. else{
  371.   v=0;
  372.   if(on_off==1){
  373.    if(u==8)
  374.     u=0;
  375.    if(direction==1) //正转脉冲
  376.        P1=FFW[u];
  377.    else
  378.     P1=REV[u];   //反转脉冲
  379.    u++;
  380.    }
  381. }
  382. }

复制代码


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

使用道具 举报

沙发
ID:74225 发表于 2015-3-11 20:04 | 只看该作者
请问大神这段程序void delayB(uchar x)    //x*0.14MS{uchar i;   while(x--){for (i=0; i<13; i++)有什么作用呢,   还有那个TL0=0X33,TH0=0xf5和你的程序里的TH0=(65536-1000)/256;
TL0=(65536-1000)%256是一样的吗
回复

使用道具 举报

板凳
ID:246189 发表于 2017-12-5 15:28 | 只看该作者
有proteus电路图吗?
回复

使用道具 举报

地板
ID:246189 发表于 2017-12-5 15:33 | 只看该作者
楼主有proteus电路图吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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