基于51单片机的HCSR04超声波测距系统制作Word文档下载推荐.docx

上传人:b****5 文档编号:16519506 上传时间:2022-11-24 格式:DOCX 页数:23 大小:364.44KB
下载 相关 举报
基于51单片机的HCSR04超声波测距系统制作Word文档下载推荐.docx_第1页
第1页 / 共23页
基于51单片机的HCSR04超声波测距系统制作Word文档下载推荐.docx_第2页
第2页 / 共23页
基于51单片机的HCSR04超声波测距系统制作Word文档下载推荐.docx_第3页
第3页 / 共23页
基于51单片机的HCSR04超声波测距系统制作Word文档下载推荐.docx_第4页
第4页 / 共23页
基于51单片机的HCSR04超声波测距系统制作Word文档下载推荐.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

基于51单片机的HCSR04超声波测距系统制作Word文档下载推荐.docx

《基于51单片机的HCSR04超声波测距系统制作Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《基于51单片机的HCSR04超声波测距系统制作Word文档下载推荐.docx(23页珍藏版)》请在冰豆网上搜索。

基于51单片机的HCSR04超声波测距系统制作Word文档下载推荐.docx

S=(334.1+T*0.61)*N*T0/2

T:

当前环境温度值

N:

计数值

T0:

单片机计数周期=晶振频率/12(微秒)

HC-SR04测量存在不稳定性,所在对同一距离进行多次测量,并对测量结果排序,去除最大和最小值,将余下的求平均值。

程序流程图:

程序代码:

/*

*程序:

基于HC-SR04的超声波测距系统

*单片机型号:

STC90C51612MHz

*说明:

按下K1键后,指示灯点亮,开始连续进行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>

intrins.h>

#defineDelay4us(){_nop_();

_nop_();

}

/*宏定义*/

#defineucharunsignedchar//无符号8位

#defineuintunsignedint//无符号16位

#defineulongunsignedlong//无符号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;

voidHCSR04_Initialize()

//计算单片机计数周期晶振=11.953M单位us

XTALTIME=12/11.953;

//温度25度时声速的值

SPEEDSOUND=334.1+25*0.61;

Echo=0;

TMOD=0x01;

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[3],0x40);

else

//将数值转换成字符串

len=UnsigedIntToString(value);

//保留1位小数

while(stringBuf[i]!

='

{

if(len-j==1)

{

DistanceText[6+j]='

.'

j++;

}else

DistanceText[6+j]=stringBuf[i];

i++;

}

}

DistanceText[6+j]='

c'

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+'

TemperatureText[15]='

C'

LCD_Display_String(TemperatureText,0x00);

//将无符号的整数转成字符串,返回字符串长度

ucharUnsigedIntToString(uintvalue)

uchari=0,t,length;

//从个位开始转换

do

stringBuf[i]='

+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]='

returnlength;

voidBeep(uchartime)

uchari;

100;

BEEP=!

BEEP;

DelayMS(time);

BEEP=0;

DelayMS(100);

//延时函数毫秒@12.000MHz

voidDelayMS(uintms)

uchari,j;

while(ms--)

_nop_();

i=2;

j=239;

do

while(--j);

}while(--i);

//延时函数20微秒@12.000MHz

voidDelay20us()

_nop_();

i=7;

while(--i);

//定时器0中断

voidTimer0()interrupt1

//DS18B20代码:

/*----------------------------------------------

*程序功能:

DS18B20温度检测程序

STC89C5212MHz

*晶振:

12Mhz

------------------------------------------------*/

#defineucharunsignedchar//无符号8位

#defineuintunsignedint//无符号16位

//定义DS18B20端口DS18B20_DQ

sbitDS18B20_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

//数据线拉高

Delayus(10);

//延时15us-60us

status=DS18B20_DQ;

//读取数据线上的状态

Delayus(120);

returnstatus;

写一字节到DS18B20中

dat=数据

voidWriteByteToDS18B20(uchardat)

8;

DS18B20_DQ=0;

DS18B20_DQ=dat&

0x01;

//发送1位数据

Delayus(15);

//延时60us以上

DS18B20_DQ=1;

//释放总线,等待总线恢复

dat>

>

=1;

//准备下一位数据

从DS18B20中读一字节

读取的数据

ucharReadByteFromDS18B20()

uchari,dat=0;

//拉低总线,产生读信号

//释放总线,准备读1位数据

Delayus

(2);

//延时4us

if(DS18B20_DQ)dat|=0x80;

//合并每位数据

//延时60us

//拉高总线,准备读下1位数据

returndat;

读取温度值并转换成有符号的数值形式

voidReadTemperatureFromDS18B20()

ucharflag=0;

//正负符号标志

//存储当前采集的温度值

ucharTempValue[]={0,0};

if(Reset_DS18B20())

CurTempInteger=255;

CurTempDecimal=0;

WriteByteToDS18B20(0xCC);

//跳过ROM命令

WriteByteToDS18B20(0x44);

//温度转换命令

Reset_DS18B20();

//复位

WriteByteToDS18B20(0xBE);

//读取温度暂存器命令

TempValue[0]=ReadByteFromDS18B20();

//先读低字节温度值

TempValue[1]=ReadByteFromDS18B20();

//后读高字节温度值

//计算温度值

//先进行正温度与负温度判断,高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)

}

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_RW=0;

LCD_EN=0;

P0=cmd;

1602液晶写数据

dat=一个字节数据

voidWrite_LCD_Data(uchardat)

LCD_RS=1;

LCD_RW=0;

LCD_EN=0;

P0=dat;

Delay4us();

Dela

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 小学教育 > 小升初

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1