找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2216|回复: 5
收起左侧

关于单片机超声波测距,大佬们帮忙看看该加点啥,或者怎么改

[复制链接]
回帖奖励 50 黑币 回复本帖可获得 10 黑币奖励! 每人限 1 次
ID:852397 发表于 2021-4-22 20:05 | 显示全部楼层 |阅读模式
我在读大学,学习过单片机原理与应用,但是感觉不怎么懂这个东西,但对单片机是很感兴趣的。
现在有打算弄一个超声波测距显示模块,网上也买了一些硬件设备。
超声波测距模块是US-015,现在将一块1602显示屏装在一个单片机开发板上。
在本论坛也搜了资料,找了找相关的编程资料。想请问现在怎么弄,能让距离显示出来。程序该加点什么条件。
硬件方面超声波的四根线该接在开发板的哪里。
小白是真不太懂,希望有大佬能帮帮,感激不尽!

这是程序,大佬们帮忙看看该加点啥,或者怎么改,

单片机源程序如下:
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #define uint  unsigned int
  4. #define uchar unsigned char
  5. #define comm  0
  6. #define dat   1
  7. sbit RS=P2^6;                                                                //高电平数据,低电平命令
  8. sbit RW=P2^5;                                                                //读写控制脚,高电平读,低电平写
  9. sbit E=P2^7;                                                                //输入使能
  10. sbit busy=P0^7;                                                                //忙信号检测
  11. sbit SDA=P1^0;                                                                //I2C数据线
  12. sbit SCL=P1^1;                                                                //I2C时钟线
  13. sbit Buzz=P1^2;                                                                //蜂鸣器控制脚
  14. sbit LED_G=P1^3;                                                        //绿色指示灯控制脚
  15. sbit LED_R=P1^4;                                                        //红色指示灯控制脚
  16. uchar buf[6],dis_buf[6];                                        //数据缓冲区
  17. uint buffer[3];                                                                //测量距离存储区
  18. uint dis;                                                                        //最小距离存储器
  19. uchar code tab1[]={"距离障碍物:"};                        //显示字符
  20. uchar code tab2[]={"无障碍物"};
  21. uchar code tab[]={"0123456789cm"};
  22. /*****************函数声明*****************/
  23. void start_bit(void);                                                //I2C起始函数
  24. void stop_bit(void);                                                //I2C停止函数
  25. void mast_ack(void);                                                //主答函数
  26. bit write_8bit(uchar ch);                                        //I2C总线写8位数据函数
  27. bit page_rd(uchar device,uint fir_ad,uint count,uchar *firw_ad);//I2C总线页面读函数
  28. uint measure(uchar device);                                        //启动测距函数
  29. uint get_distance(void);                                        //读测距值函数
  30. void judge(void);                                                        //判断距离函数
  31. void init_lcd (void);                                                //LCD初始化函数
  32. void wr_lcd(uchar dat_comm,uchar content);//LCD写数据函数
  33. void chk_busy (void);                                                //忙信号检测
  34. void chn_disp(uchar code *chn,uchar pos,uchar n);//显示提示汉字函数
  35. uchar dat_adj(uint dat1);                                        //显示数据调整函数
  36. void disp_dist(uchar dat1);                                        //显示距离函数
  37. void disp(void);                                                        //显示函数
  38. void delay (uint us);                                                //延时函数
  39. void delay1 (uint ms);                                                //延时函数
  40. /*********************主程序***********************/
  41. void main ()
  42. {
  43.     init_lcd ();                                                        //初始化LCD
  44.     while (1)
  45.     {
  46.                 judge();                                                        //判断障碍物距离
  47.                 disp();                                                                //显示提示信息
  48.         }
  49. }
  50. /********************I2C起始函数*******************/
  51. void start_bit(void)
  52. {
  53.     SCL=1;_nop_();
  54.     SDA=1;_nop_();
  55.     SDA=0;_nop_();
  56.     SCL=0;_nop_();
  57. }
  58. /*******************I2C停止函数********************/
  59. void stop_bit(void)
  60. {
  61.     SDA=0;_nop_();
  62.     SCL=1;_nop_();
  63.     SDA=1;_nop_();
  64. }
  65. /****************I2C总线写8位数据函数**************/
  66. bit write_8bit(uchar ch)
  67. {
  68.     uchar i=8;
  69.     bit fan_w;
  70.     SCL=0;_nop_();
  71.     while (i--)
  72.     {
  73.         SDA=(bit)(ch&0x80);_nop_();                                //获取发送位数据
  74.         ch<<=1;
  75.         SCL=1;_nop_();
  76.         SCL=0;_nop_();
  77.     }
  78.     SDA=1;_nop_();
  79.     SCL=1;_nop_();
  80.     fan_w=SDA;                                                                        //应答位
  81.     SCL=0;_nop_();
  82.     return(fan_w);                                                                //返回应答位
  83. }
  84. /*****************I2C总线页面读函数****************/
  85. bit page_rd(uchar device,uint fir_ad,uint count,uchar *firw_ad)
  86. {
  87.         uchar j=8;
  88.         uchar data *ufirstwr_ad;
  89.         ufirstwr_ad=firw_ad;
  90.         start_bit();
  91.         if(write_8bit(device)!=0){stop_bit();return(0);}//送器件地址,写数据
  92.         if(write_8bit(fir_ad)!=0){stop_bit();return(0);}//送读数据寄存器首地址
  93.         start_bit();
  94.         if(write_8bit(device|0x01)!=0){stop_bit();return(0);}//准备读数据
  95.         while(count--)
  96.         {
  97.                 uchar i=8;
  98.                 while(i--)                                                                //读入数据
  99.                 {
  100.                         (*ufirstwr_ad)<<=1;
  101.                         SCL=1;_nop_();
  102.                         if(SDA) (*ufirstwr_ad)|=0x01;
  103.                         SCL=0; _nop_();
  104.                 }
  105.                 ufirstwr_ad++;
  106.                 mast_ack();                                                                //主机产生应答位
  107.         }
  108.         while(j--)
  109.         {
  110.                 (*ufirstwr_ad)<<=1;
  111.                 SCL=0;_nop_();_nop_();SCL=1;
  112.                 if(SDA) (*ufirstwr_ad)|=0x01;
  113.         }
  114.         stop_bit();                                                                        //停止I2C数据传送
  115.         return(1);
  116. }
  117. /*********************主答函数*********************/
  118. void mast_ack(void)
  119. {
  120.    SCL=0;_nop_();
  121.    SDA=0;_nop_();
  122.    SCL=1;_nop_();
  123.    SCL=0;_nop_();
  124.    SDA=1;_nop_();
  125. }
  126. /********************测距函数******************/
  127. uint measure(uchar device)
  128. {
  129.         uint temp;
  130.         start_bit();                                                                //启动I2C
  131.         while(!write_8bit(device));                                        //发器件地址
  132.         while(!write_8bit(0x00));                                        //命令寄存器
  133.         while(!write_8bit(0x51));                                        //以厘米为单位返回距离
  134.         stop_bit();                                                                        //停止I2C
  135.         delay1(100);
  136.         while(!page_rd(device,0x02,2,buf));                        //读距离值
  137.         temp=(buf[0]<<8)|buf[1];
  138.         return(buffer);                                                                //返回距离值
  139. }
  140. /*******************求最小测距值函数*****************/
  141. uint get_distance(void)
  142. {
  143.         uint mix;
  144.         buffer[0]=measure(0xe0);                                        //读左侧测距值
  145.         buffer[1]=measure(0xe2);                                        //读中间测距值
  146.         buffer[2]=measure(0xe4);                                        //读右侧测距值
  147.         if(buffer[0]<buffer[1])
  148.                 mix=buffer[0];
  149.         else
  150.                 mix=buffer[1];
  151.         if(mix>buffer[2])mix=buffer[2];                                //合并为一个16位数据
  152.         return(mix);
  153. }
  154. /*******************判断距离函数*******************/
  155. void judge(void)
  156. {
  157.         dis=get_distance();                                                        //读取测量距离最小值
  158.         if(dis<5000)
  159.         {
  160.                 LED_R=0;                                                                //红色报警灯亮
  161.                 LED_G=1;                                                                //绿色报警灯灭
  162.         }        
  163.         else
  164.         {
  165.                 LED_R=1;                                                                //红色报警灯灭
  166.                 LED_G=0;                                                                //绿色报警灯亮
  167.         }        
  168.         if(dis<3000)
  169.                 Buzz=0;                                                                        //蜂鸣器报警
  170.         else
  171.                 Buzz=1;                                                                        //蜂鸣器停止报警
  172. }
  173. /******************LCD初始化函数*******************/
  174. void init_lcd (void)
  175. {
  176.         wr_lcd (comm,0x30);                                                        //基本指令动作   
  177.         wr_lcd (comm,0x01);                                                        //清屏
  178.         wr_lcd (comm,0x06);                                                        //光标的移动方向
  179.         wr_lcd (comm,0x0c);                                                        //开显示,关游标
  180. }
  181. /*******************LCD写数据函数*****************/
  182. void wr_lcd (uchar dat_comm,uchar content)
  183. {
  184.         chk_busy ();
  185.         if(dat_comm)
  186.         {
  187.                 RS=1;                                                                        //数据
  188.                 RW=0;                                                                        //写入
  189.         }
  190.         else
  191.         {
  192.                 RS=0;                                                                        //命令
  193.                 RW=0;                                                                        //写入
  194.         }
  195.         P0=content;                                                                        //输出数据或命令
  196.         E=1;
  197.         E=0;
  198. }
  199. /********************忙信号检测********************/
  200. void chk_busy (void)
  201. {
  202.         P0=0xff;
  203.         RS=0;
  204.         RW=1;
  205.         E=1;
  206.         while(busy==1);                                                                //检验LCD是否处于忙状态
  207.         E=0;
  208. }
  209. /****************显示提示汉字函数******************/
  210. void chn_disp(uchar code *chn,uchar pos,uchar n)
  211. {
  212.         uchar i;
  213.         wr_lcd (comm,0x30);                                                        //基本指令动作
  214.         wr_lcd (comm,pos);                                                        //显示位置
  215.         for (i=0;i<n;i++)
  216.                 wr_lcd (dat,chn[i]);
  217. }
  218. /****************显示数据调整函数******************/
  219. uchar dat_adj(uint dat1)
  220. {
  221.     uchar i;
  222.         dis_buf[0]=(uchar)(dat1/1000);                                //高度千位
  223.         dis_buf[1]=(uchar)((dat1%1000)/100);                //高度百位
  224.         dis_buf[2]=(uchar)((dat1%100)/10);                        //高度十位
  225.         dis_buf[3]=(uchar)(dat1%10);                                //高度个位
  226.         dis_buf[4]=10;
  227.         for(i=0;i<3;i++)
  228.         {
  229.                 if(dis_buf[i]!=0)break;                                        //确定显示位数
  230.         }
  231.         return(i);
  232. }
  233. /******************显示距离函数********************/
  234. void disp_dist(uchar dat1)
  235. {
  236.         uchar temp,i;
  237.         if(dat1>5000)
  238.         {
  239.                 chn_disp(tab2,0x92,4);                                        //无障碍显示
  240.         }
  241.         else
  242.         {
  243.                 temp=dat_adj(dat1);
  244.                 wr_lcd(comm,0x30);                                                //基本指令
  245.                 wr_lcd(comm,temp+0x92);                                        //设置显示起始位置
  246.                 for (i=temp;i<6;i++)                                        //送显示数据
  247.                         wr_lcd(dat,tab[dis_buf[i]]);
  248.         }
  249. }
  250. /********************显示函数**********************/
  251. void disp(void)
  252. {
  253.         chn_disp(tab1,0x80,11);                                                //显示提示汉字
  254.         disp_dist(dis);                                                                //显示距离值
  255. }
  256. /********************延时函数**********************/
  257. void delay (uint us)
  258. {
  259.         while(us--);
  260. }
  261. /********************延时函数**********************/
  262. void delay1 (uint ms)
  263. {
  264.         uint i,j;
  265.         for(i=0;i<ms;i++)
  266.         for(j=0;j<15;j++)
  267.         delay(1);
  268. }
复制代码


这是硬件设备,接线问题也求助一下下。
7C40D95133CA35F763DC54F68DE1D2A5.jpg


感激不尽感激不尽!!!!!!!!!!!!
回复

使用道具 举报

ID:585428 发表于 2021-4-23 07:58 | 显示全部楼层
  1. /*
  2. 接线方式:超声波模块trig接单片机P2^0 ,超声波模块echo接单片机P2^1
  3.           P3^2接P2^1
  4. */

  5. #include "reg52.h"

  6. typedef unsigned char uchar;
  7. typedef unsigned int uint;

  8. sbit trig=P2^0;
  9. sbit echo=P2^1;
  10. sbit beep=P1^5;

  11. sbit LSA=P2^2;
  12. sbit LSB=P2^3;
  13. sbit LSC=P2^4;

  14. uint num=0;                   //计时
  15. float distance;           //距离
  16. float cm_per_num=3.40; //按照我的定时器初始化设定,1个num是100us
  17. uchar DisplayData[6];
  18. uchar code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  19.                                         0x7f,0x6f};//显示0~9的值

  20. void delay1ms(uchar xms)   
  21. {
  22.     uchar a,b,c;
  23.     for(c=xms;c>0;c--)
  24.         for(b=142;b>0;b--)
  25.             for(a=2;a>0;a--);
  26. }

  27. /*
  28. 设置工作方式为方式1,GATE=1,当中断0口输入1且TR0=1 时定时器工作
  29. 因为超声波模块的工作原理就是在接收回波时,从开始到结束,ech0=1
  30. 所以在单片机上用杜邦线将ech0的P21口和 中断0口 P32口链接
  31. 使得在回波期间,定时器工作,计算回波的时间,进而s=vt算出距离
  32. */
  33. void TimerInit()          //初始化,定时10us
  34. {
  35.     TMOD = 0x09;         
  36.     TH0 = 0xFF;
  37.     TL0 = 0x9C;
  38.     EA = 1;
  39.     ET0 = 1;
  40.     TR0 = 1;
  41. }

  42. void Timer0() interrupt 1          //中断 每过100us,num+1
  43. {
  44.     TH0 = 0xFF;
  45.     TL0 = 0x9C;
  46.         num++;
  47. }

  48. void value_distance()
  49. {
  50.         trig=0;
  51.         echo=0;
  52.         delay1ms(1);
  53.         trig=1;
  54.         delay1ms(11); //给trig一个10us以上的高电平信号
  55.         trig=0;
  56.         if(echo==1)           //如果有反射回的超声波,echo脚会在这期间持续输入高电平
  57.         {
  58.                 delay1ms(300);                //接收超声波期间不做任何动作。
  59.         }
  60.         distance=num*cm_per_num/2;   //计算距离,单位CM
  61.         num=0;
  62.                
  63. }

  64. void datapros()                         //对取得的距离进行处理
  65. {
  66.         float a= distance*100;       
  67.         DisplayData[0]=smgduan[(int)a%10];
  68.         DisplayData[1]=smgduan[(int)a%100/10];
  69.         DisplayData[2]=smgduan[(int)a%1000/100]+0x80;         //数字+小数点
  70.         DisplayData[3]=smgduan[(int)a%10000/1000];
  71.         DisplayData[4]=smgduan[(int)a/10000];       
  72.                
  73. }

  74. void DigDisplay()                           //数码管显示
  75. {
  76.         uchar i;
  77.         for(i=0;i<6;i++)
  78.         {
  79.                 switch(i)         //位选,选择点亮的数码管,
  80.                 {
  81.                         case(0):
  82.                                 LSA=0;LSB=0;LSC=0; break;//显示第0位
  83.                         case(1):
  84.                                 LSA=1;LSB=0;LSC=0; break;//显示第1位
  85.                         case(2):
  86.                                 LSA=0;LSB=1;LSC=0; break;//显示第2位
  87.                         case(3):
  88.                                 LSA=1;LSB=1;LSC=0; break;//显示第3位
  89.                         case(4):
  90.                                 LSA=0;LSB=0;LSC=1; break;//显示第4位
  91.                         case(5):
  92.                                 LSA=1;LSB=0;LSC=1; break;//显示第5位
  93.                 }
  94.                 P0=DisplayData[i];//发送段码
  95.                 delay1ms(1); //间隔一段时间扫描       
  96.                 P0=0x00;//消隐
  97.         }
  98. }

  99. void main()
  100. {
  101.         while(1)
  102.         {
  103.                 TimerInit();
  104.                 value_distance();
  105.                 datapros();
  106.                 DigDisplay();
  107.         }
  108. }
复制代码

这是我以前写的,测试过,是可以正常工作,并显示距离的。
回复

使用道具 举报

ID:895440 发表于 2021-4-23 08:02 | 显示全部楼层
gnd接地,vcc接高电平的。剩下两个看程序端口定义接
回复

使用道具 举报

ID:844772 发表于 2021-4-23 09:25 | 显示全部楼层
你主要不是接线问题,用的超声测距模块US-015,不是IIC设备,不能按你的程序使用,二楼的是正确的。
回复

使用道具 举报

ID:838572 发表于 2021-11-29 17:06 | 显示全部楼层
Trig Echo脚接好就行
回复

使用道具 举报

ID:523803 发表于 2021-12-12 23:43 | 显示全部楼层
你那个超声波模块不是IIC协议的好像
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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