基于51单片机的智能密码锁设计
摘要:
目前使用的智能密码锁大多数是基于单片机技术,本次设计以AT89C51作为主控芯片与数据存储单元,结合矩阵键盘的输入、LCD液晶显示、报警、开锁等。用keil软件编写的控制程序,设计了一款具有设定和修改密码,并且具有报警功能的智能密码锁控制系统。
这种密码锁具有设计简单,易于开发,成本较低,安全可靠,操作方便等特点,可应用于住宅、办公室的保险箱及档案柜等需要防盗的场所,有比较强的实用性。 关键词:矩阵键盘;LCD;电磁锁;报警
The design of the intelligent password lock based on 51 single chip microcomputer
Abstract:
The intelligent password lock most currently used are based on single chiptechnology, the design takes AT89C51 as the main control chip and the data storage unit, combined with the matrix keyboard input, the LCD liquid crystal display, alarm, lock etc.. Control program is compiled with keil software, designed a set and modify the password, and has intelligent cipher alarm lock control system.
The cipher lock has the advantages of simple design, easy development, low cost, safe and reliable, convenient, safe and file cabinets need security can be applied to residential, office space, a relatively strong practical.
Keywords: matrix keyboard; LCD; electromagnetic lock; alarm
目 录
1、引言 .................................. 错误!未定义书签。 2、系统总体设计 .......................................... 1 2.1设计要求 .......................................... 1 2.2整体方案设计 ...................................... 1 3.硬件系统设计 ........................................... 2 3.1 单片机系统 ....................................... 2 3.2 矩阵键盘 ......................................... 4 3.3 LCD显示 .......................................... 6 3.4 报警系统 ......................... 错误!未定义书签。 3.5 复位电路 ......................................... 7 4.软件设计 ............................................... 8 4.1 软件的总体设计 ................................... 8 4.2 软件各子程序的设计 ............................... 8 5.调试与总结 ............................................ 12 6.仿真图 ................................................ 12 参考文献 ................................................ 14 致谢 .................................................... 15 附录 .................................................... 16
1.引言
随着人们生活水平的提高和安全意识的加强,对安全的要求也就越来越高。锁自古以来就是把守护门的铁将军,人们对它要求甚高,既要安全可靠的防盗,又使用方便,这也是制锁者长期以来研制的主题。随着电子技术的发展,各类电子产品应运而生,电子密码锁就是其中之一。据有关资料介绍,电子密码锁的研究从20世纪30年代就开始了,在一些特殊场所早就有所应用。这种锁是通过键盘输入一组密码完成开锁过程。研究这种锁的初衷,就是为提高锁的安全性。电子锁的密钥量(密码量)极大,可以与机械锁配合使用,并且可以避免因钥匙被仿制而留下安全隐患。电子锁只需记住一组密码,无需携带金属钥匙,免除了人们携带金属钥匙的烦恼,因而被越来越多的人所欣赏。电子锁的种类繁多,例如数码锁,指纹锁,磁卡锁,IC卡锁,生物锁等,但较实用的还是按键式电子密码锁。
单片机已经在家电领域中得到了广泛的应用,这是一种利用AT89S51单片机来设计电子密码锁方法.该系统主要由单片机、矩阵键盘、LED显示和报警系统等几个部分组成,可以完成开锁、修改密码、超次锁定、报警等功能,具有结构简单、功能齐全和安全可靠等特点。
2.系统总体的设计
2.1设计要求
1、系统通过4*4的矩阵键盘输入或设定开锁密码 2、可以通过LCD查看已输入的字符个数(显示*) 3、用户可以自行设定和修改密码。 4、按每个密码键时都有声音提示。
5、开锁密码错3次要报警1分钟,报警期间输入密码无效,以防窃贼多次试探密码。
6、键入的8位开锁密码完全正确才能开锁,开锁时要有1秒的提示音。 7、电磁锁的电磁线圈每次充电5秒,然后恢复初态。 8、密码设定完毕后要有2秒的提示音。
2.2整体方案设计
对于电子密码锁的设计,需要解决几个问题:键盘输入、数码管显示、单片机电路、密码比较、修改密码等。其中最主要的就是解决掉电保存以及修改密码的问题。先写一个循环写入8个初始密码到芯片内部EEPROM程序,先下载程序写入初始密码,此时EEPROM已存有初始密码,再把密码锁程序下载到单片机,运行电子密码锁。
1
本设计主要由单片机、矩阵键盘、LCD显示器和密码存储等部分组成。其中矩阵键盘用于输入数字密码和进行各种功能的实现。由用户通过连接单片机的矩阵键盘输入密码,后经过单片机对用户输入的密码与自己保存的密码进行对比,从而判断密码是否正确,然后控制引脚的高低电平传到开锁电路或者报警电路控制开锁还是报警,P0口用于电子显示屏来显示提示语句和密码输入按键。
3.硬件系统设计
3.1 单片机系统
本次设计选用单片机作为系统的核心部件,实现控制与处理的功能。单片机具有资源丰富、速度快、编程容易等优点。利用单片机内部的随机存储器(RAM)和只读存储器(ROM)及其引脚资源,外接数码管显示(LED),键盘输入等实现数据的处理传输和显示功能,基本上能实现设计指标。
单片机是在微处理的基础上发展起来的。未处理最早出现在20世纪70年代中期,是微计算机的核心,需要和存储器以及I/O接口电路共同组成应用系统。
我国引进微计算机嵌入技术是在改革开放时期,到现在已经有30年了。最早大规模的引进的是Z80单片机。
而单片机技术的引进是从8051开始的。它是Intel公司研发的技术。 AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。AT89C2051是一种带2K字节闪烁可编程可擦除只读存储器的单片机。单片机的可擦除只读存储器可以反复擦除100次。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,AT89C2051是它的一种精简版本。AT89C单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
其主要特性: ·与MCS-51 兼容
·4K字节可编程闪烁存储器 寿命:1000写/擦循环 数据保留时间:10年 ·全静态工作:0Hz-24Hz ·三级程序存储器锁定 ·128*8位内部RAM ·32可编程I/O线
·两个16位定时器/计数器
2
·5个中断源 ·可编程串行通道
·低功耗的闲置和掉电模式 ·片内振荡器和时钟电路
图1 AT89C51引脚图
引脚功能说明:
VCC:供电电压。 GND:接地。
P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。
P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。
P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对
3
外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。P3口也可作为AT89C51的一些特殊功能口,P3口同时为闪烁编程和编程校验接收一些控制信号。
RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时,将使单片机复位。
ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时,ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。
PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的PSEN信号将不出现。
EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。
XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。 XTAL2:来自反向振荡器的输出。
3.2 矩阵键盘
在单片机按键使用过程中,当键盘中按键数量较多时 为了减少端口的占用通常将按键排列成矩阵 形式如下图所示,在矩阵式键盘中 每条水平线和垂直线在交叉处不直接连通而是通过一个按键加以连接,到底这样做是出意何种目的呢?大家看下面电路图,单片机的整一个8位端口可以构成4*4=16个矩阵式按键,相比独立式按键接法多出了一倍,而且线数越多区别就越明显,假如再多加一条线就可以构成20个按键的键盘,但是独立式按键接法只能多出1个按键。由此可见,在需要的按键数量比较多时,采用矩阵法来连接键盘是非常合理的,矩阵式结构的键盘显然比独立式键盘复杂一些,单片机对其进行识别也要复杂一些。 矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,上图中,
4
列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。这样,当按键没有按下时,所有的输入端都是高电平,代表无键按下。行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。
图2 矩阵键盘电路
每一条水平(行线)与垂直线(列线)的交叉处不相通,而是通过一个按键来连通,利用这种行列矩阵结构只需要N条行线和M条列线,即可组成具有NM个按键的键盘。
在这种行列式矩阵键盘非键盘编码的单片机系统中,键盘处理程序首先执行等待按键并确认有无按键按下的程序段。当确认有按键按下后,下一步就要识别哪一个按键按下。对键的识别通常有两种方法:一种是常用的逐行扫描查询法;另一种是速度较快的线反转法。对照图所示的4×4键盘,说明线反转个工作原理。首先辨别键盘中有无键按下,有单片机I/O口向键盘送全扫描字,然后读入行线状态来判断。方法是:向行线输出全扫描字00H,把全部列线置为低电平,然后将列线的电平状态读入累加器A中。如果有按键按下,总会有一根行线电平被拉至低电平从而使行线不全为1。判断键盘中哪一个键被按下使通过将列线逐列置低电平后,检查行输入状态来实现的。方法是:依次给列线送低电平,然后查所有行线状态,如果全为1,则所按下的键不在此列;如果不全为1,则所按下的键必在此列,而且是在与零电平行线相交的交点上的那个键。
每按下一个键,都会有1秒的提示音出现。需要键入8位密码才能开锁。
5
表1 按键及功能表
3.3 LCD显示
LCD产品制造涉及光学、半导体、电机、化工、材料等各项领域,上下游所需技术层面极广,所以少有单一厂商能从材料到成品全部都做,因此各领域分工明显,上游材料包括玻璃基板、ITO导电玻璃厂、偏光板、彩色滤光片、光源模块、液晶、半导体制造工序所需光罩,液晶驱动IC、印刷电路板(PCB)等;中游则集合各材料,制造LCD面板,提供给下游应用厂商使用,由于下游应用产品众多,所需面板规格几乎都不相同,需根据产品切割面板尺寸,因此LCD面板较没有规格产品;下游应用产品种类众多,从各式家电、消费性、信息、通信及工业产品,只要是需要显示的器具,都需使用LCD产品。
特点:
液晶显示器件在直流电压作用下会发生电解作用,故必须用交流驱动,并且限定交流成分中的直流分量不大于几十毫伏;
由于液晶在电场作用下光学性能的改变是依靠液晶作为弹性连续体的弹性变形,响应时间长,所以交变驱动电压的作用效果不取决于其峰值,在频率小于1000Hz情况下,液晶透光率的改变只与外加电压的有效值有关;
液晶单元是容性负载,液晶的电阻在大多数情况下可以忽略不计,是无极性的,即正压和负压的作用效果是一样的。
图3 显示电路
6
显示器部分由液晶显示器LCD取代普通的显示器。开锁时,按下键盘上的开锁按键后,利用键盘上的数字键0-9输入密码,每按下一个数字后在显示器上显示一个“*”,输入多少位就显示多少个“*”。
3.4 报警系统
防盗报警系统是指当非法侵入防范区时,引起报警的装置,它是用来发出出现危险情况信号的。防盗报警系统就是用探测器对建筑内外重要地点和区域进行布防。它可以及时探测非法入侵,并且在探测到有非法人侵时,及时向有关人员示警。譬如门磁开关、玻璃破碎报警器等可有效探测外来的人侵,红外探测器可感知人 员在楼内的活动等。一旦发生人侵行为,能及时记录入侵的时间、地点,同时通过报警设备发出报警信号。
安防行业智能化成为重要的发展趋势。智能化其实就是在普通的监控报警的过程中增加了智能分析反应、智能控制的功能。智能化可以让防盗报警系统工作更有效率,让用户更省心。
图4 报警电路
在本次设计中,密码输入正确,成功开锁。当开锁密码输入错误时密码输入错误时喇叭长时提示,3次密码输入错误时报警电路报警1分钟,即红色二极管灯亮。报警期间,输入密码无效,以防窃贼多次试探密码。
3.5 复位电路
复位是单片机的初始化操作。单片机在启动运行时,都需要先复位,其作用
是使CPU和系统中其它部件都处于一个确定的初始状态,并从这个状态开始工作。因而,复位是一个很重要的操作方式,但是单片机本身是不能自动进行复位的,必须配合相应的外部电路才能实现。整个复位电路包括内外两个部分。外部电路产生的复位信号通过复位引脚RST进入片内的斯密特触发器(抑制噪声),
7
再与片内复位电路相连。单片机的外部复位电路有上电自动复位和按键手动复位两种。本次设计中我们使用了按键电平复位。
图5 复位电路
4.软件设计
4.1 软件的总体设计
软件的设计主要包括:密码的固定、键盘识别判断、密码显示、密码比较、密码对处理、错报警。
智能密码锁工作的主要过程是LCD数码管提示开始输入密码,通过键盘输入密码,同时LCD显示密码输入情况,按下确认键后判断密码的正确性,作出开锁或报警处理。当输入密码连续输入错误3次时,系统报警。密码的设定,假设预设的密码为\"0123456789\"共10位密码。
4.2 软件各子程序的设计
8
图6 键盘扫描流程
矩阵键盘扫描程序: #ifndef __KEY_H__ #define __KEY_H__
#define uchar unsigned char #define uint unsigned int #define KEY_PORT P3 // 0 1 2 3 // 4 5 6 7 // 8 9 a b // c d e f
const unsigned char keytable4X4[]={ 0x7e, 0xbe, 0xde, 0xee, 0x7d, 0xbd, 0xdd, 0xed, 0x7b, 0xbb, 0xdb, 0xeb,
0x77, 0xb7, 0xd7, 0xe7};//定义存到FLASH中 void delay_50us(uint t) //50us 延时
{
uchar j;
for(;t>0;t--) for(j=19;j>0;j--) }
uchar keyscan(void)
{
uchar temp1,temp2,temp;
uchar j=0; //键值
KEY_PORT = 0xf0; //P3.0-P3.3发全0,准备读列状态 delay_50us(20);
if((KEY_PORT & 0xf0)==0xf0)
return(0xff); //如果P3.4-P3.7不全为1,有键按下 delay_50us(20); //延时10毫秒去抖动
if((KEY_PORT&0x0f0)==0xf0) //重读高4位,若还是不全为1定有键按下 return(0xff);
temp1=KEY_PORT & 0xf0; //读高4位状态
KEY_PORT = 0x0f; //P3.4-P3.7发为0,准备读低4位状态 temp2=KEY_PORT & 0x0f; //P1.0-P1.3发为0,读P2低4位状态
9
temp= temp1+temp2; while(temp2 != 0x0f) temp2=P3; switch(temp) {
case 0x7e:return 1;break; case 0x7d:return 4;break; case 0x7b:return 7;break; case 0x77:return 10;break;//* case 0xbe:return 2;break; case 0xbd:return 5;break; case 0xbb:return 8;break; case 0xb7:return 0;break; case 0xde:return 3;break; case 0xdd:return 6;break; case 0xdb:return 9;break; case 0xd7:return 11;break;//# case 0xee:return 12;break; case 0xed:return 13;break; default:return 0xff;break; }
} // 0 1 2 3 // 4 5 6 7 // 8 9 a b // c d e f
//const unsigned char keytable4X4[]={ //0x7e, 0xbe, 0xde, 0xee, //0x7d, 0xbd, 0xdd, 0xed, //0x7b, 0xbb, 0xdb, 0xeb,
//0x77, 0xb7, 0xd7, 0xe7};//定义存到FLASH中 // 1 2 3 开始 // 4 5 6 修改密码 // 7 8 9
// 0 enter del
10
确定矩阵式键盘上何键被按下介绍一种“行扫描法”。行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法。判断键盘中有无键按下具体步骤如下:
先将列线p3.7-p3.4置0111,然后检测行线的状态。如果p3.3-p3.0为0111,则0被按下;如果p3.3-p3.0为1011,则1被按下;如果p3.3-p3.0为1101,则2被按下,如果p3.3-p3.0为1110,则3被按下。 以此类推,对键盘进行循环扫描,实现对键盘的读入数据。
显示程序:
#ifndef __DISPLAY_H__ #define __DISPLAY_H__ #define uchar unsigned char #define uint unsigned int
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
void SEG_Latch(void) //段码锁存子程序
{
P2 |= 0xe0;//P2.7~P2.5=111,Y7=0,Y7C=1,即U7的LE=1,段码数据选通
_nop_();
P2 &= 0x1f;//P2.7~P2.5=000,Y7=1,Y7C=0,即U7的LE=0,段码数据被锁存
}
void BIT_Latch(void) //位码锁存子程序
{
P2 |= 0xC0; //P2.7~P2.5=110,Y6=0,Y6C=1,即U8的LE=1,位码数据选通
_nop_();
P2 &= 0x1f; //P2.7~P2.5=000,Y6=1,Y6C=0,即U8的LE=0,位码数据被锁存
}
void display(uchar *point) {
unsigned char i=0; for(i=0;i<8;i++) {
DataPort=WeiMa[i]; //取位码 BIT_Latch(); //数据锁存
DataPort=DuanMa[*(point+i)]; //取显示数据,段码
11
SEG_Latch(); //数据锁存
delay_50us(20); // 扫描间隙延时,时间太长会闪烁,太短不亮 DataPort=0xff; //关显示,消除重影 SEG_Latch(); //数据锁存 } } #endif
采用LCD动态显示,由单片机P0口进行输出显示,P2口扫描。为了实现LCD显示器的动态扫描,除了要给显示器的输入之外,还有对显示器选择位的控制,这就是通常所说的段控和位控。因此,多位LCD显示器接口电路需要有两个输出口,其中一个用于8条段控线,另一个用于输出位控线,位控线的数目等于显示器的位数。
这一系统使密码锁的安全性能得以体现,为人们的住房、生产、工作等提供了一个保障。
5.调试与总结
本次设计将我所学的知识充分的应用到了生活实践上去,和以前设计的相比,此次设计难度更加大,对我的考验也更大。
单片机系统进行编译KEIL软件的程序,编译完成后,开始画仿真图的设计,对应着KEIL程序连接各个端口,连接完毕后,将KEIL程序录入到仿真电路中,进行仿真运行电路。
这一次的设计大部分要求都已经完成,但是还是有很多缺陷,有些设计要求还是无法实现:如电磁线圈每5秒充电一次,然后恢复初态等。
通过这次设计,发现自己还是有很多不足的地方,还要加强对专业知识的学习和对实际操作的练习。 单片机领域是无边无际的,我们还要慢慢摸索,碰到问题解决问题,不断的提升自己的能力。不辜负老师对我们的期望。
6.仿真图
输入密码:
图7 显示输入密码
12
密码输入正确:
密码输入错误:警报灯亮:
重新输入密码:
图8 显示密码输入正确
图9显示密码输入错误
图10 警报灯亮
图11 显示重新输入密码
13
参考文献
[1] 李连华. 基于FPGA的电子密码锁设计.中国科技信息,2006,(01):64 [2] 许琦. 基于FPGA的电子密码锁的设计.科技信息,2006,(10):240-241
[3] 王卫兵,刘克刚,朱秋萍. 用FPGA的电子密码锁.电子技术,2005,(01):26-28
[4] 赵益丹,徐晓林,周振峰.电子密码锁的系统原理、设计程序及流程图.嘉兴学院学报,2003,15(S1):103-105
[5] 陆重阳,卢东华.FPGA技术及其发展趋势.微电子技术,2003,(01):5-7 [6] 王晓勇.FPGA的基本原理及运用.舰船电子工程,2005,(02):82-85 [7] 程耀林.FPGA的系统设计方法解析.现代电子技术,2005,(19):90-93 [8] 石文轩,宋薇. 基于单片机MCS一1的智能密码锁设计[M]. 武汉:武汉工程职业技术学院学报,2004 [9] 谭浩强. C++程序设计[M].北京:清华大学出版社,2004
[10] 祖龙起,刘仁杰. 一种新型可编程密码锁[J]. 大连轻工业学院学报,2002,(01):1~89 [11] 李明喜. 新型电子密码锁的设计[J]. 机电产品开发与创新,2004,(03):46~123 [12] 董继成. 一种新型安全的单片机密码锁[J]. 电子技术,2004,(03):1~55 [13] 杨茂涛. 一种电子密码锁的实现[J]. 福建电脑,2004,(08):1~25
14
致 谢
行文至此,我的这篇论文已接近尾声;岁月如梭,我三年的大学时光也即将敲响结束的钟声。离别在即,站在人生的又一个转折点上,心中难免思绪万千,一种感恩之情油然而生。生我者父母。感谢生我养我,含辛茹苦的父母。是你们,为我的学习创造了条件;是你们,一如既往的站在我的身后默默的支持着我。没有你们就不会有我的今天。谢谢你们,我的父亲母亲!
在这三年中,老师的谆谆教导、同学的互帮互助使我在专业技术和为人处事方面都得到了很大的提高。感谢江苏农林职业技术学院在我三年的大学生活当中对我的教育与培养,感谢江苏农林职业技术学院的所有专业老师,没有你们的辛勤劳动,就没有我们今日的满载而归,感谢大学三年曾经帮助过我的所有同学。在制作毕业设计过程中我曾经向老师们和同学们请教过不少的问题,老师们的热情解答和同学们的热心帮助才使我的毕业设计能较为顺利的完成。在此我向你们表示最衷心的感谢。
15
附录:
Protues仿真图:
Keil程序:
#include DuanMa[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x8c,0x86,0xab,0xaf,0xff}; unsigned char WeiMa[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; unsigned char tempdata[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; 16 unsigned char key[8]={0,0,0,0,0,0,0,0}; unsigned char inputkey[8]={0,0,0,0,0,0,0,0}; bit sureflag=0; bit changeflag=0; bit changeflag1=0; void SEG_Latch(void) { P2 |= 0xe0; _nop_(); P2 &= 0x1f; } void BIT_Latch(void) { P2 |= 0xc0; _nop_(); P2 &= 0x1f; } void display(uchar *point) { unsigned char i=0; for(i=0;i<8;i++) { DataPort=WeiMa[i]; BIT_Latch(); DataPort=DuanMa[*(point+i)]; SEG_Latch(); delay_50us(20); DataPort=0xff; SEG_Latch(); } } void main(void) { int i,j=0,n; 17 unsigned char keytemp; unsigned char temp[8]={14,14,14,14,14,14,14,14}; unsigned char mima[8]={1,2,3,4,5,6,7,8}; P2=0xa0; P0=0x00; P2&=0x1f; while(1) { keytemp = keyscan(); if(keytemp != 0xff) { if((keytemp < 10)) { if(changeflag1==0) temp[i]= keytemp; else { temp[i]=keytemp; mima[i]=keytemp; } i++; if(i>7) { i=0; if(changeflag1) { changeflag=0; changeflag1=0; } } } else if(keytemp == 11) { sureflag=1; for(j=0;j<8;j++) 18 { if(temp[j]!=mima[j]) { sureflag=0; break; } } if(sureflag) { if(changeflag==0) { temp[0]=0; temp[1]=10; temp[2]=11; temp[3]=12; for(j=4;j<8;j++) temp[j]=14; } else { temp[0]=13; for(j=1;j<8;j++) temp[j]=14; changeflag1=1; } } else { temp[0]=11; temp[1]=13; temp[2]=13; for(j=3;j<8;j++) temp[j]=14; } } 19 else if(keytemp==10) { for(j=0;j<8;j++) temp[j]=14; sureflag=0; i=0; } else if(keytemp==12) { changeflag=1; } else if(keytemp==13) { for(j=0;j<8;j++) temp[j]=mima[j]; } } display(temp); } } 20 因篇幅问题不能全部显示,请点此查看更多更全内容