资讯详情

51单片机项目设计:基于超声波的 车库停车系统、车位检测系统设计(8个超声波测距模块)keil+protues仿真

基于51单片机的车库停车系统

代码模拟数据链接https://download.csdn.net/download/mbs520/12742296 在这里插入图片描述

一、设计要求:

本设计主要用于室内停车场,采用51单片机或嵌入式系统,结合超声波传感器,检查停车位是否停车,占用停车位LED实时显示模块形式,也可显示剩余停车位数。

使用超声波传感器来检测停车位的占用情况,并计算该区域的剩余停车位。我们假设一个区域有四个停车位。通过超声波检测,我们发现占用停车位相应位置的数字灯点亮并显示: 剩下的2车位。

每个车位上,相距一定距离,安装一个超声波传感器,可以防止误判。剩余车位也就是在LED在此区域的剩余停车位数,而不是整个停车场的剩余停车位数。

led显示模块系统是在停车场面对面的两个停车位每个停车位安装传感器超声波测距模块必须有8个超声波传感器,不能使用16个引脚,9个引脚,超声波传感器连接引脚,接收端或门,占用单片机引脚,然后通过程序判断哪个超声波传感器有回波。

数字管只显示区域内剩余的停车位数,不显示占用的停车位数,即停车位总数不变,然后分为两个区域 A区和B区的每个区。八个停车位没就是多了两个数字管,多了一个红灯,一个绿灯。控制交通流量的按钮(加一减一)由于模拟不能反映超声波传感器的功能,所以用开关代替超声波传感器代表停车位偶数代表停车位,然后或门只有一个超声波测距模块距离设置为40-5040-50cm的开关 (提问者的问题已经解决)

  • 单片机采用51系列单片机(stc89c52)能满足需求。
  • 三个数字管,一个显示总剩余停车位数,一个显示A区剩余停车位,一个显示B区剩余停车位。动态扫描需要3 7=10个IO口
  • 发送端连接八个超声模块IO八个接收端各接一个IO口。占9个IO口
  • 八个LED,每个LED对应一个停车位的状态,车库内有红灯,车库内无车不亮,占8个IO口
  • 一盏红绿灯,车库里8个停车位都有红灯,如果剩下的停车位有绿灯。IO口
  • 合计29个IO口

二、模拟测试:

仿真采用proteus库中没有的超声波测距模块可以100%模拟实物hc-sr04超声测距模块的通信原理是利用加减按钮模拟物体的实际距离。

三、代码解读

1.配置头文件包含单片机寄存器的定义

#include "reg52.H" 

2、重定义IO口,读写方便

sbit RX0 =P2^0;  //超声接收 sbit RX1 =P2^1; sbit RX2 =P2^2; sbit RX3 =P2^3; sbit RX4 =P2^4; sbit RX5 =P2^5; sbit RX6 =P2^6; sbit RX7 =P2^7; sbit TX  = P3^0;   ///超声波发送  sbit LS1  = P3^3; ///数码管位 sbit LS2  = P3^4;   sbit LS3 = P3^5;    sbit LED_Green  = P3^6;   //绿灯 sbit LED_Red  = P3^7; //红灯 

3.定义全局变量 ,保存停车位信息和距离信息等

unsigned int  time=0; ///测距时间 unsigned char flag=0;  //溢出标志
unsigned long S[8]=0; //距离数据
unsigned char sg[]=  { 
        0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char wei[]={ 
        0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
unsigned char R=0;//车位的8个指示灯
char a_carport,b_carport;//A区与B区剩余车位

4、延时函数、用执行空语句来消耗CPU的时间,达到延时的目的、

void delay_ms(unsigned int m)//毫秒级延时
{ 
        
    unsigned int b,c;
    for(c=0;c<m;c++)
        for(b=0;b<120;b++);
}
void delay(unsigned int t)//微秒级延时
{ 
        
	while(t--);
}

5、数码管显示函数, 数码管是用动态扫描方式显示,先位选,后发送数据,依次点亮数码管,视觉残留效果让人眼睛是看到的是静态的。一开始,先显示第一个数码管,位选第一个数码管,发送总剩余车位信息段码数值显示数码管,然后显示第二个数码管,发送A区剩余车位段码数值,然后显示第三个数码管,发送B区剩余车位段码数值。循环执行即可显示数码管。

void display(unsigned char ab,unsigned char a,unsigned char b)
{ 
        
	TX=0;
	LS1=0;LS2=1;LS3=1;//位选,第一个数码管亮
	P0=sg[ab];	//发送段码,显示数字
	delay_ms(1); //稳定
	LS1=1;LS2=0;LS3=1;
	P0=sg[a];	 
	delay_ms(1);
	LS1=1;LS2=1;LS3=0;
	P0=sg[b];	 
	delay_ms(1);
}

6、超声波测距程序 由于这里有8个超声波模块,有8个发送引脚和8个接收引脚,显然这样要16个引脚,太占用IO口,于是利用8个发送引脚合为一个发送引脚,就可以9个IO驱动8个超声波模块,每次都让8个超声波模块发射超声波,然后开始第一个超声波模块接收距离数据,距离数据的接收处理步骤:首先读出T0的计时数值,T0计数器TH0、TL0合为16位计数器,每微秒计数加一,所以读出的计数器的值就是超声波一去一回,两个距离的时间,那么就得到计算距离公式S[i]=(int)(time*1.7)/100; 测得每个超声波模块的距离重复操作,i从0一直计到7,直到测量到第8个距离数据,保存数据到数组,开始下一步。

void Superwave_Conut(void)//超声波测距 8组
{ 
        
	int i;
	for(i=0; i<8; i++)
	{ 
        
		if(i==0)
		{ 
        
			TX=1;			         
			delay(10);
			TX=0; 
			while(!RX0);		
			TR0=1;			
			while(RX0);		
			TR0=0;			
		}
		if(i==1)
		{ 
        
			TX=1;			         
			delay(10);
			TX=0; 
			while(!RX1);		
			TR0=1;			
			while(RX1);		
			TR0=0;			
		}
		if(i==2)
		{ 
        
			TX=1;			         
			delay(10);
			TX=0; 
			while(!RX2);		
			TR0=1;			
			while(RX2);		
			TR0=0;			
		}
		if(i==3)
		{ 
        
			TX=1;			          
			delay(10);
			TX=0; 
			while(!RX3);		
			TR0=1;			
			while(RX3);		
			TR0=0;			
		}
		if(i==4)
		{ 
        
			TX=1;			          
			delay(10);
			TX=0; 
			while(!RX4);		
			TR0=1;			
			while(RX4);		
			TR0=0;			
		}
		if(i==5)
		{ 
        
			TX=1;			        
			delay(10);
			TX=0; 
			while(!RX5);		
			TR0=1;			
			while(RX5);		
			TR0=0;			
		}
		if(i==6)
		{ 
        
			TX=1;			     
			delay(10);
			TX=0; 
			while(!RX6);		
			TR0=1;			
			while(RX6);		
			TR0=0;			
		}
		if(i==7)
		{ 
        
			TX=1;			         
			delay(10);
			TX=0; 
			while(!RX7);		
			TR0=1;			
			while(RX7);		
			TR0=0;			
		}
		time=TH0*256+TL0;	
		TH0=0;
		TL0=0;				 
		if(!flag)			
		{ 
        				  
			S[i]=(time*2)/100;    
		}else flag=0;
	}
} 

7、8组距离数据处理 通过之前的超声波程序已经把8个车位的距离数据测量好了,现在只需要处理距离数据。 首先判断第一个车位距离是否大于200CM,如果大于,表示车位无车,剩余车位计数加一,对应车位灯显示无车,如果小于,表示车位有车,剩余车位计数不变,对应车位灯显示有车。依次判断8个车位的距离数据,就可计算出A区、B区和总车库的剩余车位信息,依据这个信息就可以控制红绿灯以及车位指示LED。

void Carport_Count(void) //数据处理
{ 
        
	int i;
	a_carport=0;b_carport=0,R=0;  
	for(i=0; i<8; i++)
	{ 
        
		if(S[i]>230) 
		{ 
        
			if(i<4)a_carport++;		
			if(i>=4)b_carport++;
			R|=wei[i];		 
		}
	}
}

8、红绿灯显示 红绿灯主要是用来提示或警告外来人员车库有无剩余车位,在8组距离数据处理函数已经得到车库内剩余车位数量,通过判断剩余车位数量即可正确显示控制红绿灯,如果有剩余的车位就显示绿灯,如果没有剩余车位就显示红灯

void led_gr(void )	 //红绿灯显示
{ 
        
   if((a_carport+b_carport)>0)	   
	{ 
        
		LED_Green=0;
		LED_Red=1;
	}else
	{ 
        
	  	LED_Green=1;
		LED_Red=0;
	}
}

9、定时器中断,用来判断定时器是否溢出,也就是16位计数器是否已经从0计数到65535,如果是,则溢出,溢出标志置一,超声波测距函数如果检测到溢出,则此次测距作废,保证数据的正确性

void zd0() interrupt 1 		//定时器中断,
{ 
        
	flag=1;						
}

10、主函数 主函数是整个程序执行的入口处,首先进行初始化设置,即定时器参数的设定,设置16位定时器向上计数,然后设置显示函数及键盘扫描函数和超声波函数的死循环,进行实时显示并不断扫描独立按键,每隔50ms左右读一次超声波检测到的数据,利用超声波检测到的距离来判断停车位是否有车,从而来驱动数码管显示剩余的停车位数量,显示当前所剩的停车位的数量,并且通过LED来显示当前停车位是否有车。主程序框图如下图5.1 所示。 本系统软件设计部分的单片机内部资源分配为:超声波测距占用定时器0(T0),每50ms超声波进行一次测距,下面就程序部分单片机内部资源初始化程序简要分析。初始化设T0为方式1,允许T0中断,开启总中断,计算每个传感器模块距离保存到数组S[8]中,并通过数组中的数据计算剩余车位,根据有无车位控制红绿灯显示,超声波传感器将距离数据传送到红绿灯、车库LED灯,数码管。

void main(void)
{ 
         
	int i;			 
	flag=0;
	TX=0;//初始化定时器
	TMOD=0x11;		
	TH0=0;
	TL0=0;          
	ET0=1;				
	EA=1;					
	while(1)
	{ 
        
		Superwave_Conut();		//测距 
		Carport_Count();		//数据分析
		led_gr();		//红绿灯
		P1=~R;			//车位灯
		for(i=0; i<100; i++)	 //数码管显示
		{ 
        
			display(a_carport+b_carport,a_carport,b_carport);	
			//display(S[0]/100%10,S[0]/10%10,S[0]%10);
		}
		
	}
}

分享: https://marketing.csdn.net/poster/109?utm_source=NEWFXDT

标签: 光电开关传感器sg243

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台