微机系统与应用课程设计报告课程设计题目成绩矩阵式键盘数字密码锁设计评语:教师:年月日班级:031013学号:03101305姓名:林佳福实验地点:E楼Ⅱ区312实验时间:2013.3.12-3.17矩阵式键盘数字密码锁设计一.实验目的1.掌握微机系统总线与各芯片管脚连接方法,提高接口扩展硬件电路的连接能力。2.初步掌握键盘扫描,密码修改和计时报警程序的编写方法。3.掌握通过矩阵式键盘扫描实现密码锁功能的设计思路和实现方法。二.实验内容矩阵式键盘数字密码锁设计,根据设定好的密码,采用4x4矩阵键盘实现密码的输入功能。当密码输入正确之后,锁就打开(绿灯亮),10秒之后,锁自动关闭(红灯亮);如果连续输入三次密码不正确,就锁定按键5秒钟,同时发出报警(黄灯闪),5秒后,解除按键锁定,恢复密码输入。数字密码锁操作键盘参考上面设定,也可以自行设计键盘。用户初始密码为“123456”,系统加电运行后,密码锁初始状态为常闭(红灯亮),用户可以选择开锁或修改密码:如果选择开锁就按“Open”键,系统提示输入密码,输入用户密码+“#”键后,如果密码正确,就打开锁(绿灯亮),系统等待10秒,然后重新关闭密码锁,若密码错,提示重新输入,连续三次错误,提示警告词同时报警(黄灯闪),锁定键盘5秒,然后重新进入初始状态;如果选择修改密码就按”ModifySecret”键,系统提示输入旧密码,输入旧密码+“#”键后,如果正确,系统提示输入新密码,输入新密码+“#”后,新密码起效,重新进入初始状态;如果旧密码错,不能修改密码,密码锁直接进入初始状态。三.实验基本任务1)具有开锁、修改用户密码等基本的密码锁功能。2)对于超过3次密码密码错误,锁定键盘5秒,系统报警。5秒后解除锁定。4)通过LCD字符液晶和LED指示灯(红,绿,黄)实时显示相关信息。5)用户密码为6位数字,显示采用“*”号表示。6)码锁键盘设计合理,功能完善,方便用户使用。本次实验还做了附加的任务(1)增加了管理员(Admin)功能,如果用户忘记密码可向管理员求助。管理员密码为8位数字(系统内预先已设定),管理员按“Admin”键后,系统提示输入管理员密码,输入管理员密码+“#”键后,如果正确,系统自动恢复用户初始密码为“123456”;如果错误,程序停止运行,系统退出。2)增加了输入清除功能(*),在输入密码过程中,如果中途按下“*”键,则清除前面的输入,开始重新输入密码。四.实验设计方案实验用到8255作为并行接口设备,用以ISA总线与外设的连接,本次用的是8255的A口作为输出口,C口的高4位与B口是输入,C口低4位是输出口,所以控制住设置为ox8a,8253作为时钟器,作为控制提示灯的时间闪烁,8255的A口接键盘的rom,B口接col,地址线都连接在总线下面的芯片上接口,其他的读写控制线都接入ISA总线上。如下图的接线设置五.实验器材8086CPU,可编程并行接口8255,可编程定时器8253,LCD显示屏,LED灯,4x4矩阵键盘。六.实验原理图ISA控制信号和地址总线(JS4)向PC机送信号接口地址JS8A0A1CS及接口地址8253时钟源(JS32)TRL交通灯A0A1CS及接口地址LCDB口低三位A0A1CS及接口地址C口低四位8255键盘KEYA口低四位七.程序代码#includeStdAfx.h#includePCI9052DLL.h#includestdio.h#includemath.h#includestring.h#includestdlib.h#includeiostream.h#includewindows.hunsignedcharvalue[4][4]={{'1','2','3','M'},{'4','5','6','O'},{'7','8','9','A'},{'0','#','*','S'}};//键盘标示unsignedcharlittle[4][4]={{'a','b','c','\0'},{'d','e','f','\0'},{'g','h','i','\0'},{'j','\0','\0','S'}};//shift键的字母表示charMimachar[6]={'1','2','3','4','5','6'};charGuanlikey[8]={'1','2','3','4','5','6','7','8'};intMimasum=0;intGuanlisum=0;charWodemima[6];charGuanlichar[8];boolModify=false;boolNewmima=false;intErrorcount=0;boolEqual(chara[],charb[])//比较字符串是否相等{inti;for(i=0;i6;i++){if(Mimachar[i]!=Wodemima[i])returnfalse;}returntrue;}boolisnum(chartmp)//判断是否为数字{returntmp='9'&&tmp='0';}boolisoper(chartmp)//判断是否为操作符{returntmp=='#'||tmp=='*'||tmp=='S'||tmp=='A'||tmp=='O'||tmp=='M'?true:false;}boolischar(chartmp)//判断是否为小写字母{returntmp='a'&&tmp='j';}voidinit8255()//初始化8255{OpenDevice();OutByte(0xde03,0x82);}voidend8255()//结束8255{CloseDevice();}voidInitLCD()//初始化LCD{unsignedchardata[4]={0x01,0x06,0x0f,0x38};unsignedcharch[6]=Open!;inti;for(i=0;i4;i++){OutByte(0xde08,data[i]);//????!!!!Sleep(100);}for(i=0;i6;i++){OutByte(0xde09,ch[i]);//在LCD上显示Open!Sleep(50);}Sleep(1000);}voidinit8253()//初始化8253{OpenDevice();}unsignedcharkbscan()//键盘扫描{introw_va[4]={0x0e,0x0d,0x0b,0x07};//选中每一行时的A口值unsignedchardata;unsignedchardata_tmp;Sleep(200);//第一次消除抖动--每次键盘扫描的时间间隔至少为200毫秒for(inti=0;i4;i++,i%=4){inttmp=row_va[i];OutByte(0xde00,tmp);//循环扫描第一到四行InByte(0xde01,&data);if(data==NULL)//扫描不到的情况排除掉{}elseif((data&0x0f)!=0x0f)//检测这一行是否有按键被按下{Sleep(10);//第二次消除抖动--如果10ms之后还是相同的按键就执行下面的。InByte(0xde01,&data_tmp);data_tmp=data_tmp&0x0f;if(data_tmp!=data)continue;//否则不执行下面的while(data_tmp==data)//第三次消除抖动--判断按键是否弹起。弹起则结束循环{InByte(0xde01,&data);data=data&0x0f;Sleep(10);if(data==0x0f){Sleep(100);InByte(0xde01,&data);data=data&0x0f;}}switch(data_tmp){case0x0e:returnvalue[i][0];case0x0d:returnvalue[i][1];case0x0b:returnvalue[i][2];case0x07:returnvalue[i][3];}}}returnNULL;}voidClear()//清空屏幕{OutByte(0xde08,0x01);}voiddisplayOnLcd()//在LCD上显示*号.{unsignedcharstmp[2]=*;for(inti=0;i1;i++)OutByte(0xde09,stmp[i]);}intmain(intargc,char*argv[])//主函数{init8255();//初始化8255init8253();InitLCD();//初始化LCDSleep(100);unsignedchartemp;Start_Position://------起始位置----起始条件OutByte(0xde02,0xFE);//红灯亮temp='\0';//指令符号printf(pleaseinputOpen!);while(1){intj=0;temp=kbscan();//获取在键盘中得到的数字printf(thekey:%c\n,temp);if(temp=='O'){Mimasum=0;Clear();//清空屏幕while(1){temp=kbscan();j++;printf(第%d次键盘扫描:%c\n,j,temp);if(isnum(temp)){if(Mimasum6){Wodemima[Mimasum]=temp;Mimasum++;displayOnLcd();//上屏幕LCD一个*号}}elseif(isoper(temp)){if(temp=='#')//密码匹配{if(Mimasum==6){if(Newmima==true)//修改密码标志为true且原密码正确--修改密码{inti;for(i=0;i6;i++)Mimachar[i]=Wodemima[i];Newmima=false;printf(新密码为:);for(i=0;i6;i++){printf(%c,Mimachar[i]);}printf(\n);}elseif(Equal(Mimachar,Wodemima)){if(Modify==true)//Modify为true--修改密码{Newmima=true;//把修改密码标志赋值为trueModify=false;Mimasum=0;Clear();//清空屏幕printf(输入新密码:\n);//提示:输入新密码}else{printf(密码正确!\n);OutByte(0xde02,0x7f);//绿灯亮Sleep(10000);//绿灯亮10SOutByte(0xde02,0xFE);//红灯亮&&绿灯灭Mimasum=0;Errorcount=0;gotoStart_Position;//回到最前面}}else{Errorcount++;printf(密码错误次数%d次!!\n,Errorcount);if(Errorcount=3)//提示重新输入的显示{OutByte(0xde02,0xFD);//黄灯亮Sleep(1000);OutByte(0xde02,0xFF);//黄灯灭Sleep(1000);OutByte(0xde02,0xFD);//黄灯亮Sleep(1000);OutByte(0xde02,0xFF);//黄灯灭Sleep(1000);OutByte(0xde02,0xFD);//黄灯亮Sleep(1000);OutByte(0xde02,0xFE);//红灯亮&&绿灯灭Mimasum=0;//初始Errorcount=0;Clear();//清空屏幕gotoStart_Position;}else{printf(请重新输入密码:\n);}}}}elseif(temp=='*'){Mimasum=0;//重新输入密码Clear();//清空屏幕}elseif(temp=='A'){Guanlisum=0;C