找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2004|回复: 0
收起左侧

有关51单片机的超声波测距(HC—SR04)程序

[复制链接]
ID:711832 发表于 2020-3-20 22:48 | 显示全部楼层 |阅读模式
超声波的学习参考资料+原理图+使用手册

原理图

原理图

单片机源程序如下
  1. #include <AT89x51.H>                //器件配置文件
  2. #include <intrins.h>
  3. #define  RX  P2_7
  4. #define  TX  P2_6

  5. #define LCM_RW  P3_4 //定义LCD引脚
  6. #define LCM_RS  P3_3
  7. #define LCM_E   P3_5
  8. #define LCM_Data  P1

  9. #define Key_Data P2_0 //定义Keyboard引脚
  10. #define Key_CLK  P3_2

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

  12. void LCMInit(void);
  13. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
  14. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
  15. void Delay5Ms(void);
  16. void Delay400Ms(void);
  17. void Decode(unsigned char ScanCode);
  18. void WriteDataLCM(unsigned char WDLCM);
  19. void WriteCommandLCM(unsigned char WCLCM,BuysC);

  20. unsigned char ReadDataLCM(void);
  21. unsigned char ReadStatusLCM(void);
  22. unsigned char code mcustudio[] ={"mcustudio.com.cn"};
  23. unsigned char code email[] =    {"fhwxaoo@163.com "};
  24. unsigned char code Cls[] =      {"                "};
  25. unsigned char code ASCII[15] =    {'0','1','2','3','4','5','6','7','8','9','.','-','M'};

  26. static unsigned char DisNum = 0; //显示用指针                                 
  27.        unsigned int  time=0;
  28.            unsigned long S=0;
  29.            bit      flag =0;
  30.            unsigned char disbuff[4]           ={ 0,0,0,0,};


  31. //写数据
  32. void WriteDataLCM(unsigned char WDLCM)
  33. {
  34.         ReadStatusLCM(); //检测忙
  35.         LCM_Data = WDLCM;
  36.         LCM_RS = 1;
  37.         LCM_RW = 0;
  38.         LCM_E = 0; //若晶振速度太高可以在这后加小的延时
  39.         LCM_E = 0; //延时
  40.         LCM_E = 1;
  41. }

  42. //写指令
  43. void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
  44. {
  45.         if (BuysC) ReadStatusLCM(); //根据需要检测忙
  46.         LCM_Data = WCLCM;
  47.         LCM_RS = 0;
  48.         LCM_RW = 0;        
  49.         LCM_E = 0;
  50.         LCM_E = 0;
  51.         LCM_E = 1;        
  52. }

  53. //读数据
  54. unsigned char ReadDataLCM(void)
  55. {
  56.         LCM_RS = 1;
  57.         LCM_RW = 1;
  58.         LCM_E = 0;
  59.         LCM_E = 0;
  60.         LCM_E = 1;
  61.         return(LCM_Data);
  62. }

  63. //读状态
  64. unsigned char ReadStatusLCM(void)
  65. {
  66.         LCM_Data = 0xFF;
  67.         LCM_RS = 0;
  68.         LCM_RW = 1;
  69.         LCM_E = 0;
  70.         LCM_E = 0;
  71.         LCM_E = 1;
  72.         while (LCM_Data & Busy); //检测忙信号
  73.         return(LCM_Data);
  74. }

  75. void LCMInit(void) //LCM初始化
  76. {
  77.         LCM_Data = 0;
  78.         WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
  79.         Delay5Ms();
  80.         WriteCommandLCM(0x38,0);
  81.         Delay5Ms();
  82.         WriteCommandLCM(0x38,0);
  83.         Delay5Ms();

  84.         WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
  85.         WriteCommandLCM(0x08,1); //关闭显示
  86.         WriteCommandLCM(0x01,1); //显示清屏
  87.         WriteCommandLCM(0x06,1); // 显示光标移动设置
  88.         WriteCommandLCM(0x0F,1); // 显示开及光标设置
  89. }

  90. //按指定位置显示一个字符
  91. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
  92. {
  93.         Y &= 0x1;
  94.         X &= 0xF; //限制X不能大于15,Y不能大于1
  95.         if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
  96.         X |= 0x80; //算出指令码
  97.         WriteCommandLCM(X, 1); //发命令字
  98.         WriteDataLCM(DData); //发数据
  99. }

  100. //按指定位置显示一串字符
  101. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
  102. {
  103.         unsigned char ListLength;

  104.   ListLength = 0;
  105.         Y &= 0x1;
  106.         X &= 0xF; //限制X不能大于15,Y不能大于1
  107.         while (DData[ListLength]>0x19) //若到达字串尾则退出
  108.                 {
  109.                         if (X <= 0xF) //X坐标应小于0xF
  110.                                 {
  111.                                         DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
  112.                                         ListLength++;
  113.                                         X++;
  114.                                 }
  115.                 }
  116. }

  117. //5ms延时
  118. void Delay5Ms(void)
  119. {
  120.         unsigned int TempCyc = 5552;
  121.         while(TempCyc--);
  122. }

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



  244.                
复制代码
51hei.png
全部资料51hei下载地址:
超声波测距资料(HC-SR04)_TB - 副本.rar (2.62 MB, 下载次数: 21)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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