电子密码锁总结报告 本文简介:基于单片机的电子密码锁设计TheDesignofElectronicPassword-lockwithSCM:刘根鑫、王浩、许锦玮:电气与信息工程学院:信息工程:10-4:04101800、04101806、04101810:2012-11-13学生姓名所在院系所学专业所在班级学号时间指导教师第一章
电子密码锁总结报告 本文内容:
基于单片机的电子密码锁设计
The
Design
of
Electronic
Password-lock
with
SCM
:
刘根鑫、王浩、许锦玮
:
电气与信息工程学院
:
信息工程
:
10-4
:04101800、04101806、04101810
:
2012-11-13
学生姓名
所在院系
所学专业
所在班级
学
号
时
间
指导教师
第一章
课题任务
基于51单片机的简易电子密码锁
一、
实现功能:
1、设置6位密码,密码通过键盘输入,若密码正确,则将锁打开。
2、密码可以由用户自己修改设定(只支持6位密码),锁打开后才能修改密码。修改密码之前必须再次输入密码,在输入新密码时候需要二次确认,以防止误操作。
3、报警、锁定键盘功能。密码输入错误显示器会出现错误提示,若密码输入错误次数超过3次,蜂鸣器报警并且锁定键盘。
4、AT24C02保存密码,支持复位保存,掉电保存功能。
第2章
系统总体方案设计
方案一:采用数字电路控制。其原理方框图如图2-1所示。
图2-1
数字密码锁电路方案
采用数字密码锁电路的好处就是设计简单。用以74LS112双JK触发器构成的数字逻辑电路作为密码锁的核心控制,共设了9个用户输入键,其中只有4个是有效的密码按键,其它的都是干扰按键,若按下干扰键,键盘输入电路自动清零,原先输入的密码无效,需要重新输入;如果用户输入密码的时间超过40秒(一般情况下,用户不会超过40秒,若用户觉得不便,还可以修改)电路将报警80秒,若电路连续报警三次,电路将锁定键盘5分钟,防止他人的非法操作。
电路由两大部分组成:密码锁电路和备用电源(UPS),其中设置UPS电源是为了防止因为停电造成的密码锁电路失效,使用户免遭麻烦。
密码锁电路包含:键盘输入、密码修改、密码检测、开锁电路、执行电路、报警电路、键盘输入次数锁定电路。
方案二:采用一种是用以AT89S51为核心的单片机控制方案。利用单片机灵活的编程设计和丰富的IO端口,及其控制的准确性,不但能实现基本的密码锁功能,还能添加调电存储、声光提示甚至添加遥控控制功能。其原理如图2-2所示。
显示模块
键盘输入模块
AT89C51
报警电路
复位电路
开锁电路
密码存储模块
图2-2单片机控制方案
通过比较以上两种方案,单片机方案有较大的活动空间,不但能实现所要求的功能而且能在很大的程度上扩展功能,而且还可以方便的对系统进行升级,所以我们采用后一种方案。
本方案采用一种是用以89c51为核心的单片机控制方案。利用单片机灵活的编程设计和丰富的I/O端口,及其控制的准确性,实现基本的密码锁功能。
作用说明:
开锁:
插上电源后,输入正确密码,然后按【#】(确认)键,此时锁会打开,可以看到显示open,密码锁打开。
1、
退出并关锁:按下【*】(取消)键,此时锁关闭,所有输入清除。
2、
修改密码:在开锁状态下,再次输入正确的密码并按下【#】(确认)键,此时听到两声提示,输入新的六位密码并按【D】(重设)键,再重复输入一次新密码并按【D】,会听到报警并锁定键盘:当输入密码错误后,报警并锁定键盘3秒,如3秒内又有按键,3秒再启动。
当重置新密码时,新密码会保存于AT24C02存储器里。
第3章
硬件电路设计
3.1
键盘电路设计
使用矩阵键盘,所以本设计就采用行列式键盘,同时也能减少键盘与单片机接口时所占用的I/O线的数目,在按键比较多的时候,通常采用这样方法。其原理如图3.1
。
图3.1
矩阵键盘
每一条水平(行线)与垂直线(列线)的交叉处不相通,而是通过一个按键来连通,利用这种行列式矩阵结构只需要N条行线和M条列线,即可组成具有N×M个按键的键盘。
在这种行列式矩阵键盘非键盘编码的单片机系统中,键盘处理程序首先执行等待按键并确认有无按键按下的程序段。
当确认有按键按下后,下一步就要识别哪一个按键按下。对键的识别通常有两种方法:一种是常用的逐行扫描查询法;另一种是速度较快的线反转法。
对照图3.1所示的4×4键盘,说明线反转个工作原理。
首先辨别键盘中有无键按下,有单片机I/O口向键盘送全扫描字,然后读入行线状态来判断。方法是:向行线输出全扫描字00H,把全部列线置为低电平,然后将列线的电平状态读入累加器A中。如果有按键按下,总会有一根行线电平被拉至低电平从而使行线不全为1。
判断键盘中哪一个键被按下使通过将列线逐列置低电平后,检查行输入状态来实现的。方法是:依次给列线送低电平,然后查所有行线状态,如果全为1,则所按下的键不在此列;如果不全为1,则所按下的键必在此列,而且是在与零电平行线相交的交点上的那个键。
具体的功能设计如下
按键说明
采用4X4键盘输入,键盘对应名称如下:
1
2
3
A
4
5
6
B
7
8
9
C
0
#
D
其中,【0—9】为数字键,用于输入相应的密码,
【*】号键为取消当前操作
【#】号键为确认
其它键无功能及定义
3.2开关电路
电磁继电器的工作原理和特性
电磁式继电器一般由铁芯、线圈、衔铁、触点簧片等组成的。只要在线圈两端加上一定的电压,线圈中就会流过一定的电流,从而产生电磁效应,衔铁就会在电磁力吸引的作用下克服返回弹簧的拉力吸向铁芯,从而带动衔铁的动触点与静触点(常开触点)吸合。当线圈断电后,电磁的吸力也随之消失,衔铁就会在弹簧的反作用力返回原来的位置,使动触点与原来的静触点(常闭触点)吸合。这样吸合、释放,从而达到了在电路中的导通、切断的目的。对于继电器的“常开、常闭”触点,可以这样来区分:继电器线圈未通电时处于断开状态的静触点,称为“常开触点”;处于接通状态的静触点称为“常闭触点”。
当输入正确密码时,二极管导通发光。输入错误密码时,二极管不能导通。
3.3
报警电路
当输入错误密码时,电路中蜂鸣器开始报警。当输入密码错误三次时,蜂鸣器持续报警,并锁定键盘
3.4
密码存储模块
密码经过修改后,存储在AT24C02中,从而实现掉电保护
3.5复位电路
复位操作完成单片机片内电路的初始化,使单片机从一种确定的状态开始运行。
当8XX51单片机的复位引脚RST出现5ms以上的高电平时单片机就完成了复位操作。如果RST持续为高电平,单片机就处于循环复位状态,而无法执行程序。因此要求复位后能脱离复位状态。
根据应用的要求,复位操作通常有两种基本形式:上电复位、开关复位。上电复位要求接通电源后,自动实现复位操作。
第四章
程序设计
主程序设计流程图如图5-1所示。
开始
初始化
修改
开锁
密码正确
输入旧密码
N
原密码相同
Y
开锁
出错报警
N
N
Y
设新密码
返回
图5-1主程序流程图
键功能程序流程图如图5-2所示。
键功能程序
键值=0~9?
键值=开锁?
键值=确认?
键值=设置?
返回
密码输入程序
确认程序
设置程序
开锁程序
Y
N
Y
N
Y
N
Y
N
图5-2
键功能流程图
开锁程序流程图如图5-3所示。
LCD初始化
按开锁键
输入密码
确认程序
开锁
N
输入密码正确?
报警程序
开锁成功
返回
Y
图5-3
开锁流程图
第五章
系统调试
先在proteus中仿真出来结果,能够达到预期目标。通过自己的焊接,使得实物的密码锁也成功满足要求。当输入正确密码时,液晶显示屏上显示open,且绿灯亮。当输入密码错误时,屏上显示error,且发出滴滴滴的报警声。
第六章
总
结
作为一名电气专业的大三学生,我觉得做利用单片机做电子综合设计设计是十分有意义的,而且是十分必要的。在已度过的大学时间里,我们大多数接触的是专业基础课。我们在课堂上掌握的仅仅是专业课的理论知识,如何去锻炼我们的实践能力?如何把我们所学的专业基础课理论知识运用到实践中去呢?我想做类似的电子综合设计就为我们提供了良好的实践平台。
在做本次课程设计的过程中,我感触最深的当属查阅大量的设计资料了。为了让自己的设计更加完善,查阅这方面的设计资料是十分必要的,同时也是必不可少的。我们是在做电子综合设计,但我们不是艺术家,他们可以抛开实际尽情在幻想的世界里翱翔,而我们一切都要有据可依,有理可寻,不切实际的构想永远只能是构想,永远无法升级为设计。
其次,在这次课程设计中,我们运用到了以前所学的专业课知识,如:protel99制图、汇编语言、c语言等。虽然过去从未独立应用过它们,但在学习的过程中带着问题去学我发现效率很高,这是我做这次课程设计的又一收获。
最后,要做好一个电子综合设计,就必须做到:在设计程序之前,对所用单片机的内部结构有一个系统的了解,知道该单片机内有哪些资源;要有一个清晰的思路和一个完整的的软件流程图;在设计程序时,不能妄想一次就将整个程序设计好,反复修改、不断改进是程序设计的必经之路;要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现功能,而应该让人一看就能明白你的思路,这样也为资料的保存和交流提供了方便;在设计过程中遇到问题是很正常的,但我们应该将每次遇到的问题记录下来,并分析清楚,以免下次再碰到同样的问题。
在焊接完成了调试的过程中,也出现了一些问题,一开始,液晶屏不亮,则根据情况找出原因是没有调节滑动变阻器改变灰度。当屏幕有显示之后,发现密码总是存不进去,则进一步找出是AT24c02连接有问题,经过反复的检查电路,发现其正极没有连接,经过连接之后,终于实现了理想的功能。在整个电子设计的过程当中,发现问题,并解决问题,才是我们急需锻炼的能力。
另外,这次课程设计让我感到了团队合作的重要性。在团队中,我们互帮互助,对整个课程设计来说,这是至关重要的,缺少每一个人都会对我们的设计产生影响。
几周的课程设计结束了,但是从中学到的知识会让我受益终身。发现、提出、分析、解决问题和实践能力的提高都会受益于我在以后的学习、工作和生活中。同时意识到自己还有很多不足的地方,以后还得继续改进,争取做到越来越好。
第七章
参考文献
1
康华光
.
电子技术基础(模拟部分).
第五版
.
高等教育出版社
2
赵晓安.
MCS-51单片机原理及应用.
天津:天津大学出版社,2001.3
3
李广第.
单片机基础.
第1版.北京:北京航空航天大学出版社,1999
4
袁小平.
电子技术综合设计教程
.机械工业出版社
5
谭浩强
.C程序设计.
清华大学出版社
附录:A
程序如下:
#include
#include
#define
LCM_Data
P0
#define
uchar
unsigned
char
#define
uint
unsigned
int
#define
w
6//定义密码位数
sbit
lcd1602_rs=P2^5;
sbit
lcd1602_rw=P2^6;
sbit
lcd1602_en=P2^7;
sbit
Scl=P3^4;//24C02串行时钟
sbit
Sda=P3^5;//24C02串行数据
sbit
ALAM
=
P2^1;//报警
sbit
KEY
=
P2^0;//开锁
sbit
open_led=P2^2;//开锁指示灯
bit
operation=0;//操作标志位
bit
pass=0;//密码正确标志
bit
ReInputEn=0;//重置输入充许标志
bit
s3_keydown=0;//3秒按键标志位
bit
key_disable=0;//锁定键盘标志
unsigned
char
countt0,second;//t0中断计数器,秒计数器
void
Delay5Ms(void);
unsigned
char
code
a[]={0xFE,0xFD,0xFB,0xF7};
//控盘扫描控制表
unsigned
char
code
start_line[]=
{“password:
“};
unsigned
char
code
name[]
=
{“===Coded
Lock===”};//显示名称
unsigned
char
code
Correct[]
=
{“correct
“};
//输入正确
unsigned
char
code
Error[]
=
{“error
“};
//输入错误
unsigned
char
code
codepass[]=
{“pass
“};
unsigned
char
code
LockOpen[]=
{“open
“};//OPEN
unsigned
char
code
SetNew[]
=
{“SetNewWordEnable”};
unsigned
char
code
Input[]
=
{“input:
“};//INPUT
unsigned
char
code
ResetOK[]
=
{“ResetPasswordOK
“};
unsigned
char
code
initword[]=
{“Init
password.”};
unsigned
char
code
Er_try[]=
{“error,try
again!”};
unsigned
char
code
again[]=
{“input
again
“};
unsigned
char
InputData[6];//输入密码暂存区
unsigned
char
CurrentPassword[6]={1,3,1,4,2,0};
//当前密码值
unsigned
char
TempPassword[6];
unsigned
char
N=0;//密码输入位数记数
unsigned
char
ErrorCont;//错误次数计数
unsigned
char
CorrectCont;//正确输入计数
unsigned
char
ReInputCont;
//重新输入计数
unsigned
char
code
initpassword[6]={0,0,0,0,0,0};
//=====================5ms延时==============================
void
Delay5Ms(void)
{
unsigned
int
TempCyc
=
5552;
while(TempCyc--);
}
//===================400ms延时==============================
void
Delay400Ms(void)
{
unsigned
char
TempCycA
=
5;
unsigned
int
TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
}
}
//=============================================================================================
//================================24C02========================================================
//=============================================================================================
void
mDelay(uint
t)
//延时
{
uchar
I;
while(t--)
{
for(i=0;i0;x--)
for(y=110;y>0;y--);
}
//--------------------------写指令---------------------------
write_1602com(uchar
com)//****液晶写入指令函数****
{
lcd1602_rs=0;//数据/指令选择置为指令
lcd1602_rw=0;
//读写选择置为写
P0=com;//送入数据
delay(1);
lcd1602_en=1;//拉高使能端,为制造有效的下降沿做准备
delay(1);
lcd1602_en=0;//en由高变低,产生下降沿,液晶执行命令
}
//-------------------------写数据-----------------------------
write_1602dat(uchar
dat)//***液晶写入数据函数****
{
lcd1602_rs=1;//数据/指令选择置为数据
lcd1602_rw=0;
//读写选择置为写
P0=dat;//送入数据
delay(1);
lcd1602_en=1;
//en置高电平,为制造下降沿做准备
delay(1);
lcd1602_en=0;
//en由高变低,产生下降沿,液晶执行命令
}
//-------------------------初始化-------------------------
void
lcd_init(void)
{
write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据
write_1602com(0x0c);//开显示不显示光标
write_1602com(0x06);//整屏不移动,光标自动右移
write_1602com(0x01);//清显示
}
//========================================================================================
//=========================================================================================
//==============将按键值编码为数值=========================
unsigned
char
coding(unsigned
char
m)
{
unsigned
char
k;
switch(m)
{
case
(0x18):
k=1;break;
case
(0x28):
k=2;break;
case
(0x48):
k=3;break;
case
(0x88):
k=’A’;break;
case
(0x14):
k=4;break;
case
(0x24):
k=5;break;
case
(0x44):
k=6;break;
case
(0x84):
k=’B’;break;
case
(0x12):
k=7;break;
case
(0x22):
k=8;break;
case
(0x42):
k=9;break;
case
(0x82):
k=’C’;break;
case
(0x11):
k=’*’;break;
case
(0x21):
k=0;break;
case
(0x41):
k=’#’;break;
case
(0x81):
k=’D’;break;
}
return(k);
}
//=====================按键检测并返回按键值===============================
unsigned
char
keynum(void)
{
unsigned
char
row,col,I;
P1=0xf0;
if((P1
Delay5Ms();
if((P1
//确定行线
i=0;
P1=a[i];
//精确定位
while(i<4)
{
if((P1
//确定列线
break;
//已定位后提前退出
}
else
{
i++;
P1=a[i];
}
}
}
else
{
return
0;
}
while((P1
return
(row|col);
//行线与列线组合后返回
}
else
return
0;
//无键按下时返回0
}
//=======================一声提示音,表示有效输入========================
void
OneAlam(void)
{
ALAM=0;
Delay5Ms();
ALAM=1;
}
//========================二声提示音,表示操作成功========================
void
TwoAlam(void)
{
ALAM=0;
Delay5Ms();
ALAM=1;
Delay5Ms();
ALAM=0;
Delay5Ms();
ALAM=1;
}
//========================三声提示音,表示错误========================
void
ThreeAlam(void)
{
ALAM=0;
Delay5Ms();
ALAM=1;
Delay5Ms();
ALAM=0;
Delay5Ms();
ALAM=1;
Delay5Ms();
ALAM=0;
Delay5Ms();
ALAM=1;
}
//=====================显示输入的N个数字,用H代替以便隐藏============================
void
DisplayOne(void)
{
//DisplayOneChar(9+N,1,’*’);
write_1602com(yi+5+N);
write_1602dat(‘*’);
}
//=======================显示提示输入=========================
void
DisplayChar(void)
{
unsigned
char
I;
if(pass==1)
{
//DisplayListChar(0,1,LockOpen);
write_1602com(er);
for(i=0;i<16;i++)
{
write_1602dat(LockOpen[i]);
}
}
else
{
if(N==0)
{
//DisplayListChar(0,1,Error);
write_1602com(er);
for(i=0;i<16;i++)
{
write_1602dat(Error[i]);
}
}
else
{
//DisplayListChar(0,1,start_line);
write_1602com(er);
for(i=0;i<16;i++)
{
write_1602dat(start_line[i]);
}
}
}
}
void
DisplayInput(void)
{
unsigned
char
I;
if(CorrectCont==1)
{
//DisplayListChar(0,0,Input);
write_1602com(er);
for(i=0;i<16;i++)
{
write_1602dat(Input[i]);
}
}
}
//========================重置密码==================================================
//==================================================================================
void
ResetPassword(void)
{
unsigned
char
I;
unsigned
char
j;
if(pass==0)
{
pass=0;
DisplayChar();
ThreeAlam();
}
else
{
if(ReInputEn==1)
{
if(N==6)
{
ReInputCont++;
if(ReInputCont==2)
{
for(i=0;i<6;)
{
if(TempPassword[i]==InputData[i])//将两次输入的新密码作对比
i++;
else
{
//DisplayListChar(0,1,Error);
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(Error[j]);
}
ThreeAlam();//错误提示
pass=0;
ReInputEn=0;//关闭重置功能,
ReInputCont=0;
DisplayChar();
break;
}
}
if(i==6)
{
//DisplayListChar(0,1,ResetOK);
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(ResetOK[j]);
}
TwoAlam();//操作成功提示
WrToROM(TempPassword,0,6);//将新密码写入24C02存储
ReInputEn=0;
}
ReInputCont=0;
CorrectCont=0;
}
else
{
OneAlam();
//DisplayListChar(0,1,again);
//显示再次输入一次
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(again[j]);
}
for(i=0;i<6;i++)
{
TempPassword[i]=InputData[i];//将第一次输入的数据暂存起来
}
}
N=0;//输入数据位数计数器清零
}
}
}
}
//=======================输入密码错误超过三过,报警并锁死键盘======================
void
Alam_KeyUnable(void)
{
P1=0x00;
{
ALAM=~ALAM;
Delay5Ms();
}
}
//=======================取消所有操作============================================
void
Cancel(void)
{
unsigned
char
I;
unsigned
char
j;
//DisplayListChar(0,1,start_line);
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(start_line[j]);
}
TwoAlam();//提示音
for(i=0;i<6;i++)
{
InputData[i]=0;
}
KEY=1;//关闭锁
ALAM=1;//报警关
operation=0;//操作标志位清零
pass=0;//密码正确标志清零
ReInputEn=0;//重置输入充许标志清零
ErrorCont=0;//密码错误输入次数清零
CorrectCont=0;//密码正确输入次数清零
ReInputCont=0;//重置密码输入次数清零
open_led=1;
s3_keydown=0;
key_disable=0;
N=0;//输入位数计数器清零
}
//==========================确认键,并通过相应标志位执行相应功能===============================
void
Ensure(void)
{
unsigned
char
I,j;
RdFromROM(CurrentPassword,0,6);
//从24C02里读出存储密码
if(N==6)
{
if(ReInputEn==0)//重置密码功能未开启
{
for(i=0;i<6;)
{
if(CurrentPassword[i]==InputData[i])
{
i++;
}
else
{
ErrorCont++;
if(ErrorCont==3)//错误输入计数达三次时,报警并锁定键盘
{
write_1602com(er);
for(i=0;i<16;i++)
{
write_1602dat(Error[i]);
}
do
Alam_KeyUnable();
while(1);
}
else
{
TR0=1;//开启定时
key_disable=1;//锁定键盘
pass=0;
break;
}
}
}
if(i==6)
{
CorrectCont++;
if(CorrectCont==1)//正确输入计数,当只有一次正确输入时,开锁,
{
//DisplayListChar(0,1,LockOpen);
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(LockOpen[j]);
}
TwoAlam();//操作成功提示音
KEY=0;//开锁
pass=1;//置正确标志位
TR0=1;//开启定时
open_led=0;//开锁指示灯亮
for(j=0;j<6;j++)//将输入清除
{
InputData[i]=0;
}
}
else//当两次正确输入时,开启重置密码功能
{
//DisplayListChar(0,1,SetNew);
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(SetNew[j]);
}
TwoAlam();
//操作成功提示
ReInputEn=1;//允许重置密码输入
CorrectCont=0;//正确计数器清零
}
}
else//=========================当第一次使用或忘记密码时可以用131420对其密码初始化============
{
if((InputData[0]==1)
//强制将初始密码写入24C02存储
//DisplayListChar(0,1,initword);//显示初始化密码
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(initword[j]);
}
TwoAlam();
Delay400Ms();
TwoAlam();
N=0;
}
else
{
//DisplayListChar(0,1,Error);
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(Error[j]);
}
ThreeAlam();//错误提示音
pass=0;
}
}
}
else//当已经开启重置密码功能时,而按下开锁键,
{
//DisplayListChar(0,1,Er_try);
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(Er_try[j]);
}
ThreeAlam();
}
}
else
{
//DisplayListChar(0,1,Error);
write_1602com(er);
for(j=0;j<16;j++)
{
write_1602dat(Error[j]);
}
ThreeAlam();//错误提示音
pass=0;
}
N=0;//将输入数据计数器清零,为下一次输入作准备
operation=1;
}
//==============================主函数===============================
void
main(void)
{
unsigned
char
KEY,NUM;
unsigned
char
I,j;
P1=0xFF;
TMOD=0x11;
TL0=0xB0;
TH0=0x3C;
EA=1;
ET0=1;
TR0=0;
Delay400Ms();
//启动等待,等LCM讲入工作状态
lcd_init();
//LCD初始化
write_1602com(yi);//日历显示固定符号从第一行第0个位置之后开始显示
for(i=0;i<16;i++)
{
write_1602dat(name[i]);//向液晶屏写日历显示的固定符号部分
}
write_1602com(er);//时间显示固定符号写入位置,从第2个位置后开始显示
for(i=0;i<16;i++)
{
write_1602dat(start_line[i]);//写显示时间固定符号,两个冒号
}
write_1602com(er+9);//设置光标位置
write_1602com(0x0f);//设置光标为闪烁
Delay5Ms();
//延时片刻(可不要)
N=0;//初始化数据输入位数
while(1)
{
if(key_disable==1)
Alam_KeyUnable();
else
ALAM=1;//关报警
KEY=keynum();
if(KEY!=0)
{
if(key_disable==1)
{
second=0;
}
else
{
NUM=coding(KEY);
{
switch(NUM)
{
case
(‘A’):
;
break;
case
(‘B’):;
break;
case
(‘C’):
;
break;
case
(‘D’):
ResetPassword();break;
//重新设置密码
case
(‘*’):
Cancel();break;
//取消当前输入
case
(‘#’):
Ensure();
break;
//确认键,
default:
{
//DisplayListChar(0,1,Input);
write_1602com(er);
for(i=0;i<16;i++)
{