单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机+编码器+42步进电机的源程序

  [复制链接]
跳转到指定楼层
楼主
mxk569364343 发表于 2018-5-15 10:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前几天帮别做一个51的小东西需要编码器,结果发现网上编码器的程序比较不好找,自己根据别人一个巧妙的思路写了一个读编码器读数的程序,用LCD1602显示出来。里边还有使用L298N驱动42步进电机部分,可以参考一下。

单片机源程序如下:
  1. #include <reg52.h>

  2. typedef unsigned char uchar;
  3. typedef unsigned int uint;

  4. //LCD1602定义
  5. #define LCD1602_DB P0        //LCD1602数据总线

  6. sbit LCD1602_RS = P2^7;         //RS端
  7. sbit LCD1602_RW = P2^6;         //RW端
  8. sbit LCD1602_EN = P2^5;         //EN端

  9. uchar code digit[ ]={"0123456789"}; //定义字符数组显示数字
  10. uchar idata TEST[]="TEST";

  11. //电机正反转二维数组 0为逆时针,1为顺时针
  12. uchar code MotorCode[2][8]={{0x04,0x06,0x02,0x0a,0x08,0x09,0x01,0x05},{0x05,0x01,0x09,0x08,0x0a,0x02,0x06,0x04}};

  13. uchar MotorStatus;//电机正反转标志位

  14. sbit EncoderA=P3^2;    //编码器A相
  15. sbit EncoderB=P3^4;                 //编码器B相

  16. uint EncoderCount=0 ;
  17. /* 毫秒软件延时函数*/
  18. void delay_ms(uint x)
  19. {
  20.         uint a,b;
  21.         for(a=x;a>0;a--)
  22.                 for(b=114;b>0;b--);
  23. }

  24. /*=================================================
  25. *函数名称:Read_Busy
  26. *函数功能:判断1602液晶忙,并等待
  27. =================================================*/
  28. void Read_Busy()
  29. {
  30.         uchar busy;
  31.         LCD1602_DB = 0xff;//复位数据总线
  32.         LCD1602_RS = 0;          //拉低RS
  33.         LCD1602_RW = 1;          //拉高RW读
  34.         do
  35.         {
  36.                 LCD1602_EN = 1;//使能EN
  37.                 busy = LCD1602_DB;//读回数据
  38.                 LCD1602_EN = 0;         //拉低使能以便于下一次产生上升沿
  39.         }while(busy & 0x80); //判断状态字BIT7位是否为1,为1则表示忙,程序等待
  40. }
  41. /*=================================================
  42. *函数名称:LCD1602_Write_Cmd
  43. *函数功能:写LCD1602命令
  44. *调用:Read_Busy();
  45. *输入:cmd:要写的命令
  46. =================================================*/
  47. void LCD1602_Write_Cmd(uchar cmd)
  48. {
  49.         Read_Busy();         //判断忙,忙则等待
  50.         LCD1602_RS = 0;
  51.         LCD1602_RW = 0;        //拉低RS、RW操作时序情况1602课件下中文使用说明基本操作时序章节
  52.         LCD1602_DB = cmd;//写入命令
  53.         LCD1602_EN = 1;         //拉高使能端 数据被传输到LCD1602内
  54.         LCD1602_EN = 0;         //拉低使能以便于下一次产生上升沿
  55. }
  56. /*=================================================
  57. *函数名称:LCD1602_Write_Dat
  58. *函数功能:写LCD1602数据
  59. *调用:Read_Busy();
  60. *输入:dat:需要写入的数据
  61. =================================================*/
  62. void LCD1602_Write_Dat(uchar dat)
  63. {
  64.         Read_Busy();
  65.         LCD1602_RS = 1;
  66.         LCD1602_RW = 0;
  67.         LCD1602_DB = dat;
  68.         LCD1602_EN = 1;
  69.         LCD1602_EN = 0;
  70. }
  71. /*=================================================
  72. *函数名称:LCD1602_Clear
  73. *函数功能:LCD1602清屏
  74. =================================================*/
  75. void LCD1602_Clear()
  76. {
  77.         Read_Busy();
  78.         LCD1602_Write_Cmd(0x01); //清屏
  79. }


  80. /*=================================================
  81. *函数名称:LCD1602_Dis_OneChar
  82. *函数功能:在指定位置显示一个字符
  83. *调用:LCD1602_Write_Cmd(); LCD1602_Write_Dat();       
  84. *输入:x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行)
  85.                 dat:需要显示的数据以ASCLL形式显示
  86. =================================================*/
  87. void LCD1602_Dis_OneChar(uchar x, uchar y,uchar dat)
  88. {
  89.         if(y)        x |= 0x40;
  90.         x |= 0x80;
  91.         LCD1602_Write_Cmd(x);
  92.         LCD1602_Write_Dat(dat);               
  93. }
  94. /*=================================================
  95. *函数名称:LCD1602_Dis_Str
  96. *函数功能:在指定位置显示字符串
  97. *调用:LCD1602_Write_Cmd(); LCD1602_Write_Dat();
  98. *输入:x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行)
  99.                 *str:需要显示的字符串
  100. =================================================*/
  101. void LCD1602_Dis_Str(uchar x, uchar y, uchar *str)
  102. {
  103.         if(y) x |= 0x40;
  104.         x |= 0x80;
  105.         LCD1602_Write_Cmd(x);
  106.         while(*str != '\0')
  107.         {
  108.                 LCD1602_Write_Dat(*str++);
  109.         }
  110. }
  111. /*=================================================
  112. *函数名称:Init_LCD1602
  113. *函数功能:1602初始化
  114. *调用:        LCD1602_Write_Cmd();
  115. =================================================*/
  116. void Init_LCD1602()
  117. {
  118.         LCD1602_Write_Cmd(0x38); //        设置16*2显示,5*7点阵,8位数据接口
  119.         LCD1602_Write_Cmd(0x0c); //打开显示屏,不显示光标,光标所在位置的字符不闪烁。
  120.         LCD1602_Write_Cmd(0x06); //读写一字节后地址指针加1
  121.         LCD1602_Write_Cmd(0x01); //清除显示
  122. }

  123. void Motor_Forward() //电机正转
  124. {
  125.         TMOD=0x01;
  126.         TH0=(65535-2000)/256;
  127.         TL0=(65535-2000)%256;
  128.         EA=1;
  129.         ET0=1;
  130.         TR0=1;
  131.         MotorStatus=0;
  132. }
  133. void Motor_Reversal() //电机反转
  134. {
  135.         TMOD=0x01;
  136.         TH0=(65535-2000)/256;
  137.         TL0=(65535-2000)%256;
  138.         EA=1;
  139.         ET0=1;
  140.         TR0=1;
  141.         MotorStatus=1;
  142. }

  143. void Motor_Stop()  //停止电机
  144. {
  145.         ET0=0;
  146.         TR0=0;
  147.         P1=P1&0xF0;
  148. }


  149. uchar index = 0;  //定义节拍输出索引
  150. void time0() interrupt 1
  151. {
  152.         uchar tmp;  //定义一个临时变量

  153.         TH0=(65535-1000)/256;
  154.         TL0=(65535-1000)%256;
  155.        
  156.         tmp = P1; //用 tmp 把 P1 口当前值暂存
  157.   tmp = tmp & 0xF0; //用&操作清零低4位
  158.         //用|操作把节拍代码写到低4位
  159.   tmp = tmp | MotorCode[MotorStatus][index];
  160.         //把低4位的节拍代码和高4位的原值送回 P1
  161.   P1 = tmp;
  162.   index++;  //节拍输出索引递增
  163.   index = index & 0x07;  //用&操作实现到8归零
  164.        
  165. }

  166. Init_Encoder ()
  167. {
  168.         EA = 1;        //开总中断
  169.         EX0 = 1;//开外部中断1
  170.         IT0 = 1;//外部中断1下降沿触发
  171. }



  172. void main()
  173. {
  174.         Init_Encoder ();
  175.         Init_LCD1602();
  176.         Motor_Reversal();  
  177.         LCD1602_Dis_Str(0, 0, &TEST[0]);                                                                                //提示第一行MENU1       
  178.     while (1)
  179.                 {
  180.                         LCD1602_Dis_OneChar(0,1,digit[EncoderCount/10000]);
  181.                         LCD1602_Dis_OneChar(1,1,digit[EncoderCount%10000/1000]);
  182.                         LCD1602_Dis_OneChar(2,1,digit[EncoderCount%1000/100]);
  183.                         LCD1602_Dis_OneChar(3,1,digit[EncoderCount%100/10]);
  184.                         LCD1602_Dis_OneChar(4,1,digit[EncoderCount%10/1]);
  185.                         delay_ms(100);
  186. //      delay_ms(500);  //延时 2 ms,即 2 ms 执行一拍
  187. //                        Motor_Reversal(); //电机反转
  188. //                        delay_ms(500);  //延时 2 ms,即 2 ms 执行一拍
  189. //                        Motor_Stop();
  190. //                        delay_ms(500);  //延时 2 ms,即 2 ms 执行一拍
  191.     }
  192.        
  193. }

  194. //外部中断1中断服务程序
  195. void int0() interrupt 0
  196. {
  197.         if (EncoderB)
  198.         {
  199.                 EncoderCount++;     //正转
  200.         }else
  201.         {
  202.                 EncoderCount--;     //反转
  203.         }
  204.         if (EncoderCount==360)
  205.         Motor_Stop();       
  206. }  
复制代码

所有资料51hei提供下载:
42步进电机 编码器.rar (32.23 KB, 下载次数: 168)


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

使用道具 举报

沙发
7454679 发表于 2018-7-29 00:29 | 只看该作者
好东西
回复

使用道具 举报

板凳
15942379927 发表于 2018-10-21 20:26 | 只看该作者
好贴  顶上去
回复

使用道具 举报

地板
lindeijun1 发表于 2018-10-22 15:36 | 只看该作者
好东西,顶一顶!!
回复

使用道具 举报

5#
liliqun 发表于 2018-11-25 11:39 | 只看该作者
学习学习
回复

使用道具 举报

6#
hongaa 发表于 2018-11-25 12:08 | 只看该作者
好东西,顶一顶!!
回复

使用道具 举报

7#
letter1996 发表于 2018-11-26 18:58 | 只看该作者
谢谢大佬
回复

使用道具 举报

8#
letter1996 发表于 2018-11-26 19:01 | 只看该作者
谢谢大佬的分享
回复

使用道具 举报

9#
梦园心田 发表于 2019-1-22 01:34 来自手机 | 只看该作者
太强了。。
回复

使用道具 举报

10#
gdatgb 发表于 2019-1-24 14:34 | 只看该作者
谢谢大佬的分享,学习 学习!!
回复

使用道具 举报

11#
gdatgb 发表于 2019-1-24 14:35 | 只看该作者
有没有电路图啊????
回复

使用道具 举报

12#
电子123456 发表于 2019-5-4 16:30 | 只看该作者
楼主用的是八拍的吗?
回复

使用道具 举报

13#
钻研旋律 发表于 2019-5-21 22:16 | 只看该作者
顶上去,学习了
回复

使用道具 举报

14#
肖蠢蠢 发表于 2019-6-10 17:03 | 只看该作者
大哥,没图?
回复

使用道具 举报

15#
1606050540011 发表于 2019-6-10 19:14 | 只看该作者
很给力!
回复

使用道具 举报

16#
鹏博士PBs 发表于 2019-6-10 21:43 | 只看该作者
42步进电机用的是多少拍的啊
回复

使用道具 举报

17#
Tars 发表于 2019-6-18 12:01 | 只看该作者
感谢大佬!!!!!!!!!!!!!
回复

使用道具 举报

18#
ttaniscy 发表于 2019-8-5 10:22 | 只看该作者
这个是好东西,谢谢分享
回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51Hei单片机16群 联系QQ:125739409;技术交流QQ群7344883

Powered by 单片机教程网

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