【单片机课程设计】汽车盲区检测系统

  • 课程设计要求:
  1. 汽车盲区检测行人,包括左前、右前、 左后、 右后。
  2. 显示各路距离,当距离比较近蜂鸣器提示报警,且阈值可以设置。
  • 主要设计思想
    四个方位分别一个超声波模块,利用程序实现分时检测
    每个超声波反应时间不得少于80ms,所以需要处理相隔时间

项目回顾:单个超声波实现倒车雷达

  • 主要代码:

1602.c

#include "1602.h"
#include "delay.h"

#define CHECK_BUSY

sbit RS = P2^6;   //定义端口 
sbit RW = P2^5;
sbit EN = P2^7;

#define RS_CLR RS=0 
#define RS_SET RS=1

#define RW_CLR RW=0 
#define RW_SET RW=1 

#define EN_CLR EN=0
#define EN_SET EN=1

#define DataPort P0

/*------------------------------------------------
              判忙函数
------------------------------------------------*/
 bit LCD_Check_Busy(void) 
 { 
#ifdef CHECK_BUSY
 DataPort= 0xFF; 
 RS_CLR; 
 RW_SET; 
 EN_CLR; 
 _nop_(); 
 EN_SET;
 return (bit)(DataPort & 0x80);
#else
 return 0;
#endif
 }
/*------------------------------------------------
              写入命令函数
-----------------   ----------------------------*/
 void LCD_Write_Com(unsigned char com) 
 {  
 while(LCD_Check_Busy()); //忙则等待
 RS_CLR; 
 RW_CLR; 
 EN_SET; 
 DataPort= com; 
 _nop_(); 
 EN_CLR;
 }
/*------------------------------------------------
              写入数据函数
------------------------------------------------*/
 void LCD_Write_Data(unsigned char Data) 
 { 
 while(LCD_Check_Busy()); //忙则等待
 RS_SET; 
 RW_CLR; 
 EN_SET; 
 DataPort= Data; 
 _nop_();
 EN_CLR;
 }

/*------------------------------------------------
                清屏函数
------------------------------------------------*/
 void LCD_Clear(void) 
 { 
 LCD_Write_Com(0x01); 
 DelayMs(5);
 }
/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
 void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) 
 {     
 if (y == 0) 
 	{     
	 LCD_Write_Com(0x80 + x);     //表示第一行
 	}
 else 
 	{      
 	LCD_Write_Com(0xC0 + x);      //表示第二行
 	}        
 while (*s) 
 	{     
 LCD_Write_Data( *s);     
 s ++;     
 	}
 }

/*------------------------------------------------
              初始化函数
------------------------------------------------*/
 void LCD_Init(void) 
 {
   LCD_Write_Com(0x38);    /*显示模式设置*/ 
   DelayMs(5); 
   LCD_Write_Com(0x38); 
   DelayMs(5); 
   LCD_Write_Com(0x38); 
   DelayMs(5); 
   LCD_Write_Com(0x38);  
   LCD_Write_Com(0x08);    /*显示关闭*/ 
   LCD_Write_Com(0x01);    /*显示清屏*/ 
   LCD_Write_Com(0x06);    /*显示光标移动设置*/ 
   DelayMs(5); 
   LCD_Write_Com(0x0C);    /*显示开及光标设置*/
   }


1602.h

#include<reg52.h>
#include<intrins.h>

#ifndef __1602_H__
#define __1602_H__

 bit LCD_Check_Busy(void) ;
 void LCD_Write_Com(unsigned char com) ;
 void LCD_Write_Data(unsigned char Data) ;
 void LCD_Clear(void) ;
 void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) ;
 void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) ;
 void LCD_Init(void) ;
 void Lcd_User_Chr(void);   
#endif

delay.c

#include "delay.h"
/*------------------------------------------------
 uS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
 长度如下 T=tx2+5 uS 
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{   
 while(--t);
}
/*------------------------------------------------
 mS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
     
 while(t--)
 {
     //大致延时1mS
     DelayUs2x(245);
	 DelayUs2x(245);
 }
}

delay.h

#ifndef __DELAY_H__
#define __DELAY_H__
void DelayUs2x(unsigned char t);
void DelayMs(unsigned char t);

#endif

main.c

#include<reg52.h>
#include"1602.h"
#include"delay.h"

#define  K1_MODE  1
#define  K2_ADD  2
#define  K3_DEC  3

#define uchar unsigned char
#define uint unsigned int

sbit trig1=P1^7; // 分别对应四路超声波
sbit echo1=P1^6;
sbit trig2=P1^5;
sbit echo2=P1^4;
sbit trig3=P1^3;
sbit echo3=P1^2;
sbit trig4=P1^1;
sbit echo4=P1^0;

sbit led1=P2^0; // 四个led灯显示哪一路距离过近
sbit led2=P2^1;
sbit led3=P2^2;
sbit led4=P2^3;

sbit beep=P3^4; // 蜂鸣器报警
sbit key3=P3^2; // 模式选择
sbit key2=P3^0;	// 减小阈值
sbit key1=P3^1;	// 增加阈值

uchar mode=0;                               // 设置阈值模式选择
uchar s1=0,s2=0,s3=0,s4=0;                  // 四路距离
uchar minx1=20,minx2=20,minx3=20,minx4=20;  // 设置阈值默认值
uchar dis_buf[4];                           // 暂存距离值

void delay_us(uint c)
{
	while(--c);
}

void delay_10ms(uchar c1)
{
	uchar a,b;
	for(;c1>0;c1--)
	{
		for(a=38;a>0;a--)
			for(b=130;b>0;b--);
		if(key1==0||key2==0||key3==0)
			return;
	}	
}

void Dis_DataPros()
{
	// 显示四路距离
	LCD_Write_String(0,0,"LF:");
	dis_buf[0]=s1/100+'0';
	dis_buf[1]=s1/10%10+'0';
	dis_buf[2]=s1%10+'0';
	dis_buf[3]='\0';
	LCD_Write_String(3,0,dis_buf);

	LCD_Write_String(8,0,"RF:");
	dis_buf[0]=s2/100+'0';
	dis_buf[1]=s2/10%10+'0';
	dis_buf[2]=s2%10+'0';
	dis_buf[3]='\0';
	LCD_Write_String(11,0,dis_buf);

	LCD_Write_String(0,1,"LB:");
	dis_buf[0]=s3/100+'0';
	dis_buf[1]=s3/10%10+'0';
	dis_buf[2]=s3%10+'0';
	dis_buf[3]='\0';
	LCD_Write_String(3,1,dis_buf);

	LCD_Write_String(8,1,"RB:");
	dis_buf[0]=s4/100+'0';
	dis_buf[1]=s4/10%10+'0';
	dis_buf[2]=s4%10+'0';
	dis_buf[3]='\0';
	LCD_Write_String(11,1,dis_buf);
}

//mode:  0-单次扫描   1~4-连续扫描
uchar KEY_Scan(uchar mode)
{
	static uchar is_key=1;                  // 按键标志位
	if(is_key&&(key1==0||key2==0||key3==0)) // 某一个按键按下
	{
		// 消抖
		delay_10ms(1);

		is_key=0;              // 标志位变0
		if(key3==0)			   // 检测三个按键
		{
			return K1_MODE;
		}
		else if(key1==0)
		{
			return K2_ADD;
		}
		else if(key2==0)
		{
			return K3_DEC;	
		}
	}
	else if(key1==1&&key2==1&&key3==1)
	{
		is_key=1;			   // 按键抬起,标志位重置
	}
	if(mode)                   // 连续扫描
	{
		is_key=1;
	}
	return 0;	
}

void KEY_Pros()
{
	uchar key;
	key=KEY_Scan(0);

	
	if(key==K1_MODE)   // 模式选择
	{
		mode++;
		LCD_Clear();

		if(mode==1) LCD_Write_String(0,0,"SETX1:   ");		
		else if(mode==2) LCD_Write_String(0,0,"SETX2:   ");
		else if(mode==3) LCD_Write_String(0,0,"SETX3:   ");		
		else if(mode==4) LCD_Write_String(0,0,"SETX4:   ");
		else 
		{
			mode=0;
			Dis_DataPros();	
		}
	}


	if(mode==1)	 // 左前阈值设置
	{
		switch(key)	
		{
			case K2_ADD: 	   // 加
						minx1++;
						if(minx1>=200) minx1=0;
						break;
			case K3_DEC: 	 // 减
						minx1--;
						if(minx1<=0) minx1=200;
						break;
		}

		dis_buf[0]=minx1/100+'0';
		dis_buf[1]=minx1/10%10+'0';
		dis_buf[2]=minx1%10+'0';
		dis_buf[3]='\0';
	   	LCD_Write_String(6,0,dis_buf);
	}	
	else if(mode==2)  // 右前阈值设置
	{
		switch(key)	
		{
			case K2_ADD: 	   // 加
						minx2++;
						if(minx2>=200) minx2=0;
						break;
			case K3_DEC: 	 // 减
						minx2--;
						if(minx2<=0) minx2=200;
						break;
		}

		dis_buf[0]=minx2/100+'0';
		dis_buf[1]=minx2/10%10+'0';
		dis_buf[2]=minx2%10+'0';
		dis_buf[3]='\0';
	   	LCD_Write_String(6,0,dis_buf);
	}
	else if(mode==3)  // 左后阈值设置
	{
		switch(key)	
		{
			case K2_ADD: 	   // 加
						minx3++;
						if(minx3>=200) minx3=0;
						break;
			case K3_DEC: 	 // 减
						minx3--;
						if(minx3<=0) minx3=200;
						break;
		}

		dis_buf[0]=minx3/100+'0';
		dis_buf[1]=minx3/10%10+'0';
		dis_buf[2]=minx3%10+'0';
		dis_buf[3]='\0';
	   	LCD_Write_String(6,0,dis_buf);;
	}
	else if(mode==4)  // 右后阈值设置
	{
		switch(key)	
		{
			case K2_ADD: 	   // 加
						minx4++;
						if(minx3>=200) minx3=0;
						break;
			case K3_DEC: 	 // 减
						minx4--;
						if(minx3<=0) minx3=200;
						break;
		}

		dis_buf[0]=minx4/100+'0';
		dis_buf[1]=minx4/10%10+'0';
		dis_buf[2]=minx4%10+'0';
		dis_buf[3]='\0';
	   	LCD_Write_String(6,0,dis_buf);
	}


}

void sound()
{
	uchar i=100;
	while(i--)
	{
		beep=!beep;
		delay_us(10);
	}
}

void dis_compare()
{
	if(s1<=minx1||s2<=minx2||s3<=minx3||s4<=minx4)
		if(s1!=0&&s2!=0&&s3!=0&&s4!=0)
			sound();
}

void update_1()
{
	s1=(TH0*256+TL0)/58;
	Dis_DataPros();
	if(s1<=minx1)
	{
		LCD_Write_Com(0x86);
		LCD_Write_Data('!');
		led1=0; sound();
	}
	else if(s1>minx1)
	{
		LCD_Write_Com(0x86);
		LCD_Write_Data(' ');
		led1=1;
	}

}

void update_2()
{
	s2=(TH0*256+TL0)/58;
	Dis_DataPros();
	if(s2<=minx2)
	{
		LCD_Write_Com(0x8e);
		LCD_Write_Data('!');
		led2=0; sound();
	}
	else if(s2>minx2)
	{
		LCD_Write_Com(0x8e);
		LCD_Write_Data(' ');
		led2=1;
	}
}

void update_3()
{
	s3=(TH0*256+TL0)/58;
	Dis_DataPros();
	if(s3<=minx3)
	{
		LCD_Write_Com(0xc6);
		LCD_Write_Data('!');
		led3=0; sound();
	}
	else if(s3>minx3)
	{
		LCD_Write_Com(0xc6);
		LCD_Write_Data(' ');
		led3=1;
	}
}

void update_4()
{
	s4=(TH0*256+TL0)/58;
	Dis_DataPros();
	if(s4<=minx4)
	{
		LCD_Write_Com(0xce);
		LCD_Write_Data('!');
		led4=0; sound();
	}
	else if(s4>minx4)
	{
		LCD_Write_Com(0xce);
		LCD_Write_Data(' ');
		led4=1;
	}
}

void send_1()
{
	trig1=1;
	delay_us(5);
	trig1=0;

	while(echo1==0)
	{
		if(key1==0||key2==0||key3==0)
			return;
	}
	TR0=1;
	TH0=0;
	TL0=0;
	while(echo1==1)
	{
		if(key1==0||key2==0||key3==0)
			return;
	}
	TR0=0;		
	update_1();
	delay_10ms(2);
}

void send_2()
{
	trig2=1;
	delay_us(5);
	trig2=0;

	while(echo2==0)
	{
		if(key1==0||key2==0||key3==0)
			return;
	}
	TR0=1;
	TH0=0;
	TL0=0;
	while(echo2==1)
	{
		if(key1==0||key2==0||key3==0)
			return;
	}
	TR0=0;		
	update_2();
	delay_10ms(2);
}

void send_3()
{
	trig3=1;
	delay_us(5);
	trig3=0;

	while(echo3==0)
	{
		if(key1==0||key2==0||key3==0)
		return;
	}
	TR0=1;
	TH0=0;
	TL0=0;
	while(echo3==1)
	{
		if(key1==0||key2==0||key3==0)
			return;
	}
	TR0=0;		
	update_3();
	delay_10ms(2);
}

void send_4()
{
	trig4=1;
	delay_us(5);
	trig4=0;

	while(echo4==0)
	{
		if(key1==0||key2==0||key3==0)
			return;
	}
	TR0=1;
	TH0=0;
	TL0=0;
	while(echo4==1)
	{
		if(key1==0||key2==0||key3==0)
			return;
	}
	TR0=0;		
	update_4();
	delay_10ms(2);
}

void main()
{
	TMOD=0X01;	
	TH0=0;
	TL0=0;
	ET0=1;
	EA=1;

	LCD_Init();  // LCD初始化
	DelayMs(20); //延时有助于稳定
	LCD_Clear(); // 清屏

	while(1)
	{
		send_1();		
		send_2();		
		send_3();		
		send_4();		
		
		dis_compare();	
		
		if(mode==0)	Dis_DataPros();		
		KEY_Pros();
		while(mode!=0) KEY_Pros();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为梦而生~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值