简易51单片机密码锁

电子类 专栏收录该内容
10 篇文章 0 订阅

简易51单片机密码锁

直接上码;
Code ①

main.c

#include<reg52.h> //一般不需改动,头文件包含特殊功能寄存器的定义;
#include<stdio.h>
#include"1602.h"
#include"delay.h"
#include"keyboard.h"
unsigned char code password[]={1,2,3,4,5,6,7,8};//可更改此密码做多组测试;
//定义密码,实际上密码需要存在E²prom中,可以通过程序更改。请自行添加;
main(){
unsigned char num,i,j;                  
unsigned char passwordtemp[16];           //最大输入16个;
unsigned char inputtimes;                 //密码输入错误次数;
unsigned char passwordlength,PLen;        //输入密码长度,实际密码长度;
bit Flag;
PLen=sizeof(password)/sizeof(password[0]);//用于计算出实际密码长度;
LCD_Init();                               //初始化液晶屏;
DelayMs(10);                              //延时用于稳定,可以去掉;
LCD_Clear();                              //清屏;
LCD_Write_String(0,0,"  Welcome! ");      //写入第一行信息,主循环中不再更改此信息,所以在while之前写入;
LCD_Write_String(0,1,"Input password!");   //写入第二行信息,提示输入密码
while (1) {                                //主循环;
num=KeyPro();                              //扫描键盘;
if(num!=0xff) {                            //如果扫描是按键有效值则进行处理;
    if(i==0)         //输入是第一个字符的时候需要把改行清空,方便观看密码;
    LCD_Write_String(0,1,"                "); //清除该行;
    if(i<16){
    passwordtemp=num;
    LCD_Write_Char(i,1,'*');                //输入的密码用"*"代替;
     }
    i++;                                    //输入数值累加;
    if((15==num)|| (i==16))                 //输入按键值15或者密码输入到;最大值16,表示输入结束,需要进行比对;
      {
      passwordlength=i-1;                   //计算输入密码长度;
      i=0;                                  //计数器复位
      if(passwordlength==PLen){             //长度相等则比较,否则直接输出错误;
      Flag=1;                            //先把比较位置1;
      for(j=0;j<PLen;j++)                //循环比较8个数值,如果有一个不等 则最终Flag值为0;
      Flag=Flag&&(passwordtemp[j]==password[j]);//比较输入值和已有密码;
         }
      if(Flag)                          //如果比较全部相同,标志位置1;
       {
        LCD_Write_String(0,1,"                ");//清除该行;
        LCD_Write_String(0,1,"Right Open!>>>>");//密码正确显示的信息;
        inputtimes=0;                     //输入正确则次数清零,重新计数;
        Flag=0;                           //清除正确标志;
        }
      else
        {
        LCD_Write_String(0,1,"                "); //清除该行;
        LCD_Write_String(0,1,"Wrong! Retry!"); //密码错误,提示重新输入;
        inputtimes++;                    //连续输入错误,则次数累加;
        if(inputtimes==3){ 
        LCD_Write_String(0,1,"                ");//清除该行
        LCD_Write_String(0,1,"Wrong 3 times!");  //密码错误,提示重新输入;
        while(1);       //停止该位置,重启电源后才能输入,实际实用中则需要等到一定时间后才能再次输入。
       }}}}}}

Code ②

keyboard.c

#include<reg52.h>   //一般不需改动,头文件包含特殊功能寄存器的定义
#include"keyboard.h"
#include"delay.h"

#define KeyPort P3

/*------------------按键扫描函数,返回扫描键值------------------*/
unsigned char KeyScan(void){  //键盘扫描函数,使用行列反转扫描法
 unsigned char cord_h,cord_l;//行列值中间变量
 KeyPort=0x0f;            //行线输出全为0
 cord_h=KeyPort&0x0f;     //读入列线值
 if(cord_h!=0x0f)    //先检测有无按键按下
 {
  DelayMs(10);        //去抖
  if((KeyPort&0x0f)!=0x0f){
    cord_h=KeyPort&0x0f;  //读入列线值
    KeyPort=cord_h|0xf0;  //输出当前列线值
    cord_l=KeyPort&0xf0;  //读入行线值
    while((KeyPort&0xf0)!=0xf0);//等待松开并输出
    return(cord_h+cord_l);//键盘最后组合码值
   }
  }return(0xff);     //返回该值
}

/*--------------按键值处理函数,返回扫键值---------------*/
unsigned char KeyPro(void)
{
 switch(KeyScan())
 {
  case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值;
  case 0x7d:return 1;break;//1
  case 0x7b:return 2;break;//2
  case 0x77:return 3;break;//3
  case 0xbe:return 4;break;//4
  case 0xbd:return 5;break;//5
  case 0xbb:return 6;break;//6
  case 0xb7:return 7;break;//7
  case 0xde:return 8;break;//8
  case 0xdd:return 9;break;//9
  case 0xdb:return 10;break;//a
  case 0xd7:return 11;break;//b
  case 0xee:return 12;break;//c
  case 0xed:return 13;break;//d
  case 0xeb:return 14;break;//e
  case 0xe7:return 15;break;//f
  default:return 0xff;break;//break
 }}

Code ③

delay.c

#include "delay.h"
void DelayUs2x(unsigned char t){   
 while(--t);
}
void DelayMs(unsigned char t){   
 while(t--){
     //大致延时1mS
     DelayUs2x(245);
	 DelayUs2x(245);
 }}

Code ④

1602.c

#include "1602.h"
#include "delay.h"

#define CHECK_BUSY

sbit RS = P2^4;   //定义端口 
sbit RW = P2^5;
sbit EN = P2^6;

#define RS_CLR RS=0 
#define RS_SET RS=1

#define RW_CLR RW=0 
#define RW_SET RW=1 

#define EN_CLR EN=0
#define EN_SET EN=1

#define DataPort P0

/*------------判忙函数------------------*/
 bit LCD_Check_Busy(void){ 
#ifdef CHECK_BUSY
 DataPort= 0xFF; 
 RS_CLR; 
 RW_SET; 
 EN_CLR; 
 _nop_(); 
 EN_SET;
 return (bit)(DataPort & 0x80);
#else
 return 0;
#endif
 }
 
/*------------写入命令函数------------------*/
 void LCD_Write_Com(unsigned char com) 
 {  
 while(LCD_Check_Busy()); //忙则等待
 RS_CLR; 
 RW_CLR; 
 EN_SET; 
 DataPort= com; 
 _nop_(); 
 EN_CLR;
 }
 
/*------------写入数据函数-----------------*/
 void LCD_Write_Data(unsigned char Data) 
 { 
 while(LCD_Check_Busy()); //忙则等待
 RS_SET; 
 RW_CLR; 
 EN_SET; 
 DataPort= Data; 
 _nop_();
 EN_CLR;
 }
 
/*-----------------清屏函数---------------------*/
 void LCD_Clear(void){ 
 LCD_Write_Com(0x01); 
 DelayMs(5);
 }
 
/*---------------------写入字符串函数-------------------------*/
 void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s){          
 while (*s){     
 LCD_Write_Char(x,y,*s);     
 s ++;  x++;   
 	}
 }
 
/*-------------------写入字符函数----------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data){     
 if (y == 0){     
 	LCD_Write_Com(0x80 + x);     
 	}    
 else 
 	{     
 	LCD_Write_Com(0xC0 + x);     
 	}        
 LCD_Write_Data( Data);  
 }
 
/*-------------------初始化函数------------------------*/
 void LCD_Init(void){
   LCD_Write_Com(0x38);    //显示模式设
   DelayMs(5); 
   LCD_Write_Com(0x38); 
   DelayMs(5); 
   LCD_Write_Com(0x38); 
   DelayMs(5); 
   LCD_Write_Com(0x38);  
   LCD_Write_Com(0x08);    //显示关闭
   LCD_Write_Com(0x01);    //显示清屏
   LCD_Write_Com(0x06);    //显示光标移动设置
   DelayMs(5); 
   LCD_Write_Com(0x0C);    //显示开及光标设置
   }

Code ⑤

1602.h

#include<reg52.h> //一般不需改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>

#ifndef __1602_H__
#define __1602_H__

 bit LCD_Check_Busy(void) ;
 void LCD_Write_Com(unsigned char com) ;
 void LCD_Write_Data(unsigned char Data) ;
 void LCD_Clear(void) ;
 void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) ;
 void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) ;
 void LCD_Init(void) ;  
#endif

Code ⑥

delay.h

#ifndef __DELAY_H__
#define __DELAY_H__

void DelayUs2x(unsigned char t);
void DelayMs(unsigned char t);
#endif

Code ⑦

keyboard.h

#ifndef __KEYBOARD_H__
#define __KEYBOARD_H__

unsigned char KeyScan(void);  //键盘扫描函数,使用行列反转扫描法
unsigned char KeyPro(void);
#endif

相应的代码打包会另行上传,点击下面链接
密码锁代码打包

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:技术黑板 设计师:CSDN官方博客 返回首页

打赏作者

镐猛酸钾

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值