找回密码
 立即注册

QQ登录

只需一步,快速开始

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

遥控步进电机1602液晶显示 原理图和源程序分享

[复制链接]
跳转到指定楼层
楼主
这个可以直接用在铣床和车床上。遥控步进电机lcd1602液晶显示

下载:
遥控步进电机1602显示.rar (133.63 KB, 下载次数: 51)


部分源码预览:

  1. /********************************************************************

  2. ***********************************************************************/

  3. #include <reg51.h>
  4. #include <intrins.h>
  5. #include "lcd1602.h"

  6. #define uchar unsigned char
  7. #define uint  unsigned int

  8. uchar LCD_ID_1[16] = {"Red Control"};
  9. uchar LCD_ID_2[16] = {"You press the:-"};

  10. void delay(uchar x);  //x*0.14MS
  11. void delay1(int ms);

  12. uchar distemp = 0;

  13. sbit IRIN = P3^3;         //红外接收器数据线

  14. uchar IRCOM[7];

  15. sbit E=P1^2;                //1602使能引脚
  16. sbit RW=P1^1;                //1602读写引脚       
  17. sbit RS=P1^0;                //1602数据/命令选择引脚




  18. unsigned char cMode = 0;
  19. unsigned char s1_num;
  20. unsigned int iSetData, iCurData;
  21. signed char RL;         // 方向
  22. signed char iSet[3];
  23. signed char iCur[3];
  24. unsigned char T0_NUM;
  25. unsigned char fx_flag;
  26. unsigned char fx_flag2 = 0;


  27. sbit MotorEn = P2^1;     // 使能
  28. sbit FX = P2^0;          // 方向
  29. sbit CLK = P2^2;         // 脉冲


  30. unsigned int gStep = 0;
  31. unsigned long gMainchong = 0;
  32. unsigned int gJd = 0;
  33. unsigned char dj_flag = 0;

  34. /********************************************************************
  35. * 名称 : Delay()
  36. * 功能 : 延时,延时时间大概为1毫秒
  37. * 输入 : 无
  38. * 输出 : 无
  39. ***********************************************************************/
  40. void Delay_1ms(uint i)
  41. {
  42.         uint x,j;
  43.         for(j=0;j<i;j++)
  44.         for(x=0;x<=148;x++);       
  45. }

  46. /********************************************************************
  47. * 名称 : delay()
  48. * 功能 : 延时,延时时间大概为140US。
  49. * 输入 : 无
  50. * 输出 : 无
  51. ***********************************************************************/

  52. void Delay2()
  53. {
  54.         int i,j;
  55.         for(i=0; i<=10; i++)
  56.         for(j=0; j<=2; j++)
  57.         ;
  58. }

  59. /********************************************************************
  60. * 名称 : enable(uchar del)
  61. * 功能 : 1602命令函数
  62. * 输入 : 输入的命令值
  63. * 输出 : 无
  64. ***********************************************************************/
  65. void enable(uchar del)
  66. {
  67. //        P0 = del;
  68. P2 = del;
  69.         RS = 0;
  70.         RW = 0;
  71.         E = 0;
  72.         Delay2();
  73.         E = 1;
  74.         Delay2();
  75. }

  76. /********************************************************************
  77. * 名称 : write(uchar del)
  78. * 功能 : 1602写数据函数
  79. * 输入 : 需要写入1602的数据
  80. * 输出 : 无
  81. ***********************************************************************/

  82. void write(uchar del)
  83. {
  84. //        P0 = del;
  85. P2 = del;
  86.         RS = 1;
  87.         RW = 0;
  88.         E = 0;
  89.         Delay2();
  90.         E = 1;
  91.         Delay2();
  92. }

  93. /********************************************************************
  94. * 名称 : L1602_init()
  95. * 功能 : 1602初始化,请参考1602的资料
  96. * 输入 : 无
  97. * 输出 : 无
  98. ***********************************************************************/
  99. void L1602_init(void)
  100. {
  101.         enable(0x38);
  102.         Delay_1ms(5);
  103.         enable(0x38);
  104.         Delay_1ms(5);
  105.         enable(0x38);
  106.         Delay_1ms(5);
  107.         enable(0x38);
  108.         enable(0x08);       
  109.         enable(0x0c);
  110.         enable(0x04);
  111.         enable(0x01);
  112. }

  113. /********************************************************************
  114. * 名称 : L1602_char(uchar hang,uchar lie,char sign)
  115. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
  116.                  L1602_char(1,5,'b')
  117. * 输入 : 行,列,需要输入1602的数据
  118. * 输出 : 无
  119. ***********************************************************************/
  120. void L1602_char(uchar hang,uchar lie,char sign)
  121. {
  122.         uchar a;
  123.         if(hang == 1) a = 0x80;
  124.         if(hang == 2) a = 0xc0;
  125.         a = a + lie - 1;
  126.         enable(a);
  127.         write(sign);
  128. }

  129. /********************************************************************
  130. * 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
  131. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
  132.                   L1602_string(1,5,"ab cd ef;")
  133. * 输入 : 行,列,需要输入1602的数据
  134. * 输出 : 无
  135. ***********************************************************************/
  136. void L1602_string(uchar hang,uchar lie,uchar *p)
  137. {
  138.         uchar a;
  139.         if(hang == 1) a = 0x80;
  140.         if(hang == 2) a = 0xc0;
  141.         a = a + lie - 1;
  142.         enable(a);
  143.         while(1)
  144.         {
  145.                 if(*p == '\0') break;
  146.                 write(*p);
  147.                 p++;
  148.         }
  149. }






  150. /**********************************************************/
  151. void delay(unsigned char x)    //x*0.14MS
  152. {
  153. unsigned char i;
  154.   while(x--)
  155. {
  156.   for (i = 0; i<13; i++) {}
  157. }
  158. }

  159. /**********************************************************/
  160. void delay1(int ms)
  161. {
  162. unsigned char y;
  163.   while(ms--)
  164. {
  165.   for(y = 0; y<250; y++)
  166.   {
  167.    _nop_();
  168.    _nop_();
  169.    _nop_();
  170.    _nop_();
  171.   }
  172. }
  173. }


  174. //
  175. void Ang2()          
  176. {
  177.         iCurData = gMainchong*0.9/8.0;
  178.         if(iCurData > 999)
  179.                 iCurData = 0;
  180.         write_sfm(2, 7, iCurData);
  181. }



  182. // 计算并显示42步进电机角度
  183. void Ang3()       
  184. {
  185.         float f_ja;
  186.         unsigned char ge;
  187.         f_ja = (float)(gMainchong*0.9/8.0);
  188.         ge = ((unsigned int)(f_ja*10.0)) % 10 ;
  189. //        if(f_ja > 5)
  190. //                iCurData += 1;
  191.         write_sfm(2, 7, iCurData);
  192. }






  193. // 42步进电机左转
  194. void left(unsigned int Speed,unsigned int road)
  195. {
  196.         //步进节拍A-D-C-B
  197.         FX = 1;
  198.         do{               
  199.                 CLK=CLK^0x01;               //   输出脉冲
  200.                 mDelay(road);                //这里的延时就可控制转速

  201.                 gMainchong++;       // 作为显示角度的脉冲数         
  202.                 Ang2();          // 计算并显示角度
  203. // 显示方向箭头
  204.                 switch(fx_flag)
  205.                 {
  206.                         case 0:
  207.                                 write_string(2, 13, "<");
  208.                                 break;
  209.                         case 1:
  210.                                 write_string(2, 14, "<");
  211.                                 break;
  212.                         case 2:
  213.                                 write_string(2, 15, "<");
  214.                                 break;
  215.                         case 3:
  216.                                 write_string(2, 13, "   ");
  217.                                 break;
  218.                         default:
  219.                                 break;
  220.                 }
  221.                 Speed--;
  222.         }       
  223.         while(Speed);
  224.         Ang3();          // 计算并显示角度
  225.     MotorEn = 0; // 步进电机停止
  226.         iCurData = 0;
  227.         TR0 = 0;        // 关闭定时器
  228.         write_string(2, 13, "<<<");
  229. }




  230. // 42步进电机
  231. void right(unsigned int Speed,unsigned int road) // 脉冲数    间隔时间
  232. {
  233.         //步进节拍:A-B-C-D
  234.         FX = 0;
  235.         do{               
  236.                 CLK=CLK^0x01;               //   输出脉冲
  237.                 mDelay(road);                //这里的延时就可控制转速

  238.                 gMainchong++;       // 作为显示角度的脉冲数
  239.                 Ang2();          // 计算并显示角度

  240.                         fx_flag2++;
  241.         if(fx_flag2 >= 50)
  242.         {
  243.                  fx_flag++;
  244.                 fx_flag2 = 0;
  245.                 if(fx_flag >= 5)
  246.                         fx_flag = 0;
  247.         }
  248.                

  249. // 显示方向箭头
  250.                 switch(fx_flag)
  251.                 {
  252.                         case 0:
  253.                                 write_string(2, 13, ">");
  254.                                 break;
  255.                         case 1:
  256.                                 write_string(2, 14, ">");
  257.                                 break;
  258.                         case 2:
  259.                                 write_string(2, 15, ">");
  260.                                 break;
  261.                         case 3:
  262.                                 write_string(2, 13, "   ");
  263.                                 break;
  264.                         default:
  265.                                 break;
  266.                 }
  267.                 Speed--;   // 脉冲数在减小
  268.         }       
  269.         while(Speed);
  270.         Ang3();          // 计算并显示角度
  271.         MotorEn = 0; // 步进电机停止
  272.         iCurData = 0;
  273.         TR0 = 0;        // 关闭定时器



  274.         write_string(2, 13, ">>>");
  275. }




  276. //  8细分
  277. void  RightStepAll()
  278. {
  279.         unsigned int ja = 0;

  280.         ja =  (unsigned int)((iSetData/0.9)*8.0);    // 脉冲
  281.         if(ja != 0)
  282.                 right(ja, 10);

  283. }



  284. void  LeftStepAll()
  285. {
  286.         unsigned int ja = 0;
  287.         ja =  (unsigned int)((iSetData/0.9)*8.0);    // 脉冲
  288.         if(ja != 0)
  289.         left(ja, 10);

  290. }











  291. void hw_disponse()
  292. {
  293.         if(IRCOM[2] == 0x0c)         // 功能键
  294.         {
  295.                 s1_num++;       
  296.                 cMode = 0;        // 功能模式
  297.                 if(s1_num ==1)          // 第1次被按下
  298.                 {
  299.                         write_com(0x80+7);          // 角度 百位
  300.                         write_com(0x0f);      // 光标闪烁
  301.                 }
  302.                 if(s1_num ==2)
  303.                 {
  304.                         write_com(0x80+8);
  305.                 }
  306.                 if(s1_num == 3)
  307.                 {
  308.                         write_com(0x80+9);
  309.                 }
  310.                 if(s1_num == 4)
  311.                 {
  312.                         write_com(0x80+13);
  313.                 }
  314.                 if(s1_num == 5)
  315.                 {
  316.                         s1_num = 0;            // 记录按键清零
  317.                         cMode = 0;             // 退出模式
  318.                         write_com(0x0c);           // 取消光标闪烁
  319.                 }
  320.         }
  321.         else if(IRCOM[2] == 0x18)        // +
  322.         {
  323.                 cMode = 0;
  324.                 if(s1_num == 1)                          // 百
  325.                 {
  326.                         iSet[0]++;
  327.                         if(iSet[0] >= 10)
  328.                                 iSet[0] = 0;
  329.                         iSetData = iSet[0]*100 + iSet[1]*10 + iSet[2];
  330.                         write_sfm(1, 7, iSetData);
  331.                     write_com(0x80+7);
  332.                 }
  333.                 if(s1_num == 2)
  334.                 {
  335.                         iSet[1]++;
  336.                         if(iSet[1] >= 10)
  337.                                 iSet[1] = 0;
  338.                         iSetData = iSet[0]*100 + iSet[1]*10 + iSet[2];
  339.                         write_sfm(1, 7, iSetData);
  340.                     write_com(0x80+8);
  341.                 }
  342.                 if(s1_num == 3)
  343.                 {
  344.                         iSet[2]++;
  345.                         if(iSet[2] >= 10)
  346.                                 iSet[2] = 0;
  347.                         iSetData = iSet[0]*100 + iSet[1]*10 + iSet[2];
  348.                         write_sfm(1, 7, iSetData);
  349.                     write_com(0x80+9);
  350.                 }
  351.                 if(s1_num == 4)          // 方向
  352.                 {
  353.                         RL++;
  354.                         if(RL > 1)
  355.                                 RL = 0;
  356.                         if(RL == 0)
  357.                                 write_string(1, 13, "R");
  358.                         else
  359.                                 write_string(1, 13, "L");
  360.                         write_com(0x80+13);
  361.                 }       
  362.         }
  363.         else if(IRCOM[2] == 0x5e)        //-
  364.         {
  365.                 cMode = 0;
  366.                 if(s1_num == 1)
  367.                 {
  368.                         iSet[0]--;
  369.                         if(iSet[0] < 0)
  370.                                 iSet[0] = 9;
  371.                         iSetData = iSet[0]*100 + iSet[1]*10 + iSet[2];
  372.                         write_sfm(1, 7, iSetData);
  373.                         write_com(0x80+7);
  374.                 }
  375.                 if(s1_num == 2)
  376.                 {
  377.                         iSet[1]--;
  378.                         if(iSet[1] < 0)
  379.                                 iSet[1] = 9;
  380.                         iSetData = iSet[0]*100 + iSet[1]*10 + iSet[2];
  381.                         write_sfm(1, 7, iSetData);
  382.                     write_com(0x80+8);
  383.                 }
  384.                 if(s1_num == 3)
  385.                 {
  386.                         iSet[2]--;
  387.                         if(iSet[2] < 0)
  388.                                 iSet[2] = 9;
  389.                         iSetData = iSet[0]*100 + iSet[1]*10 + iSet[2];
  390.                         write_sfm(1, 7, iSetData);
  391.                         write_com(0x80+9);
  392.                 }
  393.                 if(s1_num == 4)          // 方向
  394.                 {
  395.                         RL--;
  396.                         if(RL < 0)
  397.                                 RL = 1;
  398.                         if(RL == 0)
  399.                                 write_string(1, 13, "R");
  400.                         else
  401.                                 write_string(1, 13, "L");
  402.                         write_com(0x80+13);
  403.                 }       
  404.         }
  405.         else if(IRCOM[2] == 0x08)        // 运行
  406.         {
  407.                 cMode = 0;
  408.                 gMainchong = 0;
  409.                 iCurData = 0;
  410.         //        write_sfm(2, 7, iCurData);   // 当前角度已经复位
  411.         write_sfm(2, 7, 66);
  412.                 write_string(2, 13, "   ");
  413.         //        T0_Init();

  414.                 MotorEn = 1; // added 5-30

  415.         //        TR0 = 1;       // 启动
  416.                 if(RL == 0)    // 右转
  417.                         RightStepAll();
  418.                 if(RL == 1)
  419.                         LeftStepAll();               
  420.         }
  421.         else
  422.         {
  423.            ;
  424.         }  


  425. }  




  426. /*******************************************************************/
  427. main()
  428. {

  429.     IE = 0x84;                 //允许总中断中断,使能 INT1 外部中断
  430.     TCON = 0x10;               //触发方式为脉冲负边沿触发
  431.    
  432.     IRIN=1;                    //I/O口初始化
  433.        
  434.     delay1(10);                 //延时


  435.         MotorEn = 0;     // L297 使能(只有智能,才能正常工作,否则停止)
  436.         init_1602();                             //lcd1602初始化
  437.         write_string(1, 2, "set:");
  438.         write_sfm(1,7,iSetData);
  439.         write_string(2, 2, "cur:");
  440.         write_sfm(2,7,0);
  441.         mDelay(1);
  442.         write_string(1, 13, "R");       
  443.         write_string(2, 13, ">>>");
  444.         iSetData = 0;
  445.   
  446.     while(1);

  447. } //end main
  448. /**********************************************************/
  449. void IR_IN() interrupt 2 using 0
  450. {
  451.   unsigned char j,k,N=0;
  452.      EX1 = 0;   
  453.          delay(15);
  454.          if (IRIN==1)
  455.      { EX1 =1;
  456.            return;
  457.           }
  458.                            //确认IR信号出现
  459.   while (!IRIN)            //等IR变为高电平,跳过9ms的前导低电平信号。
  460.     {delay(1);}

  461. for (j=0;j<4;j++)         //收集四组数据
  462. {
  463.   for (k=0;k<8;k++)        //每组数据有8位
  464.   {
  465.    while (IRIN)            //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
  466.      {delay(1);}
  467.     while (!IRIN)          //等 IR 变为高电平
  468.      {delay(1);}
  469.      while (IRIN)           //计算IR高电平时长
  470.       {
  471.     delay(1);
  472.     N++;           
  473.     if (N>=30)
  474.          { EX1=1;
  475.          return;}                  //0.14ms计数过长自动离开。
  476.       }                        //高电平计数完毕               
  477.      IRCOM[j]=IRCOM[j] >> 1;                  //数据最高位补“0”
  478.      if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}  //数据最高位补“1”
  479.      N=0;
  480.   }//end for k
  481. }//end for j
  482.    
  483.    if (IRCOM[2]!=~IRCOM[3])
  484.    { EX1=1;
  485.      goto LOOP; }

  486.    switch(IRCOM[2])
  487.    {
  488.         case 0x16:
  489.                         distemp = 0;
  490.                         break;
  491.                 case 0x0c:
  492.                         distemp = 1;
  493.                         break;
  494.                 case 0x18:
  495.                         distemp = 2;
  496.                         break;
  497.                 case 0x5e:
  498.                         distemp = 3;
  499.                         break;
  500.                 case 0x08:
  501.                         distemp = 4;
  502.                         break;
  503.                 case 0x1c:
  504.                         distemp = 5;
  505.                         break;
  506.                 case 0x5a:
  507.                         distemp = 6;
  508.                         break;
  509.                 case 0x42:
  510.                         distemp = 7;
  511.                         break;
  512.                 case 0x52:
  513.                         distemp = 8;
  514.                         break;
  515.                 case 0x4a:
  516.                         distemp = 9;
  517.                         break;
  518.    }
  519.    

  520. hw_disponse();                  



  521.     EX1 = 1;
  522.         LOOP:;
  523. }
复制代码


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

使用道具 举报

沙发
ID:79544 发表于 2017-6-13 16:37 | 只看该作者
楼主:你是驱动什么型号步进电机。电机的引脚怎么定义的
回复

使用道具 举报

板凳
ID:228228 发表于 2017-8-18 10:28 | 只看该作者
下载学习下 非常感谢
回复

使用道具 举报

地板
ID:89286 发表于 2017-8-20 20:52 | 只看该作者
thanks for sharing
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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