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

📄 pwlock.c

📁 开发环境 KEIl 用4*4键盘组成0~9,确认,取消,共12个数字按键,用6位7段数码管组成显示电路,加电后,显示888888,输入密码时,会逐位显示F,密码输入过程中有错,可以按取消键再重新
💻 C
字号:
/*****************************************/
/* Copyright (c) 2005, 通信工程学院      */
/* All rights reserved.                  */
/* 作    者:戴 佳						 */
/*****************************************/

#include "PWLock.h"

/* 键消抖延时函数 */
void delay(void)
{
	uchar i;
	for (i=300;i>0;i--);
}

/* 键扫描函数 */
uchar keyscan(void)
{
	uchar scancode,tmpcode;
	P1 = 0xf0;			 					// 发全0行扫描码
	if ((P1&0xf0)!=0xf0)					// 若有键按下
	{
		delay();							// 延时去抖动
		if ((P1&0xf0)!=0xf0)				// 延时后再判断一次,去除抖动影响
		{
			scancode = 0xfe;
			while((scancode&0x10)!=0)		// 逐行扫描
			{
				P1 = scancode;				// 输出行扫描码
				if ((P1&0xf0)!=0xf0)		// 本行有键按下
				{
					tmpcode = (P1&0xf0)|0x0f;

					/* 返回特征字节码,为1的位即对应于行和列 */
					return((~scancode)+(~tmpcode));
				}
				else scancode = (scancode<<1)|0x01;		// 行扫描码左移一位
			}
		}
	}
	return(0);								// 无键按下,返回值为0 	
}

/* 定时器0中断服务子程序,2ms定时动态扫描显示 */
void time0_int(void) interrupt 1 
{
	/* 重置2ms定时 */
	TH0 = -2000/256;
	TL0 = -2000%256;

	if (showflag==1)
		display();				// 调用显示函数
}

/* 定时器1中断服务子程序,50ms*/
void time1_int(void) interrupt 3 
{
	uchar k;
	/* 重置50ms定时 */
	TH1 = -50000/256;
	TL1 = -50000%256;

	if (t1count<10)				
	{
		t1count++;
	}
	else						// 计时到1s
	{
		TR1 = 0;				// 关闭计数器1
		t1count = 0;	
		green = 1;				// 绿灯不亮
		red = 1;				// 红灯不亮
		showflag = 1;			// 打开数码管显示
		digbit = 0x01;			// 从数码管第1位开始动态显示
		for (k=0;k<6;k++)		// 显示888888
			wordbuf[k] = 8;
	}
}

/* 根据共阴极字型编码表获取0~9,A~B字型代码 */
uchar getcode(uchar i)
{
	uchar p;
	switch (i)
	{
		case 0:	 p=0x3f;	break;			/* 0 */
		case 1:	 p=0x06;	break;			/* 1 */
		case 2:	 p=0x5B;	break;			/* 2 */
		case 3:	 p=0x4F;	break;			/* 3 */
		case 4:	 p=0x66;	break;			/* 4 */
		case 5:	 p=0x6D;	break;			/* 5 */
		case 6:	 p=0x7D;	break;			/* 6 */
		case 7:	 p=0x07;	break;			/* 7 */
		case 8:	 p=0x7F;	break;			/* 8 */
		case 9:	 p=0x67;	break;			/* 9 */
		case 10: p=0x77;	break;			/* A */
		case 11: p=0x7C;	break;			/* B */
		case 12: p=0x39;	break;			/* C */
		case 13: p=0x5E;	break;			/* D */
		case 14: p=0x79;	break;			/* E */
		case 15: p=0x71;	break;			/* F */
		default: 			break;
	}
	return(p);
}

/* 显示函数 */
void display(void)
{
	uchar i;
	switch (digbit)
	{
		case 1:		i=0;	break;
		case 2:		i=1;	break;
		case 4:		i=2;	break;
		case 8:		i=3;	break;
		case 16:	i=4;	break;
		case 32:	i=5;	break;
		default: 	break;
	}  

	P2 = 0x0;						// 关闭显示
	P0 = getcode(wordbuf[i]);		// 送字型码
	P2 = digbit;					// 送字位码
	
	if (digbit<0x20)				// 共6位
		digbit = 2*digbit;			// 左移一位
	else
	    digbit = 0x01;
}

/* 密码比较函数 */
bit pwcmp(void)
{
	bit flag;
	uchar i;
	for (i=0;i<6;i++)
	{
		if (pw[i]==pwbuf[i])
			flag = 1;
		else
		{
			flag = 0;
			i = 6;
		}
	}
	return(flag);
} 

/* 主程序 */
void main()
{
	uchar j,key;

	P2 = 0x00;							// 关闭数码管显示
	
	TMOD = 0x11;						// T0,T1工作方式1

	/* 2ms 定时设置 */
	TH0 = -2000/256;		  // (65536-2000)+1=补码形式的-2000
	TL0 = -2000%256;

	/* 50ms 定时设置 */
	TH1 = -50000/256;
	TL1 = -50000%256;
	
	/* 启动计数器0,关闭计数器1 */
	TR0 = 1;
	ET0 = 1;
	TR1 = 0;
	ET1 = 1;
	EA = 1;

	count = 0;						// 初始没有输入密码,计数器设为0
	enterflag = 0;					// 没有按下确认键
	pwflag = 0;						// 密码标志先置为0
    green = 1;						// 绿灯不亮
	red = 1;						// 红灯不亮
	
	/* 假设内定密码为888888 */
	pw[0] = 8;
	pw[1] = 8;
	pw[2] = 8;
	pw[3] = 8;
	pw[4] = 8;
	pw[5] = 8;
	
	digbit = 0x01;					// 从第一位数码管开始动态扫描

	/* 刚加电时,显示888888 */
	for (j=0;j<6;j++)
		wordbuf[j] = 8;

	showflag = 1;					// 打开数码管显示

  	while(1)
  {	  P1 = 0xf0;
      if ((P1&0xf0)!=0xf0)	//	 有健按下
		{
			key = keyscan();					// 调用键盘扫描函数
			switch(key)
	   		{
	      		case 0x11:						// 1行1列,数字0
					if (count<6)
					{
						wordbuf[count] = 0x0f;	// 对应密码位上显示“F”
						pwbuf[count] = 0;
						count++;
					}
					break;
				case 0x21:						// 1行2列,数字1
					if (count<6)
					{
						wordbuf[count] = 0x0f;	// 对应密码位上显示“F"
						pwbuf[count] = 1;
						count++;
					}
					break;			
				case 0x41:						// 1行3列,数字2
					if (count<6)
					{
						wordbuf[count] = 0x0f;	// 对应密码位上显示“F"
						pwbuf[count] = 2;
						count++;
					}
					break;
	     		case 0x81:						// 1行4列,数字3
					if (count<6)
					{
						wordbuf[count] = 0x0f;	// 对应密码位上显示“F"
						pwbuf[count] = 3;
						count++;
					}
					break;
				case 0x12:						// 2行1列,数字4
					if (count<6)
					{
						wordbuf[count] = 0x0f;	// 对应密码位上显示“F"
						pwbuf[count] = 4;
						count++;
					}
					break;
				case 0x22:						// 2行2列,数字5
					if (count<6)
					{
						wordbuf[count] = 0x0f;	// 对应密码位上显示“F"
						pwbuf[count] = 5;
						count++;
					}
					break;
				case 0x42:						// 2行3列,数字6
					if (count<6)
					{
						wordbuf[count] = 0x0f;	// 对应密码位上显示“F"
						pwbuf[count] = 6;
						count++;
					}
					break;
				case 0x82:						// 2行4列,数字7
					if (count<6)
					{
						wordbuf[count] = 0x0f;	// 对应密码位上显示“F"
						pwbuf[count] = 7;
						count++;
					}
					break;
				case 0x14:						// 3行1列,数字8
					if (count<6)
					{
						wordbuf[count] = 0x0f;	// 对应密码位上显示“F"
						pwbuf[count] = 8;
						count++;
					}
					break;
				case 0x24:						// 3行2列,数字9
					if (count<6)
					{
						wordbuf[count] = 0x0f;	// 对应密码位上显示“F"
						pwbuf[count] = 9;
						count++;
					}
					break;
				case 0x44:						// 3行3列,确认键
					enterflag = 1;				// 确认键按下
					if (count==6) 				// 只有输入6个密码后按确认键才作密码比较
						pwflag = pwcmp();
					else						
						pwflag = 0;				// 否则直接pmflag赋0
					break;
				case 0x84:						// 3行4列,取消键
					count = 0;					// 密码计数清零
					for (j=0;j<6;j++)
					{
						wordbuf[j] = 8;			// 数码管显示888888
						pwbuf[j] = 0x0f;		// 用FFFFFF清除已经输入的密码
					}
					break;
				default:break;
			}
		    while((P1&0xf0)!=0xf0);  //松手检测
			   
			}
			
			
			if (enterflag==1)					// 如果按下确认键
			{
				enterflag = 0; 					// 标志位置回0
				count = 0;						// 密码位计数器清零
				for (j=0;j<6;j++)
					pwbuf[j] = 0x0f;			// 用FFFFFF清除已经输入的密码			
				showflag = 0;					// 关闭数码管显示
				TR1 = 1;						// 计数器1开始计数
				t1count = 0;					// 定时器1由50ms累积到1s所用的计数器
				if (pwflag==1)			
					green = 0; 					// 绿灯亮
				else							
					red = 0; 					// 红灯亮		
			}
		   
	    		 
	}   
}


⌨️ 快捷键说明

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