倒车雷达程序(超声波测距)
开发时间:2014年5月7日星期三 姓名:杨言安 地点:山西大学 //----------------------------------------------------------------------------------------------------------------------------- // 名称:简易倒车雷达
//----------------------------------------------------------------------------------------------------------------------------- //说明:单片机控制超声波模块时时测量汽车后面障碍物的距离(测量范围为3cm--4m),//并将距离值显示在数码管上。当汽车后面有障碍物时数码管会显示障碍物的距离同时告警//电路发出"嘀嘀嘀"的声音,当障碍物离汽车的距离小于0.5米时告警电路发出"嘀嘀嘀"的声//音的频率增加,以此提醒车主注意安全。(单片机型号STC89C52,晶振频率12MHz,超声波模块HC-SR04)
//----------------------------------------------------------------------------------------------------------------------------- //原理:超声波模块触发端口Trig受单片机P1.0口控制,在发送超声波时P1.0口至少维持10us高电平。当超声波接收到返回的超声波时,超声波模块的Echo端口(接单片机的INT0口)会输出高电平,高电平持续的时间就是超声波从发射到接收的时间,测试距离=((高电平时间)*340m/s))/2。利用单片机的定时计数器T0来测量高电平持续的时间:定时/计数器T0使用GATE0门控卫和TR0双重控制来测量高电平持续的时间,当超声波接收到返回信号时,即TNT0口变为高电平时,此时让TR0=1开始计时,当INT0口变为低电平时,让TR0=0,即停止计时。这样高电平持续的时间保持在寄存器TH0和TL0中,即T=256*TH0+TL0;所以距离S=(T*340)/2,再将S在数码管上显示出来。告警部分是由蜂蜜器来控制,在计算完距离后还要判断所测的距离是否小于0.5米,如果是则蜂鸣器发出急促的告警声音,如果大于0.5则发出缓慢的告警声音,表示有障碍物。(本程序最大的亮点是只利用一个定时/计数器完成了超声波的测距。)
//------------------------------------------------------------------------------------------------------------------------------ #include
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
sbit dula=P2^6;//数码管段选信号使能端
sbit wela=P2^7;//数码管位选信号使能端
sbit Dot=P0^7;//小数点使能端
sbit Trig=P1^0;//超声波模块触发端
sbit LED=P1^1;//发光二极管,用于显示是否超出测量范围
sbit beer=P2^3;//蜂鸣器控制口
bit warming;//告警位变量
ulong time;//时间变量,单位为us
ulong distance;//距离变量
uchar code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0};//共阴数码管段代码
uchar data disp_buf[]={0x00,0x00,0x00,0x00};//显示缓存
//------------------------------------------------------------------------------------------------------------------------------ // 长延时函数:用于数码管动态显示
//------------------------------------------------------------------------------------------------------------------------------ void Delay_ms(uint xms)
uint i,j;
for(i=xms;i>0;i--)
for(j=115;j>0;j--);
}
//------------------------------------------------------------------------------------------------------------------------------ // 短延时函数:用于超声波发射
//------------------------------------------------------------------------------------------------------------------------------ void delay_us()
{
uchar i;
for(i=0;i
}
//------------------------------------------------------------------------------------------------------------------------------ // 数值计算:计算距离并校正,最后将其拆分成单个的数字存取到显示缓存中,供数码管//显示时调用
//------------------------------------------------------------------------------------------------------------------------------ caculate()
{
uint temp1,temp2;
distance=time*172;//计算距离
distance/=1000;//单位换算成毫米
distance+=10;//校正误差
if(distance
warming=1;
else
warming=0;//有障碍物是发出一般性警告,告警声音间隔长
disp_buf[0]=(uchar)(distance/1000);//提取千位值
temp1=(uint)(distance%1000);
disp_buf[1]=(uchar)(temp1/100);//提取百位值
temp2=(uchar)(temp1%100);
disp_buf[2]=(uchar)(temp2/10);//提取十位值
disp_buf[3]=(uchar)(temp2%10);//提取个位值
}
//------------------------------------------------------------------------------------------------------------------------------ // 显示函数:将距离值显示在数码管上
//------------------------------------------------------------------------------------------------------------------------------ void Display()
{
dula=1;
P0=table[disp_buf[0]];//显示千位
Dot=1;//显示小数点
dula=0;
P0=0xff;
P0=0xfe; wela=0; Delay_ms(1); dula=1; P0=table[disp_buf[1]];//显示百位 dula=0; P0=0xff; wela=1; P0=0xfd; wela=0; Delay_ms(1); dula=1; P0=table[disp_buf[2]];//显示百位 dula=0; P0=0xff; wela=1; P0=0xfb; wela=0; Delay_ms(1); dula=1;
P0=table[disp_buf[3]];//显示十位
dula=0;
P0=0xff;
wela=1;
P0=0xf7;
wela=0;
Delay_ms(1);
}
//------------------------------------------------------------------------------------------------------------------------------ //定时/计数器0中断服务函数:如果测量距离超过4米时,定时计数器会溢出产生中断 //------------------------------------------------------------------------------------------------------------------------------ void external0() interrupt 1
{
TR0=0;//停止计数
TH0=0x00;
TL0=0x00;//T0清零
LED=~LED;//点亮发光二极管
Delay_ms(3);
LED=1;
//------------------------------------------------------------------------------------------------------------------------------ // 主函数
//------------------------------------------------------------------------------------------------------------------------------ void main()
{
uchar i;
INT0=0;//将外部中断0拉低,为检测电平变化做准备
Trig=0;//将触发端拉低
LED=1;//关闭发光二极管
TMOD=0x09;//打开定时计数器门控卫(GATE0=1)且让定时计数器工作在16位计数模式下
TH0=0x00;//初始化定时/计数器0
TL0=0x00;
EA=1;//开总中断 ET0=1;//开定时器T0中断 while(1) { for(i=0;i
{
uchar c;
beer=1;
for(c=0;c
Display();
beer=0;
}
TH0=0x00;//定时计数器清零,为下次测量做准备 TL0=0x00;
}
}
注:本程序在对超出测量范围是的响应不是很完善,读者可以根据自己的情况加以改善。