基于51单片机的HC-SR04超声波测距系统制作_第1页
基于51单片机的HC-SR04超声波测距系统制作_第2页
基于51单片机的HC-SR04超声波测距系统制作_第3页
基于51单片机的HC-SR04超声波测距系统制作_第4页
基于51单片机的HC-SR04超声波测距系统制作_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于51单片机带温度补偿的HC-SR04超声波测距系统利用从网上购买的HC-SR04超声波模块制作了一个测距装置,HC-SR04自身不带温度补偿功能,所以加上一个使用DS18B20做的温度测量模块。整个系统包括:51单片机最小系统,超声波测距模块、温度测量模块、液晶显示模块。使用了如下主要元器件:元件说明数量STC90C516RC51单片机1HC-SR04超声波测距模块1DS18B20温度测量模块1lcd1602液晶显示模块1系统电路图51单片机最小系统单片机型号:STC90C516,晶振:12Mhz。自己动手焊接的最小系统板。LCD1602A液晶显示模块:#defineDelay4us(){_nop_();_nop_();_nop_();_nop_();}/*宏定义*/#defineuchar unsignedchar //无符号8位#defineuint unsignedint //无符号16位#defineulong unsignedlong //无符号32位/*全局变量定义*/sbitK1=P1^0; //按下K1后,开始测距sbitLEDRed=P1^1; //测距指示灯,亮表示正在测距,灭表示测距完成sbitBEEP=P1^5; //报警测量超出范围sbitTrig=P1^7; //HC-SR04触发信号输入sbitEcho=P1^6; //HC-SR04回响信号输出floatxdataDistanceValue=0.0; //测量的距离值floatxdataSPEEDSOUND; //声速floatxdataXTALTIME; //单片机计数周期ucharxdatastringBuf[6]; //数值转字符串缓冲 //LCD1602提示信息ucharcodePrompts[][16]={ {"MeasureDistance"}, //测量距离 {"-OutofRange-"}, //超出测量范围 {"MAXrange400cm"}, //测距最大值400cm {"MINrange2cm"}, //测距最小值2cm {""}, //清屏 {"PressK1Start"} //按键开始测量};ucharxdataDistanceText[]="Range:";//测量结果字符串ucharxdataTemperatureText[]="Temperature:";//测量温度值/*外部函数声明*/externvoidLCD_Initialize();externvoidLCD_Display_String(uchar*,uchar);externvoidReadTemperatureFromDS18B20();externintxdataCurTempInteger;//毫秒延时函数voidDelayMS(uintms);//20微秒延时函数voidDelay20us();//HCSR04初始化voidHCSR04_Initialize();//测量距离floatMeasuringDistance();//测距的数值排序求平均floatDistanceStatistics();//输出距离值到LCD1602上voidDisplayDistanceValue(floatdat);//将无符号的整数转成字符串,返回字符串长度,不包括'\0'结束符ucharUnsigedIntToString(uintvalue);//蜂鸣器voidBeep(uchartime);//显示温度值voidDisplayTemperatureValue();//测量距离floatMeasuringDistance(){ //最大定时时间约65ms TH0=0; TL0=0; //生成20us的脉冲宽度的触发信号 Trig=1; Delay20us(); Trig=0; //等待回响信号变高电平 while(!Echo); TR0=1; //启动定时器0 //等待回响信号变低电平 while(Echo); TR0=0; //关闭定时器0 //返回距离值(mm) return(SPEEDSOUND*XTALTIME*((float)TH0*256+(float)TL0))/2000;}//HCSR04初始化voidHCSR04_Initialize(){ //计算单片机计数周期晶振=11.953M 单位us XTALTIME=12/11.953; //温度25度时声速的值 SPEEDSOUND=334.1+25*0.61; Trig=0; Echo=0; TMOD=0x01;}//输出距离值到LCD1602上voidDisplayDistanceValue(floatdat){ uchari=0,j=0,len; uintvalue; value=(uint)dat; //范围检查大于4000mm和小于20mm都为超出测量范围 if(value>4000) { LCD_Display_String(Prompts[1],0x00); LCD_Display_String(Prompts[2],0x40); Beep(2); } elseif(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(Prompts[0],0x00); LCD_Display_String(DistanceText,0x40); }}//显示温度值voidDisplayTemperatureValue(){ TemperatureText[13]=CurTempInteger/10+'0'; TemperatureText[14]=CurTempInteger%10+'0'; TemperatureText[15]='C'; LCD_Display_String(TemperatureText,0x00); }//将无符号的整数转成字符串,返回字符串长度ucharUnsigedIntToString(uintvalue){ uchari=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'; returnlength;}//蜂鸣器voidBeep(uchartime){ uchari; for(i=0;i<100;i++) { BEEP=!BEEP; DelayMS(time); } BEEP=0; DelayMS(100);}//延时函数毫秒@12.000MHzvoidDelayMS(uintms){ uchari,j; while(ms--) { _nop_(); i=2; j=239; do { while(--j); }while(--i); }}//延时函数20微秒@12.000MHzvoidDelay20us(){ uchari; _nop_(); i=7; while(--i);}//定时器0中断voidTimer0()interrupt1{} //DS18B20代码:/*----------------------------------------------*程序功能:DS18B20温度检测程序*单片机型号:STC89C5212MHz*晶振:12Mhz------------------------------------------------*//*包含头文件*/#include<reg51.h>#include<intrins.h>/*宏定义*/#defineuchar unsignedchar //无符号8位#defineuint unsignedint //无符号16位//定义DS18B20端口DS18B20_DQsbitDS18B20_DQ=P3^7;//当前采集的温度值整数部分intxdataCurTempInteger;//当前采集的温度值小数部分intxdataCurTempDecimal;/*----------------------------------------------------------------*功能:延时函数STC89C52@12MHz12T模式*参数:无*返回:无----------------------------------------------------------------*/voidDelayus(uintcount) { while(--count);}/*----------------------------------------------------------------*功能:DS18B20复位及状态检测*参数:无*返回:0或1,1表示未准备好,0表示准备好----------------------------------------------------------------*/ucharReset_DS18B20(){ ucharstatus; DS18B20_DQ=1; Delayus(1); //开始复位过程 DS18B20_DQ=0; //数据线拉低 Delayus(100); //延时480us-960us DS18B20_DQ=1; //数据线拉高 Delayus(10); //延时15us-60us status=DS18B20_DQ; //读取数据线上的状态 Delayus(120); returnstatus;}/*----------------------------------------------------------------*功能:写一字节到DS18B20中*参数:dat=数据*返回:无----------------------------------------------------------------*/voidWriteByteToDS18B20(uchardat){ uchari; for(i=0;i<8;i++) { DS18B20_DQ=0; DS18B20_DQ=dat&0x01; //发送1位数据 Delayus(15); //延时60us以上 DS18B20_DQ=1; //释放总线,等待总线恢复 dat>>=1; //准备下一位数据 }}/*----------------------------------------------------------------*功能:从DS18B20中读一字节*参数:无*返回:读取的数据----------------------------------------------------------------*/ucharReadByteFromDS18B20(){ uchari,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); //延时60us DS18B20_DQ=1; //拉高总线,准备读下1位数据 } returndat;}/*----------------------------------------------------------------*功能:读取温度值并转换成有符号的数值形式*参数:无*返回:无----------------------------------------------------------------*/voidReadTemperatureFromDS18B20(){ ucharflag=0;//正负符号标志 //存储当前采集的温度值 ucharTempValue[]={0,0}; if(Reset_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,否则不需要。 TempValue[1]=~TempValue[1]; TempValue[0]=~TempValue[0]+1; if(TempValue[0]==0x00)TempValue[1]++; flag=1;//负数标志 } //将温度值分为整数和小数两部分存储(默认为12位精度) CurTempInteger=((TempValue[1]&0x07)<<4)|((TempValue[0]&0xF0)>>4); if(flag)CurTempInteger=-CurTempInteger; CurTempDecimal=(TempValue[0]&0x0F)*625; }}// LCD1602程序代码:/*----------------------------------------------*程序功能:1602液晶显示程序*单片机型号:STC90C16012MHz------------------------------------------------*//*1602液晶显示器控制端口分配,数据使用P0端口*/sbitLCD_RS=P2^6;sbitLCD_RW=P2^5;sbitLCD_EN=P2^7;/*--------------------------------------------*功能:毫秒级延时函数*参数:ms=毫秒数值*返回:无--------------------------------------------*/voidLCDDelay(uintms){ uchari,j; while(ms--) { _nop_(); i=2; j=239; do { while(--j); }while(--i); } }/*--------------------------------------------*功能:1602液晶忙状态检测*参数:无*返回:0或1,1表示状态忙,0表示状态闲--------------------------------------------*/bitLCD_Busy_Check(){ bitresult; LCD_RS=0; LCD_RW=1; LCD_EN=1; Delay4us(); result=(bit)(P0&0x80); LCD_EN=0; returnresult;}/*--------------------------------------------*功能:1602液晶写指令*参数:cmd=1602LCD指令*返回:无--------------------------------------------*/voidWrite_LCD_Command(ucharcmd){ while(LCD_Busy_Check()); LCD_RS=0; LCD_RW=0; LCD_EN=0; _nop_(); _nop_(); P0=cmd; Delay4us(); LCD_EN=1; Delay4us(); LCD_EN=0;}/*--------------------------------------------*功能:1602液晶写数据*参数:dat=一个字节数据*返回:无--------------------------------------------*/voidWrite_LCD_Data(uchardat){ while(LCD_Busy_Check()); LCD_RS=1;LCD_RW=0;LCD_EN=0; P0=dat;Delay4us(); LCD_EN=1;Delay4us();LCD_EN=0;}/*--------------------------------------------*功能:设置1602液晶显示位置*参数:pos=位置地址值*返回:无--------------------------------------------*/voidLCD_Set_POS(ucharpos){ Write_LCD_Command(pos|0x80);}/*--------------------------------------------*功能:1602液晶初始化*参数:无*返回:无--------------------------------------------*/voidLCD_Initialize(){ Write_LCD_Command(0x01); LCDDelay(5); Write_LCD_Command(0x38); LCDDelay(5); Write_LCD_Command(0x0C); LCDDelay(5); Write_LCD_Command(0x06); LCDDelay(5);}/*--------------------------------------------*功能:在1602液晶指定的行上显示字符串(共两行,一行16个字符)*参数:*str=字符串指针,LineNo=行首地址(第一行0x00,第二行0x40)*返回:无--------------------------------------------*/voidLCD_Display_String(uchar*str,ucharLineNo){ uchark; LCD_Set_POS(LineNo); for(k=0;k<16;k++) { Write_LCD_Data(str[k]); } }/*--------------------------------------------*功能:在1602液晶指定位置显示一个字符(共两行,一行16个字符)*参数:Dat=一个字符,X=列位置(0-15) Y=行位置(0,1)*返回:无--------------------------------------------*/voidLCD_Display_OneChar(ucharDat,ucharX,ucharY){ Y&=0x01; //限制Y不能大于1(2行,0-1) X&=0x0F; //限制X不能大于15(16个字符,0-15) if(Y){X|=0x40;}//当要在第二行显示时地址码+0x40; X|=0x80;//算出指令码 Write

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论