找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机超声波测距代码与实测数据

[复制链接]
跳转到指定楼层
楼主
超声波测距 数值显示

单片机源程序如下:

  1. #include <reg52.h>
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include <intrins.h>
  5. #include <string.h>

  6. #define uchar        unsigned char
  7. #define uint        unsigned int
  8. #define ulong        unsigned long

  9. sbit DQ = P2^7;  //定义18B20引脚
  10. /*
  11. sbit G1 = P2^0;//数码管1
  12. sbit G2 = P2^1;//数码管2
  13. sbit G3 = P2^2;//数码管3
  14. sbit G4 = P2^3;//数码管4
  15. sbit key1=P3^5;//按键1
  16. */
  17. sbit G1 = P1^0;//数码管1
  18. sbit G2 = P1^1;//数码管2
  19. sbit G3 = P1^2;//数码管3
  20. sbit G4 = P1^3;//数码管4
  21. sbit key1=P1^4;//按键1

  22. sbit RX=P3^2;//回波引脚
  23. sbit TX=P3^3;//产生脉冲引脚

  24. uchar keyvalue=0;//键值
  25. uint keycount=0;//计时
  26. float time=0;//反射时间
  27. float C,T;//速度,温度
  28. unsigned int  timer=0;//计时
  29. unsigned long S=0;//测量的距离

  30. bit flag =0;//中断溢出标志
  31. unsigned char const discode[] ={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0xff/*-*/};//段码0-9
  32. unsigned char const positon[4]={ 0xfe,0xfd,0xfb,0xf7};//位选
  33. unsigned char disbuff[4] ={ 0,0,0,0,},posit=0;//自定义变量
  34. unsigned char tx[10]={0,0,0x2E,0,0,0,0,0xDF,0x43,0x0A};//存储温度
  35. /********************************************************************
  36. * 名称 : Delay()
  37. * 功能 : 微秒级延时函数
  38. * 输入 : num
  39. * 输出 : 无
  40. ***********************************************************************/
  41. void Delay(int num)//延时函数
  42. {
  43.         while(num--) ;
  44. }
  45. /********************************************************************
  46. * 名称 : Delaynms()
  47. * 功能 : 毫秒级延时函数
  48. * 输入 : num
  49. * 输出 : 无
  50. ***********************************************************************/
  51. void Delaynms(unsigned int di) //延时
  52. {
  53.         unsigned int da,db;
  54.          for(da=0;da<di;da++)
  55.                    for(db=0;db<100;db++);
  56. }
  57. /********************************************************************
  58. * 名称 : Init_DS18B20()
  59. * 功能 : 初始化ds1820
  60. * 输入 : 无
  61. * 输出 : dat
  62. ***********************************************************************/        
  63. void Init_DS18B20(void)//初始化ds1820
  64. {
  65.         unsigned char x=0;
  66.         DQ = 1;    //DQ复位
  67.         Delay(8);  //稍做延时
  68.         DQ = 0;    //单片机将DQ拉低
  69.         Delay(80); //精确延时 大于 480us
  70.         DQ = 1;    //拉高总线
  71.         Delay(14);
  72.         x=DQ;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
  73.         Delay(20);
  74. }
  75. /********************************************************************
  76. * 名称 : ReadOneChar()
  77. * 功能 : 从DS18B20读取一节数据
  78. * 输入 : 无
  79. * 输出 : dat
  80. ***********************************************************************/
  81. unsigned char ReadOneChar(void)//读一个字节
  82. {
  83.         unsigned char i=0;
  84.         unsigned char dat = 0;
  85.         for (i=8;i>0;i--)
  86.         {
  87.                 DQ = 0; // 给脉冲信号
  88.                 dat>>=1;
  89.                 DQ = 1; // 给脉冲信号
  90.                 if(DQ)
  91.                 dat|=0x80;
  92.                 Delay(4);
  93.         }
  94.         return(dat);
  95. }

  96. /********************************************************************
  97. * 名称 : WriteOneChar()
  98. * 功能 : 对DS18B20写一节数据
  99. * 输入 : dat
  100. * 输出 : 无
  101. ***********************************************************************/
  102. void WriteOneChar(unsigned char dat)//写一个字节
  103. {
  104.         unsigned char i=0;
  105.         for (i=8; i>0; i--)
  106.         {
  107.                 DQ = 0;
  108.                 DQ = dat&0x01;
  109.                 Delay(2);
  110.                 DQ = 1;
  111.                 dat>>=1;
  112.         }
  113.         
  114. }
  115. /********************************************************************
  116. * 名称 : ReadTemperature()
  117. * 功能 : 读取数据  转换温度
  118. * 输入 : 无
  119. * 输出 : 无
  120. ***********************************************************************/
  121. void ReadTemperature(void)//读取温度
  122. {
  123.         unsigned char a=0;
  124.         unsigned char b=0;
  125.         unsigned char Data_L=0;
  126.         unsigned char num=0;

  127.         Init_DS18B20();

  128.         WriteOneChar(0xCC); // 跳过读序号列号的操作
  129.         WriteOneChar(0x44); // 启动温度转换
  130.         Init_DS18B20();
  131.         WriteOneChar(0xCC); //跳过读序号列号的操作
  132.         WriteOneChar(0xBE); //读取温度寄存器

  133.         a=ReadOneChar();  //读低8位
  134.         b=ReadOneChar(); //读高8位

  135.   tx[0] = (a/16+b*16)/10;      //整数部分


  136.         tx[1] = (a/16+b*16)%10;

  137.   Data_L=a&0X0F;
  138.   for(num=3;num<7;num++)                 //小数部分
  139.   {
  140.      Data_L=Data_L*10;                                 //10           //100                //40                 //80
  141.      tx[num]=Data_L/16;                         //0          //6                        //2                         //5
  142.      Data_L=Data_L%16;                                 //10           //4                        //8
  143.         }

  144. }
  145. /********************************************************************
  146. * 名称 : Display(void)               
  147. * 功能 : 数码管显示距离
  148. * 输入 : 无
  149. * 输出 : 无
  150. ***********************************************************************/
  151. void Display(void)                                 
  152.         {
  153.          if(posit==0)
  154.          {
  155.            P0=(discode[disbuff[posit]])&0x7f;
  156.          }
  157.          else
  158.          {
  159.           P0=discode[disbuff[posit]];
  160.          }
  161.           P2=positon[posit];
  162.           if(++posit>=4)
  163.           posit=0;
  164.         }
  165. /********************************************************************
  166. * 名称 : Conut(void)
  167. * 功能 : 计算距离
  168. * 输入 : 无
  169. * 输出 : 无
  170. ***********************************************************************/
  171. void Conut(void)
  172.         {
  173.          uchar i;
  174.          time=TH0*256+TL0;
  175.          TH0=0;
  176.          TL0=0;
  177.          if(time>290)//补偿
  178.          {
  179.                   i=time/290;
  180.                   time=time+i*25;
  181.          }
  182.          ReadTemperature();         //读取温度               
  183.          T=(tx[0]*1000+tx[1]*100+tx[3]*10+tx[4]);//温度
  184.          C=331.4+0.607*T/100;//当时温度对应的声波速度
  185.          
  186.          S=time*C/2/1000; //算出来是MM
  187.          //S=time/58*10;//(time*1.7)/100;     //算出来是CM        
  188.          if((S>=7000)||flag==1) //超出测量范围显示“-”
  189.          {         
  190.           flag=0;
  191.           disbuff[0]=10;           //“-”
  192.           disbuff[1]=10;           //“-”
  193.           disbuff[2]=10;           //“-”
  194.                 disbuff[3]=10;           //“-”
  195.          }
  196.          else
  197.          {
  198.                                 disbuff[0]=S/1000;
  199.                                 disbuff[1]=S%1000/100;
  200.                                 disbuff[2]=S%100%100/10;
  201.                                 disbuff[3]=S%100%100%10;
  202.          }
  203.          
  204.         }
  205. /********************************************************************
  206. * 名称 : zd0()
  207. * 功能 : T0中断用来计数器溢出,超过测距范围
  208. * 输入 : 无
  209. * 输出 : 无
  210. ***********************************************************************/
  211. void zd0() interrupt 1         
  212.   {
  213.     flag=1;                                                         //中断溢出标志
  214.   }
  215. /********************************************************************
  216. * 名称 : zd3()
  217. * 功能 : T1中断用来扫描数码管和计800MS启动模块
  218. * 输入 : 无
  219. * 输出 : 无
  220. ***********************************************************************/
  221. void  zd3()  interrupt 3
  222.   {
  223.                  TH1=0xf8;
  224.            TL1=0x30;
  225.                  timer++;
  226.                  if(keyvalue==1)
  227.                      keycount++;
  228.                 Display();//数码管显示
  229.   }
  230. /********************************************************************
  231. * 名称 : scankey()
  232. * 功能 : 按键扫描
  233. * 输入 : 无
  234. * 输出 : 无
  235. ***********************************************************************/
  236. void scankey()
  237. {
  238.         if(key1==0)//按键按下
  239.         {
  240.                 Delaynms(5);//消抖
  241.                 if(key1==0)//再次检测按键
  242.                 {
  243.                         keyvalue=1;
  244.                         while(!key1);//等待释放
  245.                 }
  246.         }
  247.                
  248. }
  249. /********************************************************************
  250. * 名称 : timeInit()
  251. * 功能 : 定时器初始化
  252. * 输入 : 无
  253. * 输出 : 无
  254. ***********************************************************************/
  255. void  timeInit()
  256. {
  257.           TMOD=0x11;                   //设T0为方式1,GATE=1;
  258.                 TH0=0;
  259.                 TL0=0;         
  260.                 TH1=0xf8;                   //2MS定时
  261.                 TL1=0x30;
  262.                 ET0=1;             //允许T0中断
  263.                 ET1=1;                           //允许T1中断
  264.                 //TR1=1;                           //开启定时器
  265.                 EA=1;                           //开启总中断
  266. }
  267. /********************************************************************/
  268. /********************************************************************/
  269. /* 名称 : main()
  270. /* 功能 : 主函数
  271. /* 输入 : 无
  272. /* 输出 : 无
  273. /********************************************************************/
  274. /********************************************************************/
  275. void main(void)
  276. {  
  277.         uchar  ab=0,i;
  278.         Init_DS18B20();//18b20初始化
  279.         timeInit();//定时器初始化
  280.         while(1)
  281.         {         
  282.     scankey();//按键扫描        
  283.                 if(keyvalue==1)
  284.                 {
  285.                         TR1=1;                           //开启定时器        
  286.                         if(RX==1)//当RX为零时等待        
  287.                         {
  288.                         TR0=1;                            //开启计数
  289.                         ab=1;
  290.                         }
  291.                         if(RX==0&&ab==1)                        //当RX为1计数并等待
  292.                         {
  293.                         TR0=0;                                //关闭计数
  294.                         Conut();                        //计算
  295.                         ab=0;
  296.                         }

  297.                 }
  298.          if(timer>=400&&ab==0)
  299.                  {
  300.                         timer=0;
  301.                         TX=1;                                        //800MS  启动一次模块
  302.                         _nop_();
  303.                         _nop_();
  304.                         _nop_();
  305.                         _nop_();
  306.                         _nop_();
  307.                         _nop_();
  308.                         _nop_();
  309.                         _nop_();
  310.                         _nop_();
  311.                         _nop_();
  312.                         _nop_();
  313.                         _nop_();
  314.                         _nop_();
  315.                         _nop_();
  316.                         _nop_();
  317.                         _nop_();
  318.                         _nop_();
  319.                         _nop_();
  320.                         _nop_();
  321.                         _nop_();
  322.                         _nop_();
  323.                         TX=0;
  324.                         
  325.                  }
  326.                
  327.                 if(keycount>=4800)
  328.                                 {
  329.                                         keyvalue=0;
  330.                                         keycount=0;
  331.                                         TR1=0;
  332.                                         P2=0xff;
  333.                                 }
  334.                
  335.         }
  336.         
  337. }
复制代码

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

使用道具 举报

沙发
ID:1 发表于 2018-12-9 00:56 | 只看该作者
补全原理图或者详细说明一下电路连接即可获得100+黑币
回复

使用道具 举报

板凳
ID:803357 发表于 2021-5-16 17:16 | 只看该作者
if(time>290)那部分怎么理解?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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