找回密码
 立即注册

QQ登录

只需一步,快速开始

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

超声波测距程序LCD1602显示 自己修改 测试成功

[复制链接]
跳转到指定楼层
楼主
ID:204162 发表于 2017-5-24 09:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
超声波测距

单片机源程序如下:
  1. /*********************************************************************************
  2. * 【编写时间】: 5月18日
  3. * 【作    者】: 1277668379
  4. * 【版    本】: 1.0
  5. * 【网    站】:
  6. * 【实验平台】:  单片机开发板
  7. * 【外部晶振】: 11.0592mhz       
  8. * 【主控芯片】: STC89C52
  9. * 【编译环境】: Keil μVisio5       
  10. * 【程序功能】: LCD1602显示超声波测距                                                                                           
  11. * 【使用说明】: 见下文
  12. **********************************************************************************/

  13. /*
  14. SMC1602A(16*2)模拟口线接线方式
  15. 连接线图:       
  16.        ---------------------------------------------------
  17.        |LCM-----51   |        LCM-----51   |        LCM------51      |
  18.        --------------------------------------------------|
  19.        |DB0-----P0.0 |        DB4-----P0.4 |        RW-------P2.1    |
  20.        |DB1-----P0.1 |        DB5-----P0.5 |        RS-------P2.2    |
  21.        |DB2-----P0.2 |        DB6-----P0.6 |        E--------P2.0    |
  22.        |DB3-----P0.3 |        DB7-----P0.7 |        VLCD接1K电阻到GND|
  23.        ---------------------------------------------------
  24. 接线:模块TRIG接 P3.0  RXD  ECH0 接P3.1  TXD

  25. 本程序源码只供学习参考,不得应用于商业用途,如有需要请联系作者。

  26. [注:AT89x51使用12M或11.0592M晶振,实测使用11.0592M]
  27. =============================================================*/
  28. #include <AT89x51.H>                //器件配置文件
  29. #include <intrins.h>
  30. #define  RX  P3_1
  31. #define  TX  P3_0

  32. #define LCM_RW  P2_1 //定义LCD引脚
  33. #define LCM_RS  P2_2
  34. #define LCM_E   P2_0
  35. #define LCM_Data  P0


  36. #define Busy    0x80 //用于检测LCM状态字中的Busy标识

  37. void LCMInit(void);
  38. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
  39. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
  40. void Delay5Ms(void);
  41. void Delay400Ms(void);
  42. void Decode(unsigned char ScanCode);
  43. void WriteDataLCM(unsigned char WDLCM);
  44. void WriteCommandLCM(unsigned char WCLCM,BuysC);

  45. unsigned char ReadDataLCM(void);
  46. void ReadStatusLCM(void);
  47. unsigned char code mcustudio[] ={"  LIU HENG RUI  "};
  48. unsigned char code email[] =    {"  QQ:1277668379 "};
  49. unsigned char code Cls[] =      {"                "};
  50. unsigned char code ASCII[30] =    {'0','1','2','3','4','5','6','7','8','9','.','-','M','C','D','I','S','T','A','N','C','E','T','H','E',':'};
  51.                                //   0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25
  52. static unsigned char DisNum = 0; //显示用指针                                  
  53.        unsigned int  time=0;
  54.            unsigned long S=0;
  55.            bit      flag =0;
  56.            unsigned char disbuff[4]           ={ 0,0,0,0,};


  57. //写数据
  58. void WriteDataLCM(unsigned char WDLCM)
  59. {
  60.         ReadStatusLCM(); //检测忙
  61.         LCM_RS = 1;
  62.         LCM_RW = 0;
  63.         LCM_Data = WDLCM;
  64.         LCM_E = 1; //若晶振速度太高可以在这后加小的延时
  65.         LCM_E = 0; //延时
  66. }

  67. //写指令
  68. void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
  69. {
  70.         if (BuysC) ReadStatusLCM(); //根据需要检测忙
  71.         LCM_RS = 0;
  72.         LCM_RW = 0;       
  73.         LCM_Data = WCLCM;
  74.         LCM_E = 1;
  75.         LCM_E = 0;       
  76. }

  77. //读数据
  78. unsigned char ReadDataLCM(void)
  79. {
  80.         LCM_RS = 1;
  81.         LCM_RW = 1;
  82.         LCM_E = 0;
  83.         LCM_E = 0;
  84.         LCM_E = 1;
  85.         return(LCM_Data);
  86. }

  87. //读状态
  88. void ReadStatusLCM(void)
  89. {
  90.         unsigned char sta;
  91.         LCM_Data = 0xFF;
  92.         LCM_RS = 0;
  93.         LCM_RW = 1;
  94.         do
  95.     {
  96.         LCM_E = 1;
  97.         sta = LCM_Data;
  98.         LCM_E = 0;    //使能,用完就拉低,释放总线
  99.     }while(sta & 0x80);
  100. }

  101. void LCMInit(void) //LCM初始化
  102. {
  103.         LCM_Data = 0;
  104.         WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
  105.         Delay5Ms();
  106.         WriteCommandLCM(0x38,0);
  107.         Delay5Ms();
  108.         WriteCommandLCM(0x38,0);
  109.         Delay5Ms();

  110.         WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
  111.         WriteCommandLCM(0x08,1); //关闭显示
  112.         WriteCommandLCM(0x01,1); //显示清屏
  113.         WriteCommandLCM(0x06,1); // 显示光标移动设置
  114.         WriteCommandLCM(0x0F,1); // 显示开及光标设置
  115. }

  116. //按指定位置显示一个字符
  117. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
  118. {
  119.         Y &= 0x1;
  120.         X &= 0xF; //限制X不能大于15,Y不能大于1
  121.         if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
  122.         X |= 0x80; //算出指令码
  123.         WriteCommandLCM(X, 1); //发命令字
  124.         WriteDataLCM(DData); //发数据
  125. }

  126. //按指定位置显示一串字符
  127. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
  128. {
  129.         unsigned char ListLength;

  130.   ListLength = 0;
  131.         Y &= 0x1;
  132.         X &= 0xF; //限制X不能大于15,Y不能大于1
  133.         while (DData[ListLength]>0x19) //若到达字串尾则退出
  134.                 {
  135.                         if (X <= 0xF) //X坐标应小于0xF
  136.                                 {
  137.                                         DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
  138.                                         ListLength++;
  139.                                         X++;
  140.                                 }
  141.                 }
  142. }

  143. //5ms延时
  144. void Delay5Ms(void)
  145. {
  146.         unsigned int TempCyc = 5552;
  147.         while(TempCyc--);
  148. }

  149. //400ms延时
  150. void Delay400Ms(void)
  151. {
  152.         unsigned char TempCycA = 5;
  153.         unsigned int TempCycB;
  154.         while(TempCycA--)
  155.                 {
  156.                         TempCycB=7269;
  157.                         while(TempCycB--);
  158.                 };
  159. }
  160. /********************************************************/
  161.     void Conut(void)
  162.         {
  163.          time=TH0*256+TL0;
  164.          TH0=0;
  165.          TL0=0;
  166.        
  167.          S=(time*1.7)/10;     //算出来是CM*10
  168.          if((S>=7000)||flag==1) //超出测量范围显示“-”
  169.          {         
  170.           flag=0;
  171.           DisplayOneChar(0, 1, ASCII[14]);  //显示D
  172.           DisplayOneChar(1, 1, ASCII[15]);  //显示I
  173.           DisplayOneChar(2, 1, ASCII[16]);  //显示S
  174.           DisplayOneChar(3, 1, ASCII[17]);  //显示T
  175.                 DisplayOneChar(4, 1, ASCII[18]);  //显示A
  176.           DisplayOneChar(5, 1, ASCII[19]);  //显示N
  177.                 DisplayOneChar(6, 1, ASCII[20]);  //显示C
  178.                 DisplayOneChar(7, 1, ASCII[21]);  //显示E
  179.                 DisplayOneChar(8, 1, ASCII[25]);  //显示:
  180. //        DisplayOneChar(9, 1, ASCII[23]);  //显示
  181.           DisplayOneChar(9, 1, ASCII[11]);  //百位
  182.           DisplayOneChar(10, 1, ASCII[11]);        //十位
  183.           DisplayOneChar(11, 1, ASCII[11]);  //个位
  184.                 DisplayOneChar(12, 1, ASCII[10]);  //显示.
  185.                 DisplayOneChar(13, 1, ASCII[11]);  //小数点后一位
  186.           DisplayOneChar(14, 1, ASCII[13]);  //显示C
  187.           DisplayOneChar(15, 1, ASCII[12]);        //显示M
  188.          }
  189.          else
  190.          {
  191.           disbuff[0]=S%10000/1000;
  192.           disbuff[1]=S%10000%1000/100;
  193.           disbuff[2]=S%10000%1000%100/10;
  194.                 disbuff[3]=S%10000%1000%100%10;
  195.                  
  196.                 DisplayOneChar(0, 1, ASCII[14]);  //显示D
  197.           DisplayOneChar(1, 1, ASCII[15]);  //显示I
  198.           DisplayOneChar(2, 1, ASCII[16]);  //显示S
  199.           DisplayOneChar(3, 1, ASCII[17]);  //显示T
  200.                 DisplayOneChar(4, 1, ASCII[18]);  //显示A
  201.           DisplayOneChar(5, 1, ASCII[19]);  //显示N
  202.                 DisplayOneChar(6, 1, ASCII[20]);  //显示C
  203.                 DisplayOneChar(7, 1, ASCII[21]);  //显示E
  204.                 DisplayOneChar(8, 1, ASCII[25]);  //显示:

  205.                  
  206.           DisplayOneChar(9, 1, ASCII[disbuff[0]]);
  207.           DisplayOneChar(10, 1, ASCII[disbuff[1]]);
  208.           DisplayOneChar(11, 1, ASCII[disbuff[2]]);
  209.                 DisplayOneChar(12, 1,  ASCII[10]);        //显示.
  210.                 DisplayOneChar(13, 1, ASCII[disbuff[3]]);
  211.           DisplayOneChar(14, 1,  ASCII[13]);        //显示C
  212.           DisplayOneChar(15, 1, ASCII[12]);        //显示M
  213.          }
  214.         }
  215. /********************************************************/
  216.      void zd0() interrupt 1                  //T0中断用来计数器溢出,超过测距范围
  217.   {
  218.     flag=1;                                                         //中断溢出标志
  219.   }
  220. /********************************************************/
  221.      void  StartModule()                          //启动模块
  222.   {
  223.           TX=1;                                             //启动一次模块
  224.           _nop_();
  225.           _nop_();
  226.           _nop_();
  227.           _nop_();
  228.           _nop_();
  229.           _nop_();
  230.           _nop_();
  231.           _nop_();
  232.           _nop_();
  233.           _nop_();
  234.           _nop_();
  235.           _nop_();
  236.           _nop_();
  237.           _nop_();
  238.           _nop_();
  239.           _nop_();
  240.           _nop_();
  241.           _nop_();
  242.           _nop_();
  243.           _nop_();
  244.           _nop_();
  245.           TX=0;
  246.   }
  247. /********************************************************/
  248. void delayms(unsigned int ms)
  249. {
  250.         unsigned char i=100,j;
  251.         for(;ms;ms--)
  252.         {
  253.                 while(--i)
  254.                 {
  255.                         j=10;
  256.                         while(--j);
  257.                 }
  258.         }
  259. }
  260. /*********************************************************/
  261. void main(void)
  262. {
  263.         unsigned char TempCyc;
  264. ……………………

  265. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
超声波测距LCD1602自改.zip (39.51 KB, 下载次数: 25)


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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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