蓝桥杯单片机第10届模拟-门禁

题目

在这里插入图片描述

main.c

#include<stc15f2k60s2.h>

#define uchar unsigned char

#define s0 0
#define s1 1
#define s2 2
#define s3 3

void write_eeprom(uchar add, uchar dat);
char read_eeprom(uchar add);

code uchar semg[16] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90,
											 0xbf, 0x8c, 0x86, 0xab, 0xc6, 0xff};
code uchar semg_bit[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
uchar semg_temp[8] = {15, 15, 15, 15, 15, 15, 15, 15};

uchar state = s0;
int timeout = 0;
uchar flag_timeout = 0;
uchar flag_pass = 0;
char pass[6] = {8, 8, 8, 8, 8, 8};


void Delay400ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 17;
	j = 208;
	k = 27;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void Delay4ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 44;
	j = 4;
	do
	{
		while (--j);
	} while (--i);
}


void allinit()
{
	P2 = 0x80;	P0 = 0xff;
	P2 = 0xa0;	P0 = 0x00;
	P2 = 0xc0;	P0 = 0xff;
	P2 = 0xe0;	P0 = 0xff;
}


void Timer0Init(void)		//2毫秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x9A;		//设置定时初值
	TH0 = 0xA9;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	EA = 1;
	ET0 = 1;
}


void display()
{
	uchar i;
	
	P2 = 0xe0;	P0 = 0Xff;	P2 = 0x00;
	P2 = 0xc0;	P0 = 0Xff;	P2 = 0x00;
	
	P2 = 0xe0;	P0 = semg[semg_temp[i]];	P2 = 0x00;
	P2 = 0xc0;	P0 = semg_bit[i];	P2 = 0x00;	P0 = 0xff;
	
	i++;
	if(i == 8)
		i = 0;
}


void led()
{
	if( (flag_pass && timeout) || state == s3)
	{
		P0 = 0x10;	P2 = 0xa0;	P2 = 0x00;
	}
	else
	{
		P0 = 0x00;	P2 = 0xa0;	P2 = 0x00;
	}
	
	if(!flag_pass && timeout)
	{
		P0 = 0xfe;	P2 = 0x80;	P2 = 0x00;
	}
	else	if(state == s3)
	{
		P0 = 0x7f;	P2 = 0x80;	P2 = 0x00;
	}
	else if(state == s1)
	{	
		P0 = 0xbf;	P2 = 0x80;	P2 = 0x00;
	}
	else
	{
		P0 = 0xff;	P2 = 0x80;	P2 = 0x00;
	}
	
	P0 = 0xff;
}


void fun() interrupt 1
{
	
	display();
	led();
	
	if(flag_timeout == 1)
		timeout++;
	else
		timeout = 0;
	
}


char keyscan()
{
	static char keyvalue = -1;
	uchar keyrow, keycloumn, keycode, i, j;
	static uchar state_key = s0;
	
	P3 = 0x0f;	P44 = 0;	P42 = 0;
	keyrow = P3 & 0x0f;
	P3 = 0xf0;	P44 = 1;	P42 = 1;
	if(P44 == 0)				keycloumn = 0x70;
	else if(P42 == 0)		keycloumn = 0xb0;
	else								keycloumn = P3 & 0xf0;
	
	keycode = ~(keyrow | keycloumn);
	
	switch(state_key)
	{
		case s0:
			if(keycode)
				state_key = s1;
			else
				keyvalue = -1;
			break;
			
		case s1:
		{
			if(keycode)
			{
				for(i = 0; i < 4; i++)
					for(j = 0; j < 4; j++)
						if(keycode == ((0x80 >> j) | (0x01 << i)))
						{
							keyvalue = i * 4 + j;
							break;
						}
				state_key = s2;
			}
			else
				state_key = s0;
		}	break;
			
		case s2:
		{
			keyvalue = -1;
			if(!keycode)
				state_key = s0;
		}	break;
			
		default:	state_key = s0;	break;
	}
	
	return keyvalue;
	
}


void menu(char keyvalue)
{
	static uchar pass_num = 0;
	uchar i, pass_temp;
	
	switch(state)
	{
		case s0:
		{
			if(keyvalue == 15 && timeout == 0)
			{
				flag_timeout = 0;
				pass_num = 7;
				state = s1;
			}
			if(timeout >= 2500)
				flag_timeout = 0;
			for(i = 0; i < 8; i++)
				semg_temp[i] = 15;
		}	break;
			
		case s1:
		{
			semg_temp[0] = 10;
			semg_temp[1] = 15;
			if(keyvalue >= 0 && keyvalue <= 9)
			{
				for(i = pass_num; i < 7; i++)
					semg_temp[i] = semg_temp[i + 1];
				semg_temp[7] = keyvalue;
				pass_num--;
				if(pass_num == 1)
				{
			    Delay400ms();
					for(i = 2; i < 8; i++)
						if(pass[i - 2] != semg_temp[i])
						{
							pass_temp = 0;
							state = s0;
							break;
						}
						else
						{
							state = s2;
							pass_temp = 1;
						}
					flag_pass = pass_temp;
					flag_timeout = 1;
				}
			}
			else if(keyvalue == 13)
			{
				semg_temp[pass_num] = 15;
				for(i = 7; i > pass_num + 1; i--)
					semg_temp[i] = semg_temp[i - 1];
				if(pass_num < 7)
					pass_num++;
				else
					pass_num = pass_num;
				semg_temp[pass_num] = 15;
			}
		}	break;
		
		case s2:
		{
			semg_temp[0] = 0;
			semg_temp[1] = 15;
			semg_temp[2] = 15;
			semg_temp[3] = 15;
			semg_temp[4] = 0;
			semg_temp[5] = 11;
			semg_temp[6] = 12;
			semg_temp[7] = 13;
			if(timeout < 2500)
			{
				if(keyvalue == 14)
				{
					semg_temp[0] = 14;
					for(i = 1; i < 8; i++)
						semg_temp[i] = 15;
					pass_num = 7;
					flag_timeout = 0;
					state = s3;
				}
			}
			else
			{
				flag_pass = 0;
				flag_timeout = 0;
				timeout = 0;
				state = s0;
			}
		}	break;

		case s3:
		{
			semg_temp[0] = 14;
			semg_temp[1] = 15;
			if(pass_num > 1)
			{
				if( (keyvalue >= 0 && keyvalue <= 9) )
				{
					for(i = pass_num; i < 7; i++)
						semg_temp[i] = semg_temp[i + 1];
					semg_temp[7] = keyvalue;
					pass_num--;
				}
			}
			else
			{
				if(keyvalue == 14)
				{
					for(i = 0; i < 6; i++)
						pass[i] = semg_temp[i + 2];
					state = s0;
				}
			}
			
			if(keyvalue == 13)
			{
				semg_temp[pass_num] = 15;
				for(i = 7; i > pass_num + 1; i--)
					semg_temp[i] = semg_temp[i - 1];
				if(pass_num < 7)
					pass_num++;
				else
					pass_num = pass_num;
				semg_temp[pass_num] = 15;
			}

		}	break;
		
		default:	state = s0;	break;
	}
	
}


void save_password()
{
	static uchar i = 0, writestate = s0;
	
	switch(writestate)
	{
		case s0:
			if(state == s3)
				writestate = s1;
			else
				writestate = s0;
			break;
			
		case s1:
			if(state == s0)
				writestate = s2;
			else
				writestate = s1;
			break;
		case s2:
		{
			write_eeprom(i, pass[i]);
			i++;
			if(i == 6)
			{
				writestate = s0;
				i = 0;
			}
			else
				writestate = s2;
		}	break;
		
		default: writestate = s0;	break;
	}
}


void main()
{
	char keyvalue;
	uchar i;
	
	allinit();
	for(i = 0; i < 6; i++)
		pass[i] = read_eeprom(i);
	Timer0Init();
	
	while(1)
	{
		keyvalue = keyscan();
		menu(keyvalue);
		save_password();
		Delay4ms();
	}
	
}

iic.c

/*
  程序说明: IIC总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台 8051,12MHz
  日    期: 2011-8-9
*/

#include "reg52.h"
#include "intrins.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

#define uchar unsigned char

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */

void IIC_Delay(unsigned char i)
{
    do{_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);
}

//等待应答
bit IIC_WaitAck(void)
{
	SDA = 1;
	IIC_Delay(DELAY_TIME);
	SCL = 1;
	IIC_Delay(DELAY_TIME);
	if(SDA)    
	{   
		SCL = 0;
		IIC_Stop();
		return 0;
	}
	else  
	{ 
		SCL = 0;
		return 1;
	}
}

//通过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;    
}

void write_eeprom(uchar add, uchar dat)
{	
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();	
}

char read_eeprom(uchar add)
{
	char dat;
	
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();

	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	dat = IIC_RecByte();
	IIC_Stop();	
	
	return dat;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值