日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于51单片机编写的六位电子密码锁由LCD1602显示

發布時間:2023/12/20 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于51单片机编写的六位电子密码锁由LCD1602显示 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

基于51單片機編寫的六位電子密碼鎖由LCD1602顯示

全部內容由本人原創!
從制定計劃到焊接調試完成耗時5天!
此程序僅表示完成該項目其中的一個方法,對有興趣修改,完善的同學表示歡迎!
*注:每個關鍵的地方都有注釋方便理解哈

原理圖如下:


主程序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 。//任何時候輸入的按鍵值
char PassWordBackup[6]; //原密碼
char PassWordBackup2[6]; //臨時輸入密碼
//char Errortimes=3; //定義密碼輸入錯誤次數

void Password()
{
char i;
if(KeyChange==1)
{
KeyChange=0; //恢復按鍵判斷狀態,讓密碼只變化一次
PassWordBackup[PassWordNum-9]=KeyNum; //將當前按鍵的值進行備份
KeyNum=KeyNum%10+0x30; //***此步很重要***將變量轉換成字符輸出,因為液晶只能顯示字符
//0x30-0x39是0-9的ASCLL碼字符
LcdShowStr(PassWordNum,1,&KeyNum); //顯示相應位
for(i=PassWordNum+1;i<16;i++) //作用是將剩余位清零不顯示,避免亂碼 “清屏”
{
LcdShowStr(i,1," ");
}

PassWordNum++; //索引下一位顯示輸出if(PassWordNum>15){PassWordNum=9; //變量恢復初始值,方便下次輸入KeyChange=1; //為下次按鍵按下作準備,防止確認界面被頻繁刷新InputPassword=1; //如果輸入的密碼達到六位,跳轉是否確認密碼界面} }

}

void Determine_password() //判斷密碼函數
{
if(KeyChange1)
{
KeyChange=0;
LcdAreaClear(0,0,16); //清屏函數,設置起始位和清屏長度
LcdAreaClear(0,1,16);
LcdShowStr(0,0,“Press 1 OK”);
LcdShowStr(0,1,“Press 2 Cancel”);
if(KeyNum1)
{
InputPassword=2; //跳轉進入密碼設置成功界面
KeyChange=1;
}
else if(KeyNum==2)
{
LcdShowStr(0,0,“Please Set Init”);
LcdShowStr(0,1,"Password: ");
InputPassword=0;
}
}
}

void Password_Set_successfully() //密碼設置成功顯示跳轉界面
{
static long i=0;
if(KeyChange1)
{
KeyChange=0;
LcdAreaClear(0,0,16); //清屏函數,設置起始位和清屏長度
LcdAreaClear(0,1,16);
LcdShowStr(0,0,“Password”);
LcdShowStr(0,1,“Set Successfully”);
}
i++;
if(i%5000) //顯示一段時間后準備返回密碼輸入界面
{
LcdAreaClear(0,0,16); //清屏函數,設置起始位和清屏長度
LcdAreaClear(0,1,16);
LcdShowStr(7,1,“return 3s”);
}
if(i%10000) //顯示一段時間后準備返回密碼輸入界面
{
LcdAreaClear(0,0,16); //清屏函數,設置起始位和清屏長度
LcdAreaClear(0,1,16);
LcdShowStr(7,1,“return 2s”);
}
if(i%15000) //顯示一段時間后準備返回密碼輸入界面
{
LcdAreaClear(0,0,16); //清屏函數,設置起始位和清屏長度
LcdAreaClear(0,1,16);
LcdShowStr(7,1,“return 1s”);
}
if(i%2000==0)
{
i=0;
InputPassword=5; //倒計時結束,進入密碼輸入界面
LcdAreaClear(0,0,16); //清屏函數,設置起始位和清屏長度
LcdAreaClear(0,1,16);
LcdShowStr(0,0,“Please Input”);
LcdShowStr(0,1,"Password: ");
}
}

void Password2() //正式輸入密碼函數
{
static char Errortimes=3; //盡量設計為局部變量,否則程序易跑飛
char i;
char n; //定義一個錯誤次數的備份變量
if(KeyChange)
{
KeyChange=0;
PassWordBackup2[PassWordNum-9]=KeyNum; //將當前按鍵的值進行備份
KeyNum=KeyNum%10+0x30;
LcdShowStr(PassWordNum,1,&KeyNum);
for(i=PassWordNum+1;i<16;i++) //作用是將剩余位清零不顯示,避免亂碼 “清屏”
{
LcdShowStr(i,1," “);
}
PassWordNum++;
if(PassWordNum>15) //密碼輸入完成,進行對比
{
PassWordNum=9;
for(i=0;i<6;i++)
{
if(PassWordBackup2[i]==PassWordBackup[i])InputPassword=6;//如果循環對比后每次都相等則進入正確界面
else
{
LcdAreaClear(0,0,16); //清屏函數,設置起始位和清屏長度
LcdAreaClear(0,1,16);
LcdShowStr(0,0,” Waring !");
LcdShowStr(0,1,"The last ");

n=Errortimes; //將錯誤次數給變量不改變本身n=n%10+0x30; LcdShowStr(9,1,&n);LcdShowStr(11,1,"times");Errortimes--;if(Errortimes<0){InputPassword=8;KeyChange=1;break;}InputPassword=7;break ; //否則跳出當前循環; //進入警告界面}}KeyChange=1; //為下次界面只執行一次做準備} }

}

void Change_password() //密碼對比成功進入改密選項界面
{
if(KeyChange)
{
KeyChange=0;
LcdAreaClear(0,0,16); //清屏函數,設置起始位和清屏長度
LcdAreaClear(0,1,16);
LcdShowStr(0,0,“1 ChangePassword”);
LcdShowStr(0,1,“2 Quit”);
}
if(KeyNum1) //回到初始設置密碼狀態
{
InputPassword=0;
LcdAreaClear(0,0,16); //清屏函數,設置起始位和清屏長度
LcdAreaClear(0,1,16);
LcdShowStr(0,0,“Please Set Init”);
LcdShowStr(0,1,“Password:”);
}
if(KeyNum2) //退出選項,并且為下次輸入密碼做準備
{
InputPassword=5;
LcdAreaClear(0,0,16); //清屏函數,設置起始位和清屏長度
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; //針對無源蜂鳴器調頻

if(i>60000) {i=0;InputPassword=5;LcdAreaClear(0,0,16); //清屏函數,設置起始位和清屏長度LcdAreaClear(0,1,16);LcdShowStr(0,0,"Please Input");LcdShowStr(0,1,"Password: ");KeyChange=0; //防止輸入位錯誤 }

}

void Locked()
{
if(KeyChange)
{
KeyChange=0;
LcdAreaClear(0,0,16); //清屏函數,設置起始位和清屏長度
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; //跳轉初始密碼輸入
case 1 :KeyNum=kscan();Determine_password();break; //判斷界面
case 2 :Password_Set_successfully();break; //密碼設置成功界面

case 5 :KeyNum=kscan();Password2();break; //正式輸入密碼界面case 6 :KeyNum=kscan();Change_password();break;case 7 :Waring();break; //密碼錯誤警告界面case 8 :Locked();break; //已被鎖定界面default :break;} }

}

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;

/* 等待液晶準備好 */
void LcdWaitReady()
{
unsigned char sta;

LCD1602_DB = 0xFF; LCD1602_RS = 0; LCD1602_RW = 1; do {LCD1602_E = 1;sta = LCD1602_DB; //讀取狀態字LCD1602_E = 0; } while (sta & 0x80); //bit7等于1表示液晶正忙,重復檢測直到其等于0為止

}
/* 向LCD1602液晶寫入一字節命令,cmd-待寫入命令值 /
void LcdWriteCmd(unsigned char cmd)
{
LcdWaitReady();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;
LCD1602_E = 1;
LCD1602_E = 0;
}
/ 向LCD1602液晶寫入一字節數據,dat-待寫入數據值 /
void LcdWriteDat(unsigned char dat)
{
LcdWaitReady();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_E = 1;
LCD1602_E = 0;
}
/ 設置顯示RAM起始地址,亦即光標位置,(x,y)-對應屏幕上的字符坐標 */
void LcdSetCursor(unsigned char x, unsigned char y)
{
unsigned char addr;

if (y == 0) //由輸入的屏幕坐標計算顯示RAM的地址addr = 0x00 + x; //第一行字符地址從0x00起始 elseaddr = 0x40 + x; //第二行字符地址從0x40起始 LcdWriteCmd(addr | 0x80); //設置RAM地址

}
/* 在液晶上顯示字符串,(x,y)-對應屏幕上的起始坐標,str-字符串指針 */
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
{
LcdSetCursor(x, y); //設置起始地址
while (*str != ‘\0’) //連續寫入字符串數據,直到檢測到結束符
{
LcdWriteDat(*str++);
}
}

/* 區域清除,清除從(x,y)坐標起始的len個字符位 /
void LcdAreaClear(unsigned char x, unsigned char y, unsigned char len)
{
LcdSetCursor(x, y); //設置起始地址
while (len–) //連續寫入空格
{
LcdWriteDat(’ ');
}
}
/ 初始化1602液晶 /
void InitLcd1602()
{
LcdWriteCmd(0x38); //162顯示,5*7點陣,8位數據接口
LcdWriteCmd(0x0C); //顯示器開,光標關閉
LcdWriteCmd(0x06); //文字不動,地址自動+1
LcdWriteCmd(0x01); //清屏
}

#endif

按鍵部分:

//網站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) //延時函數
{
while(i–);
}

char kscan()
{
char cnt=0; //定義變量
char j,k; //定義行列掃描變量
P1=0xFF; //按鍵端口賦初值
for(j=0;j<4;j++) //行掃描
{
P1&=~(0x01<<j); //第四位循環拉低電平
for(k=0;k<4;k++) //列掃描
{
ksta[j][k]=P1&(0x10<<k); //循環將高四位IO口電平送入數組
if(ksta[j][k]!=kbackup[j][k]) //判斷按鍵初值和備份值是否發生變化
{
delay(100); //延時消抖
if(ksta[j][k]==0) //二次確定該按鍵按下
{
cnt=j*4+k; //改變變量
KeyChange=1; //使主函數內的按鍵值判斷發生變化讓密碼輸入時只執行一次
}
kbackup[j][k]=ksta[j][k]; //備份按鍵狀態,使程序只執行一次

}}P1|=0xFF; //端口置1} return cnt;

}

#endif

蜂鳴器部分:

#ifndef _beep_H
#define _beep_H

#include"reg52.h"

sbit Beep=P3^7;

#endif

了解整體結構不難的哈,并且有很強的拓展性。

總結

以上是生活随笔為你收集整理的基于51单片机编写的六位电子密码锁由LCD1602显示的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。