⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 利用89s52开发的密码锁.有兴趣的自己
💻 C
字号:
/*
   //*************************************************************************
   //
   //                  9键密码锁演示源文件
   //
   //           COPYRIGHT (c)   2006 BY 明浩
   //           --  ALL RIGHTS RESERVED  --
   //
   // File Name:	main.c
   // Created:		2007.3.10
   // Modified:		2007.3.10
   // Revision:		1.0
   //
   //*************************************************************************
   //*************************************************************************
*/

#include <at89x051.h>
#include <INTRINS.H>

//引脚定义,可以自行定义使用
#define Key		P1
#define RLed	P3_5
#define GLed	P3_4
#define CS	P3_1
#define SO	P3_0
#define SI	P3_3
#define	SCK	P3_2
#define Switch	P3_7

void RESWDI(void);
void WREN(void);
void WRSR(void);
void WRDI(void);
void WIPCHK(void);
unsigned char RSDR(void);
unsigned char INPUTByte(void);
void OUTByte(unsigned char Byte);
void WriteByte(unsigned char Byte, unsigned char ADD);
unsigned char ReadByte(unsigned  char ADD);
void Delay10ms();
void CLSPSW();

unsigned char KSVel[3]={0xFB,0xF7,0xEF};
unsigned char data UPSW[6]={3,1,5,8,1,8}, KPSW[6], KN; //写入的密码
unsigned int SW, SW2;

void main(void)
{
	unsigned char Temp;

	CS = 0;
	KN = 0;
	SW = 0;
	SW2 = 0;
	CLSPSW();

	WREN();
	WRSR();	//看门狗复位时间1.4s
	WRDI();

	for (Temp=0; Temp<6; Temp++)
		{		
			WREN();
			WriteByte(UPSW[Temp],Temp+1); //这里演示读出和写入 EEPROM	 
			UPSW[Temp] = ReadByte(Temp+1); //从EEPROM读数据到数组; 这里使用1-6地址
			//可以改成可以更改密码的
			WRDI();
		}
	
	EA = 1;					//允许CPU中断
	ET0 = 1; 				//定时器0中断打开
	TMOD = 0x1;			//设定时器0为模式1,16位模式
	TH0 = 0xB1;
	TL0 = 0xE1;			//设定时值为20000us(20ms)调整
	TR0 = 1;				//开始定时
	
	RLed = 0; //指示灯状态	红灯亮
	GLed = 1;

	while(1);
}

//定时中断
void KeyAndDis_Time0(void) interrupt 1
{
	unsigned char data Temp, TempV, TempN;

	TR0 = 0;
	TH0 = 0xB2;
	TL0 = 0x06; //设定时值(己调整)

	RESWDI(); //喂狗

	if (Switch==0) //继电器被打开时计数
		SW++;

	if (SW > 500)
		{
			SW = 0; 
			Switch = 1; //继电器打开时间,10秒
			RLed = 0;
			GLed = 1;
		}

	if (KN>0)
		SW2++;

	if (SW2 > 1000)
		{
			SW2 = 0;
			KN = 0; //二十秒内没有输入完6个数则要重新输入
			CLSPSW();
		}

	for (Temp=0; Temp<3; Temp++)
		{
			Key = KSVel[Temp];		
			TempV = Key;
			if (TempV<0xE0) //有键被按下时
				{
					Delay10ms(); //延时
					if (TempV == Key)
						{
							SW2 = 0;
							if (P1_7==0) KPSW[KN]=Temp*3+1;
							if (P1_6==0) KPSW[KN]=Temp*3+2;
							if (P1_5==0) KPSW[KN]=Temp*3+3;
							KN++;
							GLed = 0;	//当键按下时 GLED亮1S
							for (TempV=0; TempV<30; TempV++)
								{
								 Delay10ms();
								}
							GLed = 1;
							if (KN==6)
								{
									TempN = 0;
									for (TempV=0; TempV<6; TempV++)
										{
											if (KPSW[TempV] == UPSW[TempV])
												TempN++;
										}
									if (TempN==6)
										{
											Switch = 0;
											GLed = 0;
											RLed = 1; //绿灯亮
										}
									CLSPSW();
									KN = 0;
									SW2 = 0;
								}
						}
				}
		}
	TR0 = 1;
}

//---------------------------------
//x5045子程序
//---------------------------------
void RESWDI(void) //复位看门狗(喂狗)
{
 CS = 0;
 CS = 1;
}

void WREN(void) //写使能锁存
{
	SCK=0;
	CS=0;
	OUTByte(0x06); //发送06H写使能命令字
 	SCK=0;
 	CS=1;
}

void WRDI(void) //写使能复位(禁止写)
{
	SCK=0;
	CS=0;
	OUTByte(0x04); //发送04H写禁止命令字
 	SCK=0;
 	CS=1;
}

void WRSR(void) //写状态寄存器
{
	SCK=0;
	CS=0;
	OUTByte(0x01); //发送01H写寄存器命令字
	OUTByte(0x20); //发送寄存器值BL0,BL1为0没写保护,WD0=0 WD1=0看门狗复位时间为1.4s
 	SCK=0;
 	CS=1;
	WIPCHK(); //判断是否写入
}

unsigned char RSDR(void) //读状态寄存器
{
	unsigned char Temp;

	SCK=0;
	CS=0;
	OUTByte(0x05); //发送05H读状态寄存器命令字
	Temp = INPUTByte(); //读状态寄存器值
 	SCK=0;
 	CS=1;
	return Temp;
}

void WIPCHK(void) //检查WIP位,判断是否写入完成
{
	unsigned char Temp;
	unsigned int TempCyc;
	
	for(TempCyc=0;TempCyc<0xFFFF;TempCyc++)
		{
			Temp = RSDR(); //读状态寄存器
			Temp = Temp&0x01;
			if (!Temp)
				TempCyc = 0xFFFE;
		}
}

void OUTByte(unsigned char Byte) //输出一个定节
{
	unsigned char TempCyc;

	for(TempCyc=0;TempCyc<8;TempCyc++)
		{
			SCK = 0;
			SI = Byte & 0x80;
			Byte = Byte<<1; //右移				 -+
			SCK = 1;
		}
	SI=0; //使SI处于确定的状态
}

unsigned char INPUTByte(void) //输入一个字节
{
	unsigned char Temp=0, TempCyc;
	
	for(TempCyc=0;TempCyc<8;TempCyc++)
		{
			Temp = Temp<<1; //右移
			SCK = 0;
			SCK = 0;
			SCK = 1;
			SCK = 1;
			if (SO) 
				Temp = Temp|0x01; //SO为1,则最低位为1
		}
	return Temp;
}

unsigned char ReadByte(unsigned  char ADD) //读地址中的数据这里不做先导字处理,只能读00-FFH
{
	unsigned char Temp;

	SCK=0;
	CS=0;
	OUTByte(0x3); //发送读指令03H 如要支持000-FFF则要把高位地址左移3位再为03H相或
	OUTByte(ADD); //发送低位地址
	Temp = INPUTByte();
	SCK=0;
	CS=1;
	return Temp;
}

void WriteByte(unsigned char Byte, unsigned char ADD) //向地址写入数据这里同样不做先导字处理,只能写00-FFH
{
	SCK=0;
	CS=0;
	OUTByte(0x2); //发送写指令02H 如要支持000-FFF则要把高位地址左移2位再为02H相或
	OUTByte(ADD); //发送低位地址
	OUTByte(Byte); //发送数据
	SCK=0;
	CS=1;
	WIPCHK(); //判断是否写入
}

void Delay10ms()
{
	unsigned int Temp;
	
	for (Temp=0; Temp<1900; Temp++);
}

void CLSPSW()
{
	unsigned char Temp;
	
	for (Temp=0; Temp<6; Temp++)
		KPSW[Temp] = 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -