蓝桥杯单片机国赛第三届(超级详细注释)
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) 蓝桥杯单片机国赛第三届(超级详细注释)