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

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

代码仿真资料链接https://download.csdn.net/download/mbs520/12742296
在这里插入图片描述

一、设计要求:

毕业设计原题:

本设计主要用于室内停车场中,利用51单片机或者嵌入式系统,结合超声波传感器,检测车位是否有车辆停入,并将车位占用情况,以LED模块形式进行实时显示,还可以将剩余车位数显示出来。

利用超声波传感器,检测车位占用情况,并计算该区域剩余车位。我们假设一个区域内有4个车位,用超声波检测,发现占用车位相应位置的数码灯点亮,同时显示: 剩余“2”个车位。

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

led是显示模块这个系统做的是停车场面对面各2个车位每个车位上安装一个传感器超声波测距模块必须要有8个超声波传感器,可以不用16个引脚,而用9个引脚,发送端一个超声波传感器连一个引脚,接收端用或门,占用单片机一个引脚,然后通过程序来判断,哪个超声波传感器有回波。

数码管只显示区域内剩余车位数,不用显示占用车位数,就是车位总数不变然后划分为两个区域 A区和B区每个区。八个车位没变就是多了两个数码管,多了一个红灯,一个绿灯。控制车流量的按键(加一减一)由于仿真的时候体现不了超声波传感器的功能所以用开关代替超声波传感器按奇数下代表车位进车偶数下代表车位出车然后或门只用一个超声波测距模块距离设置为40-50厘米每个车位上都放一个开关一共八个车位 (出题人的问题已解决)

解题方案:

  • 单片机采用51系列单片机(stc89c52)可以满足需求。
  • 三个数码管,一个显示总剩余车位数,一个显示A区域剩余车位,一个显示B区域剩余车位。动态扫描需要3+7=10个IO口
  • 八个超声波模块,发送端接同一个IO口,8个接收端各接一个IO口。占9个IO口
  • 八个LED,每个LED对应一个车位的状态,车库内有车亮红灯,车库内无车不亮,占8个IO口
  • 一个红绿灯,车库内8个车位都有车亮红灯,如果还有剩余车位亮绿灯。占2个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

猜你喜欢

转载自blog.csdn.net/mbs520/article/details/108207818