基于51单片机倒车雷达系统

摘 要

随着科技的发展,人们生活水平的提高,城市发展建设加快,城市给交通系统也有较大发展,其状况不断改善。但是,由于多种原因合成时间住的许多不可预见因素,城市还是经常出现大量的交通事故,特别是倒车时,看不到后方而导致大量的交通事故。因此,设计出好的倒车雷达系统,对于减少城市的交通事故将有一个很好的控制作用。当然这要求倒车雷达系统,具有精度高,抗干扰强,价格应该低,适宜推广等特点,这样基于超声波的测距系统,完全可以胜任此任务。

本设计采用以A T89C51单片机为核心的低成本、高精度、微型化数字显示超

声波测距仪的硬件电路和软件设计方法。整个电路采用模块化设计,由主程序、发射子程序、接收子程序、显示子程序等模块组成。各探头的信号经单片机综合分析处理,实现超声波测距仪的各种功能。在此基础上设计了系统的总体方案,最后通过硬件和软件实现了各个功能模块。该设计设抗干扰能力较好,实时性良好,误差可以达到mm 级,可以有效地解决汽车倒车作用。

本系统在倒车时不断测量汽车尾部与其后面障碍物的距离,并随时显示其距

离,并用语音及时提示。在不同的距离范围内,不同的温度下测出距离,发出报警 信号,以提高汽车倒车时的安全性的仪器。

目录

第一章 绪论 …………………………………………3

1.1 课题背景,目的和意义 ………………………………………3

1.2两种常用的超声波测距方案 …………………………………3

第2章 超声波测距系统设计 …………………………………3

2.1 超声波测距的原理 ………………………………4

2.2超声波测距系统电路的设计 …………………………4

2.2.1 总体设计方案 ……………………………………4

2.2.2发射电路的设计 ………………………………4

2.2.3接收电路的设计 ……………………4

2.2.4显示模块的设计 ………………………………………5

2.2.5 温度补偿模块设计………………………………5

2.2.6 语音处理模块………………………………………5

第三章 超声波测距系统的软件设 ……………………………..5

3.1总体流程图 ……………………………..5

3.2 程序及分析 ……………………………..6

第四章 电路调试及误差分析 ……………………………..7

4.1电路的调试 ……………………………..7

4.2系统的误差分析 ……………………………..7

第5章 功能扩展………………………………………7

参考文献 ……………………………..7

附录:„„„„„„„„„„„„„„„8-22

第1章 绪论

1.1 课题背景,目的和意义

由于社会的进步,经济的发展和生活水平的不断提高,汽。

车数量逐年增长,造成道路交通拥挤不堪,交通事故频繁发生

汽车倒车报警器:在倒车时不断测量汽车尾部与其后面障碍物的距离,并随时显示

其距离,并用语音及时提示。在不同的距离范围内,不同的温度下测出距离,发出

报警信号,以提高汽车倒车时的安全性的仪器。

2.2两种常用的超声波测距方案

2.2.1基于CPLD 的超声波测距系统

CPLD 模块主要由发射模块,16位计时计数器模块,接收模块,顺序执行计

数器模块和六选一数据选择器模块五部分组成。其总体框图如图1所示。

CPLD 模块主要完成超声波的发射、接收和时间的测量。超声波发射模块启动

40KHz 的超声波发射,当发射脉冲串达到设定值后,关闭超声波的发射,同时启动

六路计时计数器模块开始计时; 信号经过障碍物反射回来,接收电路接收到回波后,

将其进行整形,作为接收模块的信号,当接收完回波脉冲信号后,接收模块输出端

发出信号,关闭计时计数器停止工作; 当所有的回波接收完毕后,顺序执行计数器输

出端发出信号启动单片机开始接收数据,通过顺序执行计数器的计数值、数据选择

器的选择端与计时计数器的控制端分别读取六路不同的计数值。所有的数据读取完

后,清除计时计数器的计数值,准备下一次的循环计数。

2.2.1基于单片机的超声波测距系统

本警器由单片机来控制。整个控制系统由超声波发射电路、超声波接收电路、

报警电路、复位电路、显示电路组成。实行实时数字显示测得的距离,在不同的距

离范围内发出不同的报警信号,驾驶员可根据个人需要调整设置报警距离,以减少

事故的发生。本作品将采用此种方法。

第二章 超声波测距系统设计

2.1 超声波测距的原理

超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声

波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就

立即停止计时。超声波在空气中的传播速度为c ,根据计时器记录的时间t ,

就可以计算出发射点距障碍物的距离(s),即:s=ct/2 。这就是所谓的时间差

测距法。

2.2超声波测距系统电路的设计

2.2.1 总体设计方案

该设计总体基于51,包括发射模块,接收模块,显示模块,语音模块,温

度补偿模块。由发射电路发射超声波,51计数器从0开始计时,当超声波反射回来,

接收电路接收,51停止计时,将所计得得数转化成十进制n ,因为使用的12MHz

晶体作时钟基准的89C51单片机定时器能方便的计数到1μs的精度,因此系统采用

89C51定时器能保证时间误差在1mm 的测量范围内。,则将n 与1us 相乘即可以得

到时间,从而利用超声波测距的原理就可以判断距离以是否利用利用凌阳61版的语

音处理功能,进行报警及播放当前的距离,温度和超声波传播速度。再者显示器也

将显示距离,温度,及超声波传播速度。

2.2.2发射电路的设计

用单片机直接产生的40khz 信号经过74ls04放大后直接驱动超声波发射探头。

2.2.3接收电路的设计

将超声波接收探头接收的信号经cx20106红外线专用芯片处理接收,然后送给

单片机。

2.2.4显示模块的设计

使用1602液晶屏,与单片机连接,将单片机的距离,温度,超声波数度(声

速)传送给液晶屏显示出来。

2.2.5 温度补偿模块设计

因为声速在不同温度下的传播速度是不同的,根据补偿公式

C=C0+0.607×T ℃ C0为零度时的声波速度332m/s;T 为实际温度(℃) 。采用18b20

温度传感器测温,根据测得的温度,来确定具体的声速。

2.2.6 语音处理模块

根据手中的现有的材料,利用凌阳61版的语音处理功能,播放出:“倒车请

注意”并通过51单片机和凌阳的串口通讯,将51测得的距离,温度,声速数据传

给凌阳,然后通过凌阳的语音处理将其播报出来。

第三章 超声波测距系统的软件设计

3.1总体流程图

3.1.1凌阳模块流程图

3.1.2 51单片机模块

3.2 程序及分析

(见附录)

第4章 电路调试及误差分析

5.1电路的调试(盲区问题)

由于超声波发射探头在发射超声波时,接受探头也会接受到超声波,所以在发

射超声波时,必须先关外部中断,延时一段时间,进而消除回波干扰,所以在测量

中会有盲区出现,所以硬件调试中主要的就是调节延时时间,使盲区达到最小,进

而跳高测量的精度。

通过硬件调试,来控制发射脉冲波的个数以及延时时间,并在实际测量中测

出三种不同测距模式下的盲区,分别约为5cm ,20cm 及45cm 。

、 5.2系统的误差分析 28

根据超声波测距公式L=C×T,可知测距的误差是由超声波的传播速度误差和测

量距离传播的时间误差引起的。

1. 时间误差

当要求测距误差小于1mm 时,假设已知超声波速度C=344m/s (20℃室温) ,忽

略声速的传播误差。测距误差s△t

在超声波的传播速度是准确的前提下,测量距离的传播时间差值精度只要在达

到微秒级,就能保证测距误差小于1mm 的误差。使用的12MHz 晶体作时钟基准的

89C51单片机定时器能方便的计数到1μs 的精度,因此系统采用89C51定时器能保

证时间误差在1mm 的测量范围内。

2. 超声波传播速度误差

超声波的传播速度受空气的密度所影响,空气的密度越高则超声波的传播速

度就越快.

第5章 功能扩展

将通过串口与PC 机进行通讯,并利用所学知识,用VB 写了了一个接受模块,51单片机中的数据经串

口传到电脑上显示。

参考文献 33

单片机原理与控制技术 机械工业出版社

数字电子技术教程 清华大学出版社

模拟电子技术教程 清华大学出版社

胡萍. 超声波测距仪的研制. 计算机与现代化

时德刚,刘哗. 超声波测距的研究. 计算机测量与控制 超声波测距原理

附录:

//////////////主文件程序main//////////////////////////////////////////////

3.2.1超声波测距

#include

#include

#include"18B20.h"

#include "intrins.h"

#include"LCD1602.H"

#include"Delay1.h"

#define uchar unsigned char

#define uint unsigned int

uchar ucHigh_time,ucLow_time; //超声波传输时间

uchar ucFlag; //中断标志位

uchar frq; //音乐频率节拍问题

float c; //不同温度下的超声波传播速度

/*************************针脚定义********************************/ sbit Hz40k_out =P3^6; //40k信号输出端

sbit Mod_short=P1^4;

sbit Mod_long=P1^5;

sbit Mod_out = P1^7; // 判断数据是发给电脑机还是凌阳版

sbit Key_tran=P1^6; //发送数据,开始通讯

/*****************************************************************/ /**********************函数声明***********************************/ void Tmr0_int(void);

void Int0_int(void);

void Send_40khz_long(void) ; //发射超声波

void Send_40khz_medium(void) ;

void Send_40khz_short(void) ;

int Distance_count(); //距离转换函数

float Compensate_c(); //温度补偿函数

void Display_dis(void) ; //距离显示函数

void Display_tem(void) ; //温度显示函数

void Display_c(void) ; //声速显示函数

void delayms(unsigned char ms);

void Tmr1_int(void);

/***********************子程序 ********************************/ void Tmr0_int(void)

{TMOD|=0x01; //tmr0方式1,16位计数

EA=0; //关总中断

ET0=0; //关T0中断

TR0=0; //停止计时器0

TH0=0X00;

TL0=0X00;

}

//////////////////////////////////////////////////////////////

void Int0_int(void)

{IT0=0; //低电平沿触发

EA=0; //关总中断

EX0=0; //屏蔽中断

}

/////////////////////////////////////////////////////////////

void Ustart_int(void)

{SCON |= 0x50; //串口方式1, 允许接收

TMOD |= 0x20; //定时器1定时方式2

// TCON = 0x40; //设定时器1开始计数

TH1 = 0xF3; //12MHz 2400波特率

TL1 = 0xF3;

TR1 = 0; //关闭定时器

}

///////////////////////////////////////////////////////////

void Ustart_send_lingyang(void)

{ uchar send[3];

uint V oice_v;

send[0]=Distance_count();

send[1]=Distance_count()>>8;

TR1 = 1; //启动定时器

TI=0;

SBUF=send[1]; //先发高位再发低位

while(!TI); //等待发送完成

TI=0;

while(!RI); //等待接收完成

RI=0;

//delay_ms(200);

SBUF=send[0];

while(!TI);

TI=0;

send[0]=Read_Temperature()/10;

send[1]=(Read_Temperature()/10)>>8;//发送的为实际温度的十倍37.2C 则发送372

while(!RI); //等待接收完成

RI=0;

//delay_ms(200);

SBUF=send[1];

while(!TI);

TI=0;

while(!RI); //等待接收完成

RI=0;

//delay_ms(200);

SBUF=send[0];

while(!TI);

TI=0;

V oice_v=Compensate_c(); //将浮点型转换为整型 send[0]=Voice_v;

send[1]=Voice_v>>8;

while(!RI); //等待接收完成

RI=0;

//delay_ms(200);

SBUF=send[1];

while(!TI);

TI=0;

while(!RI); //等待接收完成

RI=0;

//delay_ms(200);

SBUF=send[0];

while(!TI);

TI=0;

while(!RI); //等待接收完成

RI=0;

TR1=0;//关闭定时器

}

////////////////////////////////////////////////////////////////////////// void Ustart_send_pc(void)

{

uchar send[4];

uint V oice_v;

send[0]=Distance_count()/1000+0x30;

send[1]=Distance_count()%1000/100+0x30;

send[2]=Distance_count()%100/10+0x30;

send[3]=Distance_count()%10+0x30;

TR1 = 1; //启动定时器

TI=0;

SBUF=send[0];

while(!TI);

TI=0;

SBUF=send[1];

while(!TI);

TI=0;

SBUF=send[2];

while(!TI);

TI=0;

SBUF=send[3];

while(!TI);

TI=0;

send[0]=(Read_Temperature()/10)/100+0x30;

send[1]=(Read_Temperature()/10)%100/10+0x30;//发送的为实际温度的十倍 37.2C 则发送372

send[2]=(Read_Temperature()/10)%10+0x30;

SBUF=send[0];

while(!TI);

TI=0;

SBUF=send[1];

while(!TI);

TI=0;

SBUF=send[2];

while(!TI);

TI=0;

V oice_v=Compensate_c(); //将浮点型转换为整型

send[0]=Voice_v/100+0x30;

send[1]=Voice_v%100/10+0x30;

send[2]=Voice_v%10+0x30;

SBUF=send[0];

while(!TI);

TI=0;

SBUF=send[1];

while(!TI);

TI=0;

SBUF=send[2];

while(!TI);

TI=0;

TR1=0;//关闭定时器

}

void Key_scan(void)

{Key_tran=1;//写1准备开始读

if(Key_tran==0)

{ delay_ms(10);

while(!Key_tran) ;//等待按键放开

if (Mod_out==1)

Ustart_send_lingyang();

else

Ustart_send_pc();

}

}

////////////////////////////////////////////////////////////////////////////////////////

void Send_40khz_short(void) //从P1.0发出40KHz 的脉冲 短波测量短距离

{uchar n,p;

for(n=0;n

{Hz40k_out=1;

for(p=0;p

Hz40k_out=0;

for(p=0;p

Hz40k_out=0;

}

}

/////////////////////////////////////////////////////////////

void Send_40khz_medium(void) //从P1.0发出40KHz 的脉冲 中波 测量中距离

{uchar n,p;

for(n=0;n

{Hz40k_out=1;

for(p=0;p

Hz40k_out=0;

for(p=0;p

Hz40k_out=0;

}

}

////////////////////////////////////////////////////////////

void Send_40khz_long(void)//从P1.0发出40KHz 的脉冲长波测量长距离 {uchar n,p;

for(n=0;n

{Hz40k_out=1;

for(p=0;p

Hz40k_out=0;

for(p=0;p

Hz40k_out=0;

}

}

//////////////////////////////////////////////////////////

float Compensate_c() //温度补偿公式

{ c= 331.45+0.607*Read_Temperature()/100;

return c;

}

/////////////////////////////////////////////////////////

int Distance_count()//距离计算函数

{float Temp;

Temp=ucHigh_time*256+ucLow_time-96; //96为实际调试中距离的调整 Temp=(Temp/1000)/2;

Temp*=Compensate_c(); //毫米

return Temp;

}

///////////////////////////////////////////////////////

void Display_dis(void) //显示距离

{ switch(ucFlag)

{case 1: { LCD_gotoxy(0, 0);

write_string_LCD1602("Distance:");

if( Distance_count()/1000>0) //判读显示位数 write_number(Distance_count(),4);

else if (Distance_count()/100>0)

write_number(Distance_count(),3);

else if (Distance_count()/10>0)

{write_number(Distance_count(),2);

write_string_LCD1602(" ");}

else

{write_number(Distance_count(),1);write_string_LCD1602(" ");}

write_string_LCD1602("mm");

break;

}

case 2: { LCD_gotoxy(0, 0);

write_string_LCD1602("Distance:wrong ") ; break;

}

default : { LCD_gotoxy(0, 0);

write_string_LCD1602("Begin ") ; break;

}

}

}

///////////////////////////////////////////////////////////////////

void Display_tem(void) //显示温度

{ LCD_gotoxy(1, 0);

write_string_LCD1602("T:");

if (Read_Temperature()/100>=100)

write_number(Read_Temperature()/100,3);

else

write_number(Read_Temperature()/100,2);

write_string_LCD1602(".");

write_number(Read_Temperature()%100/10,1);

write_string_LCD1602("C");

}

///////////////////////////////////////////////////////////////

void Display_c(void) //显示声速

{LCD_gotoxy(1, 8);

write_string_LCD1602("c:");

write_number(Compensate_c(),3);

write_string_LCD1602("m/s");

}

/*****************中断处理***********************/

void INT0_Ultrasonic() interrupt 0

{ uchar ucTemp_time1,ucTemp_time2;

ucFlag=1;//外部中断标志位

TR0=0;//关定时器0

ET0=0;//屏蔽定时器0中断

EX0=0;//关外部中断

ucTemp_time1=TL0;

ucTemp_time2=TH0;

if((ucTemp_time1!=0)&&(ucTemp_time2!=0))

{ucHigh_time=TH0;

ucLow_time=TL0;

}

}

////////////////////////////////////////////////

void over()interrupt 1 //T0溢出为无效测量FFF ;

{ucFlag=2;//溢出标志位

TR0=0;//关定时器0

ET0=0;//屏蔽定时器0中断

EX0=0;//屏蔽外部中断

}

/**************************主程序************************/ void main(void)

{ Tmr0_int();

Int0_int();

Ustart_int(); //串口通讯初始化

init_LCD1602() ;

EA=1; //开总中断

while(1)

{ PX0=1; //设置外部0中断优先级为最高

TH0=0;

TL0=0;//清定时0

TR0=1;//开定时0

ET0=1;//开启定时器0中断

if(Mod_long==0)

{ Send_40khz_long();//发射40khz 脉冲 测量长距离

delay_ms(1); //1ms

delay_us(80); // 0.724ms 防回波干扰 总延时25*40/1000+1+0.724=2.724ms //盲区:2.724*170=463mm

}

if (Mod_long==1& Mod_short==1)

{ Send_40khz_medium();//发射40khz 脉冲 测量中距离

delay_us(127);// 防回波干扰 1.157ms 延时

//总延时1.157+0.05=1.207ms

//盲区:1.207*170=205.19mm

}

if(Mod_short==0)

{Send_40khz_short();//发射40khz 脉冲 测量短距离

}

EX0=1; //开启int0中断

Display_dis( ); //距离显示

Display_tem(); //温度显示

Display_c(); //声速显示

/* Tmr1_int(); 音乐播放

delay_ms(200);

delay_ms(200);

//delay_ms(200);

ET1=0; //关tmr1中断 关闭音乐,避免开音乐是中断太频繁,引起测温和测距离都不准确

*/

// delay_ms(200);

delay_ms(200);

Key_scan(); //扫描按键判断是否要发送数据与凌阳版通讯 }

}

(2)显示模块

#ifndef _RZ_LCD1602_

#define _RZ_LCD1602_

#ifndef uchar

#define uchar unsigned char

#endif

#ifndef uint

#define uint unsigned int

#endif

uchar code number[10]={"0123456789"};//用来显示数据

#define Port P2

sbit RS_LCD1602=P1^1;

sbit RW_LCD1602=P1^2;

sbit EN_LCD1602=P1^3;

void Delay_Ms_LCD1602(uint ms)

{//延时程序(以毫秒为单位) 。

uchar y,z;

for(;ms>0;ms--)

for(y=0;y

for(z=0;z

}

bit get_status_LCD1602() //读状态。

{Port=0xff;

EN_LCD1602=0;

RS_LCD1602=0;

RW_LCD1602=1;

EN_LCD1602=1;

return((bit)(Port&0x80));

}

void write_command_LCD1602(uchar com) //写命令。

{while(get_status_LCD1602());

EN_LCD1602=0;

RS_LCD1602=0;

RW_LCD1602=0;

Delay_Ms_LCD1602(5);

Port=com;

EN_LCD1602=1;

Delay_Ms_LCD1602(20);

EN_LCD1602=0;

}

void set_cursor_LCD1602(uchar line,uchar add) //设置光标的行(line),列(add)位置。

{write_command_LCD1602(0x80+line*0x40+add);

}

void write_char_LCD1602(uchar indata) //写数据。

{while(get_status_LCD1602());

EN_LCD1602=0;

RS_LCD1602=1;

RW_LCD1602=0;

Delay_Ms_LCD1602(5);

P2=indata;

EN_LCD1602=1;

Delay_Ms_LCD1602(20);

EN_LCD1602=0;

}

void Write_CGA_LCD1602(uchar *CGA_Data,uchar CGA_Index) //写自定义字符

{ uchar index;

CGA_Index&=0x07;//最多8个字符。

CGA_Index=CGA_Index

for(index=0;index

{//设置CGARAM 地址。

write_command_LCD1602(CGA_Index|index|0x40);

//写入字模数据。

write_char_LCD1602(*CGA_Data);

CGA_Data++;

}

}

void write_char_add_LCD1602(uchar indata,uchar line,uchar add)

{//在指定的行(line),列(add)位置写入字符(indata)。

set_cursor_LCD1602(line,add);

write_char_LCD1602(indata);

}

void write_string_LCD1602(uchar indata[])

{//从当位置开始写入指定长度(lenght)的字符串(indata[])。

//一次最多写入255个。

uchar index=0;

while(indata[index]!=0&&index

index++;

}

}

void cursor_show_LCD1602() //打开显示屏并显示闪烁的光标。 {write_command_LCD1602(0x0f);

}

void cursor_hide_LCD1602() //隐藏光标

{write_command_LCD1602(0x0c);

}

void clear_LCD1602() //清屏。

{while(get_status_LCD1602()&0x80);//等待空闲状态。

write_command_LCD1602(0x01);

Delay_Ms_LCD1602(50);

}

void init_LCD1602() //初始化液晶

{write_command_LCD1602(0x38);//设置显示模式。

write_command_LCD1602(0x80);//光标初始位置。

write_command_LCD1602(0x0f);//打开显示屏并显示闪烁的光标。 write_command_LCD1602(0x06);//输入数据后光标自动向后移。 cursor_hide_LCD1602(); //隐藏光标。

}

****************************************************************/ void LCD_gotoxy(uchar x, uchar y)

{ x &= 0x1; //限制x 不能大于1,y 不能大于15 y &= 0xF;

if(!x) write_command_LCD1602(0x80|y);

else write_command_LCD1602(0xC0|y);

}

/************************************************************ **************************************************************/ void write_number(uint num,uchar n)

{ uchar a; //个位

uchar b; //十位

uchar c; //百位

uchar d; //千位

uchar e; //万位

switch(n)

{case 1:write_char_LCD1602(number[num]);

break;

case 2:b=num/10;

a=num%10;

write_char_LCD1602(number[b]);

write_char_LCD1602(number[a]);

break;

case 3:c=num/100;

b=num%100/10;

a=num%10;

write_char_LCD1602(number[c]);

write_char_LCD1602(number[b]);

write_char_LCD1602(number[a]);

break;

case 4:d=num/1000;

c=num%1000/100;

b=num%1000%100/10;

a=num%10;

write_char_LCD1602(number[d]);

write_char_LCD1602(number[c]);

write_char_LCD1602(number[b]);

write_char_LCD1602(number[a]);

break;

case 5:e=num/10000 ;

d=num%10000/1000;

c=num%1000/100;

b=num%1000%100/10;

a=num%10;

write_char_LCD1602(number[e]);

write_char_LCD1602(number[d]);

write_char_LCD1602(number[c]);

write_char_LCD1602(number[b]);

write_char_LCD1602(number[a]);

break;

}}

#endif

(3)温度传感器模块

/***********************************************

*函数功能:单一18B20驱动 *

*环境:TA89S52 晶振:12M *

*版本:V1.0 测试通过(负温度未测试) *

*By Andy 2008-5-23 copyright: *

***********************************************/

#ifndef DS18B20_H

#define DS18B20_H

#include

#include

#include

typedef unsigned char byte;

typedef unsigned int word;

/**************DS18B20温度定义部分×**************/

sbit DQ=P1^0; //18B20 接口

bit flag_minus=0;

word temp_data[3];

/********************函数列表********************/

void adjust_res(char res); //res 分别等于 0x1f, 0x3f, 0x5f 温度读数分辨率分别对应

byte ow_reset(void);

byte read_byte(void);

void write_byte(char val);

word Read_Temperature(void);

/************************************************

void DS18B20_delay(word useconds)

{ for(;useconds>0;useconds--); //延时8×+7

}

byte ow_reset(void) //复位

{byte presence;

DQ = 0; //拉低总线

DS18B20_delay(29); // 保持 480us 29 DQ = 1; // 释放总线

DS18B20_delay(3); // 等待回复

presence = DQ; // 读取信号

DS18B20_delay(25); // 等待结束信号

return(presence); // 返回 0:正常 1:不存在 }

/************************************************ byte read_byte(void)

{byte i;

byte value = 0;

for (i=8;i>0;i--)

{value>>=1;

DQ = 0;

DQ = 1;

DS18B20_delay(1);

if(DQ)value|=0x80;

DS18B20_delay(6);

}

return(value);

}

/************************************************ void write_byte(char val)

{byte i;

for (i=8; i>0; i--) // 一次写一位

{DQ = 0; //

DQ = val&0x01;

DS18B20_delay(5); //

DQ = 1;

val=val/2; //向右移1位

}

DS18B20_delay(5);

}

/************************************************ void adjust_res(char res)

{ow_reset(); //复位

write_byte(0xcc); //跳过Rom

write_byte(0x4e); //写暂存器

write_byte(0x02); //写TH

write_byte(0x01); //写TL

//write_byte(0x5f); //写结构寄存器

write_byte(res);

ow_reset(); //复位

write_byte(0xcc); //跳过Rom

摘 要

随着科技的发展,人们生活水平的提高,城市发展建设加快,城市给交通系统也有较大发展,其状况不断改善。但是,由于多种原因合成时间住的许多不可预见因素,城市还是经常出现大量的交通事故,特别是倒车时,看不到后方而导致大量的交通事故。因此,设计出好的倒车雷达系统,对于减少城市的交通事故将有一个很好的控制作用。当然这要求倒车雷达系统,具有精度高,抗干扰强,价格应该低,适宜推广等特点,这样基于超声波的测距系统,完全可以胜任此任务。

本设计采用以A T89C51单片机为核心的低成本、高精度、微型化数字显示超

声波测距仪的硬件电路和软件设计方法。整个电路采用模块化设计,由主程序、发射子程序、接收子程序、显示子程序等模块组成。各探头的信号经单片机综合分析处理,实现超声波测距仪的各种功能。在此基础上设计了系统的总体方案,最后通过硬件和软件实现了各个功能模块。该设计设抗干扰能力较好,实时性良好,误差可以达到mm 级,可以有效地解决汽车倒车作用。

本系统在倒车时不断测量汽车尾部与其后面障碍物的距离,并随时显示其距

离,并用语音及时提示。在不同的距离范围内,不同的温度下测出距离,发出报警 信号,以提高汽车倒车时的安全性的仪器。

目录

第一章 绪论 …………………………………………3

1.1 课题背景,目的和意义 ………………………………………3

1.2两种常用的超声波测距方案 …………………………………3

第2章 超声波测距系统设计 …………………………………3

2.1 超声波测距的原理 ………………………………4

2.2超声波测距系统电路的设计 …………………………4

2.2.1 总体设计方案 ……………………………………4

2.2.2发射电路的设计 ………………………………4

2.2.3接收电路的设计 ……………………4

2.2.4显示模块的设计 ………………………………………5

2.2.5 温度补偿模块设计………………………………5

2.2.6 语音处理模块………………………………………5

第三章 超声波测距系统的软件设 ……………………………..5

3.1总体流程图 ……………………………..5

3.2 程序及分析 ……………………………..6

第四章 电路调试及误差分析 ……………………………..7

4.1电路的调试 ……………………………..7

4.2系统的误差分析 ……………………………..7

第5章 功能扩展………………………………………7

参考文献 ……………………………..7

附录:„„„„„„„„„„„„„„„8-22

第1章 绪论

1.1 课题背景,目的和意义

由于社会的进步,经济的发展和生活水平的不断提高,汽。

车数量逐年增长,造成道路交通拥挤不堪,交通事故频繁发生

汽车倒车报警器:在倒车时不断测量汽车尾部与其后面障碍物的距离,并随时显示

其距离,并用语音及时提示。在不同的距离范围内,不同的温度下测出距离,发出

报警信号,以提高汽车倒车时的安全性的仪器。

2.2两种常用的超声波测距方案

2.2.1基于CPLD 的超声波测距系统

CPLD 模块主要由发射模块,16位计时计数器模块,接收模块,顺序执行计

数器模块和六选一数据选择器模块五部分组成。其总体框图如图1所示。

CPLD 模块主要完成超声波的发射、接收和时间的测量。超声波发射模块启动

40KHz 的超声波发射,当发射脉冲串达到设定值后,关闭超声波的发射,同时启动

六路计时计数器模块开始计时; 信号经过障碍物反射回来,接收电路接收到回波后,

将其进行整形,作为接收模块的信号,当接收完回波脉冲信号后,接收模块输出端

发出信号,关闭计时计数器停止工作; 当所有的回波接收完毕后,顺序执行计数器输

出端发出信号启动单片机开始接收数据,通过顺序执行计数器的计数值、数据选择

器的选择端与计时计数器的控制端分别读取六路不同的计数值。所有的数据读取完

后,清除计时计数器的计数值,准备下一次的循环计数。

2.2.1基于单片机的超声波测距系统

本警器由单片机来控制。整个控制系统由超声波发射电路、超声波接收电路、

报警电路、复位电路、显示电路组成。实行实时数字显示测得的距离,在不同的距

离范围内发出不同的报警信号,驾驶员可根据个人需要调整设置报警距离,以减少

事故的发生。本作品将采用此种方法。

第二章 超声波测距系统设计

2.1 超声波测距的原理

超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声

波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就

立即停止计时。超声波在空气中的传播速度为c ,根据计时器记录的时间t ,

就可以计算出发射点距障碍物的距离(s),即:s=ct/2 。这就是所谓的时间差

测距法。

2.2超声波测距系统电路的设计

2.2.1 总体设计方案

该设计总体基于51,包括发射模块,接收模块,显示模块,语音模块,温

度补偿模块。由发射电路发射超声波,51计数器从0开始计时,当超声波反射回来,

接收电路接收,51停止计时,将所计得得数转化成十进制n ,因为使用的12MHz

晶体作时钟基准的89C51单片机定时器能方便的计数到1μs的精度,因此系统采用

89C51定时器能保证时间误差在1mm 的测量范围内。,则将n 与1us 相乘即可以得

到时间,从而利用超声波测距的原理就可以判断距离以是否利用利用凌阳61版的语

音处理功能,进行报警及播放当前的距离,温度和超声波传播速度。再者显示器也

将显示距离,温度,及超声波传播速度。

2.2.2发射电路的设计

用单片机直接产生的40khz 信号经过74ls04放大后直接驱动超声波发射探头。

2.2.3接收电路的设计

将超声波接收探头接收的信号经cx20106红外线专用芯片处理接收,然后送给

单片机。

2.2.4显示模块的设计

使用1602液晶屏,与单片机连接,将单片机的距离,温度,超声波数度(声

速)传送给液晶屏显示出来。

2.2.5 温度补偿模块设计

因为声速在不同温度下的传播速度是不同的,根据补偿公式

C=C0+0.607×T ℃ C0为零度时的声波速度332m/s;T 为实际温度(℃) 。采用18b20

温度传感器测温,根据测得的温度,来确定具体的声速。

2.2.6 语音处理模块

根据手中的现有的材料,利用凌阳61版的语音处理功能,播放出:“倒车请

注意”并通过51单片机和凌阳的串口通讯,将51测得的距离,温度,声速数据传

给凌阳,然后通过凌阳的语音处理将其播报出来。

第三章 超声波测距系统的软件设计

3.1总体流程图

3.1.1凌阳模块流程图

3.1.2 51单片机模块

3.2 程序及分析

(见附录)

第4章 电路调试及误差分析

5.1电路的调试(盲区问题)

由于超声波发射探头在发射超声波时,接受探头也会接受到超声波,所以在发

射超声波时,必须先关外部中断,延时一段时间,进而消除回波干扰,所以在测量

中会有盲区出现,所以硬件调试中主要的就是调节延时时间,使盲区达到最小,进

而跳高测量的精度。

通过硬件调试,来控制发射脉冲波的个数以及延时时间,并在实际测量中测

出三种不同测距模式下的盲区,分别约为5cm ,20cm 及45cm 。

、 5.2系统的误差分析 28

根据超声波测距公式L=C×T,可知测距的误差是由超声波的传播速度误差和测

量距离传播的时间误差引起的。

1. 时间误差

当要求测距误差小于1mm 时,假设已知超声波速度C=344m/s (20℃室温) ,忽

略声速的传播误差。测距误差s△t

在超声波的传播速度是准确的前提下,测量距离的传播时间差值精度只要在达

到微秒级,就能保证测距误差小于1mm 的误差。使用的12MHz 晶体作时钟基准的

89C51单片机定时器能方便的计数到1μs 的精度,因此系统采用89C51定时器能保

证时间误差在1mm 的测量范围内。

2. 超声波传播速度误差

超声波的传播速度受空气的密度所影响,空气的密度越高则超声波的传播速

度就越快.

第5章 功能扩展

将通过串口与PC 机进行通讯,并利用所学知识,用VB 写了了一个接受模块,51单片机中的数据经串

口传到电脑上显示。

参考文献 33

单片机原理与控制技术 机械工业出版社

数字电子技术教程 清华大学出版社

模拟电子技术教程 清华大学出版社

胡萍. 超声波测距仪的研制. 计算机与现代化

时德刚,刘哗. 超声波测距的研究. 计算机测量与控制 超声波测距原理

附录:

//////////////主文件程序main//////////////////////////////////////////////

3.2.1超声波测距

#include

#include

#include"18B20.h"

#include "intrins.h"

#include"LCD1602.H"

#include"Delay1.h"

#define uchar unsigned char

#define uint unsigned int

uchar ucHigh_time,ucLow_time; //超声波传输时间

uchar ucFlag; //中断标志位

uchar frq; //音乐频率节拍问题

float c; //不同温度下的超声波传播速度

/*************************针脚定义********************************/ sbit Hz40k_out =P3^6; //40k信号输出端

sbit Mod_short=P1^4;

sbit Mod_long=P1^5;

sbit Mod_out = P1^7; // 判断数据是发给电脑机还是凌阳版

sbit Key_tran=P1^6; //发送数据,开始通讯

/*****************************************************************/ /**********************函数声明***********************************/ void Tmr0_int(void);

void Int0_int(void);

void Send_40khz_long(void) ; //发射超声波

void Send_40khz_medium(void) ;

void Send_40khz_short(void) ;

int Distance_count(); //距离转换函数

float Compensate_c(); //温度补偿函数

void Display_dis(void) ; //距离显示函数

void Display_tem(void) ; //温度显示函数

void Display_c(void) ; //声速显示函数

void delayms(unsigned char ms);

void Tmr1_int(void);

/***********************子程序 ********************************/ void Tmr0_int(void)

{TMOD|=0x01; //tmr0方式1,16位计数

EA=0; //关总中断

ET0=0; //关T0中断

TR0=0; //停止计时器0

TH0=0X00;

TL0=0X00;

}

//////////////////////////////////////////////////////////////

void Int0_int(void)

{IT0=0; //低电平沿触发

EA=0; //关总中断

EX0=0; //屏蔽中断

}

/////////////////////////////////////////////////////////////

void Ustart_int(void)

{SCON |= 0x50; //串口方式1, 允许接收

TMOD |= 0x20; //定时器1定时方式2

// TCON = 0x40; //设定时器1开始计数

TH1 = 0xF3; //12MHz 2400波特率

TL1 = 0xF3;

TR1 = 0; //关闭定时器

}

///////////////////////////////////////////////////////////

void Ustart_send_lingyang(void)

{ uchar send[3];

uint V oice_v;

send[0]=Distance_count();

send[1]=Distance_count()>>8;

TR1 = 1; //启动定时器

TI=0;

SBUF=send[1]; //先发高位再发低位

while(!TI); //等待发送完成

TI=0;

while(!RI); //等待接收完成

RI=0;

//delay_ms(200);

SBUF=send[0];

while(!TI);

TI=0;

send[0]=Read_Temperature()/10;

send[1]=(Read_Temperature()/10)>>8;//发送的为实际温度的十倍37.2C 则发送372

while(!RI); //等待接收完成

RI=0;

//delay_ms(200);

SBUF=send[1];

while(!TI);

TI=0;

while(!RI); //等待接收完成

RI=0;

//delay_ms(200);

SBUF=send[0];

while(!TI);

TI=0;

V oice_v=Compensate_c(); //将浮点型转换为整型 send[0]=Voice_v;

send[1]=Voice_v>>8;

while(!RI); //等待接收完成

RI=0;

//delay_ms(200);

SBUF=send[1];

while(!TI);

TI=0;

while(!RI); //等待接收完成

RI=0;

//delay_ms(200);

SBUF=send[0];

while(!TI);

TI=0;

while(!RI); //等待接收完成

RI=0;

TR1=0;//关闭定时器

}

////////////////////////////////////////////////////////////////////////// void Ustart_send_pc(void)

{

uchar send[4];

uint V oice_v;

send[0]=Distance_count()/1000+0x30;

send[1]=Distance_count()%1000/100+0x30;

send[2]=Distance_count()%100/10+0x30;

send[3]=Distance_count()%10+0x30;

TR1 = 1; //启动定时器

TI=0;

SBUF=send[0];

while(!TI);

TI=0;

SBUF=send[1];

while(!TI);

TI=0;

SBUF=send[2];

while(!TI);

TI=0;

SBUF=send[3];

while(!TI);

TI=0;

send[0]=(Read_Temperature()/10)/100+0x30;

send[1]=(Read_Temperature()/10)%100/10+0x30;//发送的为实际温度的十倍 37.2C 则发送372

send[2]=(Read_Temperature()/10)%10+0x30;

SBUF=send[0];

while(!TI);

TI=0;

SBUF=send[1];

while(!TI);

TI=0;

SBUF=send[2];

while(!TI);

TI=0;

V oice_v=Compensate_c(); //将浮点型转换为整型

send[0]=Voice_v/100+0x30;

send[1]=Voice_v%100/10+0x30;

send[2]=Voice_v%10+0x30;

SBUF=send[0];

while(!TI);

TI=0;

SBUF=send[1];

while(!TI);

TI=0;

SBUF=send[2];

while(!TI);

TI=0;

TR1=0;//关闭定时器

}

void Key_scan(void)

{Key_tran=1;//写1准备开始读

if(Key_tran==0)

{ delay_ms(10);

while(!Key_tran) ;//等待按键放开

if (Mod_out==1)

Ustart_send_lingyang();

else

Ustart_send_pc();

}

}

////////////////////////////////////////////////////////////////////////////////////////

void Send_40khz_short(void) //从P1.0发出40KHz 的脉冲 短波测量短距离

{uchar n,p;

for(n=0;n

{Hz40k_out=1;

for(p=0;p

Hz40k_out=0;

for(p=0;p

Hz40k_out=0;

}

}

/////////////////////////////////////////////////////////////

void Send_40khz_medium(void) //从P1.0发出40KHz 的脉冲 中波 测量中距离

{uchar n,p;

for(n=0;n

{Hz40k_out=1;

for(p=0;p

Hz40k_out=0;

for(p=0;p

Hz40k_out=0;

}

}

////////////////////////////////////////////////////////////

void Send_40khz_long(void)//从P1.0发出40KHz 的脉冲长波测量长距离 {uchar n,p;

for(n=0;n

{Hz40k_out=1;

for(p=0;p

Hz40k_out=0;

for(p=0;p

Hz40k_out=0;

}

}

//////////////////////////////////////////////////////////

float Compensate_c() //温度补偿公式

{ c= 331.45+0.607*Read_Temperature()/100;

return c;

}

/////////////////////////////////////////////////////////

int Distance_count()//距离计算函数

{float Temp;

Temp=ucHigh_time*256+ucLow_time-96; //96为实际调试中距离的调整 Temp=(Temp/1000)/2;

Temp*=Compensate_c(); //毫米

return Temp;

}

///////////////////////////////////////////////////////

void Display_dis(void) //显示距离

{ switch(ucFlag)

{case 1: { LCD_gotoxy(0, 0);

write_string_LCD1602("Distance:");

if( Distance_count()/1000>0) //判读显示位数 write_number(Distance_count(),4);

else if (Distance_count()/100>0)

write_number(Distance_count(),3);

else if (Distance_count()/10>0)

{write_number(Distance_count(),2);

write_string_LCD1602(" ");}

else

{write_number(Distance_count(),1);write_string_LCD1602(" ");}

write_string_LCD1602("mm");

break;

}

case 2: { LCD_gotoxy(0, 0);

write_string_LCD1602("Distance:wrong ") ; break;

}

default : { LCD_gotoxy(0, 0);

write_string_LCD1602("Begin ") ; break;

}

}

}

///////////////////////////////////////////////////////////////////

void Display_tem(void) //显示温度

{ LCD_gotoxy(1, 0);

write_string_LCD1602("T:");

if (Read_Temperature()/100>=100)

write_number(Read_Temperature()/100,3);

else

write_number(Read_Temperature()/100,2);

write_string_LCD1602(".");

write_number(Read_Temperature()%100/10,1);

write_string_LCD1602("C");

}

///////////////////////////////////////////////////////////////

void Display_c(void) //显示声速

{LCD_gotoxy(1, 8);

write_string_LCD1602("c:");

write_number(Compensate_c(),3);

write_string_LCD1602("m/s");

}

/*****************中断处理***********************/

void INT0_Ultrasonic() interrupt 0

{ uchar ucTemp_time1,ucTemp_time2;

ucFlag=1;//外部中断标志位

TR0=0;//关定时器0

ET0=0;//屏蔽定时器0中断

EX0=0;//关外部中断

ucTemp_time1=TL0;

ucTemp_time2=TH0;

if((ucTemp_time1!=0)&&(ucTemp_time2!=0))

{ucHigh_time=TH0;

ucLow_time=TL0;

}

}

////////////////////////////////////////////////

void over()interrupt 1 //T0溢出为无效测量FFF ;

{ucFlag=2;//溢出标志位

TR0=0;//关定时器0

ET0=0;//屏蔽定时器0中断

EX0=0;//屏蔽外部中断

}

/**************************主程序************************/ void main(void)

{ Tmr0_int();

Int0_int();

Ustart_int(); //串口通讯初始化

init_LCD1602() ;

EA=1; //开总中断

while(1)

{ PX0=1; //设置外部0中断优先级为最高

TH0=0;

TL0=0;//清定时0

TR0=1;//开定时0

ET0=1;//开启定时器0中断

if(Mod_long==0)

{ Send_40khz_long();//发射40khz 脉冲 测量长距离

delay_ms(1); //1ms

delay_us(80); // 0.724ms 防回波干扰 总延时25*40/1000+1+0.724=2.724ms //盲区:2.724*170=463mm

}

if (Mod_long==1& Mod_short==1)

{ Send_40khz_medium();//发射40khz 脉冲 测量中距离

delay_us(127);// 防回波干扰 1.157ms 延时

//总延时1.157+0.05=1.207ms

//盲区:1.207*170=205.19mm

}

if(Mod_short==0)

{Send_40khz_short();//发射40khz 脉冲 测量短距离

}

EX0=1; //开启int0中断

Display_dis( ); //距离显示

Display_tem(); //温度显示

Display_c(); //声速显示

/* Tmr1_int(); 音乐播放

delay_ms(200);

delay_ms(200);

//delay_ms(200);

ET1=0; //关tmr1中断 关闭音乐,避免开音乐是中断太频繁,引起测温和测距离都不准确

*/

// delay_ms(200);

delay_ms(200);

Key_scan(); //扫描按键判断是否要发送数据与凌阳版通讯 }

}

(2)显示模块

#ifndef _RZ_LCD1602_

#define _RZ_LCD1602_

#ifndef uchar

#define uchar unsigned char

#endif

#ifndef uint

#define uint unsigned int

#endif

uchar code number[10]={"0123456789"};//用来显示数据

#define Port P2

sbit RS_LCD1602=P1^1;

sbit RW_LCD1602=P1^2;

sbit EN_LCD1602=P1^3;

void Delay_Ms_LCD1602(uint ms)

{//延时程序(以毫秒为单位) 。

uchar y,z;

for(;ms>0;ms--)

for(y=0;y

for(z=0;z

}

bit get_status_LCD1602() //读状态。

{Port=0xff;

EN_LCD1602=0;

RS_LCD1602=0;

RW_LCD1602=1;

EN_LCD1602=1;

return((bit)(Port&0x80));

}

void write_command_LCD1602(uchar com) //写命令。

{while(get_status_LCD1602());

EN_LCD1602=0;

RS_LCD1602=0;

RW_LCD1602=0;

Delay_Ms_LCD1602(5);

Port=com;

EN_LCD1602=1;

Delay_Ms_LCD1602(20);

EN_LCD1602=0;

}

void set_cursor_LCD1602(uchar line,uchar add) //设置光标的行(line),列(add)位置。

{write_command_LCD1602(0x80+line*0x40+add);

}

void write_char_LCD1602(uchar indata) //写数据。

{while(get_status_LCD1602());

EN_LCD1602=0;

RS_LCD1602=1;

RW_LCD1602=0;

Delay_Ms_LCD1602(5);

P2=indata;

EN_LCD1602=1;

Delay_Ms_LCD1602(20);

EN_LCD1602=0;

}

void Write_CGA_LCD1602(uchar *CGA_Data,uchar CGA_Index) //写自定义字符

{ uchar index;

CGA_Index&=0x07;//最多8个字符。

CGA_Index=CGA_Index

for(index=0;index

{//设置CGARAM 地址。

write_command_LCD1602(CGA_Index|index|0x40);

//写入字模数据。

write_char_LCD1602(*CGA_Data);

CGA_Data++;

}

}

void write_char_add_LCD1602(uchar indata,uchar line,uchar add)

{//在指定的行(line),列(add)位置写入字符(indata)。

set_cursor_LCD1602(line,add);

write_char_LCD1602(indata);

}

void write_string_LCD1602(uchar indata[])

{//从当位置开始写入指定长度(lenght)的字符串(indata[])。

//一次最多写入255个。

uchar index=0;

while(indata[index]!=0&&index

index++;

}

}

void cursor_show_LCD1602() //打开显示屏并显示闪烁的光标。 {write_command_LCD1602(0x0f);

}

void cursor_hide_LCD1602() //隐藏光标

{write_command_LCD1602(0x0c);

}

void clear_LCD1602() //清屏。

{while(get_status_LCD1602()&0x80);//等待空闲状态。

write_command_LCD1602(0x01);

Delay_Ms_LCD1602(50);

}

void init_LCD1602() //初始化液晶

{write_command_LCD1602(0x38);//设置显示模式。

write_command_LCD1602(0x80);//光标初始位置。

write_command_LCD1602(0x0f);//打开显示屏并显示闪烁的光标。 write_command_LCD1602(0x06);//输入数据后光标自动向后移。 cursor_hide_LCD1602(); //隐藏光标。

}

****************************************************************/ void LCD_gotoxy(uchar x, uchar y)

{ x &= 0x1; //限制x 不能大于1,y 不能大于15 y &= 0xF;

if(!x) write_command_LCD1602(0x80|y);

else write_command_LCD1602(0xC0|y);

}

/************************************************************ **************************************************************/ void write_number(uint num,uchar n)

{ uchar a; //个位

uchar b; //十位

uchar c; //百位

uchar d; //千位

uchar e; //万位

switch(n)

{case 1:write_char_LCD1602(number[num]);

break;

case 2:b=num/10;

a=num%10;

write_char_LCD1602(number[b]);

write_char_LCD1602(number[a]);

break;

case 3:c=num/100;

b=num%100/10;

a=num%10;

write_char_LCD1602(number[c]);

write_char_LCD1602(number[b]);

write_char_LCD1602(number[a]);

break;

case 4:d=num/1000;

c=num%1000/100;

b=num%1000%100/10;

a=num%10;

write_char_LCD1602(number[d]);

write_char_LCD1602(number[c]);

write_char_LCD1602(number[b]);

write_char_LCD1602(number[a]);

break;

case 5:e=num/10000 ;

d=num%10000/1000;

c=num%1000/100;

b=num%1000%100/10;

a=num%10;

write_char_LCD1602(number[e]);

write_char_LCD1602(number[d]);

write_char_LCD1602(number[c]);

write_char_LCD1602(number[b]);

write_char_LCD1602(number[a]);

break;

}}

#endif

(3)温度传感器模块

/***********************************************

*函数功能:单一18B20驱动 *

*环境:TA89S52 晶振:12M *

*版本:V1.0 测试通过(负温度未测试) *

*By Andy 2008-5-23 copyright: *

***********************************************/

#ifndef DS18B20_H

#define DS18B20_H

#include

#include

#include

typedef unsigned char byte;

typedef unsigned int word;

/**************DS18B20温度定义部分×**************/

sbit DQ=P1^0; //18B20 接口

bit flag_minus=0;

word temp_data[3];

/********************函数列表********************/

void adjust_res(char res); //res 分别等于 0x1f, 0x3f, 0x5f 温度读数分辨率分别对应

byte ow_reset(void);

byte read_byte(void);

void write_byte(char val);

word Read_Temperature(void);

/************************************************

void DS18B20_delay(word useconds)

{ for(;useconds>0;useconds--); //延时8×+7

}

byte ow_reset(void) //复位

{byte presence;

DQ = 0; //拉低总线

DS18B20_delay(29); // 保持 480us 29 DQ = 1; // 释放总线

DS18B20_delay(3); // 等待回复

presence = DQ; // 读取信号

DS18B20_delay(25); // 等待结束信号

return(presence); // 返回 0:正常 1:不存在 }

/************************************************ byte read_byte(void)

{byte i;

byte value = 0;

for (i=8;i>0;i--)

{value>>=1;

DQ = 0;

DQ = 1;

DS18B20_delay(1);

if(DQ)value|=0x80;

DS18B20_delay(6);

}

return(value);

}

/************************************************ void write_byte(char val)

{byte i;

for (i=8; i>0; i--) // 一次写一位

{DQ = 0; //

DQ = val&0x01;

DS18B20_delay(5); //

DQ = 1;

val=val/2; //向右移1位

}

DS18B20_delay(5);

}

/************************************************ void adjust_res(char res)

{ow_reset(); //复位

write_byte(0xcc); //跳过Rom

write_byte(0x4e); //写暂存器

write_byte(0x02); //写TH

write_byte(0x01); //写TL

//write_byte(0x5f); //写结构寄存器

write_byte(res);

ow_reset(); //复位

write_byte(0xcc); //跳过Rom


相关内容

  • 基于单片机的倒车雷达设计毕业设计
  • 基于单片机的倒车雷达设计 摘 要 随着社会经济的发展,交通运输业日益兴旺,汽车的数量大幅攀升.交通拥挤状况也日益严重,倒车撞车事件屡屡发生,造成了不可避免的人生伤亡和经济损失,针对这种情况,设计一种响应快,可靠性高且较为经济的汽车防撞预警系统势在必行,超声波测距法是最常见的一种距离测距方法,本文介绍 ...

  • 基于单片机的超声波传感器测距系统
  • 河北科技师范学院欧美学院 科技技能训练--------综述 姓 名 胡连 学 号 9310080311 专 业 电气工程及自动化 院 系 机电科学与工程系 指导老师 王宽 王枫 欧美学院机电科学与工程系 2011年7 月 基于单片机的超声波传感器测距系统 摘要 如今,拥有汽车的人越来越多,随之带来的 ...

  • 倒车雷达电路
  • 基于MSP430F2274单片机的倒车雷达设计 随着人们对汽车辅助驾驶系统智能化要求的提高和汽车电子系统的网络化发展,新型的倒车雷达应能够连续测距并显示障碍物距离,并具有通信功能,能够把数据发送到汽车总线上去. 以往的倒车雷达设计使用的元器件较多,功能也较简单.本文介绍的基于新型高性能超低功耗单片机 ...

  • 超声波倒车雷达系统设计
  • 目录 摘要:.............................................................. 3 Abstract ........................................................... 4 第一章绪论 .. ...

  • 100个自动化概论课结课论文题目
  • 1. 智能压力传感器系统设计 2. 智能定时器 3. 液位控制系统设计 4. 液晶控制模块的制作 5. 嵌入式激光打标机运动控制卡软件系统设计 6. 嵌入式激光打标机运动控制卡硬件系统设计 7. 基于单片机控制的数字气压计的设计与实现 8. 基于MSC1211的温度智能温度传感器 9. 机器视觉系统 ...

  • 单片机毕业设计题目
  • 1. 智能压力传感器系统设计 2. 智能定时器 3. 液位控制系统设计 4. 液晶控制模块的制作 5. 嵌入式激光打标机运动控制卡软件系统设计 6. 嵌入式激光打标机运动控制卡硬件系统设计 7. 基于单片机控制的数字气压计的设计与实现 8. 基于MSC1211的温度智能温度传感器 9. 机器视觉系统 ...

  • 自动化毕业设计论文题目
  • 自 动 化 毕 业 设 计 论 文 题 目 1. 智能压力传感器系统设计 2. 智能定时器 3. 液位控制系统设计 4. 液晶控制模块的制作 5. 嵌入式激光打标机运动控制卡软件系统设计 6. 嵌入式激光打标机运动控制卡硬件系统设计 7. 基于单片机控制的数字气压计的设计与实现 8. 基于MSC12 ...

  • 通信工程毕业设计题目精选
  • 不管怎样,生活还是要继续向前走去.有的时候伤害和失败不见得是一件坏事,它会让你变得更好,孤单和失落亦是如此.每件事到最后一定会变成一件好事,只要你能够走到最后. 通信工程毕业设计题目精选 1. 智能压力传感器系统设计 2. 智能定时器 3. 液位控制系统设计 4. 液晶控制模块的制作 5. 嵌入式激 ...

  • 电气自动化设计论文题目大全
  • 机电一体化 毕 业 设 计 论 文 题 目 第1-100个电气自动化毕业设计论文题目 1. 智能压力传感器系统设计 2. 智能定时器 3. 液位控制系统设计 4. 液晶控制模块的制作 5. 嵌入式激光打标机运动控制卡软件系统设计 6. 嵌入式激光打标机运动控制卡硬件系统设计 7. 基于单片机控制的数 ...