汽车倒车雷达系统的设计与实现2009-09-30 10:22引 言
随着中国经济的持续增长和汽车价格的持续下降,越来越多的家庭拥有了私家车。在享受汽车给人们带来便利的同时,由于倒车而产生的问题也日益突出。据初步调查统计,15%的汽车事故是由汽车倒车“后视”不良造成的。早期的倒车防撞仪可以测试车后一定距离范围的障碍物从而发出警报,后来发展到根据距离分段报警。随着人们对汽车驾驶辅助系统易用性要求的提高,对汽车倒车雷达的要求也越来越高。本文设计的基于单片机AT89C51的倒车雷达,采用美国DAL-LAS半导体公司生产的DS18B20单总线型数字温度传感器进行温度补偿提高了测距精度,采用OC-MJ12232C_3液晶显示模块对车距进行实时显示和ISD4004语音芯片实现了倒车雷达语音报警的功能,并可以根据距离的不同做出不同的语音提示。由于采用了超声波专用集成电路芯片LM1812,有效地提高了系统的可靠性和稳定性。
1 超声波测距原理
超声传感器是一种将其他形式的能转变为所需频率的超声能或是把超声能转变为同频率的其他形式的能的器件。超声波测距原理是利用单片机在超声波传感器发射超声波的同时单片机的T0计数器开始计数,当检测到回波信号后单片机的T0计数器停止计数。测得的时间和声速相乘就可以得到超声波往返过程中走过的路程,所以所测距离S为声波传输距离的一半:
S=Ct/2
式中:S为超声波发射点与被测障碍物之间的距离;C为声波在介质中的传输速率;t为超声波发射到超声波返回的时间间隔。声波在空气中传输速率为:
式中:T为绝对温度;C0=331.45 m/s。
采用单片机脉冲计数的方法,可精确测出t的值。假设单片机幕�髦芷谖猅机,则有t=NT机,则测得的距离为:
2 系统硬件电路设计
2.1 系统结构
系统框图如图1所示。该系统由单片机控制电路、超声波发射与接收电路、温度补偿电路、LCD显示电路以及语音报警电路等几部分组成。单片机AT89C51是整个系统的核心部件,协调各部分电路的工作。单片机在超声波信号发射的同时开始计时,超声波信号在空气中传播遇到障碍物后发生反射,反射的回波信号经过处理后输入到单片机的INTO端产生中断,计数器停止计数。通过计数器测得的脉冲数可得到超声波信号往返所需要的时间,从而达到测距的目的。超声波探头选用TCF40-25TR1型收发一体式超声波传感器,谐振频率为40 kHz;超声发射与接收电路采用LM1812专业集成电路,不仅外围元件较少,电路简单,而且有更好的稳定性及可靠性;温度补偿电路采用一线制数字温度传感器DS18B20,利用声速和温度之间的关系对声速进行校正,从而消除温度对声速的影响;语音报警电路采用ISD4004,可实现汽车倒车过程中的语音报警。
2.2 单片机控制电路
系统控制部分的核心是ATMEL公司生产的AT89C51。AT89C51采用40引脚的双列直插式封装(DIP)形式,内部由CPU,4 KB的ROM,256 B的RAM,2个16位的定时/计数器T0和T1,4个8位的I/O端口和一个全双工串行通信口等部分组成。AT89C51单片机具有系统结构简单,成本低,可靠性高,低功耗等特点。特别是内部集成了4 KB的FLASH程序存储器,使单片机系统的结构更加简单,也使其得到了广泛的应用。同时,它还具有高级语言编程的特点,指令丰富,软件开发简单。AT89C51单片机是整个系统的核心部件,其作用是控制超声波专用集成芯片LM1812的发射和接收,对计时器的计数结果进行数据处理后送入LCD显示以及控制语音报警电路工作。
2.3 超声波发射和接收电路
本系统采用超声波专用集成电路LM1812作为超声波发射和接收电路的主控芯片。LM1812是一种通用型超声波收发器,主要用在各种各样的测距、定向和通信中。芯片包括一个脉冲调制C类发射器,一个高增益接收器,一个脉冲调制检测器及噪音抑制电路。LM1812第1脚外
vae.la
/////////////////////////////////////////////////////////////////////////////======基于51单片机的ISD4004多段语音录放实验=======/////////
/////////==================== isd.c ===================//////////
///////// 控制IC: AT89C51/52,STC89C51/52RC//////////
///////// 系统晶振:22.1184MHz //////////
///////// 程序编写:东冬(自然风) //////////
///////// 调试时间:2009/02/13 //////////
///////// 版本:ISD4004_1.0V //////////
////////////////////////////////////////////////////////////////////
/* *** 作说明:1、按住K1键开始录音,放开K1键结束录音;再按住K1键,开始录第二段;以此类推;
2、按一下K2键,开始放音,等该段放音结束,继续等待;再按下K2键,放第二段,以此类推
PS:每一段录音长度要手动设置,不能自主控制录音长度(以待后改)*/
#include "STC89C52RC.H"
//#include <reg52.h>
#include <intrins.h>
#include "MyType.h"
//=======分段录音首地址定义======================
#define ISD_ADDS1 0x0000 //录音存放地址1
#define ISD_ADDS2 0x0100 //录音存放地址2
#define ISD_ADDS3 0x0200 //录音存放地址3
#define ISD_ADDS4 0x0300 //录音存放地址4
#define ISD_ADDS5 0x0400 //录音存放地址5
//========ISD4004指令定义========================
#define POWER_UP 0x20 //上电指令
#define SET_PLAY 0xE0 //指定放音指令
#define PLAY 0xF0 //当前放音指令
#define SET_REC 0xA0 //指定录音指令
#define REC 0xB0 //当前录音指令
#define SET_MC 0xE1 //指定快进指令
#define MC 0xF1 //快进执行指令
#define STOP 0x30 //停止当前 *** 作
#define STOP_WRDN 0xF1 //停止当前 *** 作并掉电
#define RINT 0x30 //读状态:OVF和EOM
//=========ISD4004--c51接口定义=================
sbit ISD_SS = P0^0//片选
sbit ISD_MOSI = P0^1//数据输入
sbit ISD_SCLK = P0^2//ISD4004 时钟
sbit ISD_INT = P3^3//溢出中断
sbit ISD_RAC = P3^2//行地址时钟
sbit ISD_MISO = P3^6//数据输出
//==========按键定义==========================
sbit K1 = P1^0 //录音键
sbit K2 = P1^1 //放音键
//==========BEEP开关定义======================
#define Beep_ON (P0&=0x7f) //蜂鸣器开
#define Beep_OFF (P0|=0x80) //蜂鸣器关
//==========ISD4004函数定义===================
void ISD_SPI_Send8( uchar isdx8 )//spi 串行发送子程序,8位数据,从低到高
void ISD_SPI_Send16( uint isdx16 )//spi 串行发送子程序,16位数据.从低到高
uint ISD_SPI_Radd(void) //读取标行地址
void ISD_Stop(void) //发送 stop 指令
void ISD_PowerUp(void) //发送上电指令,并延迟 50ms
void ISD_PowerDown(void) //发送掉电指令,并延迟 50ms
void ISD_Play(void) //发送放音指令,并延迟 50ms
void ISD_SetPlay(uint add) //发送指定放音指令,并延迟 50ms
void ISD_Rec(void)//发送录音指令,并延迟 50ms
void ISD_SetRec(uint add) //发送指定录音指令,并延迟 50ms
uchar ISD_Chk_Isdovf(void)
void PLAY_now(uchar add_sect) //按指定地址开始放音
void REC_now(uchar add_sect) //按指定地址开始录音
//========延时函数===========================
void Delay1Ms(uchar t) //延时t*1毫秒
void Delay()
////////////////////////////////////////////////////////////////////////
//程序开始 //
////////////////////////////////////////////////////////////////////////
/*******************************主程序*********************************/
main ()
{
uchar i,j
while (1)
{
//=========================K1录音键================================
if(K1==0) //K1键按下。录音
{
REC_now(i++) //录第一段
if(i>5) i = 0
while(K1==0) //等待录音完毕
{
if (ISD_INT==0) //如果芯片OVF溢出,进行 蜂鸣器 提示,如果取消录音(松开 AN 键)则停止录音,芯片复 位
{
while(K1==0)
{
Beep_ON
Delay1Ms(250)
Beep_OFF
Delay1Ms(250)
}
}
}
ISD_Stop() //发送停止命令
ISD_PowerDown()
}
//============================K2放音键================================
if(K2==0)
{
PLAY_now(j++)//放第一段
if(j>5) j = 0
while(ISD_INT==1)//等待一段放音完毕的 EOM 中断信号
ISD_Stop()//放音完毕,发送 stop 指令
ISD_PowerDown()
}
}
}
/******************************************************************
名称:PLAY_now(uchar add_sect)
功能:按指定地址段开始播放
指令:
调用:无
返回:无
/*****************************************************************/
void PLAY_now(uchar add_sect)
{
ISD_PowerUp()//ISD 上电
Delay1Ms(50)
switch (add_sect) //发送 setplay 指令,从 0x0000 地址开始放
{
case 1: ISD_SetPlay(ISD_ADDS1)break//发送地址的 SetRec 指令
case 2: ISD_SetPlay(ISD_ADDS2)break//发送地址的 SetRec 指令
case 3: ISD_SetPlay(ISD_ADDS3)break//发送地址的 SetRec 指令
case 4: ISD_SetPlay(ISD_ADDS4)break//发送地址的 SetRec 指令
case 5: ISD_SetPlay(ISD_ADDS5)break//发送地址的 SetRec 指令
//case 6:……
}
ISD_Play()//发送放音指令
}
/******************************************************************
名称:REC_now(uchar add_sect)
功能:按指定地址段开始录音
指令:
调用:无
返回:无
/******************************************************************/
void REC_now(uchar add_sect)
{
ISD_PowerUp()//ISD 上电
Delay1Ms(50)//延迟录音
ISD_PowerUp()//ISD 上电
Delay1Ms(100)//延迟录音
switch (add_sect)
{
case 1: ISD_SetRec(ISD_ADDS1)break//发送地址的 SetRec 指令
case 2: ISD_SetRec(ISD_ADDS2)break//发送地址的 SetRec 指令
case 3: ISD_SetRec(ISD_ADDS3)break//发送地址的 SetRec 指令
case 4: ISD_SetRec(ISD_ADDS4)break//发送地址的 SetRec 指令
case 5: ISD_SetRec(ISD_ADDS5)break//发送地址的 SetRec 指令
//case 6:……
}
ISD_Rec()//发送 rec 指令
}
/******************************************************************
名称:ISD_SPI_Send8(uchar isdx)
功能:spi 串行发送子程序,8 位数据
指令:
调用:无
返回:无
/******************************************************************/
void ISD_SPI_Send8( uchar isdx8 )
{
uchar i
ISD_SS = 0 //选中ISD4004
ISD_SCLK = 0
for(i=0i<8i++)//先发低位再发高位,依次发送。
{
if ((isdx8 &0x01) == 1) //发送最低位
ISD_MOSI = 1
else
ISD_MOSI = 0
isdx8 >>= 1 //右移一位
ISD_SCLK = 1 //时钟下降沿发送
ISD_SCLK = 0
}
}
/******************************************************************
名称:ISD_SPI_Send16(uint isdx16)
功能:spi 串行发送子程序,16位数据
指令:
调用:无
返回:无
/******************************************************************/
void ISD_SPI_Send16( uint isdx16 )
{
uchar i
ISD_SS = 0 //选中ISD4004
ISD_SCLK = 0
for(i=0i<16i++) //先发低位再发高位,依次发送。
{
if ((isdx16&0x0001)==1) //发送最低位
ISD_MOSI = 1
else
ISD_MOSI = 0
isdx16 = isdx16 >>1 //右移一位
ISD_SCLK=1 //时钟下降沿发送
ISD_SCLK=0
}
}
/******************************************************************
名称:ISD_SPI_Radd(void)
功能:读取16位行地址
指令:
调用:无
返回:无
/******************************************************************/
uint ISD_SPI_Radd(void)
{
uchar i
uint addsig
ISD_SS = 0 //选中ISD4004
ISD_SCLK = 0
//==============读16位地址================
for(i=0i<16i++) //读行地址
{
ISD_SCLK = 1 //时钟下降沿数据移出ISD
ISD_SCLK = 0
if (ISD_MISO == 1)
addsig |= 0x8000
if (i<15) addsig >>= 1//最先读出的是地址的低位,所以要左移,最后一次地址不用左移,否则地址溢出
}
ISD_Stop()//发送 stop 指令
ISD_SS = 1//关闭 spi 通信端
return addsig//返回地址值
}
/******************************************************************
名称:ISD_Stop(void)
功能:发送 stop 指令
指令:ISD_SPI_Send8(uchar isdx8)
调用:无
返回:无
/******************************************************************/
void ISD_Stop(void)
{
//ISD_SS = 0
ISD_SPI_Send8(STOP)
ISD_SS = 1//关闭片选
}
/******************************************************************
名称:ISD_PowerUp(void)
功能:发送上电指令,并延迟 50ms
指令:ISD_SPI_Send8(uchar isdx8)
调用:无
返回:无
/******************************************************************/
void ISD_PowerUp(void)
{
ISD_SS = 0//选中ISD4004
ISD_SPI_Send8(POWER_UP)
ISD_SS = 1
}
/******************************************************************
名称:ISD_PowerDown(void)
功能:发送掉电指令,并延迟 50ms
指令:ISD_SPI_Send8(uchar isdx8)
调用:无
返回:无
/******************************************************************/
void ISD_PowerDown(void)
{
ISD_SS = 0
ISD_SPI_Send8(STOP_WRDN)
ISD_SS = 1
}
/******************************************************************
名称:ISD_Play(void)
功能:发送play指令,并延迟 50ms
指令:ISD_SPI_Send8(uchar isdx8)
调用:无
返回:无
/******************************************************************/
void ISD_Play(void)
{
ISD_SS = 0
ISD_SPI_Send8(PLAY)
ISD_SS = 1
}
/******************************************************************
名称:ISD_Rec(void)
功能:发送rec录音指令,并延迟 50ms
指令:ISD_SPI_Send8(uchar isdx8)
调用:无
返回:无
/******************************************************************/
void ISD_Rec(void)
{
ISD_SS = 0
ISD_SPI_Send8(REC)
ISD_SS = 1
}
/******************************************************************
名称:ISD_SetPlay(uint add)
功能:发送setplay指令,并延迟 50ms
指令:ISD_SPI_Send8(uchar isdx8)
ISD_SPI_Send16(uint isdx16)
调用:无
返回:无
/******************************************************************/
void ISD_SetPlay(uint add)
{
Delay1Ms(1)
ISD_SPI_Send16(add) //发送放音起始地址
ISD_SPI_Send8(SET_PLAY)//发送 setplay 指令字节
ISD_SS = 1
}
/******************************************************************
名称:ISD_SetRec(uint add)
功能:发送setrec指令,并延迟 50ms
指令:ISD_SPI_Send8(uchar isdx8)
ISD_SPI_Send16(uint isdx16)
调用:无
返回:无
/******************************************************************/
void ISD_SetRec(uint add)
{
Delay1Ms(1)
ISD_SPI_Send16(add)//发送录音起始地址
ISD_SPI_Send8(SET_REC)//发送 setrec 指令字节
ISD_SS = 1
}
//************************************
//检查芯片是否溢出(读 OVF,并返回 OVF 值)
//************************************
/*uchar ISD_Chk_Isdovf(void)
{
ISD_SS=0
ISD_SCLK=0
ISD_SCLK=1
ISD_SCLK=0
if (ISD_MISO==1)
{
ISD_SCLK=0
ISD_SS =1//关闭 spi 通信端
ISD_Stop()//发送 stop 指令
return 1//OVF 为 1,返回 1
}
else
{
ISD_SCLK=0
ISD_SS =1//关闭 spi 通信端
ISD_Stop()//发送 stop 指令
return 0//OVF 为 0,返回 0
}
}*/
/*=========================================================================
名称: void Delay1Ms(uchar t)
功能:延时0.1ms
参数:t,最大255
调用: 无
返回:无
=========================================================================*/
void Delay1Ms(uchar t)
{
uchar i
for (t>0t--)
{
for (i=0i<150i++)
{
_nop_()_nop_()_nop_()_nop_()_nop_()
_nop_()_nop_()_nop_()_nop_()_nop_()
}
}
}
//========================================
void Delay()
{
uchar i
uint d=5000
while (d--)
{
i=255
while (i--)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)