蓝桥杯单片机国赛第三届(超级详细注释)

Posted 一心向月

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯单片机国赛第三届(超级详细注释)相关的知识,希望对你有一定的参考价值。

直接看题目先。
全部程序:提取码:azxy



#include "STC15F2K60S2.h"
#include "intrins.h"
#include "ds1302.h" 
#include "iic.h"
typedef unsigned char u8;
typedef unsigned int u16;

sbit TX=P1^0;//超声波发射引脚
sbit RX=P1^1;//超声波接收引脚

sbit H1=P3^0;
sbit H2=P3^1;
sbit H3=P3^2;
sbit H4=P3^3;
			 //矩阵键盘引脚定义
sbit L1=P4^4;
sbit L2=P4^2;
sbit L3=P3^5;
sbit L4=P3^4;

u8 code duan[12]=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf;//0~9

u8 mima[6]=6,5,4,3,2,1;//正确密码存储数组
u8 mima1[6]=10,10,10,10,10,10;//输入时显示的密码数组
u8 store_addr[6]=0x00,0x01,0x02,0x03,0x04,0x05;//密码存储在EEPROM的地址

extern unsigned char Time[3];//DS1302时分秒数组
u16 dat=0;//超声波测得的距离
u8 flag=0;//矩阵键盘按键按标志
u8 key_num=0;//按键键值
u8 model=0;//数码管显示的界面0~3 0:时间界面 1:密码待输入界面 2:修改密码界面 3:输入要修改的密码界面
u8 num=0;//记录密码长度
u8 relay=0;//继电器标志
u8 been=0;//蜂鸣器标志
u16 count=0;//继电器响应时间标志
u16 count1=0;//蜂鸣器响应时间标志
u8 error_flag=0;//密码错误次数记录
u8 aa;//保证第一次上电密码是654321

void delay(u16 i)//延迟函数

	while(i--);


void Delay5ms()//延迟5MS,方便EEPROM连续写

	unsigned char i, j;

	i = 59;
	j = 90;
	do
	
		while (--j);
	 while (--i);


void Chan_hc573(u8 chose)//锁存器选择

	switch(chose)
	
		case 4:
			P2 = (P2 & 0x1f) | 0x80; break;
		case 5:
			P2 = (P2 & 0x1f) | 0xa0; break;
		case 6:
			P2 = (P2 & 0x1f) | 0xc0; break;
		case 7:
			P2 = (P2 & 0x1f) | 0xe0; break;
	
	P2 = (P2 & 0x1f) | 0x00;


void Init_system()//初始化开发板,关闭LED灯,蜂鸣器,继电器

	P0=0x00;
	Chan_hc573(5);
	P0=0xff;
	Chan_hc573(4);


void Smg_display(u8 com,u8 dat)//控制数码管的位选和段选

	P0=0xff;
	Chan_hc573(7);
	P0=0x01<<com;
	Chan_hc573(6);
	P0=dat;
	Chan_hc573(7);
	delay(1000);


void Close_smg()//数码管消隐

	P0=0x00;
	Chan_hc573(6);
	P0=0xff;
	Chan_hc573(7);


void Wire_mima()//密码复位和保证第一次上电密码是654321

	Wire_dat(store_addr[0],6);Delay5ms();
	Wire_dat(store_addr[1],5);Delay5ms();
	Wire_dat(store_addr[2],4);Delay5ms();
	Wire_dat(store_addr[3],3);Delay5ms();
	Wire_dat(store_addr[4],2);Delay5ms();
	Wire_dat(store_addr[5],1);Delay5ms();


void Read_mima()//读取EEPROM里面的密码

	u8 i=0;
	for(i=0;i<6;i++) mima[i]=Read_dat(store_addr[i]);

//========================================//
//================自动门状态==============//
//========================================//
void Delay12us()//延迟12US,用于超声波发射

	unsigned char i;

	_nop_();
	_nop_();
	i = 36;
	while (--i);


void scan_csp()//超声波发射40Khz的频率

	u8 i=0;
	for(i=0;i<8;i++)
	
		TX=1;
		Delay12us();
		TX=0;
		Delay12us();
	


void Try_cj()//超声波所测得的距离

	TMOD &= 0x0F;
	EA=1;
	ET0=1;
	TH0=0;
	TL0=0;
	TF0=0;
	scan_csp();
	TR0=1;
	while((TF0==0)&(RX==1));
	TR0=0;
	if(TF0==1)
	
		TF0=0;
		dat=999;
	
	else
	
		dat=(TH0<<8)|TL0;
		dat=dat*0.017+3;//测得的距离
	
	if(dat<30) relay=1;TR1=1;//小于30cm继电器打开,定时器1打开


void Display_time()//显示从DS1302中所读取到的时间

	Smg_display(0,duan[Time[0]/16]); //时
	Smg_display(1,duan[Time[0]%16]); 
	Smg_display(2,duan[11]); 
	Smg_display(3,duan[Time[1]/16]); //分
	Smg_display(4,duan[Time[1]%16]); 
	Smg_display(5,duan[11]);
	Smg_display(6,duan[Time[2]/16]); //秒
	Smg_display(7,duan[Time[2]%16]); 
	Close_smg();					 //数码管消隐

//========================================//
//================密码门状态==============//
//========================================//
void Display_mima()//密码门状态时所显示的界面

	if(model==1)
	
		Smg_display(0,duan[11]); //显示 —
		Smg_display(1,duan[11]); //显示 —
	
	else if(model==2)
	
		Smg_display(0,duan[10]); //数码管熄灭 
		Smg_display(1,duan[11]); //显示 —
	
	else if(model==3)
	
		Smg_display(0,duan[11]);//显示 —
		Smg_display(1,duan[10]); //数码管熄灭
		
	Smg_display(2,duan[mima1[0]]); 
	Smg_display(3,duan[mima1[1]]); 
	Smg_display(4,duan[mima1[2]]); 
	Smg_display(5,duan[mima1[3]]); //显示所输入的密码
	Smg_display(6,duan[mima1[4]]); 
	Smg_display(7,duan[mima1[5]]);
	Close_smg();


void Clear_mima()//用于密码输入正确或错误时清除已输入的密码,回到待输入状态

	u8 i;
	for(i=0;i<6;i++) mima1[i]=10;


void Key_down()//矩阵键盘的程序,通过按下的按键获取键值

	H1=0;
	H2=H3=H4=L1=L2=L3=L4=1;
	if(L1==0)					//键值0
	
		delay(1000);
		if(L1==0)
		
			flag=1;
			while(L1==0) 
			key_num=0;
		
	
	else if(L2==0)				//键值1
	
		delay(1000);
		if(L2==0)
		
			flag=1;
			while(L2==0) 
			key_num=1;
		
	
	else if(L3==0)				//键值2
	
		delay(1000);
		if(L3==0)
		
			flag=1;
			while(L3==0) 
			key_num=2;
		
	
	else if(L4==0)				//键值3
	
		delay(1000);
		if(L4==0)
		
			flag=1;
			while(L4==0) 
			key_num=3;
		
	
	H2=0;
	H1=H3=H4=L1=L2=L3=L4=1;
	if(L1==0)					//键值4
	
		delay(1000);
		if(L1==0)
		
			flag=1;
			while(L1==0) 
			key_num=4;
		
	
	else if(L2==0)				//键值5		
	
		delay(1000);
		if(L2==0)
		
			flag=1;
			while(L2==0) 
			key_num=5;
		
	
	else if(L3==0)				//键值6
	
		delay(1000);
		if(L3==0)
		
			flag=1;
			while(L3==0) 
			key_num=6;
		
	
	else if(L4==0)				//键值7
	
		delay(1000);
		if(L4==0)
		
			flag=1;
			while(L4==0) 
			key_num=7;
		
	
	H3=0;
	H2=H1=H4=L1=L2=L3=L4=1;
	if(L1==0)					//键值8
	
		delay(1000);
		if(L1==0)
		
			flag=1;
			while(L1==0) 
			key_num=8;
		
	
	else if(L2==0)				//键值9
	
		delay(1000);
		if(L2==0)
		
			flag=1;
			while(L2==0) 
			key_num=9;
		
	
	else if(L3==0)				//设置键
	
		delay(1000);
		if(L3==0)
			
			while(L3==0) 
			if(model==0) model=2;
		
	
	else if(L4==0)				//复位键
	
		delay(1000);
		if(L4==0)
		
			while(L4==0) 
			mima[0]=6;mima[1]=5;mima[2]=4;
			mima[3]=3;mima[4]=2;mima[5]=1;
			Wire_mima();
		
	
	H4=0;
	H2=H3=H1=L1=L2=L3=L4=1;
	if(L3==0)
	
		delay(1000);
		if(L3==0)				//确认键
		
			count=0;count1=0;
			while(L3==0) 
			key_num=14;
		
	
	else if(L4==0)				蓝桥杯单片机国赛第三届(超级详细注释)

蓝桥杯单片机第三届国赛题目-门禁系统

蓝桥杯单片机第十一届国赛程序设计题--温度时钟国赛

蓝桥杯单片机第十一届国赛程序设计题--温度时钟国赛

蓝桥杯单片机第十一届国赛程序设计题--温度时钟国赛

蓝桥杯第十三届Web组国赛天气趋势A详细题解