带温度补偿的超声波测距程序
温度补偿超声波测距仪

摘要本文给出了系统总体框架、硬件电路、软件设计和程序流程图,并在硬件平台上实现了所设计的功能。
超声测距是一种非接触式的检测方式。
与其它方法相比,如电磁的或光学的方法,它不受光线、被测对象颜色等影响。
对于被测物处于黑暗、有灰尘烟雾、电磁干扰、有毒等恶劣的环境下有一定的适应能力。
而本文介绍的基于单片机STC90C516RD+的超声波测距系统的设计方案与软硬件实现。
采用温度传感器DS18B20 采集温度数据,液晶显示屏LCD1602C 显示温度数据及来回波的时间,当环境温度变化较大时,提取测得的温度,根据不同的温度对超声波测距系统的声速进行修正。
测距时接收到回波,点亮绿色发光二极管;当没有回波时,定时器溢出,点亮红色发光二极管。
关键词:红色发光二极管;超声波测距;温度补偿;温度传感器;电磁干扰目录摘要 (Ⅰ)第1章绪论 (1)1.1 概述 (1)1.2 系统软硬件的调试 (1)第2章系统设计原理 (2)2.1 系统主要硬件结构 (2)2.2 单片机主机系统介绍 (2)2.2.1 单片机控制模块 (2)2.2.2 温度数据采集模块 (2)2.2.3 主件LCD1602C的结构 (3)2.3 超声波测距的设备 (4)2.3.1 超声波测距系统的硬件电路设计 (4)2.3.2 超声波发射电路 (4)2.3.3 超声波检测接收电路 (5)第3章系统的软件设计 (6)3.1 语言的选用 (6)3.2 系统控制流程 (7)3.3 程序设计流程图 (10)3.4 超声波测距仪的算法设计 (12)3.5 超声波发生子程序和接收中断程序 (12)3.6 电路仿真 (12)第4章安装调试 (13)第5章电路特点和误差分析 (14)结论 (15)参考文献 (16)附录 (17)致谢 (24)第1章绪论1.1 概述制作超声波测距系统,并外加温度补偿使测距更精确。
前期制作超声波发送与接收电路,经过调试正常可用后,编写相应的超声波程序,完成对于整个测距系统的控制。
51单片机超声波测距离(带温度补偿)

超声波模块原理图:发射接收原理图PCB:51单片机原理图:软件部分C语言程序:/*=========================================================== =========调试要求:1.MCU:A T89S52芯片或AT89C522.晶振:12MHz调试注意:本程序带温度补偿,采用DS18B20测量温度1.LCD1602液晶屏有显示后,才接入超声波模块。
2.注意超声波模块电源的极性。
不清楚请参好淘宝的电路图3.没有选用频率为12MHz晶振,用了别的频率晶振,单片机定时器的测量值与发出的40KHz频率脉冲不对。
4.使用者经常误发出20KHZ脉冲当40KHZ脉冲。
(40KHz频率脉冲,周期25us,占空比为50% = 12.5us)5.如果是用开发板调超声波模块,请检查开发板上的电路是否与超声波模块的控制脚复用了, 若复用了,请通过跳线分开发板上的电路。
6如果使用的是万用板,请确定单片机的复位电路和晶振电路是否正常,同时单片机的31脚(EA)记得接高电平。
============================================================= =======*/#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//===============================LCD1602接口定义=====================/*-----------------------------------------------------|DB0-----P2.0 | DB4-----P2.4 | RW-------P0.1 ||DB1-----P2.1 | DB5-----P2.5 | RS-------P0.2 ||DB2-----P2.2 | DB6-----P2.6 | E--------P0.0 ||DB3-----P2.3 | DB7-----P2.7 | 注意,P0.0到P0.2需要接上拉电阻---------------------------------------------------============================================================= */#define LCM_Data P2 //数据接口#define Busy 0x80 //用于检测LCM状态字中的Busy标识sbit LCM_RW = P0^1; //读写控制输入端,LCD1602的第五脚sbit LCM_RS = P0^2; //寄存器选择输入端,LCD1602的第四脚sbit LCM_E = P0^0; //使能信号输入端,LCD1602的第6脚//===============================超声波模块定义========================sbit RemPin =P3^2;// 接收端(这个不能修改,因为是外部中断(INT0)的引脚) sbit TxPin =P3^1;// 发射端//******************************************************************** ***//ds18b20数字温度传感器控制引脚定义sbit dq_ds18b20=P3^3;//定义控制DS18B20//******************************************************************** ***//LCD显示模块的函数声明void WriteDataLCM (uchar WDLCM);//LCD模块写数据void WriteCommandLCM (uchar WCLCM,BuysC); //LCD模块写指令uchar ReadDataLCM (void);//LCD模块读数据uchar ReadStatusLCM (void);//读LCD模块的忙标void DisplayOneChar (uchar X,uchar Y,uchar ASCII);//在第X+1行的第Y+1位置显示一个字符void DisplayListChar (uchar X,uchar Y,uchar delayms,uchar code *DData); void DisplayCursorPos (uchar X, uchar Y);void LCMInit (void);void DisplayIntData (uchar X, uchar Y,int ZhengShu,uchar Digit,uchar XiaoShu);void DisplayCharData (uchar X, uchar Y,uchar ZiFu);//******************************************************************** **//延时函数声明void delay25us_40KHz(unsigned char us);void DelayUs(uint us);void DelayMs(uint Ms);void delay_3us();//3US的延时程序void delay_8us(unsigned int t);//8US延时基准程序void delay_50us(unsigned int t);//延时50*T微妙函数的声明//******************************************************************** ***//DS18B20测温函数定义void w_1byte_ds18b20(uchar value);//向DS18B20写一个字节uchar r_1byte_ds18b20(void);//从DS18B20读取一个字节的数据void rest_ds18b20(void);//DS18B20复位程序void readtemp_ds18b20(void);//读取温度void display_temp(void);//温度显示程序//******************************************************************** ***//参数定义uint length = 0; // 测距的长度0.00Muchar flag = 0; // 测距的标志有信号接收=1uchar templ,temph;uint speed;//根据温度计算出来的声音速度uchar t_b,t_s,t_g,t_x;//从左到右分别存储温度百位,十位,个位,小数位uchar flag1;//温度正负性暂存,1为正数,0为负数const unsigned char tabl3[]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x0 8,0x09,0x09};/*=========================================================== ================主程序============================================================= ================*/void main(void){uchar i;LCMInit(); //1602初始化EX0 = 1; //允许总中断中断,使能INT0 外部中断ET0 = 1;TMOD=0x11; //设定T0为16位时器,设定T1为16位时器DisplayOneChar( 0,14,'m');DisplayListChar(0,0,0, "Distanc: "); //显示字符串while(1){readtemp_ds18b20();display_temp();//显示温度for(i=0;i<20;i++){DisplayIntData(0, 13,length,5,3);//显示测量距离TH0=0x00;TL0=0x00;TR0=1; //启动定时器0EA = 1; //允许所有中断delay25us_40KHz(15); //发出脉冲信号DelayMs(200);}}}//******************************************************************** ***********//温度显示函数void display_temp(){if(flag1==1)//温度为正数时的显示程序{DisplayOneChar( 1,2,'+');}else{DisplayOneChar( 1,2,'-');}//显示温度信息DisplayOneChar( 1,0,'T');DisplayOneChar( 1,1,':');DisplayOneChar( 1,3,t_s+0x30);DisplayOneChar( 1,4,t_g+0x30);DisplayOneChar( 1,5,'.');DisplayOneChar( 1,6,t_x+0x30);//显示速度信息DisplayOneChar( 1,8,'S');DisplayOneChar( 1,9,':');DisplayOneChar( 1,10,speed/100%10+0x30);DisplayOneChar( 1,11,speed/10%10+0x30);DisplayOneChar( 1,12,speed%10+0x30);DisplayOneChar( 1,13,'M');DisplayOneChar( 1,14,'/');DisplayOneChar( 1,15,'S');}//****************************************************//读取温度void readtemp_ds18b20(void){uchar temp32;rest_ds18b20();w_1byte_ds18b20(0xcc); //跳过读序列号的操作w_1byte_ds18b20(0x44); //启动温度转换delay_8us(2);rest_ds18b20();w_1byte_ds18b20(0xcc); //跳过读序列号的操作w_1byte_ds18b20(0xbe); //读取温度寄存器等(共可读9个寄存器)前两个就是温度templ=r_1byte_ds18b20();temph=r_1byte_ds18b20();if((temph&0xf0))//判断温度的正负性{flag1=0;temph=-temph;templ=-templ;t_x=tabl3[templ & 0x0f];//计算温度的小数temp32=temph & 0x0f;temp32<<=4;templ>>=4;temp32=temp32 | templ;t_b=temp32/100%10;//计算温度的百位数据t_s=temp32/10%10;//计算温度的十位数据t_g=temp32%10;//计算温度的个位数据speed=331.4-0.607*(temp32 | templ);}else//为正数{t_x=tabl3[templ & 0x0f];//计算温度的小数temp32=temph & 0x0f;temp32<<=4;templ>>=4;temp32=temp32 | templ;t_b=temp32/100%10;//计算温度的百位数据t_s=temp32/10%10;//计算温度的十位数据t_g=temp32%10;//计算温度的个位数据flag1=1;speed=311.4+0.607*(temp32 | templ);}}/*=========================================================== =========功能:在1602显示一个整数数据说明:显示一个整数数据-9999->32625. 从右至左显示数据5位:============================================================= =========*/void DisplayIntData(uchar X, uchar Y,int ZhengShu,uchar Digit,uchar XiaoShu) {uchar i=0,k=0, BCD[5]={0};if(Digit>5) Digit=5;if(ZhengShu<0){k=1;//负数示志位ZhengShu=-ZhengShu;}BCD[4] =ZhengShu / 10000; //求出万位数据ZhengShu = ZhengShu % 10000;BCD[3] =ZhengShu / 1000; //求出千位数据ZhengShu = ZhengShu % 1000;BCD[2] =ZhengShu / 100; //求出百位数据ZhengShu = ZhengShu % 100;BCD[1] =ZhengShu / 10; //求出十位数据BCD[0] =ZhengShu % 10; //求出个位数据for(i=0;i<Digit;i++)//输出显示的数值{if((i==XiaoShu)&&(0!=XiaoShu)){DisplayOneChar(X,Y-i,'.');//输出小数点Y= Y-1;}DisplayOneChar(X,Y-i,BCD[i]+0x30); //显示一个字符}if(k==1)DisplayOneChar(X,Y-1,'-');//输出负符}//****************************************************************//读一个字节uchar r_1byte_ds18b20(void){uchar i=0;uchar value= 0;for (i=0;i<8;i++){value>>=1;dq_ds18b20=0;// DQ_L;delay_3us();dq_ds18b20=1; //DQ_H;delay_8us(2);if(dq_ds18b20==1) value|=0x80;delay_8us(6); //延时40us}dq_ds18b20=1;return value;}//******************************************************************** ***********//子程序功能:向DS18B20写一字节的数据void w_1byte_ds18b20(uchar value){uchar i=0;for(i=0;i<8;i++){dq_ds18b20=1;delay_3us();dq_ds18b20=0;delay_8us(2);if (value& 0x01) dq_ds18b20=1; //DQ = 1delay_50us(1); //延时50us 以上delay_8us(2);value>>=1;}dq_ds18b20=1; //DQ = 1}//;**************************************************//ds18b20复位子程序void rest_ds18b20(void){rest:delay_3us(); //稍做延时delay_3us();dq_ds18b20=1;delay_3us();dq_ds18b20=0;// DQ_L;delay_50us(11);//480us<T<960usdq_ds18b20=1;//拉高总线delay_8us(5);if(dq_ds18b20==1){return;}delay_50us(2); //延时90usif(dq_ds18b20==1){return;}else{goto rest;}}//==============================超声波模块测试子程序================================================/*=========================================================== =========注意:是用12MHz晶振设定延时时间:x*25us 与产生40KHZ的脉冲============================================================= =======*/void delay25us_40KHz(unsigned char us){while(us--){TxPin = 0;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();TxPin = 1;_nop_();_nop_();_nop_();_nop_();}TxPin = 1;}/*=========================================================== ==================中断程序的入口(注意:接收与发射的电平是相反的)============================================================= ==================*/void init0int() interrupt 0{uint timer_us = 0;TR0=0; //关闭定时器0timer_us =TH0*256+TL0;if(timer_us>190)timer_us=timer_us-180; //修正测距的距离if(timer_us<=735){timer_us=timer_us-96;//二次修正}if(timer_us>5059){timer_us+=29;}if(timer_us>5470){timer_us+=29;}if(timer_us>6410){timer_us+=29;}if(timer_us>7410){timer_us+=29;}if(timer_us>8410){timer_us+=29;}if(timer_us>9410){timer_us+=29;}if(timer_us>10410){timer_us+=29;}length = ((unsigned long)(speed)*timer_us)/2000;//计算长度,是扩大100倍flag = 0;EA = 0; //禁止所有中断}/*=========================================================== =========功能:在1602显示一个字符数据说明:显示一个字符数据0~256. 从左至右显示数据3位============================================================= =========*/void DisplayCharData(uchar X, uchar Y,uchar ZiFu){uchar i=0;uchar V alueBCD[3];V alueBCD[0] = ZiFu / 100; //求出百位数据ZiFu = ZiFu % 100;V alueBCD[1] = ZiFu / 10; //求出十位数据V alueBCD[2] = ZiFu % 10; //求出个位数据for(i=0;i<3;i++)//输出显示的数值{DisplayOneChar(X,Y+i,V alueBCD[i]+0x30); //显示一个字符}}/*=========================================================== ================超出测量时间============================================================= ================*/void timer0int (void) interrupt 1{TR0=0; //关闭定时器0length = 0; //超出测量时间显示示0flag = 1; //EA = 0; //禁止所有中断}/*=========================================================== ===========LCM初始化============================================================= =========*/void LCMInit(void){LCM_Data = 0;WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号DelayMs(5);WriteCommandLCM(0x38,0);DelayMs(5);WriteCommandLCM(0x38,0);DelayMs(5);WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号WriteCommandLCM(0x08,1); //关闭显示WriteCommandLCM(0x01,1); //显示清屏WriteCommandLCM(0x06,1); // 显示光标移动设置WriteCommandLCM(0x0C,1); // 显示开及光标设置DelayMs(100);}/*=========================================================== =========显示光标的位置============================================================= =======*/void DisplayCursorPos( unsigned char X, unsigned char Y){X &= 0x1;Y &= 0xF; //限制Y不能大于15,X不能大于1if (X) Y |= 0x40; //当要显示第二行时地址码+0x40;Y |= 0x80; // 算出指令码WriteCommandLCM(Y, 1); //这里不检测忙信号,发送地址码}/*=========================================================== =========按指定位置显示一串字符:第X 行,第y列注意:字符串不能长于16个字符============================================================= =========*/void DisplayListChar(uchar X,uchar Y,uchar delayms, uchar code *DData){unsigned char ListLength;ListLength = 0;X &= 0x1;Y &= 0xF; //限制X不能大于15,Y不能大于1while (DData[ListLength]!='\0') //若到达字串尾则退出{if (Y <= 0xF) //X坐标应小于0xF{DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符ListLength++;Y++;DelayMs(delayms);//延时显示字符串}elsebreak;//跳出循环体}}/*=========================================================== =========设定延时时间:x*1us============================================================= =======*/void DelayUs(uint us){while(us--);}/*=========================================================== =========设定延时时间:x*1ms============================================================= =======*/void DelayMs(uint Ms){uint i,TempCyc;for(i=0;i<Ms;i++){TempCyc = 250;while(TempCyc--);}}//==============================LCD1602显示子程序================================================/*=========================================================== ==========写数据函数: E =高脉冲RS=1 RW=0============================================================= =========*/void WriteDataLCM(unsigned char WDLCM){ReadStatusLCM(); //检测忙LCM_Data = WDLCM;LCM_RS = 1;LCM_RW = 0;LCM_E = 0; //若晶振速度太高可以在这后加小的延时LCM_E = 0; //延时LCM_E = 1;}/*=========================================================== =========写指令函数: E=高脉冲RS=0 RW=0============================================================= =========*/void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测{if (BuysC) ReadStatusLCM(); //根据需要检测忙LCM_Data = WCLCM;LCM_RS = 0;LCM_RW = 0;LCM_E = 0;LCM_E = 0;LCM_E = 1;}/*=========================================================== =========//读数据============================================================= =========*/unsigned char ReadDataLCM(void){LCM_RS = 1;LCM_RW = 1;LCM_E = 0;LCM_E = 0;LCM_E = 1;return(LCM_Data);}/*=========================================================== =========正常读写操作之前必须检测LCD控制器状态:E=1 RS=0 RW=1;DB7: 0 LCD控制器空闲,1 LCD控制器忙。
具有温度补偿功能的超声波测距系统设计

1 引 言
2 超 声 波测 距 系统 原 理
超 声 波 测 距 与红 外 线 、激 光 测 距 相 比 ,其 对 外 界 电磁
超 声 波测距 系统 如 图 1所 示 。硬 件 主 要 有 :超 声 波 发
场 、光 线及 色彩 敏感 度低 ,更 适 于 电磁 干扰 强 、有 毒 、黑 暗 、 射电路 、超声 波接 收 电路 、温度 检测 电路 、AT89C51单 片机
Abstract: In order to overcom e the error of environm ent tem perature fluctuation caused by the ultrasonic ranging system ,this paper uses the tem perature sensor DS18B20 to acquire tem perature data in tim e.W hen the tem perature in the environm ent changes,the tem perature sensor DS1 8B20 extracts tem perature and corrects the tem perature using the com puter tim ely according to the c0rresponding relationship betw een the value of the tem perature and ultrasonic w ave to correct the change of tem perature caused by the error produced by the ultrasonic ranging system .The system takes single chip AT89C5 1 as the core,and designs temperature acquisition,ultrasonic transm ission and reception and other hardware circuits and softw are parts.T he test show s that the system can effectively avoid the errors caused by the change of the tem perature in the ranging system w ith the m easurem ent accuracy up to 1 . Keywords: ultrasonic ranging; tem perature com pensation;A T89C5 1; DS1 8B20
带温度补偿超声波测距系统设计

南通大学传感器与检测课程设计(预习)报告项目:带温度补偿的超声波测距系统设计班级:姓名:学号:联系方式:学期:2015-2016-2前言 (3)一.课题调研 (3)1.1传感器选型 (3)1.1.1可选温度传感器 DS18B20 (3)1.1.2可选用AD590温度传感器 (4)1.2超声波传感器 (5)1.2.2选用MAX232芯片做发射电路 (7)1.2.3超声波发射电路 (8)1.2.4超声波接收电路 (10)1.2.5选用TL074芯片作为接受电路 (11)1.3多种实现方法。
(12)1.3.1方法一:系统结构框图 (12)1.3.2工作原理 (12)1.3.3方案二:系统结构图如下。
(13)二.总体设计 (14)2.1电路图 (14)2.1.1超声波模块电路 (14)2.2.1主程序设计。
(19)前言以AT89S51单片机为核心,设计了一种带温度补偿的超声波测距系统。
系统包括单片机、超声波发射及接收模块、温度补偿模块、信息显示模块。
温度补偿模块采用温度传感器DS18B20 采集环境温度,根据超声波速度与温度值的对应关系及时修正波速,以纠正温度的变化引起超声波测距系统产生的误差。
一.课题调研1.1传感器选型集成传感器是采用硅半导体集成工艺而制成的,因此亦称硅传感器或单片集成温度传感器,它是将温度传感器集成在一个芯片上、可完成温度测量及模拟信号输出功能的专用IC。
模拟集成温度传感器的主要特点是功能单一(仅测量温度)、测温误差小、价格低、响应速度快、传输距离远、体积小、微功耗等,适合远距离测温、控温,不需要进行非线性校准,外围电路简单。
1.1.1可选温度传感器DS18B20由于声音的速度在不同的温度下有所不同,因此为提高精度,应通过温度补偿对超声波的传播速度进行校正。
系统采用DS18B20传感器测量温度,DS18B20 温度传感器具有不受外界干扰、精度高、测温范围宽等优点。
单片机口接DS18B20 数据总线,控制DS18B20 进行温度转换和传输数据,数据总线接10 kΩ的上拉电阻,作用是使总线控制器在温度转换期间无需一直保持高电平。
超声波测距系统中的温度补偿

机在通过单总线接口访问 DS18B20 时 , 其工作流程必 需要遵守严格的操作时序 , 如果顺序中任意一步缺少 [ 6, 7 ] 或顺序错乱 , DS18B20 将不会响应 。DS18B20 的操 作顺序是 : 第一步 : 对 DS18B20 初始化 ; 第二步 : 发送 ROM 命令 ; 第三步 : 发送功能命令 。超声波测距系统 上电后 ,单片机开始初始化 DS18B20, 检测现场温度 , 软件控制 DS18B20 的具体流程如图 4 所示 。
- 30 313 - 20 319 - 10 325 0 323 10 338 20 344 30 349 100 386
收稿日期 : 2008 - 07 - 16; 修回日期 : 2008 - 09 - 10 3 基金项目 : 天津市应用基础与前沿技术计划 ( 07JCZDJC09300) ; 天津市教委科技发展基金 ( 2006BA12) 作者简介 : 赵小强 ( 1983 —) ,男 ,天津人 ,天津理工大学学生 ,硕士研究生 ,研究方向为检测与控制技术 , ( E - mail) zhaoxiaoqiang1983@163. com。
图 3 硬件结构
・6 3 ・
・ 控制与检测 ・
312 软件设计 DS18B20 对时序和电性参数要求很高 , 所以单片
tmpw ritebyte ( 0xcc) ; tmpw ritebyte (0x44) ;
具有温度补偿功能的超声波测距系统设计

具有温度补偿功能的超声波测距系统设计超声波测距系统运行过程中,环境温度会对测距系统的测量精度造成较大影响,为了降低环境温度波动对超声波测距系统精确度的影响,需要在测距系统中增加温度补偿系统。
在具有温度补偿功能的超声波测距系统设计中,本文以单片机为控制核心,并使用温度传感器进行环境温度测量,从而实现在不同环境温度下的超声波波速确定,提高测量精度。
标签:温度补偿;超声波测距系统;单片机0 引言相较于其他测距方式,超声波测距具有更高的电磁抗干扰能力,并且对空气质量和环境光照强度要求更低,另外由于超声波测距属于非接触测距技术,用途更加广泛,同时超声波测距系统可靠性更高,制造运行所需的成本更低,当前已经取得广泛使用。
但是超声波对温度较为敏感,通过研究发现,当环境温度升高1℃时,声速下降0.607m/s。
1 超声波测距系统工作原理超声波测距系统工作过程中,由超声波发射系统发出超声波,由接收系统接收反射回的超声波,当超声波发出后,测距系统中的计数器开始同步工作,当接收器接收到第一个反射信号后,计时停止,通过当前环境温度下的声速与计时时间的相乘计算即可实现距离测量。
而要确定不同环境温度下的声速,可以通过以下公式确定声速:在超声波测距系统设计中,可以将声速公式代入到距离计算公式中,则可通过环境温度和计时时间确定距离。
在具有温度补偿功能的超声波测距系统设计中,在超声波测距系统中加入温度传感器,并将测得的环境温度传入单片机,由单片机中的程序进行距离计算,通过显示屏进行距离显示,在系统运行中,由于充分考虑了环境温度因素,所以可以极大提升超声波测距系统的精确度[1]。
2 具有温度补偿功能的超声波测距系统设计2.1 温度补偿系统设计温度补偿系统中最重要的就是温度传感器选取和与系统的连接,需要保证温度传感器有较高的灵敏度和较强的抗干扰能力,在完成温度测量后,将测量值输入单片机中,由相关程序进行距离计算。
本文选取了DS18B20温度传感器,传感器结构为两条数据总线,这两条总线能够实现温度转换和数据传输功能,在温度传感器运行过程中,可以将数据总线直接与单片机进行连接,将测量到的数据输入单片机中,在该过程中不需进行A/D转换,并且另一条数据线用于传输温度转换指令和读写指令。
基于温度补偿功能的超声波测距系统设计

基于温度补偿功能的超声波测距系统设计【摘要】设计了一款基于单片机的带有温度补偿功能的高精度超声波测距仪,利用超声波反射特性对障碍物进行测距。
由STC12C5206AD单片机、发送模块、接收模块、温度补偿模块、时钟模块、电源模块和显示模块等7部分组成。
实验结果表明该测距仪性能可靠,测量精度较高。
【关键词】超声波;测距;传感器;温度补偿目前,非接触式测距仪采用超声波、激光和雷达。
但激光和雷达的难度大、成本高,不利于普及应用,在某些应用领域有其局限性,相比之下,超声波方法具有明显的优势,因此超声波方法作为非接触监测和识别的手段,已经越来越引起人们的重视。
超声波是一种频率大于20kHz具有方向性好、指向性强、传播能量大、遇到杂质或界面会产生反射波等特点的机械波。
在机器人避障、导航系统、机械加工自动化装配及检测、自动测距、无损检测、超声定位、汽车倒车、工业测井、水库液位测量等方面已经有了广泛的应用[1]。
一、超声波测距原理当要计算某物体通过的一段路程时,只要知道物体运动的速度和所经历的时间,就可以计算它通过的路程。
利用超声波测距的方法有多种,如渡越时间检测法、相位检测法和声波幅值检测法。
相比较而言,渡越时间检测法测量时间和精度都较高,并且电路设计不复杂,因此本设计采用渡越时间检测法。
图1 超声波测距原理图超声波测距的原理如图1所示。
超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。
根据接收器接到超声波时的时间差就可以计算出距被测物体的距离:d=s/2=(V×t)/2[2] ①其中d为被测物体到测距仪之间的距离,s为超声波往返通过的路程,V为超声波在介质中的传播速度。
T为超声波从发射到接收所用的时间。
超声波的传播主要受空气密度的影响,空气密度越高其速度越快,而空气密度和温度有着密切的关系。
表1为超声波在不同温度下的波速值。
带温度补偿的360_超声波测距测速系统设计

收稿日期: 2010-04-15基金项目: 梅州市科学技术局、嘉应学院联合自然科学研究重点基金资助项目( 2009KJZ04 ) ; 梅州市科技计划重点基金资助项目( 2009A21)作者简介: 朱向庆( 1979- ) , 男, 广东梅州人, 讲师, 硕士, 主要研究方向为短距离无线通信、检测技术与自动化装置。
陈志雄( 1980-) , 男, 广东梅州人, 实验师, 硕士, 主要研究方向为嵌入式系统、数据挖掘。
文章编号: 1004- 2474( 2011) 02-0315- 05带温度补偿的360b超声波测距测速系统设计朱向庆, 陈志雄( 嘉应学院电子信息工程学院, 广东梅州514015)摘要: 采用ST C12C5A60S2 单片机控制超声波测距模块和减速步进电机, 利用超声波的反射特性进行360b范围的距离测量, 结合温度补偿算法计算系统到被测物体的距离和相对速度。
系统使用nRF24L01 无线通信芯片将测得的数据传输给计算机, 在计算机中用Visual Basic 编写的终端监控程序进行数据处理和图像显示, 并控制系统的旋转角度、测量频率和测量范围。
关键词: 超声波测距; 超声波测速; STC12C5A60S2; nRF24L01中图分类号: T N914; T P274 文献标识码: ADesign of 360b Ultrasonic Ranging and VelocityDetecting System with Temperature CompensationZHU Xiangqing, CHEN Zhixiong( S chool of Elect ronic and Inf ormat ion E ngineering, Jiaying U niver sit y, Meizhou 514015, China)Abstract: Single chip micr ocomput er ST C12C5A60S2 was used to contro l ultr aso nic distance measurementmodule and gear stepping mo tor in this paper. The reflection char act er istics of ultrasonic w ave w as used to measur edistance in the range of 360b; the distance and relative velo city between the system and measur ed object was calculatedwith tem per at ur e compensatio n method. At the same time, w ireless communication chip nRF24L01 w as used totransfer measur ed data to com puter. Visual Basic w as used to process data and display image in term ina l monito ringpr og ram, so as t o contro l the r otatio n ang le, measuring frequency and measuring range o f sy stem.Key words: ultrasonic r ang ing; ultr aso nic velo city detecting; STC12C5A60S2; nRF24L010 引言超声波是频率高于20 kHz 的声波, 其波长短,方向性好, 穿透能力强, 易于获得较集中的声能, 在水中传播距离远。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/**程序:基于HC-SR04得超声波测距系统*单片机型号:STC90C51612MHz*说明:开始连续进行7次超声波测距,每次测距间隔80ms,*完成后对7次结果排序并将最大得2个数值与最小得2个数值去除,对剩余得*3个数值取平均值。
完成后指示灯灭,输出结果到LCD1602上。
测量超出范围则发出报警声、*使用两个IO端口控制HC-SR04触发信号输入与回响信号输出,*以及一个T0定时器用于时间计数。
* 使用DS18B20测量环境温度,声速公式:V=334。
1m/s+Temperature*0、61,*单片机晶振为12Mhz(11、953M),计数时为T=1us*计算公式:S=(334。
1m/s+Temperature*0。
61)*N*T/2,N为计数值=TH0*256+TL0*/ /*包含头文件*/#include 〈reg51。
h>#include 〈intrins。
h>#define Delay4us(){_nop_();_nop_();_nop_();_nop_();}/*宏定义*/#define uchar unsignedcharﻩ//无符号8位#define uintﻩunsigned int//无符号16位#define ulongunsigned long ﻩ//无符号32位/*全局变量定义*/sbit BEEP=P1^5;ﻩﻩ//报警测量超出范围sbit Trig=P3^4; //HC-SR04触发信号输入sbitEcho=P3^2;ﻩ//HC—SR04回响信号输出float xdataDistanceValue=0。
0;ﻩ//测量得距离值float xdata SPEEDSOUND; ﻩﻩ//声速float xdataXTALTIME; ﻩ//单片机计数周期uchar xdata stringBuf[6];ﻩﻩ//数值转字符串缓冲//LCD1602提示信息uchar codePrompts[][16]={ﻩ{"Measure Distance"}, //测量距离{"-Out of Range -"}, //超出测量范围ﻩ{"MAX range400cm "}, //测距最大值400cm{”MIN range 2cm"},ﻩ//测距最小值2cm{”"},ﻩ//清屏};uchar xdata DistanceText[]="Range: ";//测量结果字符串uchar xdata TemperatureText[]="Temperature:";//测量温度值/*外部函数声明*/extern voidLCD_Initialize(); //LCD初始化extern void LCD_Display_String(uchar*, uchar);externvoid ReadTemperatureFromDS18B20();extern int xdataCurTempInteger;void DelayMS(uint ms);ﻩ//毫秒延时函数voidDelay20us(); //20微秒延时函数voidHCSR04_Initialize();//HCSR04初始化float MeasuringDistance();ﻩ//测量距离float DistanceStatistics();ﻩ//测距得数值排序求平均void DisplayDistanceValue(float dat); //输出距离值到LCD1602上uchar UnsigedIntToString(uintvalue);ﻩ//将无符号得整数转成字符串,返回字符串长度,不包括'\0'结束符void Beep(uchar time); //蜂鸣器void DisplayTemperatureValue(); //显示温度值/***测量距离***/floatMeasuringDistance(){//最大定时时间约65msTH0=0;TL0=0;//生成20us得脉冲宽度得触发信号Trig=1; ﻩﻩﻩDelay20us();ﻩTrig=0;while(!Echo);//等待回响信号变高电平ﻩTR0=1; ﻩ//启动定时器0while(Echo);//等待回响信号变低电平ﻩTR0=0; //关闭定时器0return(SPEEDSOUND*XTALTIME*((float)TH0*256+(float)TL0))/2000; //返回距离值(mm)}/***HCSR04初始化***/void HCSR04_Initialize(){ﻩXTALTIME=12/12;ﻩﻩ//计算单片机计数周期晶振=12M 单位usﻩSPEEDSOUND=334。
1+25*0、61;ﻩ//温度25度时声速得值ﻩﻩﻩTrig=0;Echo=0;TMOD=0x01;}/***输出距离值到LCD1602上***/void DisplayDistanceValue(floatdat){uchari=0,j=0,len;ﻩuint value;value=(uint)dat;//范围检查大于4000mm与小于20mm都为超出测量范围if(value〉4000)ﻩ{ﻩLCD_Display_String(Prompts[1],0x00);LCD_Display_String(Prompts[2],0x40);Beep(2);ﻩ}ﻩelse if(value<20)ﻩ{ﻩLCD_Display_String(Prompts[1],0x00);ﻩﻩLCD_Display_String(Prompts[3],0x40);Beep(2);}ﻩelse{len=UnsigedIntToString(value); //将数值转换成字符串//保留1位小数ﻩwhile(stringBuf[i]!='\0')ﻩ{ﻩﻩif(len—j==1)ﻩﻩ{ﻩﻩﻩDistanceText[6+j]='、';ﻩﻩj++;ﻩ}elseﻩﻩ{ﻩDistanceText[6+j]=stringBuf[i];ﻩi++;ﻩﻩj++;ﻩﻩ}ﻩ}ﻩDistanceText[6+j]='c';ﻩj++;ﻩﻩDistanceText[6+j]=’m’;ﻩi=7+j;ﻩﻩ//剩余位置补空格ﻩwhile(i<16)ﻩﻩ{ﻩﻩDistanceText[i]=' ';ﻩi++;ﻩ}LCD_Display_String(DistanceText,0x40);//LCD_Display_String(Prompts[0],0x00); ﻩ}}/***显示温度值***/void DisplayTemperatureValue(){TemperatureText[13]=CurTempInteger/10+'0';TemperatureText[14]=CurTempInteger%10+'0';TemperatureText[15]='C';LCD_Display_String(TemperatureText,0x00);ﻩ}/***将无符号得整数转成字符串,返回字符串长度***/ucharUnsigedIntToString(uint value){uchar i=0,t,length;//从个位开始转换do{stringBuf[i]='0'+value%10; ﻩﻩvalue=value/10;ﻩi++;ﻩ}while(value!=0);length=i;ﻩ//将字符串颠倒顺序for(i=0;i<(length/2);i++)ﻩ{ﻩt=stringBuf[i];ﻩstringBuf[i]=stringBuf[length—i-1]; ﻩstringBuf[length-i-1]=t;ﻩ}ﻩstringBuf[length]='\0’;ﻩreturn length;}/***蜂鸣器***/void Beep(uchar time){ﻩuchar i;for(i=0;i〈100;i++)ﻩ{ﻩBEEP=!BEEP;ﻩDelayMS(time);ﻩﻩ}BEEP=0;DelayMS(100);}/***延时函数毫秒@12、000MHz***/ void DelayMS(uint ms){ﻩuchar i, j;while(ms—-){ﻩ_nop_();ﻩﻩi=2;j=239;doﻩﻩ{while(—-j);ﻩﻩ}while (--i);ﻩ}}/***延时函数20微秒12、000MHz***/ void Delay20us(){uchar i;_nop_();ﻩi=7;while (--i);}/***定时器0中断***/void Timer0() interrupt 1{}//DS18B20代码:/*—------—-——-------——--—----—---——-———--—--—--—*程序功能: DS18B20温度检测程序*单片机型号:STC89C5212MHz* 晶振: 12Mhz-—----—--—-——-—--—-——--—------—-------—-------——*//*包含头文件*/#include<reg51。
h>#include<intrins、h〉/*宏定义*/#defineucharﻩunsigned char ﻩ//无符号8位#define uintﻩunsigned int//无符号16位sbit DS18B20_DQ =P3^3;ﻩ//定义DS18B20端口DS18B20_DQint xdata CurTempInteger; //当前采集得温度值整数部分int xdata CurTempDecimal;//当前采集得温度值小数部分/***功能:延时函数STC89C52 12MHz12T模式参数:无返回:无***/void Delayus(uintcount) ﻩ{ﻩwhile (--count);}/***功能:DS18B20复位及状态检测参数:无返回:0或1,1表示未准备好,0表示准备好***/ uchar Reset_DS18B20(){ﻩuchar status;ﻩDS18B20_DQ=1;ﻩDelayus(1);//开始复位过程DS18B20_DQ=0;ﻩ//数据线拉低ﻩDelayus(100); //延时480us-960usﻩDS18B20_DQ=1; ﻩ//数据线拉高ﻩDelayus(10); ﻩ//延时15us-60usstatus=DS18B20_DQ;ﻩ//读取数据线上得状态ﻩDelayus(120);ﻩreturn status;}/***功能:写一字节到DS18B20中参数:dat=数据返回:无***/void WriteByteToDS18B20(uchar dat){ﻩuchar i;for(i=0;i〈8;i++)ﻩ{ﻩﻩDS18B20_DQ=0;ﻩDS18B20_DQ=dat&0x01;ﻩ//发送1位数据ﻩDelayus(15);ﻩﻩﻩ//延时60us以上DS18B20_DQ=1;ﻩﻩﻩ//释放总线,等待总线恢复ﻩdat〉〉=1;ﻩﻩﻩ//准备下一位数据ﻩ}}/***功能:从DS18B20中读一字节参数:无返回:读取得数据***/uchar ReadByteFromDS18B20(){ﻩuchar i,dat=0;ﻩfor(i=0;i<8;i++)ﻩ{ﻩDS18B20_DQ=0; //拉低总线,产生读信号ﻩdat>>=1;ﻩDS18B20_DQ=1;ﻩ//释放总线,准备读1位数据ﻩﻩﻩDelayus(2);ﻩﻩ//延时4usﻩif(DS18B20_DQ) dat|=0x80;ﻩ//合并每位数据ﻩDelayus(15); ﻩﻩ//延时60usDS18B20_DQ=1;ﻩﻩ//拉高总线,准备读下1位数据ﻩ}ﻩreturndat;}/***功能:读取温度值并转换成有符号得数值形式参数:无返回:无***/ void ReadTemperatureFromDS18B20(){ucharflag=0;//正负符号标志ﻩ//存储当前采集得温度值ﻩucharTempValue[]={0,0};ﻩif(Reset_DS18B20())ﻩ//DS18B20复位{CurTempInteger=255;ﻩCurTempDecimal=0;}ﻩelseﻩ{ﻩWriteByteToDS18B20(0xCC);//跳过ROM命令WriteByteToDS18B20(0x44);//温度转换命令ﻩReset_DS18B20();//复位ﻩWriteByteToDS18B20(0xCC);//跳过ROM命令ﻩWriteByteToDS18B20(0xBE);//读取温度暂存器命令ﻩTempValue[0]=ReadByteFromDS18B20();//先读低字节温度值ﻩﻩTempValue[1]=ReadByteFromDS18B20();//后读高字节温度值ﻩReset_DS18B20();//复位ﻩ//计算温度值:先进行正温度与负温度判断,高5位全为1(0xF8)则为负数ﻩif((TempValue[1]&0xF8)==0xF8)ﻩ{ﻩ//负温度计算:取反加1,低字节为0时,高字节取反加1,否则不需要。