蓝桥杯单片机第十一届模拟题 智能门锁(附源码)

第十一届模拟题 智能门锁

main.c

#include<STC15F2K60S2.H>
#include<iic.h>
//typedef unsigned char u8;
//typedef unsigned int u16;

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;
sbit relay = P0^4;
sbit buzz = P0^6;
u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
u8 code t_display[]={ 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x5C,0x73,0x79,0x37,0x39};

u8 smg_count,smg_i,table[8], mscode[8]={0x7F,0x7F,0x7F,0x7F,0x7F,0x7F};
u8 key_count;
u8 key_val, button_val = 0 , state;
u8 time5s = 0;
u8 keyscan();
u8 i;

bit s6_flag;
bit flag1s;
bit key_flag;
bit code_input_flag;
bit input_error_flag;
bit open_flag;
bit change_code_flag = 0;
bit s12_flag;
bit flag5ms;
u8 time5;
#define FOSC 11059200L

#define T1MS (65536-FOSC/12/1000)   //1ms timer calculation method in 12T mode
u16 count;  

void Timer0Init();
void allInit();
u8 keyscan();
void dis_smg();
void delet_code();
void check_code();
void change_code();
void input_code();
void open(); 
void led();
void Delay5ms();
void check_index();

void main()
{
//	Delay5ms();
//			at24_w(0x05,mscode[0]);
//	Delay5ms();
//	   at24_w(0x54,mscode[1]);
//	Delay5ms();
//		 at24_w(0x53,mscode[2]);
//	Delay5ms();
//		 at24_w(0x52,mscode[3]);
//	Delay5ms();
//		 at24_w(0x51,mscode[4]);
//	Delay5ms();
//		 at24_w(0x50,mscode[5]);
//	Delay5ms();
	
		mscode[0] = at24_r(0x05);
	  mscode[1] = at24_r(0x54);
		mscode[2] = at24_r(0x53);
		mscode[3] = at24_r(0x52);
		mscode[4] = at24_r(0x51);
		mscode[5] = at24_r(0x50);
	
	 Timer0Init();
   allInit();
	 while (1)
		{
			if(key_flag)  //检测按键
			{
				key_flag = 0; //delete flag
				key_val = keyscan();
				switch( key_val )
				{
					case  7: button_val = 0; P2=0x80;P0=~0x01;P2=0x00;  break;
					case 11: button_val = 1; P2=0x80;P0=~0x02;P2=0x00; break;
					case 15: button_val = 2; P2=0x80;P0=~0x04;P2=0x00; break;
					case 19: button_val = 3; P2=0x80;P0=~0x08;P2=0x00; break;
					case  6: button_val = 4;  break;
					case 10: button_val = 5;  break;
					case 14: button_val = 6;  break;
					case 18: button_val = 7;  break;
					case  5: button_val = 8;  break;
					case  9: button_val = 9;  break;
					case  8: break;
					case 12: 
						     if(open_flag)
								 {change_code_flag = ~change_code_flag;} s12_flag = 1; break;
					case 16: s6_flag = 1; code_input_flag = 1;break;
					default : break;
				}
			//	check_index();
				  dis_smg();
				  led();
			}
			
		}
}

void check_index()
{
	for(i=0;i<8;i++)
	{
		table[i] = mscode[i];
	}
}

void tm0_isr() interrupt 1 using 1
{
    TL0 = T1MS;                     //reload timer0 low byte
    TH0 = T1MS >> 8;                //reload timer0 high byte
    if (count-- == 0)               //1ms * 1000 -> 1s
    {
        count = 1000;               
        flag1s = 1;
			  if(count % 5 == 0)
				{
					flag5ms = 0;
				}
    }
		if (smg_count-- == 0)               //smg模块
    {
        smg_count = 2;     
        P2 = (P2&0x1f)|0xe0; P0 = ~table[smg_i]; P2 = (P2&0x1f);
        P2 = (P2&0x1f)|0xc0; P0 = T_COM[smg_i]; P2 = (P2&0x1f);			
        smg_i++;
			  smg_i &= 0x07;
    }
		if (key_count-- == 0)               //1ms * 1000 -> 1s
    {
        key_count = 10;   
        key_flag = 1;			
        
    }

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

	i = 54;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}

void allInit()
{
	P2 = (P2&0x1f)|0xa0;
	P0 = 0x00;
	P2 = P2&0x1f;
	
	P2 = (P2&0x1f)|0x80;
	P0 = 0xff;
	P2 = P2&0x1f;
	
	P2 = (P2&0x1f)|0xc0;
	P0 = 0x00;
	P2 = (P2&0x1f);
	change_code_flag = 0;
	open_flag = 0;
	code_input_flag = 0;
	
}
void led()
{
	if(input_error_flag) 
	{
		P2 = 0x80 ; P0 = ~0x01; P2=0x00;
		if(flag1s)
		{
			time5++;
			if(time5 == 5)
			{
				P2 = 0x80 ; P0 = ~0x00; P2=0x00;
				input_error_flag = 0;
			}
		}
	}
//	else if(open_flag&&change_code_flag == 0)
//	{
//				P2 = 0x80 ; P0 = ~0x02; P2=0x00;
//	}
//	else if(open_flag==1&&change_code_flag)
//	{
//						P2 = 0x80 ; P0 = ~0x04; P2=0x00;
//	}
	else if(code_input_flag)
	{
						P2 = 0x80 ; P0 = ~0x40; P2=0x00;

	}
	else if(change_code_flag)
	{
						P2 = 0x80 ; P0 = ~0x80; P2=0x00;

	}
	else
	{
			P2 = 0x80 ; P0 = ~0x00; P2=0x00;

	}
	
}

void Timer0Init()
{
	  TMOD = 0x01;                    //set timer0 as mode1 (16-bit)
    TL0 = T1MS;                     //initial timer0 low byte
    TH0 = T1MS >> 8;                //initial timer0 high byte
    TR0 = 1;                        //timer0 start running
    ET0 = 1;                        //enable timer0 interrupt
    EA = 1;                         //open global interrupt switch
    count = 0;                      //initial counter
}

void dis_smg()
{
	input_code();
	if(open_flag)
	{
  open();
	}
}

u8 keyscan()
{
	u8 key = 99, keyreturn = 99;
	h1 = 0; h2 = 1; h3 = 1; h4 = 1;
	l1 = 1; l2 = 1; l3 = 1; l4 = 1;
  if(l1 != 1)  key = 7;
  if(l2 != 1)  key = 11;
	if(l3 != 1)  key = 15;
  if(l4 != 1)  key = 19;
	
  h1 = 1; h2 = 0; h3 = 1; h4 = 1;
	l1 = 1; l2 = 1; l3 = 1; l4 = 1;
	if(l1 != 1)  key = 6;
  if(l2 != 1)  key = 10;
	if(l3 != 1)  key = 14;
  if(l4 != 1)  key = 18;

  h1 = 1; h2 = 1; h3 = 0; h4 = 1;
	l1 = 1; l2 = 1; l3 = 1; l4 = 1;
	if(l1 != 1)  key = 5;
  if(l2 != 1)  key = 9;
	if(l3 != 1)  key = 13;
  if(l4 != 1)  key = 17;	
	
  h1 = 1; h2 = 1; h3 = 1; h4 = 0;
	l1 = 1; l2 = 1; l3 = 1; l4 = 1;
	if(l1 != 1)  key = 4;
  if(l2 != 1)  key = 8;
	if(l3 != 1)  key = 12;
  if(l4 != 1)  key = 16;
	
	switch(state)
	{
		case 0: if(key != 99 ) state = 1; break;
		case 1:
			if(key == 99 )
			         state = 0;
		         else
						 {
							 keyreturn = key;
							 state = 2;
						 }
						 break;
		case 2: if(key == 99 )
			         state = 0;			         
		      	break;
	}
	         return keyreturn;
}

void delet_code()
{
			table[2] = 0x00;
			table[3] = 0x00;
			table[4] = 0x00;
			table[5] = 0x00;
			table[6] = 0x00;
			table[7] = 0x00;
}

void input_code()
{
	if(s6_flag)
		{
			open_flag = 0;
		s6_flag = 0;
		//按下s16,清楚一次数码管的数据
		table[0] = 0x40;
		table[1] = 0x00;
			
		table[2] = 0x00;
		table[3] = 0x00;
		table[4] = 0x00;
		table[5] = 0x00;
		table[6] = 0x00;
		table[7] = 0x00;
	}
	
		
	if(code_input_flag)    //输入状态
	{
	  if( key_val != 99 && key_val != 4 && key_val!= 8 && key_val != 13 && key_val != 12 && key_val != 17 && key_val != 16) //有键按下
		{
			table[0] = t_display[key_val%10];
			table[2] = table[3];
			table[3] = table[4];
			table[4] = table[5];
			table[5] = table[6];
			table[6] = table[7];
			table[7] = t_display[button_val%10];
		}
		else if(key_val == 8)
		{
			delet_code();               //为什么这里按了s8并没有删除啊(get)
	//		P2 = 0x80;P0=~0x40;P2=0x00; // 根本没有进入这个函数
		}		
    else if( table[2] != 0x00 )
 		{
			check_code();
		}			
	}
}

void check_code()
{
	//密码输入正确
		if(table[2] == mscode[0] && table[3] == mscode[1] && table[4] == mscode[2] && table[5] == mscode[3] && table[6] == mscode[4] && table[7] == mscode[5])
		{
			code_input_flag = 0;
			open_flag = 1;
		}//密码输入错误
		else if(( table[2] != 0x00) && ( table[2] != mscode[0] || table[3] != mscode[1] || table[4] != mscode[2] || table[5] != mscode[3] || table[6] != mscode[4] || table[7] != mscode[5]))
		{
			input_error_flag = 1;
		}	
}

void open()
{
	P2 = (P2&0x1f)|0xa0; relay = 1; buzz = 0;  P2 = (P2&0x1f);
	        if(change_code_flag == 0 && flag1s)
					{
					table[0] = t_display[0];
		      table[1] = 0x00;
				
					table[2] = 0x00;
					table[3] = 0x00;
					table[4] = t_display[0];
					table[5] = t_display[11];
					table[6] = t_display[12];
					table[7] = t_display[13];
					}
		if( key_val != 99 && change_code_flag == 0 )  //5s熄灭
		{
			if(flag1s)
			{
			  flag1s = 0;
			  time5s++;
			if(time5s == 5)
			{
				allInit();   //初始化
				time5s = 0;
			}
		  }
		}
		else
		{
			time5s = 0;
		}
		if(change_code_flag )    //s12修改状态改变
		{
			change_code();    //修改状态

		}

}

void change_code()
{
	if(s12_flag)
		{
	s12_flag = 0;
		//按下s6,清楚一次数码管的数据

		table[0] =  t_display[0];
		table[1] = 0x00;
			
		table[2] = 0x00;
		table[3] = 0x00;
		table[4] = 0x00;
		table[5] = 0x00;
		table[6] = 0x00;
		table[7] = 0x00;
	}
	 if( key_val != 99 && key_val != 4 && key_val!= 8 && key_val != 13 && key_val != 12 && key_val != 17 && key_val != 16) //有键按下
		{
			table[0] = t_display[14];
			table[2] = table[3];
			table[3] = table[4];
			table[4] = table[5];
			table[5] = table[6];
			table[6] = table[7];
			table[7] = t_display[button_val%10];
		}
		if(table[2] != 0)
		{
			  mscode[0] = table[2];
				mscode[1] = table[3];
				mscode[2] = table[4];
				mscode[3] = table[5];
				mscode[4] = table[6];
				mscode[5] = table[7]; 
			
	Delay5ms();
			at24_w(0x05,mscode[0]);
	Delay5ms();
	   at24_w(0x54,mscode[1]);
	Delay5ms();
		 at24_w(0x53,mscode[2]);
	Delay5ms();
		 at24_w(0x52,mscode[3]);
	Delay5ms();
		 at24_w(0x51,mscode[4]);
	Delay5ms();
		 at24_w(0x50,mscode[5]);
	Delay5ms();
		}
}

iic.c

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

#include "iic.h"

//总线启动条件
void IIC_Start(void)
{
	SDA = 1;
	SCL = 1;
	somenop;
	SDA = 0;
	somenop;
	SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
	SDA = 0;
	SCL = 1;
	somenop;
	SDA = 1;
}

//应答位控制
void IIC_Ack(unsigned char ackbit)
{
	if(ackbit) 
	{	
		SDA = 0;
	}
	else 
	{
		SDA = 1;
	}
	somenop;
	SCL = 1;
	somenop;
	SCL = 0;
	SDA = 1; 
	somenop;
}

//等待应答
bit IIC_WaitAck(void)
{
	SDA = 1;
	somenop;
	SCL = 1;
	somenop;
	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++)
	{   
		if(byt&0x80) 
		{	
			SDA = 1;
		}
		else 
		{
			SDA = 0;
		}
		somenop;
		SCL = 1;
		byt <<= 1;
		somenop;
		SCL = 0;
	}
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
	unsigned char da;
	unsigned char i;
	
	for(i=0;i<8;i++)
	{   
		SCL = 1;
		somenop;
		da <<= 1;
		if(SDA) 
		da |= 0x01;
		SCL = 0;
		somenop;
	}
	return da;
}

void at24_w(u8 add, u8 dat)
{
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}

u8 at24_r(u8 add)
{
	u8 temp;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	temp = IIC_RecByte();
	IIC_Stop();
	return temp;
}

iic.h

#ifndef _IIC_H
#define _IIC_H

#include "STC15F2K60S2.H"
#include "intrins.h"
typedef unsigned char u8;
typedef unsigned int u16;
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

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

//函数声明
void IIC_Start(void); 
void IIC_Stop(void);  
void IIC_Ack(unsigned char ackbit); 
void IIC_SendByte(unsigned char byt); 
bit IIC_WaitAck(void);  
unsigned char IIC_RecByte(void); 
u8 at24_r(u8 add);
void at24_w(u8 add, u8 dat);

#endif

目前先把代码贴出来~去年写的,等复习的时候再来贴上讲解和采坑部分

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值