51单片机和LCD1602实现简单的密码锁

简介: 51单片机和LCD1602实现简单的密码锁
#include <reg52.h>   
#include "delay.h"
#include "1602.h"    
#define uc unsigned char
#define port P1
sbit  kaisuo=P2^4;
// in:输入的密码和确认密码  k:已输入密码的个数  set:设置的密码,count:密码的个数 set1:用于设置密码
uc in[16],k=0,set[16]={0,1,2},count=3,set1[16],count1=0;  
uc i=0,j=0,t=0,hang=0,lie=0;                            // i:按的是哪个键  j:接收键值  t:比较结果 
unsigned int tt,ii,jj;       // 是否大于5秒
void delay(uc c);
void delay1(uc c1);
void setting(void);
void again(void); 
uc keyscan(void);
uc input(void);
uc compare(uc *m,uc x,uc *n,uc y); 
void delay1(uc c1)
{
  uc a1,b1;
    for(;c1>0;c1--)
  { 
    for(a1=38;a1>0;a1--)
      for(b1=130;b1>0;b1--);
    port = 0xf0;
    if(port != 0xf0)  
       return;
  }
}
void delay(uc c)
{ 
  uc a,b;
    for(;c>0;c--)
    for(a=38;a>0;a--)
      for(b=130;b>0;b--);
}
uc keyscan(void)
{         
  delay(1);
  port=0xf0;
  switch(port)
  { 
    case 0xe0:lie=0;break;
    case 0xd0:lie=1;break;
    case 0xb0:lie=2;break;
    case 0x70:lie=3;break;        
  }
  port=0x0f;
  switch(port)
  { 
    case 0x0e:hang=0;break;
    case 0x0d:hang=1;break;
    case 0x0b:hang=2;break;
    case 0x07:hang=3;break;       
  }
  i=4*hang+lie;        
  return i;  
}
uc input(void)
{
  LCD_Write_String(0,0,"INPUT:");
  while(1)
  {
    j=keyscan();    // 获取键值
    port=0xf0;
    while(port != 0xf0) // 消抖
    {
      delay(1);
      port=0xf0;
    }
    delay(1);
    if(j==15)     // OK键
    {
      LCD_Clear();
      return k;
    }
    if(j==14)     // 设置密码
    {
      count1=0;  j=0;
      for(ii=0;ii<k;ii++) in[ii]=0;
      for(ii=0;ii<count1;ii++) set1[ii]=0;      
      setting();  return k;
    }
    LCD_Write_Com(0xc0+k);     // 按键后显示
    LCD_Write_Data(j+'0');
    in[k++]=j;      // 存储
    while(1)      // 如果大于5秒,退出
    {
      tt++;
      delay1(1);
      if(tt>=500)
      {
        LCD_Clear();
        LCD_Write_String(3,0,"TIME OUT!");
        tt=0;
        k=0;
        delay1(100);
        LCD_Clear();
        return 0;
      }
      port=0xf0;
      if(port != 0xf0)
      {
        tt=0;
        break;
      }
    }
  }  
}
uc compare(uc *m,uc x,uc *n,uc y)
{
  if(x != y) // 如果长度不相等,一定是错的
  {
    LCD_Write_String(4,0,"FALSE!");
    delay1(100);
    LCD_Clear();
    k=0;j=0;
    for(ii=0;ii<x;ii++) in[ii]=0;
    return 0;
  }
  else    // 如果长度相等但是某个字符不等,也是错的
  {
    for(jj=0;jj<y;jj++)
    {
      if(m[jj] != n[jj])
      {
        LCD_Write_String(4,0,"FALSE!");  
        delay1(100);
        LCD_Clear();
        k=0;j=0;
        for(ii=0;ii<x;ii++) in[ii]=0;
        return 0;
      }
    }     
    return 1;// 所有的错误类型都判断过就剩下正确的了
  }
}
void setting(void)
{   
  LCD_Write_String(1,0,"INPUT OLD:");
  delay1(200);
  k=0;
  k=input();
    if(compare(in,k,set,count)==1)
  {
    LCD_Write_String(4,0,"TRUE!");
    delay1(100);
    LCD_Clear();
    k=0;j=0;
    for(ii=0;ii<k;ii++) in[ii]=0;
  }
  else
    return;
  LCD_Write_String(1,0,"INPUT:");
  delay1(500);
  port=0xf0;    
  if(port!=0x0f)
  { 
    while(1)
    {
      j=keyscan();
      port=0xf0;
      while(port != 0xf0) // 消抖
      {
        delay(1);
        port=0xf0;
      }
      delay(1);
      if(j<=9&&count1<=16) // 输入合法,存储
        set1[count1++]=j;
      if(j==15)   // 确认密码
      {
        LCD_Clear();
        LCD_Write_String(0,0,"INPUT AGAIN:");
        delay1(200);
        j=0; k=0;
        while(j!=15) // 直到按下确认键退出
        {
          again();
          while(1)      // 如果大于5秒,退出
          {
            tt++; delay1(1);
            if(tt>=500)
            {
              LCD_Clear();
              LCD_Write_String(3,0,"TIME OUT!");
              tt=0; k=0; delay1(100);
              LCD_Clear(); return;
            }
            port=0xf0;
            if(port != 0xf0)
            {
              tt=0; break;
            }
          }     
        }
        if(compare(in,k,set1,count1)==1)   //对比成功
        { 
          LCD_Clear();
          LCD_Write_String(0,0,"SUCCESS!");
          delay1(200);
          for(ii=0;ii<count1;ii++) set[ii]=set1[ii];
          count=count1;
        }
        else
        {
          LCD_Clear();
          LCD_Write_String(0,0,"UNSUCCESS!");
          delay1(200);
          for(ii=0;ii<count1;ii++) set1[ii]=0;
        }
        delay1(100); LCD_Clear();
        k=0;j=0;
        for(ii=0;ii<k;ii++) in[ii]=0;
        return;
      }
      if(j>=10&&j<=13)         // 输入非法,重新输入
      {
        LCD_Clear(); LCD_Write_String(0,0,"ERROR!");
        delay1(100); LCD_Clear();
        for(ii=0;ii<count1;ii++) set1[ii]=0;
        return;
      }
      LCD_Write_Com(0xc0+count1);    // 按键后显示
      LCD_Write_Data(j+'0');
      while(1)      // 如果大于5秒,退出
      {
        tt++;
        delay1(1);
        if(tt>=500)
        {
          LCD_Clear(); LCD_Write_String(3,0,"TIME OUT!");
          tt=0; k=0; count1=0; for(ii=0;ii<count1;ii++) set1[ii]=0;
          delay1(100); LCD_Clear();
          return;
        }
        port=0xf0;
        if(port != 0xf0)
        {
          tt=0;
          break;
        }
      }     
    }
  }
}
void again(void)
{
  LCD_Write_String(0,0,"INPUT AGAIN:");
  delay1(200);
  j=keyscan();
  port=0xf0;
  while(port != 0xf0) // 消抖
  {
    delay(1);
    port=0xf0;
  }
  delay(1);
  if(j==15) // 按下OK键跳出
  {
    LCD_Clear();    
    return;
  }
  in[k++]=j;// 输入到in数组内 
  LCD_Write_Com(0xc0+k);     // 按键后显示
  LCD_Write_Data(j+'0');
}
void main()
{   
  LCD_Init();           //初始化液晶
  DelayMs(20);          //延时有助于稳定
  LCD_Clear();          //清屏  P2=0;
  LCD_Write_String(0,0,"INPUT:");
  while(1)
  {  
    port=0xf0;
    if(port!=0xf0)
    { 
      k=0;
      k=input();
      if(k==0)
        continue;
        if(compare(in,k,set,count)==1)
      {
        LCD_Write_String(4,0,"TRUE!");
        delay1(100);
        LCD_Clear();
        k=0;j=0;
        for(ii=0;ii<k;ii++) in[ii]=0;
      }      
    }       
  }   
}   

以上程序还存在一定的漏洞,还请各位大佬批评指正

  • 接线:
  • LCD1602数据线接P0
  • 其他参照1602.h连接
  • 矩阵键盘接P1
相关文章
|
12天前
|
存储 数据安全/隐私保护
基于51单片机的6位密码锁设计
【10月更文挑战第11天】多功能电子密码锁系统由AT89C52单片机最小系统、4×4矩阵键盘、LCD1602显示、AT24C02存储模块以及报警系统等组成,具有设置、修改六位用户密码、超次报警、超次锁定、密码错误报警等功能。
69 23
|
14天前
|
存储 传感器 安全
基于51单片机的指纹锁设计
基于51单片机的指纹锁设计
10 0
|
6月前
|
存储 数据安全/隐私保护
基于51单片机的6位密码锁设计
该文档描述了一个基于AT89C52单片机的多功能电子密码锁系统设计,具备6位密码设置与修改功能,输入错误三次会锁定,并在LCD屏上以*号隐藏真实密码。系统包括矩阵键盘、LCD显示、AT24C02存储及报警系统,当密码错误时,会有蜂鸣器报警和LED灯闪烁。此外,还提供了密码重置(通过管理员密码131420)和输入错误提示。文中附有Proteus仿真及原理图,展示了开锁、重设密码和错误输入时的响应。
97 0
|
3月前
【51单片机】在LCD1602上显示时间:包含按键进行校准时间+闹钟功能:按键设置闹钟响铃时间,以及响铃的时间长度
【51单片机】在LCD1602上显示时间:包含按键进行校准时间+闹钟功能:按键设置闹钟响铃时间,以及响铃的时间长度
|
3月前
|
C语言
【51单片机】LCD1602显示字符串,时间、时间+按键校准、秒表计时的功能代码。
【51单片机】LCD1602显示字符串,时间、时间+按键校准、秒表计时的功能代码。
|
5月前
|
数据安全/隐私保护
单片机课程设计——基于C51电子密码锁(源代码)
单片机课程设计——基于C51电子密码锁(源代码)
|
6月前
|
内存技术
模块化编程+LCD1602调试工具——“51单片机”
模块化编程+LCD1602调试工具——“51单片机”
模块化编程+LCD1602调试工具——“51单片机”
|
6月前
|
传感器
51单片机矩阵键盘超详解!(内含LCD1602代码)
51单片机矩阵键盘超详解!(内含LCD1602代码)
79 0
|
6月前
|
数据安全/隐私保护
【51单片机】初学者必学的一个矩阵键盘基本项目——(矩阵键盘密码锁)(8)
【51单片机】初学者必学的一个矩阵键盘基本项目——(矩阵键盘密码锁)(8)
|
6月前
|
数据可视化 API
【51单片机】LCD1602(可视化液晶屏)调试工具的使用(6)
【51单片机】LCD1602(可视化液晶屏)调试工具的使用(6)