基于51单片机编写的六位电子密码锁由LCD1602显示
基于51單片機(jī)編寫的六位電子密碼鎖由LCD1602顯示
全部?jī)?nèi)容由本人原創(chuàng)!
 從制定計(jì)劃到焊接調(diào)試完成耗時(shí)5天!
 此程序僅表示完成該項(xiàng)目其中的一個(gè)方法,對(duì)有興趣修改,完善的同學(xué)表示歡迎!
 *注:每個(gè)關(guān)鍵的地方都有注釋方便理解哈
原理圖如下:
 主程序main:
#include"reg52.h"
 #include"key.h"
 #include"lcd.h"
 #include “beep.h”
char InputPassword=0;
 char PassWordNum=9;
 char KeyNum=0; //字符0—9的ASCII碼是0x30-0x39 。//任何時(shí)候輸入的按鍵值
 char PassWordBackup[6]; //原密碼
 char PassWordBackup2[6]; //臨時(shí)輸入密碼
 //char Errortimes=3; //定義密碼輸入錯(cuò)誤次數(shù)
void Password()
 {
 char i;
 if(KeyChange==1)
 {
 KeyChange=0; //恢復(fù)按鍵判斷狀態(tài),讓密碼只變化一次
 PassWordBackup[PassWordNum-9]=KeyNum; //將當(dāng)前按鍵的值進(jìn)行備份
 KeyNum=KeyNum%10+0x30; //***此步很重要***將變量轉(zhuǎn)換成字符輸出,因?yàn)橐壕е荒茱@示字符
 //0x30-0x39是0-9的ASCLL碼字符
 LcdShowStr(PassWordNum,1,&KeyNum); //顯示相應(yīng)位
 for(i=PassWordNum+1;i<16;i++) //作用是將剩余位清零不顯示,避免亂碼 “清屏”
 {
 LcdShowStr(i,1," ");
 }
}
void Determine_password() //判斷密碼函數(shù)
 {
 if(KeyChange1)
 {
 KeyChange=0;
 LcdAreaClear(0,0,16); //清屏函數(shù),設(shè)置起始位和清屏長(zhǎng)度
 LcdAreaClear(0,1,16);
 LcdShowStr(0,0,“Press 1 OK”);
 LcdShowStr(0,1,“Press 2 Cancel”);
 if(KeyNum1)
 {
 InputPassword=2; //跳轉(zhuǎn)進(jìn)入密碼設(shè)置成功界面
 KeyChange=1;
 }
 else if(KeyNum==2)
 {
 LcdShowStr(0,0,“Please Set Init”);
 LcdShowStr(0,1,"Password: ");
 InputPassword=0;
 }
 }
 }
void Password_Set_successfully() //密碼設(shè)置成功顯示跳轉(zhuǎn)界面
 {
 static long i=0;
 if(KeyChange1)
 {
 KeyChange=0;
 LcdAreaClear(0,0,16); //清屏函數(shù),設(shè)置起始位和清屏長(zhǎng)度
 LcdAreaClear(0,1,16);
 LcdShowStr(0,0,“Password”);
 LcdShowStr(0,1,“Set Successfully”);
 }
 i++;
 if(i%5000) //顯示一段時(shí)間后準(zhǔn)備返回密碼輸入界面
 {
 LcdAreaClear(0,0,16); //清屏函數(shù),設(shè)置起始位和清屏長(zhǎng)度
 LcdAreaClear(0,1,16);
 LcdShowStr(7,1,“return 3s”);
 }
 if(i%10000) //顯示一段時(shí)間后準(zhǔn)備返回密碼輸入界面
 {
 LcdAreaClear(0,0,16); //清屏函數(shù),設(shè)置起始位和清屏長(zhǎng)度
 LcdAreaClear(0,1,16);
 LcdShowStr(7,1,“return 2s”);
 }
 if(i%15000) //顯示一段時(shí)間后準(zhǔn)備返回密碼輸入界面
 {
 LcdAreaClear(0,0,16); //清屏函數(shù),設(shè)置起始位和清屏長(zhǎng)度
 LcdAreaClear(0,1,16);
 LcdShowStr(7,1,“return 1s”); 
 }
 if(i%2000==0)
 {
 i=0;
 InputPassword=5; //倒計(jì)時(shí)結(jié)束,進(jìn)入密碼輸入界面
 LcdAreaClear(0,0,16); //清屏函數(shù),設(shè)置起始位和清屏長(zhǎng)度
 LcdAreaClear(0,1,16);
 LcdShowStr(0,0,“Please Input”);
 LcdShowStr(0,1,"Password: ");
 }
 }
void Password2() //正式輸入密碼函數(shù)
 {
 static char Errortimes=3; //盡量設(shè)計(jì)為局部變量,否則程序易跑飛
 char i;
 char n; //定義一個(gè)錯(cuò)誤次數(shù)的備份變量
 if(KeyChange)
 {
 KeyChange=0;
 PassWordBackup2[PassWordNum-9]=KeyNum; //將當(dāng)前按鍵的值進(jìn)行備份
 KeyNum=KeyNum%10+0x30;
 LcdShowStr(PassWordNum,1,&KeyNum);
 for(i=PassWordNum+1;i<16;i++) //作用是將剩余位清零不顯示,避免亂碼 “清屏”
 {
 LcdShowStr(i,1," “);
 }
 PassWordNum++;
 if(PassWordNum>15) //密碼輸入完成,進(jìn)行對(duì)比
 {
 PassWordNum=9;
 for(i=0;i<6;i++)
 {
 if(PassWordBackup2[i]==PassWordBackup[i])InputPassword=6;//如果循環(huán)對(duì)比后每次都相等則進(jìn)入正確界面
 else
 {
 LcdAreaClear(0,0,16); //清屏函數(shù),設(shè)置起始位和清屏長(zhǎng)度
 LcdAreaClear(0,1,16);
 LcdShowStr(0,0,” Waring !");
 LcdShowStr(0,1,"The last ");
}
void Change_password() //密碼對(duì)比成功進(jìn)入改密選項(xiàng)界面
 {
 if(KeyChange)
 {
 KeyChange=0;
 LcdAreaClear(0,0,16); //清屏函數(shù),設(shè)置起始位和清屏長(zhǎng)度
 LcdAreaClear(0,1,16);
 LcdShowStr(0,0,“1 ChangePassword”);
 LcdShowStr(0,1,“2 Quit”);
 }
 if(KeyNum1) //回到初始設(shè)置密碼狀態(tài)
 {
 InputPassword=0;
 LcdAreaClear(0,0,16); //清屏函數(shù),設(shè)置起始位和清屏長(zhǎng)度
 LcdAreaClear(0,1,16);
 LcdShowStr(0,0,“Please Set Init”);
 LcdShowStr(0,1,“Password:”);
 }
 if(KeyNum2) //退出選項(xiàng),并且為下次輸入密碼做準(zhǔn)備
 {
 InputPassword=5;
 LcdAreaClear(0,0,16); //清屏函數(shù),設(shè)置起始位和清屏長(zhǎng)度
 LcdAreaClear(0,1,16);
 LcdShowStr(0,0,“Please Input”);
 LcdShowStr(0,1,"Password: ");
 }
 }
void Waring()
 {
 static unsigned int i=0;
 i++;
 if(i%2==0)Beep=!Beep; //針對(duì)無源蜂鳴器調(diào)頻
}
void Locked()
 {
 if(KeyChange)
 {
 KeyChange=0;
 LcdAreaClear(0,0,16); //清屏函數(shù),設(shè)置起始位和清屏長(zhǎng)度
 LcdAreaClear(0,1,16);
 LcdShowStr(0,1,“Has been locked!”);
 }
}
void main()
 {
 char j;
 InitLcd1602();
 LcdShowStr(0,0,“Please Set Init”);
 LcdShowStr(0,1,“Password:”);
 Beep=1;
 while(1)
 {
 if(j%10==0)Beep=!Beep;
 switch(InputPassword)
 {
 case 0 :KeyNum=kscan();Password();break; //跳轉(zhuǎn)初始密碼輸入
 case 1 :KeyNum=kscan();Determine_password();break; //判斷界面
 case 2 :Password_Set_successfully();break; //密碼設(shè)置成功界面
}
LCD1602程序部分:
#ifndef _lcd_h
 #include"reg52.h"
#define LCD1602_DB P0
sbit LCD1602_E=P2^7;
 sbit LCD1602_RW=P2^5;
 sbit LCD1602_RS=P2^6;
/* 等待液晶準(zhǔn)備好 */
 void LcdWaitReady()
 {
 unsigned char sta;
}
 /* 向LCD1602液晶寫入一字節(jié)命令,cmd-待寫入命令值 /
 void LcdWriteCmd(unsigned char cmd)
 {
 LcdWaitReady();
 LCD1602_RS = 0;
 LCD1602_RW = 0;
 LCD1602_DB = cmd;
 LCD1602_E = 1;
 LCD1602_E = 0;
 }
 / 向LCD1602液晶寫入一字節(jié)數(shù)據(jù),dat-待寫入數(shù)據(jù)值 /
 void LcdWriteDat(unsigned char dat)
 {
 LcdWaitReady();
 LCD1602_RS = 1;
 LCD1602_RW = 0;
 LCD1602_DB = dat;
 LCD1602_E = 1;
 LCD1602_E = 0;
 }
 / 設(shè)置顯示RAM起始地址,亦即光標(biāo)位置,(x,y)-對(duì)應(yīng)屏幕上的字符坐標(biāo) */
 void LcdSetCursor(unsigned char x, unsigned char y)
 {
 unsigned char addr;
}
 /* 在液晶上顯示字符串,(x,y)-對(duì)應(yīng)屏幕上的起始坐標(biāo),str-字符串指針 */
 void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
 {
 LcdSetCursor(x, y); //設(shè)置起始地址
 while (*str != ‘\0’) //連續(xù)寫入字符串?dāng)?shù)據(jù),直到檢測(cè)到結(jié)束符
 {
 LcdWriteDat(*str++);
 }
 }
/* 區(qū)域清除,清除從(x,y)坐標(biāo)起始的len個(gè)字符位 /
 void LcdAreaClear(unsigned char x, unsigned char y, unsigned char len)
 {
 LcdSetCursor(x, y); //設(shè)置起始地址
 while (len–) //連續(xù)寫入空格
 {
 LcdWriteDat(’ ');
 }
 }
 / 初始化1602液晶 /
 void InitLcd1602()
 {
 LcdWriteCmd(0x38); //162顯示,5*7點(diǎn)陣,8位數(shù)據(jù)接口
 LcdWriteCmd(0x0C); //顯示器開,光標(biāo)關(guān)閉
 LcdWriteCmd(0x06); //文字不動(dòng),地址自動(dòng)+1
 LcdWriteCmd(0x01); //清屏
 }
#endif
按鍵部分:
//網(wǎng)站http://proteus.5d6d.com
 #ifndef _key_h
 #define _key_h
 #include"reg52.h"
bit KeyChange=0;
char ksta[4][4]={ //所有按鍵初始值
 {1,1,1,1},
 {1,1,1,1},
 {1,1,1,1},
 {1,1,1,1},
 };
char kbackup[4][4]={ //所有按鍵備份值
 {1,1,1,1},
 {1,1,1,1},
 {1,1,1,1},
 {1,1,1,1},
 };
char code truetable[]={ //真值表
 0xC0,0xF9,0xA4,0xB0,
 0x99,0x92,0x82,0xF8,
 0x80,0x90,0x88,0x83,
 0xC6,0xA1,0x86,0x8E
 };
void delay(unsigned int i) //延時(shí)函數(shù)
 {
 while(i–);
 }
char kscan()
 {
 char cnt=0; //定義變量
 char j,k; //定義行列掃描變量
 P1=0xFF; //按鍵端口賦初值
 for(j=0;j<4;j++) //行掃描
 {
 P1&=~(0x01<<j); //第四位循環(huán)拉低電平
 for(k=0;k<4;k++) //列掃描
 {
 ksta[j][k]=P1&(0x10<<k); //循環(huán)將高四位IO口電平送入數(shù)組
 if(ksta[j][k]!=kbackup[j][k]) //判斷按鍵初值和備份值是否發(fā)生變化
 {
 delay(100); //延時(shí)消抖
 if(ksta[j][k]==0) //二次確定該按鍵按下
 {
 cnt=j*4+k; //改變變量
 KeyChange=1; //使主函數(shù)內(nèi)的按鍵值判斷發(fā)生變化讓密碼輸入時(shí)只執(zhí)行一次
 }
 kbackup[j][k]=ksta[j][k]; //備份按鍵狀態(tài),使程序只執(zhí)行一次
}
#endif
蜂鳴器部分:
#ifndef _beep_H
 #define _beep_H
#include"reg52.h"
sbit Beep=P3^7;
#endif
了解整體結(jié)構(gòu)不難的哈,并且有很強(qiáng)的拓展性。
總結(jié)
以上是生活随笔為你收集整理的基于51单片机编写的六位电子密码锁由LCD1602显示的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: asp.net 使用Master模板页需
 - 下一篇: poj1308