基于51单片机的HC_SR04超声波测距系统制作_第1页
基于51单片机的HC_SR04超声波测距系统制作_第2页
基于51单片机的HC_SR04超声波测距系统制作_第3页
基于51单片机的HC_SR04超声波测距系统制作_第4页
基于51单片机的HC_SR04超声波测距系统制作_第5页
免费预览已结束,剩余11页可下载查看

付费下载

下载本文档

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

文档简介

1、基于 51 单片机带温度补偿的HC-SR04超声波测距系统利用从网上购买的 HC-SR04超声波模块制作了一个测距装置, HC-SR04自身不带温度补偿功能,所以加上一个使用 DS18B20做的温度测量模块。整个系统包括: 51 单片机最小系统,超声波测距模块、温度测量模块、液晶显示模块。使用了如下主要元器件:元件说明数量STC90C516RC51 单片机1HC-SR04超声波测距模块1DS18B20温度测量模块1lcd1602液晶显示模块1系统电路图51 单片机最小系统单片机型号:STC90C516,晶振: 12Mhz。自己动手焊接的最小系统板。LCD1602A液晶显示模块:HC-SR04超

2、声波测距模块HC-SR04超声波测距模块可提供2cm 至 400cm 的非接触式距离感测功能,测距精度可达3mm;模块自身包括超声波发射器、接收器与控制电路。实物正反两面图HC-SR04电气参数:HC-SR04工作原理及说明:1、 给 Trig触发控制信号IO 端口至少10us 的高电平信号;2、 模块自动发送8 个 40khz 的方波,并自动检测是否有信号返回;3、 有信号返回时,Echo 回响信号输出端口输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间;4、 两次测距时间间隔最少在60ms以上,以防止发射信号对回响信号的影响;超声波时序图单片机控制HC-SR04超声波测距说明:

3、原理图中,单片机的 P1.7 口接 HC-SR04的 Trig 端口, P1.6 口接 HC-SR04的 Echo 端口,超声波在传播时碰到障碍物即返回, HC-SR04模块收到回波信号后 Echo 口输出一个高电平, 单片机检测到高电平后即启动计数器开始计数,直到单片机检测到Echo 口变成低电平后结束计数,计数器的计数值乘以单片机计数周期就是超声波从发射到接收的往返时间,即距离S=v*t/2 ;由于在室温下,声速受温度的影响,其变化关系为:V=334.1+T*0.61(T为当前温度 ) ,利用DS18B20温度传感器可以得到环境温度,补偿温度对声速的影响。当温度高于26 度或低于14 度时

4、,上述公式不能完全满足对测量的修正了,所以高于26 度时取 26 度,低于14 度时取 14 度。距离计算公式为:S=(334.1+T*0.61)*N*T0/2T:当前环境温度值N:计数值T0:单片机计数周期=晶振频率 /12( 微秒 )HC-SR04测量存在不稳定性, 所在对同一距离进行多次测量,并对测量结果排序,去除最大和最小值,将余下的求平均值。程序流程图:程序代码:/* 程序:基于 HC-SR04的超声波测距系统* 单片机型号: STC90C516 12MHz*说明:按下 K1 键后,指示灯点亮,开始连续进行 7 次超声波测距,每次测距间隔 80ms,完成后对 7 次结果排序并将最大的

5、 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 <reg

6、51.h>#include <intrins.h>#define Delay4us()_nop_();_nop_();_nop_();_nop_();/* 宏定义 */#define ucharunsigned char/ 无符号 8位#define uintunsigned int/ 无符号 16位#define ulongunsigned long/ 无符号 32位/* 全局变量定义 */sbit K1=P10;/ 按下 K1 后,开始测距sbit LEDRed=P11;/ 测距指示灯,亮表示正在测距,灭表示测距完成sbit BEEP=P15;/ 报警测量超出范围sbit

7、 Trig=P17;/HC-SR04触发信号输入sbit Echo=P16;/HC-SR04回响信号输出float xdata DistanceValue=0.0; float xdata SPEEDSOUND; float xdata XTALTIME; uchar xdata stringBuf6;/ 测量的距离值/ 声速/ 单片机计数周期/ 数值转字符串缓冲/LCD1602 提示信息uchar code Prompts16="Measure Distance", "- Out of Range -", "MAX range 400cm &

8、quot;, "MIN range 2cm ", " ",/ 测量距离/ 超出测量范围/ 测距最大值/ 测距最小值/ 清屏400cm2cm" Press K1 Start "/ 按键开始测量;uchar xdata DistanceText="Range:"/uchar xdata TemperatureText="Temperature:"/测量结果字符串测量温度值/* 外部函数声明*/extern void LCD_Initialize();extern void LCD_Display_S

9、tring(uchar *, uchar);extern void ReadTemperatureFromDS18B20();extern int xdata CurTempInteger;/ 毫秒延时函数void DelayMS(uint ms);/20微秒延时函数void Delay20us();/HCSR04 初始化void HCSR04_Initialize();/ 测量距离float MeasuringDistance();/ 测距的数值排序求平均float DistanceStatistics();/ 输出距离值到 LCD1602上void DisplayDistanceValue

10、(float dat);/ 将无符号的整数转成字符串,返回字符串长度,不包括'0'结束符uchar UnsigedIntToString(uint value);/ 蜂鸣器void Beep(uchar time);/ 显示温度值void DisplayTemperatureValue();/ 测量距离float MeasuringDistance()/ 最大定时时间约 65ms TH0=0;TL0=0;/ 生成 20us 的脉冲宽度的触发信号Trig=1;Delay20us();Trig=0;/ 等待回响信号变高电平while(!Echo);TR0=1;/ 启动定时器0/ 等

11、待回响信号变低电平while(Echo);TR0=0;/ 关闭定时器0/ 返回距离值 (mm)return (SPEEDSOUND*XTALTIME*(float)TH0*256+(float)TL0)/2000;/HCSR04 初始化void HCSR04_Initialize()/ 计算单片机计数周期晶振 =11.953M单位 usXTALTIME=12/11.953;/ 温度 25 度时声速的值SPEEDSOUND=334.1+25*0.61;Trig=0;Echo=0;TMOD=0x01;/ 输出距离值到 LCD1602上void DisplayDistanceValue(float

12、dat)uchar i=0,j=0,len;uint value;value=(uint)dat;/ 范围检查大于 4000mm和小于 20mm都为超出测量范围if(value>4000)LCD_Display_String(Prompts1,0x00);LCD_Display_String(Prompts2,0x40);Beep(2);else if(value<20)LCD_Display_String(Prompts1,0x00);LCD_Display_String(Prompts3,0x40);Beep(2);else/ 将数值转换成字符串len=UnsigedIntTo

13、String(value);/ 保留 1 位小数while(stringBufi!='0')if(len-j=1)DistanceText6+j='.'j+;elseDistanceText6+j=stringBufi;i+;j+;DistanceText6+j='c'j+;DistanceText6+j='m'i=7+j;/ 剩余位置补空格while(i<16)DistanceTexti=' 'i+;/LCD_Display_String(Prompts0,0x00);LCD_Display_String(

14、DistanceText,0x40);/ 显示温度值void DisplayTemperatureValue()TemperatureText13=CurTempInteger/10+'0'TemperatureText14=CurTempInteger%10+'0'TemperatureText15='C'LCD_Display_String(TemperatureText,0x00);/ 将无符号的整数转成字符串,返回字符串长度uchar UnsigedIntToString(uint value)uchar i=0,t,length;/ 从

15、个位开始转换dostringBufi='0'+value%10;value=value/10;i+;while(value!=0);length=i;/ 将字符串颠倒顺序for(i=0;i<(length/2);i+)t=stringBufi;stringBufi=stringBuflength-i-1;stringBuflength-i-1=t;stringBuflength='0'return length;/ 蜂鸣器void Beep(uchar time)uchar i;for(i=0;i<100;i+)BEEP=!BEEP;DelayMS(

16、time);BEEP=0;DelayMS(100);/ 延时函数 毫秒 12.000MHz void DelayMS(uint ms)uchar i, j; while(ms-)_nop_();i = 2;j = 239;dowhile (-j);while (-i);/ 延时函数 20 微秒 12.000MHz void Delay20us()uchar i; _nop_();i = 7;while (-i);/ 定时器 0 中断void Timer0() interrupt 1/DS18B20 代码:/*-* 程序功能: DS18B20 温度检测程序* 单片机型号: STC89C52 12

17、MHz* 晶振:12Mhz-*/* 包含头文件 */#include <reg51.h>#include <intrins.h>/*宏定义*/#define uchar#define uintunsigned char unsigned int/ 无符号 8位/ 无符号 16 位/ 定义 DS18B20端口 DS18B20_DQ sbit DS18B20_DQ = P37;/ 当前采集的温度值整数部分int xdata CurTempInteger;/ 当前采集的温度值小数部分int xdata CurTempDecimal;/*-* 功能:延时函数 STC89C52

18、12MHz 12T模式* 参数:无* 返回:无-*/void Delayus(uint count)while (-count);/*-* 功能: DS18B20复位及状态检测* 参数:无* 返回: 0 或 1, 1 表示未准备好,0 表示准备好-*/uchar Reset_DS18B20()uchar status;DS18B20_DQ=1;Delayus(1);/ 开始复位过程DS18B20_DQ=0; Delayus(100); DS18B20_DQ=1; Delayus(10); status=DS18B20_DQ;/ 数据线拉低/ 延时 480us-960us/ 数据线拉高/ 延时

19、15us-60us/ 读取数据线上的状态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);DS18B20_DQ=1;dat>>=1;/ 延时 60us 以上/ 释放总线,等待总线恢复/ 准备下一位数据/*-* 功能:从 DS18B20中读一字节* 参数:无* 返

20、回:读取的数据-*/uchar ReadByteFromDS18B20()uchar i,dat=0;for(i=0;i<8;i+)DS18B20_DQ=0;/ 拉低总线,产生读信号dat>>=1;DS18B20_DQ=1;/ 释放总线,准备读1 位数据Delayus(2);/ 延时4usif(DS18B20_DQ) dat|=0x80;/ 合并每位数据Delayus(15);DS18B20_DQ=1;/ 延时 60us/ 拉高总线,准备读下1 位数据return dat;/*-* 功能:读取温度值并转换成有符号的数值形式* 参数:无* 返回:无-*/void ReadTem

21、peratureFromDS18B20()uchar flag=0;/正负符号标志/ 存储当前采集的温度值uchar TempValue=0,0;if(Reset_DS18B20()CurTempInteger=255;CurTempDecimal=0;elseWriteByteToDS18B20(0xCC);/跳过 ROM命令WriteByteToDS18B20(0x44);/温度转换命令Reset_DS18B20();/复位WriteByteToDS18B20(0xCC);/跳过 ROM命令WriteByteToDS18B20(0xBE);/读取温度暂存器命令TempValue0=Read

22、ByteFromDS18B20();/先读低字节温度值TempValue1=ReadByteFromDS18B20();/后读高字节温度值Reset_DS18B20();/复位/ 计算温度值/ 先进行正温度与负温度判断,高5 位全为1( 0xF8)则为负数if(TempValue1&0xF8)=0xF8)/ 负温度计算:取反加 1,低字节为 0 时,高字节取反加 1,否则不需要。TempValue1=TempValue1;TempValue0=TempValue0+1;if(TempValue0=0x00) TempValue1+;flag=1;/负数标志/ 将温度值分为整数和小数两部

23、分存储 ( 默认为 12 位精度 ) CurTempInteger=(TempValue1&0x07)<<4)|(TempValue0&0xF0)>>4);if(flag) CurTempInteger=-CurTempInteger;CurTempDecimal=(TempValue0&0x0F)*625;/ LCD1602 程序代码:/*-* 程序功能: 1602 液晶显示程序* 单片机型号: STC90C160 12MHz-*/*1602液晶显示器控制端口分配,数据使用sbit LCD_RS=P26;sbit LCD_RW=P25;sbit

24、 LCD_EN=P27;P0 端口 */*-* 功能:毫秒级延时函数* 参数: ms=毫秒数值* 返回:无-*/void LCDDelay(uint ms)uchar i, j;while(ms-)_nop_();i = 2;j = 239;dowhile (-j);while (-i);/*-* 功能: 1602 液晶忙状态检测* 参数:无* 返回: 0 或 1, 1 表示状态忙,-*/0 表示状态闲bit LCD_Busy_Check()bit result;LCD_RS=0;LCD_RW=1;LCD_EN=1;Delay4us();result=(bit)(P0&0x80);LC

25、D_EN=0;return result;/*-* 功能: 1602 液晶写指令* 参数: cmd=1602LCD指令* 返回:无-*/void Write_LCD_Command(uchar cmd)while(LCD_Busy_Check();LCD_RS=0;LCD_RW=0;LCD_EN=0;P0=cmd; Delay4us();LCD_EN=1;Delay4us(); LCD_EN=0;_nop_();_nop_();/*-* 功能: 1602 液晶写数据* 参数: dat= 一个字节数据* 返回:无-*/void Write_LCD_Data(uchar dat)while(LCD_Busy_Check();LCD_RS=1;LCD_RW=0;LCD_EN=0;P0=dat;Delay4us();LCD_EN=1;Delay4us();LCD

温馨提示

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

评论

0/150

提交评论