找回密码
 立即注册

QQ登录

只需一步,快速开始

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

脉宽测量程序 HC-SRO4超声波测距模块1602显示

[复制链接]
跳转到指定楼层
楼主
ID:238437 发表于 2017-10-10 21:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
基于超声波的1602显示,用到了单片机的脉宽测量技术
单片机源程序如下:

  1. /*============================================================
  2. //HC-SRO4 超声波测距模块 DEMO 程序
  3. ==============================================================
  4. SMC1602A(16*2)模拟口线接线方式
  5. 连接线图:        
  6.        ---------------------------------------------------
  7.        |LCM-----51   |        LCM-----51   |        LCM------51      |
  8.        --------------------------------------------------|
  9.        |DB0-----P1.0 |        DB4-----P1.4 |        RW-------P3.4    |
  10.        |DB1-----P1.1 |        DB5-----P1.5 |        RS-------P3.3    |
  11.        |DB2-----P1.2 |        DB6-----P1.6 |        E--------P3.5    |
  12.        |DB3-----P1.3 |        DB7-----P1.7 |        VLCD接1K电阻到GND|
  13.        ---------------------------------------------------
  14. 接线:模块TRIG接 P2.6  ECH0 接P2.7

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

  16. [注:AT89x51使用12M或11.0592M晶振,实测使用11.0592M]
  17. =============================================================*/
  18. #include <AT89x51.H>                //器件配置文件
  19. #include <intrins.h>

  20. #define  RX  P2_0
  21. #define  TX  P2_1

  22. #define LCM_RW  P2_5 //定义LCD引脚
  23. #define LCM_RS  P2_6 //#define LCD1602_DATAPINS P0
  24.                      //sbit LCD1602_E=P2^7;
  25.                      //sbit LCD1602_RW=P2^5;
  26.                      //sbit LCD1602_RS=P2^6;
  27. #define LCM_E   P2_7
  28. #define LCM_Data  P0

  29. //#define Key_Data P2_0 //定义Keyboard引脚
  30. //#define Key_CLK  P3_2

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

  32. void LCMInit(void);
  33. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
  34. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
  35. void Delay5Ms(void);
  36. void Delay400Ms(void);
  37. void Decode(unsigned char ScanCode);
  38. void WriteDataLCM(unsigned char WDLCM);
  39. void WriteCommandLCM(unsigned char WCLCM,BuysC);

  40. unsigned char ReadDataLCM(void);
  41. unsigned char ReadStatusLCM(void);
  42. unsigned char code mcustudio[] ={"***2017.09.07***"};
  43. unsigned char code email[] =    {"***tangjiale****"};
  44. unsigned char code Cls[] =      {"                "};
  45. unsigned char code ASCII[15] =    {'0','1','2','3','4','5','6','7','8','9','.','*','M'};

  46. static unsigned char DisNum = 0; //显示用指针                                 
  47.        unsigned int  time=0;
  48.            unsigned long S=0;
  49.            bit      flag =0;
  50.            unsigned char disbuff[4]           ={ 0,0,0,0,};


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

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

  73. //读数据
  74. unsigned char ReadDataLCM(void)
  75. {
  76.         LCM_RS = 1;
  77.         LCM_RW = 1;
  78.         LCM_E = 0;
  79.         LCM_E = 0;
  80.         LCM_E = 1;
  81.         return(LCM_Data);
  82. }

  83. //读状态
  84. unsigned char ReadStatusLCM(void)
  85. {
  86.         LCM_Data = 0xFF;
  87.         LCM_RS = 0;
  88.         LCM_RW = 1;
  89.         LCM_E = 0;
  90.         LCM_E = 0;
  91.         LCM_E = 1;
  92.         while (LCM_Data & Busy); //检测忙信号
  93.         return(LCM_Data);
  94. }

  95. void LCMInit(void) //LCM初始化
  96. {
  97.         LCM_Data = 0;
  98.         WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
  99.         Delay5Ms();
  100.         WriteCommandLCM(0x38,0);
  101.         Delay5Ms();
  102.         WriteCommandLCM(0x38,0);
  103.         Delay5Ms();

  104.         WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
  105.         WriteCommandLCM(0x08,1); //关闭显示
  106.         WriteCommandLCM(0x01,1); //显示清屏
  107.         WriteCommandLCM(0x06,1); // 显示光标移动设置
  108.         WriteCommandLCM(0x0F,1); // 显示开及光标设置
  109. }

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

  120. //按指定位置显示一串字符
  121. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
  122. {
  123.         unsigned char ListLength;

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

  137. //5ms延时
  138. void Delay5Ms(void)
  139. {
  140.         unsigned int TempCyc = 5552;
  141.         while(TempCyc--);
  142. }

  143. //400ms延时
  144. void Delay400Ms(void)
  145. {
  146.         unsigned char TempCycA = 5;
  147.         unsigned int TempCycB;
  148.         while(TempCycA--)
  149.                 {
  150.                         TempCycB=7269;
  151.                         while(TempCycB--);
  152.                 };
  153. }
  154. /********************************************************/
  155.     void Conut(void)
  156.         {
  157.          time=TH0*256+TL0;
  158.          TH0=0;
  159.          TL0=0;
  160.         
  161.          S=(time*1.87)/100;    //算出来是M
  162.          if((S>=700)||flag==1) //超出测量范围显示“*”
  163.          {         
  164.           flag=0;
  165.          
  166.           DisplayOneChar(0, 1, ASCII[11]);
  167.           DisplayOneChar(1, 1, ASCII[10]);        //显示点
  168.           DisplayOneChar(2, 1, ASCII[11]);
  169.           DisplayOneChar(3, 1, ASCII[11]);
  170.           DisplayOneChar(4, 1, ASCII[12]);        //显示M
  171.          }
  172.          else
  173.          {
  174.           disbuff[0]=S%1000/100;
  175.           disbuff[1]=S%1000%100/10;
  176.           disbuff[2]=S%1000%10 %10;
  177.           DisplayOneChar(0, 1, ASCII[disbuff[0]]);
  178.           DisplayOneChar(1, 1, ASCII[10]);        //显示点
  179.           DisplayOneChar(2, 1, ASCII[disbuff[1]]);
  180.           DisplayOneChar(3, 1, ASCII[disbuff[2]]);
  181.           DisplayOneChar(4, 1, ASCII[12]);        //显示M
  182.          }
  183.         }
  184. /********************************************************/
  185.      void zd0() interrupt 1                  //T0中断用来计数器溢出,超过测距范围
  186.   {
  187.     flag=1;                                                         //中断溢出标志
  188.   }
  189. /********************************************************/
  190.      void  StartModule()                          //启动模块
  191.   {
  192.           TX=1;                                             //启动一次模块
  193.           _nop_();
  194.           _nop_();
  195.           _nop_();
  196.           _nop_();
  197.           _nop_();
  198.           _nop_();
  199.           _nop_();
  200.           _nop_();
  201.           _nop_();
  202.           _nop_();
  203.           _nop_();
  204.           _nop_();
  205.           _nop_();
  206.           _nop_();
  207.           _nop_();
  208.           _nop_();
  209.           _nop_();
  210.           _nop_();
  211.           _nop_();
  212.           _nop_();
  213.           _nop_();
  214.           TX=0;
  215.   }
  216. /********************************************************/
  217. void delayms(unsigned int ms)
  218. {
  219.         unsigned char i=100,j;
  220.         for(;ms;ms--)
  221.         {
  222.                 while(--i)
  223.                 {
  224.                         j=10;
  225.                         while(--j);
  226.                 }
  227.         }
  228. }
  229. /*********************************************************/
  230. void main(void)
  231. {
  232.         unsigned char TempCyc;
  233.         Delay400Ms(); //启动等待,等LCM讲入工作状态
  234.         LCMInit(); //LCM初始化
  235.         Delay5Ms(); //延时片刻(可不要)
  236.         DisplayListChar(0, 0, mcustudio);
  237.         DisplayListChar(0, 1, email);
  238.         ReadDataLCM();//测试用句无意义
  239.         for (TempCyc=0; TempCyc<10; TempCyc++)
  240.         Delay400Ms(); //延时
  241.         DisplayListChar(0, 1, Cls);        
  242.         while(1)
  243.         {
  244.          TMOD=0x01;                   //设T0为方式1,GATE=1;
  245.          TH0=0;
  246.          TL0=0;         
  247.          ET0=1;             //允许T0中断
  248.          EA=1;                           //开启总中断                        
  249.         
  250.         while(1)
  251.           {
  252.              StartModule();
  253.                 // DisplayOneChar(0, 1, ASCII[0]);
  254.              while(!RX);                //当RX为零时等待
  255.              TR0=1;                            //开启计数
  256.              while(RX);                        //当RX为1计数并等待
  257.              TR0=0;                                //关闭计数
  258.          Conut();                        //计算
  259.                  delayms(80);                //80MS
  260.                  
  261.           }
  262.         }
  263. }



  264.                
复制代码

所有资料51hei提供下载:
超声波测距LC1602显示.zip (39.81 KB, 下载次数: 16)


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

使用道具 举报

沙发
ID:89286 发表于 2017-10-11 07:00 | 只看该作者
thanks for sharing
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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