单片机实验8

要求:设密码锁的正确密码为8位数字01234567。16个矩阵键盘按键分别对应0-F,按下每一个按键在8位共阴数码管上从左到右依次显示刚才所按下的数字。当按下8个数字后,再按下任意一个按键实现将所按下的8个数字与正确密码对比,如若密码一致,数码管上显示oPEn,如若密码不正确,数码管上显示Err。密码正确或错误后再按下按键重新显示按下的数字。实验原理图如图1: 
图1 矩阵键盘按键原理图
<center>图1 矩阵键盘按键原理图</center>

代码如下:

#include <reg51.h>
#include <intrins.h>
sbit LATCH1=P2^2;
sbit LATCH2=P2^3;
unsigned char code DuanMa[]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char code WeiMa[]= {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsigned char KeyScan(void);
unsigned char KeyPro(void);
unsigned char TempData[8] = {0,0,0,0,0,0,0,0};
unsigned char password[8] = {0,1,2,3,4,5,6,7}; 
unsigned char password1[8] = {0,1,2,3,4,5,6,7};
void Display(void);
int k = 0;
int flag;
int j;
void delay() 
{   
    int y;
    for(y=300;y>0;y--);
}


void main()
{

    TMOD = 0x01;
    TR0 = 1;
    EA = 1;
    ET0 = 1;
    TH0 = (65536 - 1000) / 256;
    TL0 = (65536 - 1000) % 256;
    while (1)
    {
        flag = KeyPro();
        if(flag != 0xff)
        {
            if (k < 8)
            {
                password1[k] = flag;
                TempData[k++] = DuanMa[flag];
            }
            else if (k == 8)
             {
                int flg = 1;
                for  (j = 0; j < 8;j++)
                {
                    if (password1[j] != password[j])
                    {
                        flg = 0;
                    }
                }
                if (!flg)
                {
                    TempData[0] = 0x79;
                    TempData[1] = 0x50;
                    TempData[2] = 0x50;
                    TempData[3] = 0;
                    TempData[4] = 0;
                    TempData[5] = 0;
                    TempData[6] = 0;
                    TempData[7] = 0;
                }
                else
                {
                    TempData[0] = 0x5c;
                    TempData[1] = 0x73;
                    TempData[2] = 0x79;
                    TempData[3] = 0x54;
                    TempData[4] = 0;
                    TempData[5] = 0;
                    TempData[6] = 0;
                    TempData[7] = 0;
                }
                k++;
             }
            else 
            {
                k =0;
                for (j = 0; j < 8;j++)
                {
                     TempData[j] = 0;
                }   
            }
        }
    }

}
void inti0() interrupt 1
{
    TH0 = (65536 - 1000) / 256;
    TL0 = (65536 - 1000) % 256;
    Display();
}
unsigned char KeyScan(void) 
 //键盘扫描函数
{
 unsigned char temp1,temp2;
//行列值中间变量
 P1=0x0f;            //列线输出全为0,检测行线
 if(P1!=0x0f)    //先检测有无按键按下
 {delay ();        //延时去抖几ms
  if(P1!=0x0f)
    {
        temp1 = P1;
        P1 = 0xf0;
        temp2 = P1;
        while (P1 != 0xf0);
        return(temp1+temp2);
  //键盘最后组合特征值
    }
 }return(0xff);     //返回该值
}
unsigned char KeyPro(void)
{ switch(KeyScan())
{case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值
  case 0xbe:return 1;break;//1
  case 0xde:return 2;break;//2
  case 0xee:return 3;break;//3
  case 0x7d:return 4;break;//4
  case 0xbd:return 5;break;//5
  case 0xdd:return 6;break;//6
  case 0xed:return 7;break;//7
  case 0x7b:return 8;break;//8
  case 0xbb:return 9;break;//9
  case 0xdb:return 10;break;//a
  case 0xeb:return 11;break;//b
  case 0x77:return 12;break;//c
  case 0xb7:return 13;break;//d
  case 0xd7:return 14;break;//e
  case 0xe7:return 15;break;//f
  default:return 0xff;break;}
 }
void Display(void)
{     static unsigned char i=0;
      P0=0;   //清空数据,防止有交替重影
      LATCH1=1;     //LATCH1=P2.2,段锁存 
      LATCH1=0;
      P0 =WeiMa[i]; //取位码 
      LATCH1=1;     // LATCH2=P2.3位锁存
      LATCH1=0;
      P0=TempData[i]; //取显示数据对应的段码
      LATCH2=1;     //段锁存
      LATCH2=0;
      i++;
      if(i==8)
      i=0;
}

猜你喜欢

转载自blog.csdn.net/chao_shine/article/details/78877568