蓝桥杯单片机第四届国赛:超声波测距报警

本次使用到的模块和第三届国赛门禁系统完全一样但是这一届略复杂:超声波测距、EEPROM读和写、时钟DS1302、矩阵键盘、数码管显示

注意:

     1.超声波模块,超声波接收到信号的时候,会把接收信号RX从高拉低,所以我们在判断的时候一定要判断正确。

     2.打开定时器2的中断:IE2 |= 0X04.

第四届使用到的模块和第三届一样,这里各个模块的读写操作可以看我写的第三届:https://blog.csdn.net/qq_43715171/article/details/105323533

#include <STC15F2K60S2.H>
#include <intrins.h>
#include "iic.h"
#include "ds1302.h"


#define u8 unsigned char
#define u16 unsigned int

sbit TX = P1^0;
sbit RX = P1^1;

u8 code LED[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
u8 Digcom = 0,yi = 1,er = 2,san = 3,si = 4,wu = 5,liu = 6,qi = 7,ba = 8;
u8 Digbuf[] = {8,8,8,8,8,8,8,8};

u8 KEY,KEY_TEMP;

u8 Tsonic = 0;
bit sonic_flag = 0,alarm_flag = 0,LED_flag1 = 0,LED_flag2 = 0;
u16 distance,alarm_distance = 30,T_led = 0;


u16 T_start = 0;
bit Start_flag = 1;

bit s7_flag = 1,s6_flag = 1,s5_flag = 1,s4_flag = 1;

bit flicker_flag = 1,time_flag = 1;
u8 button = 1;
u8 hour = 11,min = 50,sec = 59;
u16 T_flicker = 999;

extern u8 Time[];

void Delay13us()		//@11.0592MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 33;
	while (--i);
}


void delay_ms(u16 ms)
{
	u16 i,j;
	for(i = ms; i>0 ; i--)
		for(j = 845; j>0 ; j--);
}

void INIT(void)
{
	P2 |= 0X80;
	P2 &= 0X9F;
	P0 = 0XFF;
	
	P2 |= 0XA0;
	P2 &= 0XBF;
	P0 = 0X00;
	
	P2 |= 0XC0;
	P2 &= 0XDF;
	P0 = 0XFF;
	P2 |= 0XE0;
	P2 &= 0XFF;
	P0 = 0XFF;
}

void Start(void)	//上电时,数码管全亮
{
	P2 |= 0XC0;
	P2 &= 0XDF;
	P0 = 0X01;
	P2 |= 0XE0;
	P2 &= 0XFF;
	P0 = 0X00;
	delay_ms(1);
	
	P2 |= 0XC0;
	P2 &= 0XDF;
	P0 = 0X02;
	P2 |= 0XE0;
	P2 &= 0XFF;
	P0 = 0X00;
	delay_ms(1);
	
	P2 |= 0XC0;
	P2 &= 0XDF;
	P0 = 0X04;
	P2 |= 0XE0;
	P2 &= 0XFF;
	P0 = 0X00;
	delay_ms(1);
	
	P2 |= 0XC0;
	P2 &= 0XDF;
	P0 = 0X08;
	P2 |= 0XE0;
	P2 &= 0XFF;
	P0 = 0X00;
	delay_ms(1);
	
	P2 |= 0XC0;
	P2 &= 0XDF;
	P0 = 0X10;
	P2 |= 0XE0;
	P2 &= 0XFF;
	P0 = 0X00;
	delay_ms(1);
	
	P2 |= 0XC0;
	P2 &= 0XDF;
	P0 = 0X20;
	P2 |= 0XE0;
	P2 &= 0XFF;
	P0 = 0X00;
	delay_ms(1);
	
	P2 |= 0XC0;
	P2 &= 0XDF;
	P0 = 0X40;
	P2 |= 0XE0;
	P2 &= 0XFF;
	P0 = 0X00;
	delay_ms(1);
	
	P2 |= 0XC0;
	P2 &= 0XDF;
	P0 = 0X80;
	P2 |= 0XE0;
	P2 &= 0XFF;
	P0 = 0X00;
	delay_ms(1);
	
	P2 |= 0XC0;
	P2 &= 0XDF;
	P0 = 0XFF;
	P2 |= 0XE0;
	P2 &= 0XFF;
	P0 = 0XFF;
}

void KEY_BTN(void)
{
	KEY_TEMP = P3 & 0X0F;
	if(KEY_TEMP != 0X0F && KEY == 0XFF)
	{
		delay_ms(5);
		KEY_TEMP = P3 & 0X0F;
		if(KEY_TEMP != 0X0F)
		{
			KEY = KEY_TEMP;
			switch(KEY_TEMP)
			{
				case 0X0E:	//s7按键切换显示
					if(s6_flag == 0)
					s7_flag = !s7_flag; 
					break;
				case 0X0D:
					s6_flag = 1;
					if(s7_flag)
					{
						flicker_flag = 1;
						T_flicker = 999;
						
						if(++button == 3)
						{
							s6_flag = 0;
							flicker_flag = 0;
							button = 0;
							Time[0] = ((sec/10)<<4)|(sec%10);
							Time[1] = ((min/10)<<4)|(min%10);
							Time[2] = ((hour/10)<<4)|(hour%10);
							Time[3] = 0x00;Time[4] = 0x00; Time[5] = 0x00; Time[6] = 0x00;
							DS1302_INIT();
						}
					}
					else
					{
						if(alarm_flag)
						{
							s6_flag = 0;
							alarm_flag = 0;
							Write_AT24C02(0xa0,alarm_distance);
						}
						else
						{
							alarm_distance = Read_AT24C02(0xa0);
							alarm_flag = 1;
						}
					}
					break;
				case 0X0B:
					if(s7_flag && flicker_flag)
					{
						if(button == 1)
						{
							if(++hour==24) hour = 0;
							
						}
						else if(button == 2)
						{
							if(++min==60) min = 0;
						}
//						else if(button == 3)
//						{
//							if(++sec==60) sec = 0;
//						}
					}
					else if(!s7_flag && alarm_flag)
					{
						if(alarm_distance != 99)
							alarm_distance++;
					}
					break;
				case 0X07:
					if(s7_flag && flicker_flag)
					{
						if(button == 1)
						{
							if(hour == 0)
							{
								hour = 23;
							}
							else
							{
								hour--;
							}
							
						}
						else if(button == 2)
						{
							if(min == 0)
							{
								min = 59;
							}
							else
							{
								min--;
							}
						}
//						else if(button == 3)
//						{
//							if(sec == 0)
//							{
//								sec = 59;
//							}
//							else
//							{
//								sec--;
//							}
//						}
					}
					else if(!s7_flag && alarm_flag)
					{
						if(alarm_distance != 0)
							alarm_distance--;
					}
					break;
			}
		}
	}
	else if(KEY_TEMP == 0X0F && KEY != 0X0F)
	{
		delay_ms(5);
		KEY_TEMP = P3 & 0X0F;
		if(KEY_TEMP == 0X0F)
		{
			KEY = 0XFF;
		}
	}
}

void Timer2Init(void)		//1毫秒@11.0592MHz
{
	AUXR |= 0x04;		//定时器时钟1T模式
	T2L = 0xCD;		//设置定时初值
	T2H = 0xD4;		//设置定时初值
	AUXR |= 0x10;		//定时器2开始计时
	IE2 |= 0X04; 
	EA = 1;
}

void Timer0Init(void)
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x00;		//设置定时初值
	TH0 = 0x00;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 0;		//定时器0开始计时
}

void timer2()interrupt 12
{
	if(!Start_flag)
	{
		P2 |= 0XC0;
		P2 &= 0XDF;
		P0 = 0x01<<Digcom;
		P2 |= 0XE0;
		P2 &= 0XFF;
		P0 = LED[Digbuf[Digcom]];
		if(++Digcom == 8) Digcom = 0;
	}
	
	if(++T_start == 1000 && Start_flag)
	{
		T_start = 0;
		Start_flag =	0; 
		INIT();
		Timer0Init();
		DS1302_INIT();
	}
	
	if(++Tsonic == 200)
	{
		Tsonic = 0;
		sonic_flag = 1;
	}
	
	if(++T_flicker == 1000 && flicker_flag)
	{
		T_flicker = 0;
		
		Digbuf[0] = hour/10;		Digbuf[1] = hour%10;
		Digbuf[2] = 10;					Digbuf[3] = min/10;   
	  Digbuf[4] = min%10;			Digbuf[5] = 10;
		Digbuf[6] = sec/10;			Digbuf[7] = sec%10;
		if(button == 1 && time_flag){Digbuf[0] = 11;		Digbuf[1] = 11;}
		else if(button == 2 && time_flag){Digbuf[3] = 11;		Digbuf[4] = 11;}
		else if(button == 3 && time_flag){Digbuf[6] = 11;		Digbuf[7] = 11;}
		
		time_flag = !time_flag;
		
	}
	
	if(++T_led == 500)
	{
		T_led = 0;
		if(LED_flag1)
		{
			LED_flag2 = !LED_flag2;
			if(LED_flag2)
			{
				P2 |= 0X80;
				P2 &= 0X9F;
				P0 = 0XFE;	//L1亮
			}
			else
			{
				P2 |= 0X80;
				P2 &= 0X9F;
				P0 = 0XFF;	//L1灭
			}
		}
	}
}	
void	sonic_send(void)
{
	u8 i = 8;
	while(i--)
	{
		TX = 1;
		Delay13us();
		TX = 0;
		Delay13us();
	}
}

void main(void)
{
	u16 temp;
	
	P2 |= 0X80;
	P2 &= 0X9F;
	P0 = 0XFe;	//L1亮
	
	P2 |= 0XA0;
	P2 &= 0XBF;
	P0 = 0X40;	//蜂鸣器打开
	Timer2Init();
	Write_AT24C02(0xa0,30);
	delay_ms(5);
	alarm_distance = Read_AT24C02(0xa0);

	while(1)
	{
		
		if(sonic_flag && !Start_flag)
		{
			
			sonic_flag = 0;
			TR0 = 0;
			sonic_send();
			TR0 = 1;
			while(RX == 1 && TF0 == 0);
			TR0 = 0;
			if(TF0)
			{
				TF0 = 0;
				distance = 999;
			}
			else
			{
				distance = TH0;
				distance = (distance<<8)|TL0;
				distance = (unsigned int)(distance*0.00153718);
			}
			TH0 = 0;
			TL0 = 0;
			
			if(distance <= alarm_distance)
			{
				LED_flag1 = 0;
				P2 |= 0X80;
				P2 &= 0X9F;
				P0 = 0XFF;	//L1灭
				
				P2 |= 0XA0;
				P2 &= 0XBF;
				P0 = 0X40;	//蜂鸣器打开
			}
			else if(distance > alarm_distance)
			{
				temp =(unsigned int) (alarm_distance*1.2);
				if(distance <= temp)
				{
					LED_flag1 = 1;
				}	
				else
				{
					LED_flag1 = 0;
					
					P2 |= 0X80;
					P2 &= 0X9F;
					P0 = 0XFF;	//L1灭
				}
					P2 |= 0XA0;
					P2 &= 0XBF;
					P0 = 0X00;	
			}
		}
		
		if(Start_flag)	//上电初始化
		{
			Start();
		}
		else if(s7_flag && !s6_flag)
		{
			DS1302_Getime();
			Digbuf[0] = Time[2]/16;			Digbuf[1] = Time[2]%16;
			Digbuf[2] = 10;							Digbuf[3] = Time[1]/16;   
			Digbuf[4] = Time[1]%16;			Digbuf[5] = 10;
			Digbuf[6] = Time[0]/16;			Digbuf[7] = Time[0]%16;			
		}
//超声波检测程序
		else if(!s7_flag && !s6_flag)
		{
			Digbuf[0] = 11;			Digbuf[1] = 11;
			Digbuf[2] = 11;			Digbuf[3] = 11; 
			if(distance == 999)
			{
				Digbuf[4] = 11;		Digbuf[5] = 11;
				Digbuf[6] = 11;		Digbuf[7] = 11;
			}
			else
			{
				Digbuf[4] = 11;		Digbuf[5] = distance/100;
				Digbuf[6] = distance/10%10;		Digbuf[7] = distance%10;
			}
		}
		else if(!s7_flag && alarm_flag)
		{
			Digbuf[0] = 11;			Digbuf[1] = 11;
			Digbuf[2] = 11;			Digbuf[3] = 10;
			Digbuf[4] = 10;			Digbuf[5] = alarm_distance/100;
			Digbuf[6] = alarm_distance/10%10;			Digbuf[7] = alarm_distance%10;
		}
		
		KEY_BTN();
	}
}

猜你喜欢

转载自blog.csdn.net/qq_43715171/article/details/105345149