基于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