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

下载本文档

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

文档简介

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

2、4超声波测距模块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*T 0/2T:当前环境温度值N:计数值T0:单片机计数周期=晶振频率/12( 微秒 )HC-SR04测量存在不稳定性,所在对同一距离进行多次测量,并对测量结果排序,去除最大和最小值,将余下的求平均值。程序流程图:完美整理程序代码:/* 程序:基于HC-SR04的超声波测距系统* 单片机型号:STC90C516 12MHz* 说明:按下K1 键后,指示灯点亮,开始连续进行7 次超声波测距,每次测距间隔80ms,完成后对7 次结果排序并将最大的2 个数值和最小的2

5、 个数值去除,对剩余的* 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

6、>#define Delay4us()_nop_();_nop_();_nop_();_nop_();/ 无符号 8 位/ 无符号16 位/ 无符号32 位/* 宏定义 */#define uchar#define uint#define ulongunsigned charunsigned intunsigned long/ 测量的距离值/ 声速/ 单片机计数周期/ 数值转字符串缓冲/* 全局变量定义*/sbit K1=P10;/ 按下 K1 后,开始测距sbit LEDRed=P11;/ 测距指示灯,亮表示正在测距,灭表示测距完成sbit BEEP=P15;/ 报警测量超出范围sbi

7、t 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 ", "MIN range 2cm &q

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

9、void ReadTemperatureFromDS18B20();extern int xdata CurTempInteger;/ 毫秒延时函数void DelayMS(uint ms);/20 微秒延时函数void Delay20us();/HCSR04 初始化void HCSR04_Initialize();/ 测量距离float MeasuringDistance();/ 测距的数值排序求平均float DistanceStatistics();/ 输出距离值到LCD1602上void DisplayDistanceValue(float dat);/ 将无符号的整数转成字符串,返回

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

11、闭定时器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 dat) uchar i=0,j=0,len;uint va

12、lue;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=UnsigedIntToString(value);/ 保留 1 位小数wh

13、ile(stringBufi!='0') if(len-j=1)DistanceText6+j='.' j+; else DistanceText6+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(DistanceText,0x40);/

14、显示温度值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;/ 从个位开始转换dostringBufi=&#

15、39;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(time);BEEP=0;DelayM

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

17、clude <reg51.h>#include <intrins.h>/ 无符号 8 位/ 无符号 16 位/* 宏定义 */#define ucharunsigned char#define uintunsigned int/ 定义DS18B20端口DS18B20_DQsbit DS18B20_DQ = P37;/ 当前采集的温度值整数部分int xdata CurTempInteger;/ 当前采集的温度值小数部分int xdata CurTempDecimal;/* 功能:延时函数STC89C52 12MHz 12T模式* 参数:无* 返回:无*/ void De

18、layus(uint count) while (-count);/* 功能:DS18B20复位及状态检测* 参数:无* 返回: 0 或 1, 1 表示未准备好,0 表示准备好*/ uchar Reset_DS18B20()uchar status;DS18B20_DQ=1;Delayus(1);/ 数据线拉低/ 延时480us-960us/ 数据线拉高/ 延时15us-60us/ 读取数据线上的状态/ 开始复位过程DS18B20_DQ=0;Delayus(100);DS18B20_DQ=1;Delayus(10);status=DS18B20_DQ;Delayus(120);return s

19、tatus;/* 功能:写一字节到DS18B20中* 参数: dat= 数据* 返回:无*/ void WriteByteToDS18B20(uchar dat) uchar i;for(i=0;i<8;i+)/ 发送 1 位数据/ 延时 60us 以上/ 释放总线,等待总线恢复/ 准备下一位数据DS18B20_DQ=0;DS18B20_DQ=dat&0x01;Delayus(15);DS18B20_DQ=1;dat>>=1;/* 功能:从DS18B20中读一字节* 参数:无* 返回:读取的数据*/uchar ReadByteFromDS18B20() uchar i

20、,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);/ 延时 60usDS18B20_DQ=1;/ 拉高总线,准备读下1 位数据 return dat; /* 功能:读取温度值并转换成有符号的数值形式* 参数:无* 返回:无*/ void ReadTemperatureFromDS18B20() uchar flag=0;/ 正负符号标

21、志/ 存储当前采集的温度值uchar TempValue=0,0;if(Reset_DS18B20()CurTempInteger=255;CurTempDecimal=0;跳过ROM命令温度转换命令跳过ROM命令读取温度暂存器命令elseWriteByteToDS18B20(0xCC);/WriteByteToDS18B20(0x44);/Reset_DS18B20();/ 复位WriteByteToDS18B20(0xCC);/WriteByteToDS18B20(0xBE);/TempValue0=ReadByteFromDS18B20();/ 先读低字节温度值TempValue1=Re

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

23、alue1&0x07)<<4)|(TempValue0&0xF0)>>4); if(flag) CurTempInteger=-CurTempInteger;CurTempDecimal=(TempValue0&0x0F)*625;/LCD1602程序代码:/* 程序功能:1602 液晶显示程序* 单片机型号:STC90C160 12MHz*/P0 端口 */*1602 液晶显示器控制端口分配,数据使用sbit LCD_RS=P26;sbit LCD_RW=P25;sbit LCD_EN=P27;/* 功能:毫秒级延时函数* 参数:ms=毫秒数值

24、* 返回:无*/void LCDDelay(uint ms)uchar i, j;while(ms-)_nop_();1 = 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);LCD_EN=0;return result;/* 功能:1602 液晶写指令* 参数:cmd=160

25、2LCD指令* 返回:无*/void Write_LCD_Command(uchar cmd) 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= 一个字节数据* 返回:无*/void Write_LCD_Data(uchar dat) while(LCD_Busy_Check();LCD_RS=1;LCD_RW=0;LCD_EN=0;P0=dat;Delay

26、4us();LCD_EN=1;Delay4us();LCD_EN=0;/* 功能:设置1602 液晶显示位置* 参数: pos=位置地址值* 返回:无*/void LCD_Set_POS(uchar pos)Write_LCD_Command(pos|0x80);/* 功能: 1602 液晶初始化* 参数:无* 返回:无*/ void LCD_Initialize()LCDDelay(5);LCDDelay(5);LCDDelay(5);LCDDelay(5);Write_LCD_Command(0x01);Write_LCD_Command(0x38);Write_LCD_Command(0

27、x0C);Write_LCD_Command(0x06);/* 功能:在1602 液晶指定的行上显示字符串( 共两行,一行16 个字符 )* 参数: *str= 字符串指针,LineNo= 行首地址( 第一行 0x00,第二行0x40)* 返回:无*/void LCD_Display_String(uchar *str, uchar LineNo)uchar k;LCD_Set_POS(LineNo);for(k=0;k<16;k+) Write_LCD_Data(strk);/* 功能:在1602 液晶指定位置显示一个字符( 共两行,一行16 个字符 )* 参数: Dat=一个字符,X= 列位置 (0-15)Y=行位置(0 , 1)* 返回:无*/void LCD_Display_OneChar(uchar Dat, uchar X, uchar Y)Y &= 0x01;/ 限制Y不能大于1(2 行, 0-1)X &= 0x0F; / 限制X不能大于15(16 个字符,0-15)

温馨提示

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

评论

0/150

提交评论