微机原理课题设计实验报告之矩阵式键盘数字密码锁

微机系统与应用课程设计报告

班    级:     031013             

学    号:     03101305          

姓    名:     林佳福             

实验地点:     E楼Ⅱ区312     

实验时间:     2013.3.12-3.17

  


               矩阵式键盘数字密码锁设计

一 .   实验目的

1.        掌握微机系统总线与各芯片管脚连接方法,提高接口扩展硬件电路的连接能力。

2.      初步掌握键盘扫描,密码修改和计时报警程序的编写方法。

3.      掌握通过矩阵式键盘扫描实现密码锁功能的设计思路和实现方法。

二.  实验内容

矩阵式键盘数字密码锁设计,根据设定好的密码,采用4x4矩阵键盘实现密码的输入功能。当密码输入正确之后,锁就打开(绿灯亮),10秒之后,锁自动关闭(红灯亮);如果连续输入三次密码不正确,就锁定按键5秒钟,同时发出报警(黄灯闪),5秒后,解除按键锁定,恢复密码输入。

数字密码锁操作键盘参考上面设定,也可以自行设计键盘。用户初始密码为“123456”,系统加电运行后,密码锁初始状态为常闭(红灯亮),用户可以选择开锁或修改密码:

如果选择开锁就按“Open”键,系统提示输入密码,输入用户密码+“#”键后,如果密码正确,就打开锁(绿灯亮),系统等待10秒,然后重新关闭密码锁,若密码错,提示重新输入,连续三次错误,提示警告词同时报警(黄灯闪),锁定键盘5秒,然后重新进入初始状态;

如果选择修改密码就按”Modify Secret”键,系统提示输入旧密码,输入旧密码+“#”键后,如果正确,系统提示输入新密码,输入新密码+“#”后,新密码起效,重新进入初始状态;如果旧密码错,不能修改密码,密码锁直接进入初始状态。

三. 实验基本任务

 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矩阵键盘。

六.   实验原理图

七.   程序代码

 #include "StdAfx.h"

#include "PCI9052DLL.h"

#include "stdio.h"

#include "math.h"

#include "string.h"

#include "stdlib.h"

#include "iostream.h"

#include "windows.h"

unsigned char value[4][4]={{'1','2','3','M'},{'4','5','6','O'},{'7','8','9','A'},{'0','#','*','S'}};//键盘标示

unsigned char little[4][4]={{'a','b','c','\0'},{'d','e','f','\0'},{'g','h','i','\0'},{'j','\0','\0','S'}};//shift键的字母表示

char Mimachar[6]={'1','2','3','4','5','6'};

char Guanlikey[8]={'1','2','3','4','5','6','7','8'};

int Mimasum=0;

int Guanlisum=0;

char Wodemima[6];

char Guanlichar[8];

bool Modify=false;

bool Newmima=false;

int Errorcount=0;

bool Equal(char a[],char b[])//比较字符串是否相等

{

int i;

for(i=0;i<6;i++)

{

    if(Mimachar[i]!=Wodemima[i]) return false;

}

return true;

}

bool isnum(char tmp)//判断是否为数字

{

return tmp<='9'&&tmp>='0';

}

bool isoper(char tmp)//判断是否为操作符

{

return tmp=='#'||tmp=='*'||tmp=='S'||tmp=='A'||tmp=='O'||tmp=='M' ? true : false;

}

bool ischar(char tmp)//判断是否为小写字母

{

return tmp>='a'&&tmp<='j';

}

void init8255()//初始化8255

{

OpenDevice();

OutByte(0xde03, 0x82);

}

void end8255()//结束8255

{

CloseDevice();

}

void InitLCD()//初始化LCD

{

unsigned char data[4]={0x01,0x06,0x0f,0x38};

unsigned char ch[6]="Open!";

int  i;

    for (i=0;i<4;i++)

{

    OutByte(0xde08, data[i]);//????!!!!

    Sleep(100);

}

for (i=0;i<6;i++)

{  

    OutByte(0xde09, ch[i]);//在LCD上显示Open!

    Sleep(50 );

}

Sleep(1000);

}

void init8253()//初始化8253

{

OpenDevice();

}

unsigned char kbscan()//键盘扫描

{

int row_va[4]={0x0e,0x0d,0x0b,0x07};  //选中每一行时的A口值

unsigned char data;

unsigned char data_tmp;

Sleep(200);          //第一次消除抖动--每次键盘扫描的时间间隔至少为200毫秒

for(int  i=0;i<4;i++,i%=4)

{

    int tmp=row_va[i];

    OutByte(0xde00, tmp);             //循环扫描第一到四行

    InByte(0xde01,&data);

    if(data==NULL)                    //扫描不到的情况排除掉

    {

    }

    else if((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)

       {

           case 0x0e: return value[i][0];

           case 0x0d: return value[i][1];

           case 0x0b: return value[i][2];

           case 0x07: return value[i][3];

       }

    }

}

return NULL;

}

void Clear()//清空屏幕

{

OutByte(0xde08,0x01);

}

void displayOnLcd()//在LCD上显示*号.

{

unsigned char stmp[2]="*";        

for (int i=0;i<1;i++) OutByte(0xde09, stmp[i]); 

}

int main(int argc, char* argv[])              //主函数

{

    init8255();                               //初始化8255

init8253();

InitLCD();                             //初始化LCD

Sleep(100);

unsigned char temp;

Start_Position://-->-->-->  起始位置----起始条件

OutByte(0xde02,0xFE);           //红灯亮

temp = '\0';                     //指令符号

printf("please input Open!");

while(1)

{   int j=0;

    temp = kbscan();           //获取在键盘中得到的数字

    printf("the key:%c\n",temp);

    if(temp=='O')

    {

       Mimasum=0;

       Clear();               //清空屏幕

       while(1)

       {

           temp = kbscan();

          

               j++;

              printf("第%d次键盘扫描:%c\n",j,temp);

           if(isnum(temp))

           {

              if(Mimasum<6)

              {

                  Wodemima[Mimasum]=temp;

                  Mimasum++;

                  displayOnLcd();      //上屏幕LCD一个*号

              }

           }

           else if(isoper(temp))

           {

              if(temp=='#')            //密码匹配

              {

                  if(Mimasum==6)

                  {

                   if(Newmima==true) //修改密码标志为true且原密码正确--修改密码

                     {

                         int i;

                         for(i=0;i<6;i++) Mimachar[i]=Wodemima[i];

                         Newmima=false;

                         printf("新密码为:");

                         for(i=0;i<6;i++)

                         {

                            printf("%c",Mimachar[i]);

                         }

                         printf("\n");

                     }

                     else if(Equal(Mimachar,Wodemima))

                     {

                         if(Modify==true)        //Modify为true--修改密码

                         {

                            Newmima=true;     //把修改密码标志赋值为true

                            Modify=false;

                            Mimasum=0;

                            Clear();               //清空屏幕

                            printf("输入新密码:\n"); //提示:输入新密码

                         }

                         else

                         {

                            printf("密码正确!\n");

                           

                            OutByte(0xde02,0x7f);  //绿灯亮

                            Sleep(10000);           //绿灯亮10S

                            OutByte(0xde02,0xFE);  //红灯亮&&绿灯灭

                            Mimasum=0;

                            Errorcount=0;

                            goto Start_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();               //清空屏幕

                            goto Start_Position;

                         }

                         else

                         {

                            printf("请重新输入密码:\n");

                         }

                     }

                  }

              }

              else if(temp=='*')

              {

                  Mimasum=0;   //重新输入密码

                  Clear();     //清空屏幕

              }

              else if(temp=='A')

              {

                  Guanlisum=0;

                  Clear();     //清空屏幕

                  printf("请输入管理员密码:\n");

                  while(1)     //输入管理员密码

                  {

                         temp = kbscan();

                         printf("one次键盘扫描:%c\n",temp);

                         if(isnum(temp))

                         {

                            if(Guanlisum<8)

                            {

                                Guanlichar[Guanlisum]=temp;

                                Guanlisum++;

                                displayOnLcd();     //上屏幕LCD*号

                            }

                         }

                         else if(isoper(temp))

                         {

                            if(temp=='#'&& Guanlisum==8)

                            {

                                int i;

                                for(i=0;i<8;i++)

                                {

                                   if(Guanlikey[i]!=Guanlichar[i]) return 0;

                                }

                                Mimachar[0]='1';

                                Mimachar[1]='2';

                                Mimachar[2]='3';

                                Mimachar[3]='4';

                                Mimachar[4]='5';

                                Mimachar[5]='6';

                                printf("密码初始化完成.\n");

                               

                                Guanlisum=0;

                                Mimasum=0;

                                Errorcount=0;

                                Modify=false;

                                Newmima=false;

                                goto Start_Position; //回到开始

                            }

                            else if(temp=='*')

                            {

                                Guanlisum=0;

                                Clear();             //清空屏幕

                            }

                         }

                  }

              }

              else if(temp=='M')

              {

                  Modify=true;

                  Mimasum=0;

                  Clear();

                  printf("请输入原密码:\n");

              }

           }

       }

    }

}

cout<<endl;

end8255();

 // CloseDevice();

return 0;

}

八.   实验解图

九.  实验心得

    通过这次微机课题设计实验,使我学到了不少实用的知识,更重要的是做实验的过程,思考问题的方法,这与其他的实验师通用的,真正使我受益匪浅。

    在做实验之前,我没有完全将课本上的理论知识掌握透彻,但在老师的讲解中,以及实践中对这些知识的理解有了很大一步的掌握。对汇编语言的编程和微机系统的芯片有了比较深刻的认识。

   实验中遇到的主要问题是我们组以前是在5楼座的实验,5楼的实验板和3楼的不同,刚开始没有理解好地址导致编程出现了问题,后来询问老师得到了解决。

相关推荐