一、题目说明
蓝桥杯历届模拟题汇总下载链接
二、代码实现
main.c文件
#include <STC15F2K60S2.H>
#include "port.h"
#include "key.h"
#include "AT24C02.h"
#define u8 unsigned char
#define u16 unsigned int
u8 code t_display[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40,0x39,0x73,0x79,0x37}; //段码
// 0 1 2 3 4 5 6 7 8 9 black - C P E N
u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位码
u8 menu[][8] = {{10, 10, 10, 10, 10, 10, 10, 10},{11, 10, 10, 10, 10, 10, 10, 10}, {0, 10, 10, 10, 0, 13, 14, 15}, {12, 10, 10, 10, 10, 10, 10, 10}};
//index -- 0:数码管全灭 index -- 1:输密码 index -- 2:开门 index -- 3:改密码
u8 Trg, Com, index;
u16 t2_cnt;
bit tick_200ms, tick_1s, keyflag;
void Timer2Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0xCD; //设置定时初值
T2H = 0xD4; //设置定时初值
AUXR |= 0x10; //定时器2开始计时
IE2 |= 0x04; //开定时器2中断
}
//中断服务程序
void t2int() interrupt 12 //中断入口
{
static u8 i;
u8 key_val;
LED_Com(0x00);
LED_Bit(T_COM[i]);
LED_Com(t_display[menu[index][i]]);
if(++i == 8)
i = 0;
if(t2_cnt % 20 == 0)
{
key_val = KeyScan();
Trg = key_val & (key_val ^ Com);
Com = key_val;
if(Trg != 0)//注意:KeyScan()当无按键按下时,或按下相同按键未松开时,Trg为0
keyflag = 1;
}
if(t2_cnt % 200 == 0)
tick_200ms = 1;
if(++t2_cnt == 1000)
{
t2_cnt = 0;
tick_1s = 1;
}
}
void main(void)
{
u8 i, secret_code[6] = {8, 8, 8, 8, 8, 8}, input_code[6] = {10, 10, 10, 10, 10, 10}, input_num, cnt_time;//input_num -- 计数输入密码的个数 cnt_time -- 用于计数5s的时间
bit door_flag, error;
for(i = 0; i < 6; ++i)
{
AT24C02_WriteData(i, secret_code[i]);
secret_code[i] = AT24C02_ReadData(i);
}
Relay(0);
Buzzer(0);
LED(0x00);
Timer2Init();
EA = 1;
while(1)
{
if(tick_200ms)
{
tick_200ms = 0;
if(index == 1 || index == 3)
{
for(i = 0; i < input_num; ++i)
menu[index][8-input_num+i] = input_code[i];
if(input_num == 6 && index == 1)//当输入密码个数为6
{
for(i = 0; i < 6; ++i)
if(input_code[i] != secret_code[i])
break;
if(i == 6)//输入密码正确
{
index = 2;
door_flag = 1;
LED(0x00);
Relay(1);
}
else//输入密码不正确
{
LED(0x01);
error = 1;
}
cnt_time = 0;
for(i = 0; i < 6; i++)//清空输入密码及对应的显示位
{
input_code[i] = 10;
menu[1][i] = 10;
}
input_num = 0;
}
}
}
if(keyflag)
{
keyflag = 0;
if((index == 2 ||index == 3) && cnt_time < 5)//只要有按键按下且是在门开着的情况下,计数时间清0
cnt_time = 0;
switch(Trg-1)
{
case 12://输入
{
if(index == 0)//只有在初始状态输入按键才有用
{
index = 1;
LED(0x40);
}
break;
}
case 11://修改
{
if(door_flag)//要在门开着才能改密码
{
if(input_num == 6)//输了6个密码
{
index = 2;//还原到门刚打开的状态
door_flag = 1;
cnt_time = 0;
Relay(1);
for(i = 0; i < 6; i++)
{
secret_code[i] = input_code[i];
AT24C02_WriteData(i, input_code[i]);
input_code[i] = 10;
}
input_num = 0;
LED(0x00);
}
else if(input_num == 0)//没有输入任何数字
{
index = 3;
LED(0x80);
}
}
break;
}
case 10://清除
{
if(index == 1 || index == 3)
{
for(i = 0; i < input_num; i++)
{
input_code[i] = 10;
menu[index][8-input_num+i] = input_code[i];
}
input_num = 0;
}
break;
}
default:
{
if((index == 1 || index ==3) && input_num < 6 && error == 0)
{
input_code[input_num] = Trg - 1;
input_num++;
}
break;
}
}
}
if(tick_1s)
{
tick_1s = 0;
if(door_flag)
{
if(++cnt_time == 5)
{
Relay(0);
LED(0x00);
door_flag = 0;
cnt_time = 0;
index = 0;
for(i = 0; i < input_num; i++)
{
input_code[i] = 10;
menu[1][8-input_num+i] = 10;
}
input_num = 0;
}
}
else if(error)
{
if(++cnt_time == 5)
{
index = 0;
LED(0x00);
error = 1;
for(i = 0; i < input_num; i++)
{
input_code[i] = 10;
menu[3][8-input_num+i] = 10;
}
input_num = 0;
}
}
}
}
}
port.c文件
#include <STC15F2K60S2.H>
#include <intrins.h>
#include "port.h"
unsigned char bdata control;
sbit relay = control^4;
sbit buzzer = control^6;
void Relay(unsigned char k)
{
relay = k;
P0 = control;
P2 = 0xa0;
_nop_();
P2 = 0x00;
}
void Buzzer(unsigned char k)
{
buzzer = k;
P0 = control;
P2 = 0xa0;
_nop_();
P2 = 0x00;
}
void LED(unsigned char k)
{
P0 = ~k;
P2 = 0x80;
_nop_();
P2 = 0x00;
}
void LED_Bit(unsigned char k)
{
P0 = k;
P2 = 0xc0;
_nop_();
P2 = 0x00;
}
void LED_Com(unsigned char k)
{
P0 = ~k;
P2 = 0xe0;
_nop_();
P2 = 0x00;
}
key.c文件
#include <STC15F2K60S2.H>
#include <intrins.h>
#include "key.h"
unsigned char KeyScan(void)
{
unsigned char k1, k2, readData, key_val;
P44 = 1; P42 = 1; P3 = 0xf0;
if(P44 == 0)
k1 = 0x80;
else if(P42 == 0)
k1 = 0x40;
else if(P35 == 0)
k1 = 0x20;
else if(P34 == 0)
k1 = 0x10;
else
k1 = 0x00;
P44 = 0; P42 = 0; P3 = 0x0f;
k2 = ~P3 & 0x0f;
readData = k1 | k2;
switch(readData)
{
case 0x84:key_val = 9; break;
case 0x82:key_val = 5; break;
case 0x81:key_val = 1; break;
case 0x48:key_val = 11; break;
case 0x44:key_val = 10; break;
case 0x42:key_val = 6; break;
case 0x41:key_val = 2; break;
case 0x28:key_val = 12; break;
case 0x22:key_val = 7; break;
case 0x21:key_val = 3; break;
case 0x18:key_val = 13; break;
case 0x12:key_val = 8; break;
case 0x11:key_val = 4; break;
default:key_val = 0;break;
}
return key_val;
}
iic.c文件
/*
ԌѲ˵ķ: IICПȽ֯ԌѲ
ɭݾ۷: Keil uVision 4.10
Ӳݾ۷: CT107եƬܺ؛ۏʵѵƽ̨ 8051ì12MHz
ɕ ǚ: 2011-8-9
*/
#include "reg52.h"
#include "intrins.h"
#include "iic.h"
#define DELAY_TIME 3
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//Пӽޅ֨ӥ
sbit SDA = P2^1; /* ˽ߝП */
sbit SCL = P2^0; /* ʱדП */
void IIC_Delay(unsigned char i)
{
do{_nop_();_nop_();_nop_();}
while(i--);
}
//ПǴ֯͵ݾ
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//Пֹͣ͵ݾ
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//ע̍Ӧհ
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0úӦհì1ú؇Ӧհ
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//ֈսӦհ
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//ͨڽI2CПע̍˽ߝ
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//ՓI2CПʏޓ˕˽ߝ
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
AT24C02.c文件
#include "iic.h"
#include <intrins.h>
#include "AT24C02.h"
void Delay2ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 22;
j = 128;
do
{
while (--j);
} while (--i);
}
void AT24C02_WriteData(unsigned char addr, unsigned char dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
Delay2ms();
}
unsigned char AT24C02_ReadData(unsigned char addr)
{
unsigned char dat;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
dat = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
Delay2ms();
return dat;
}