基于89C51单片机的智能倒车雷达.docx
《基于89C51单片机的智能倒车雷达.docx》由会员分享,可在线阅读,更多相关《基于89C51单片机的智能倒车雷达.docx(14页珍藏版)》请在冰豆网上搜索。
基于89C51单片机的智能倒车雷达
作品研究报告
基于51单片机的倒车雷达设计
一、引言
倒车雷达(ParkingDistanceControl)是汽车泊车或者车时的安全辅助装置,能以声音或者更为直观的显示告知驾驶员周围障碍物的情况,解除了驾驶员泊车、倒车和起动车辆时前后左右探视所引起的困扰,并帮助驾驶员扫除了视野死角和视线模糊的缺陷,提高驾驶的安全性。
目前市场上中低档汽车上装备的倒车雷达探测距离最大一般只有1.5米左右,且报警系统只是采用简单的“滴滴”声。
只有稍微高档的倒车雷达才会显示距离或简单的语音提示。
考虑到实际情况,本设计从成本考虑,在实现倒车雷达的基本功能同时,综合了液晶显示(1602)、光报警(发光二极管)、声音报警(蜂鸣器)和语音提示(ISD1800)。
二、系统概述
系统采用超声波进行测距,软件设计中在50ms中断中发射超声波,超声波接收端连接到P3.2,当接收到返回的超声波时便会触发中断。
用1602实时显示距离,当距离小于指定范围时,通过液晶显示提示信息,语音提醒及用不同灯显示不同的距离。
三、硬件设计
(1)测距模块
超声波发射模块
软件产生40kHz的超声波信号,通过输出引脚输入至驱动器,经驱动器驱动后推动探头产生超声波,40kHz的超声波是利用555时基电路振荡产生。
超声波接收模块
超声波接收器包括超声波接收探头、信号放大电路及波形变换电路三部分。
超声波探头必须采用与发射探头对应的型号。
为减少负电源的使用,放大电路采用单电源供电,信号放大和变换采用了一片LM324通用运算放大器,前三级为放大器设计,后一级为比较器设计。
测距模块时序分析
(2)液晶显示模块
采用1602液晶,设置为16×2模式,第一行实时显示所测的距离,当出现危险情况时第二行显示提示信息。
(3)语音模块
美国ISD公司的一种单片8~20秒单段语音录放电路ISD1800,它的基本结构与ISD1110、1420完全相同,采用CMOS技术,内含振荡器,话筒前置放大,自动增益控制,防混淆滤波器,扬声器驱动及FLASH阵列。
电源电压3-5V,在录放模式下,按住REC录音按键不放即录音,RECLED灯会亮起,录音在松开按键时停止,放音有三种情况:
1、边沿触发放音,按PE键一下即将全段语音放出,除非断电或语音结束不能停止放音;
2、电平触发放音,按住PL键时即放音,松开按键即停止;
3、循环放音,置循环放音开关闭合,按动PE键即开始循环放音,只能断电才能停止。
四、软件设计
本设计中使用了单片机的三个中断源,分别是外部中断和两个定时器中断。
定时器0定时50ms,T0中断服务程序中触发超声波的发射,并且开外部中断0。
当超声波传感器接收到超声波时会触发外部中断0,在此中断服务程序中读出计数器TH0和TL0中的数。
此数与定时器计数初值之差再乘以机器周期即为超声波发射与接收的时间差。
再通过公式计算得到探测到的距离。
五、部分源代码
/************************1602.h*********************/
#ifndef_LCD1602_
#define_LCD1602_
#include"reg52.h"
#defineucharunsignedchar
#defineuintunsignedint
//初始化函数
voidLCD_init(void);
//写数据函数
voidput_char(uchar);
//写指令函数
voidput_command(uchar);
voidlocate(uchar,uchar);
voidput_number_1(uint);
voidput_number(int);
voidput_string(uchar*);
voidDelay_ms(uint);
#endif
/*********************1602.c*************************/
#include"LCD1602.h"
#defineclear0x01//清屏指令
#definemode0x38//模式选择指令,8位2行5×7点阵
#defineopen0x07
#definemovemode0x0f
#defineclose0x08//关显示指令
#definecursor_reset0x02//光标复位指令
#defineLCDdataP0
sbitRS=P2^6;
sbitE=P2^7;
//LCD初始化函数
voidLCD_init(void)
{
uchari=0;
put_command(0x38);//setLCD16wordsx2linesand5x7
Delay_ms(5);
put_command(0x38);
Delay_ms(5);
put_command(0x38);
Delay_ms(5);
put_command(0x38);
Delay_ms(5);
put_command(0x38);
put_command(0x38);
put_command(0x38);
put_command(0x38);
put_command(0x0e);
//put_command(0x0e);
put_command(0x01);//清显示
put_command(0x06);//光标和显示模式设置
put_command(0x02);
}
//写命令
voidput_command(ucharcommand)
{
RS=0;
//RW=0;
E=0;
LCDdata=command;
Delay_ms
(1);//5
E=1;
Delay_ms
(1);//5
E=0;
}
//写数据函数
voidput_char(uchardatar)
{
E=0;
RS=1;
//RW=0;
LCDdata=datar;
E=1;
Delay_ms
(1);//5
E=0;
}
//在光标的下个位置显示字符串word的函数
voidput_string(uchar*string)
{
while((*string)!
='\0')
{
put_char(*string);
string++;
}
}
//用三位显示数值,前面自动加空格或者负号,显示范围-99~999
voidput_number_1(uintnumber)
{
if(number<-99||number>999)
{
put_string((uchar*)"err");//超出范围
return;
}
elseif(number<0)
{
put_char(0x2d);//负号
number=-number;
}
elseif(number>99)
{
put_char(number/100+0x30);//百
number=number%100;
}
elseput_char(0x8c);//空格
put_char(number/10+0x30);//十
put_char(number%10+0x30);//个
put_char(0x20);
}
//用四位显示数值,前面自动加空格或者负号,显示范围-999~9999
voidput_number(intnumber)
{
if(number<-999||number>9999)
{
put_string((uchar*)"err");//超出范围
return;
}
elseif(number<0)
{
put_char(0x2d);//负号
number=-number;
}
elseif(number>999)
{
put_char(number/1000+0x30);//千
number=number-(number/1000)*1000;
}
elseput_char(0x8c);//空格
put_char(number/100+0x30);//百
put_char(number/10-number/100*10+0x30);//十
put_char(number%10+0x30);//个
}
//光标跳到第x(0-1)行,y(0-7)列
voidlocate(ucharx,uchary)
{
if(x)
{
y|=0x40;
}
y|=0x80;
put_command(y);
}
voidDelay_ms(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/***********************main.c***********************/
#include
#include"LCD1602.h"
sbitTRIG=P3^0;
sbitECHO=P3^2;
sbitsb=P2^0;
sbitled1=P2^1;
sbitled2=P2^2;
uintTime;
uintDistance=0;
voidInter_init(void);
voidmain()
{
led1=0;
led2=0;
Inter_init();
LCD_init();
//P3=0x00;
while
(1)
{
put_number(Distance);
locate(0,0);
if((Distance>250)&&(Distance<=300))
P1=0x7f;
elseif((Distance>200)&&(Distance<=250))
P1=0xbf;
elseif((Distance>150)&&(Distance<=200))
P1=0xdf;
elseif((Distance>100)&&(Distance<=150))
P1=0xef;
elseif(Distance<=100)
P1=0xf7;
else
P1=0xff;
if(Distance<100)
{
sb=0;
}
else
{
sb=1;
}
if((Distance<=150)&&(Distance>100))
{
led2=1;
Delay_ms(50);
led2=0;
}
elseif(Distance<=100)
{
led1=1;
Delay_ms(50);
led1=0;
}
}
}
voidInter_init(void)
{
TMOD=0x11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
ET0=1;//开定时器0溢出中断
TR0=1;//启动定时器
//EX0=1;//开外部中断