程序名:密码锁
编写人:
编写时间:
硬件支持:STC89C52RC 外部12MHZ晶振
说明备注:
1、输入密码时在LCD屏幕上显示暗码(*),设置管理员密码时显示明码。
2、用户密码3组位5位密码及管理员密码1组。
3、断电保护密码不消失。
4、可手动复位管理员密码及用户密码。
5、输入管理员密码才能修改用户密码,密码不能为6个0,管理员密码需要按复位键进行设置。
6、可指定秀给任意1组的密码。
7、LCD操作步骤提示。
8、密码输入错误3次蜂鸣器报警,输入错误5次键盘锁定(需要复位解锁)。
9、输入管理员密码才能修改用户密码,密码不能为6个0,管理员密码需要按复位键进行设置。
10、按键提示音,开锁音,错误音,报警音。
11、第一次上电强制要求设置管理员密码
此图片仅供参考
后来用STC12C5A60S2做的 用的是内部集成的eeprom 添加了刷卡开锁+更换为12864屏
因为很多功能不能仿真 没有发上来
单片机主程序:
- /********************************************************************************************/
- #include "config.h"
- #include "lcd1602.h"
- #include "eeprom.h"
- #include "LOCK.h"
- #include "delay.h"
- #include "KEY.h"
- void Timer0Init(void); //50毫秒@12.000MHz
- void Timer1Init(void); //1毫秒@12.000MHz
- /********************************************************************************************/
- // 主程序 //
- /********************************************************************************************/
- void main(void){
- LOCK=0; //初始化锁关闭状态
- ALAM=1;
- EA=1; //开启总中断
- Timer0Init(); //50毫秒@12.000MHz
- Timer1Init(); //1毫秒@12.000MHz
- Delay1ms(400); //启动等待,等LCD讲入工作状态
- Init_LCD1602(); //LCD初始化
- InitLock(); //密码锁上电初始化
- while(1){ //进入主循环
- keyjiance(); //读取按键状态、确定要执行动作
- }
- }
- void Timer0Init(void){ //50毫秒@12.000MHz
- TMOD &= 0xF0; //设置定时器模式
- TMOD |= 0x01; //设置定时器模式
- TL0 = 0xB0; //设置定时初值
- TH0 = 0x3C; //设置定时初值
- TF0 = 0; //清除TF0标志
- TR0 = 0; //定时器1停止计时
- ET0 = 1; //使能T0中断
- }
- void InterruptTimer0() interrupt 1{
- unsigned char countt0;
- TL0=0xB0;
- TH0=0x3C; //定时器重新赋初值
- countt0++; //计时变量加,加1次时50ms
- if(countt0==20){ //加到20次就是1s
- countt0=0; //变量清零
- second++; //秒加
- if(key_disable==1){ //键盘锁状态时
- if(second==3){ //秒加到1s时
- TR0=0; //关定时器
- TL0=0xB0; //再次赋初值
- TH0=0x3C; //再次赋初值
- Cancel0(); //返回--取消所有操作
- second=0; //秒清零
- }
- }
- else{ //不在键盘锁状态时
- if(second==6){ //秒加到5时
- TR0=0; //关闭定时器
- second=0; //秒清零
- Cancel0(); //返回--取消所有操作
- TL0=0xB0; //重新赋初值
- TH0=0x3C; //重新赋初值
- }
- else
- TR0=1; //打开定时器
- }
- }
- }
- void Timer1Init(void){ //1毫秒@12.000MHz
- TMOD &= 0x0F; //设置定时器模式
- TMOD |= 0x10; //设置定时器模式
- TL1 = 0x18; //设置定时初值
- TH1 = 0xFC; //设置定时初值
- TF1 = 0; //清除TF1标志
- TR1 = 1; //定时器1开始计时
- ET1 = 1; //使能T1中断
- }
- //*********************************中断服务函数**************************************
- void time1_int(void) interrupt 3{//定时器T1
- TL1 = 0x18; //重置定时初值
- TH1 = 0xFC; //重置定时初值
- KeyScan(); //矩阵键盘扫面
- }
复制代码
锁.c :
- #include "config.h"
- #include "LCD1602.h"
- #include "eeprom.h"
- #include "delay.h"
- #include "KEY.h"
- #include "LOCK.h"
- bit pass=0; //密码正确标志
- bit ReInputIx=0; //重置密码功能标志
- bit ReInputEn=0; //重置密码输入允许标志
- bit key_disable=0; //锁定键盘标志
- unsigned char ReInputBit = 0; //修改密码第几组标记
- unsigned char InputData[6]; //输入密码暂存区
- unsigned char TempPassword[6]; //修改密码第一遍暂存
- unsigned char N=0; //密码输入位数计数
- unsigned char ErrorCont = 0; //错误次数计数
- unsigned char ReInputCont; //密码次数输入计数
- unsigned char second; //t0中断计数器,秒计数器
- unsigned char code initpassword[6]={0,0,0,0,0,0}; //初始化密码
- unsigned char CurrentPassword[4][6]={ //读取EEPROM密码暂存数组
- {0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}
- };
- unsigned char code start_line[] = {"password: "};//密码
- unsigned char code name[] = {"===Coded Lock==="};//密码锁
- //=================将按键值编码为数值============================
- unsigned char coding(unsigned char m){
- unsigned char k;
- switch(m){
- case (0x31): k=1;break;
- case (0x32): k=2;break;
- case (0x33): k=3;break;
- case (0x26): k='A';break;
- case (0x34): k=4;break;
- case (0x35): k=5;break;
- case (0x36): k=6;break;
- case (0x25): k='B';break;
- case (0x37): k=7;break;
- case (0x38): k=8;break;
- case (0x39): k=9;break;
- case (0x28): k='C';break;
- case (0x1B): k='*';break;
- case (0x30): k=0;break;
- case (0x0D): k='#';break;
- case (0x27): k='D';break;
- }
- return(k);
- }
- //====================一声提示音,表示有效输入===================
- void OneAlam(void){
- ALAM=0;
- Delay1ms(50);
- ALAM=1;
- }
- //====================二声提示音,表示操作成功===================
- void TwoAlam(void){
- ALAM=0;
- Delay1ms(50);
- ALAM=1;
- Delay1ms(50);
- ALAM=0;
- Delay1ms(50);
- ALAM=1;
- }
- //====================三声提示音,表示错误========================
- void ThreeAlam(void){
- ALAM=0;
- Delay1ms(50);
- ALAM=1;
- Delay1ms(50);
- ALAM=0;
- Delay1ms(50);
- ALAM=1;
- Delay1ms(50);
- ALAM=0;
- Delay1ms(50);
- ALAM=1;
- }
- //============输入密码错误超过三过,报警并锁死键盘===============
- void Alam_KeyUnable(void){
- P1=0xFF;
- ALAM=~ALAM; //蜂鸣器一直闪烁鸣响
- Delay1ms(5);
- }
- //=====================上电初始化=============================
- // 1、判断是否上电复位还是按键复位,如果是上电复位 标志位清0退出,
- // 2、如果是按键复位,管理员密码及用户密码都清0,
- // 3、读出管理员密码 比较管理员密码是否是6个0
- // 4、如果管理员密码是6个0,一直等待用户设置管理员密码后再进入下一步
- void InitLock(void){
- unsigned char x;
- write_1602com(er+9); //设置光标位置
- write_1602com(0x0f); //设置光标为闪烁
- Write1602_ZiFuChuan(1,1,"===Coded Lock===");//向液晶屏写开机画面--英文“密码锁”
- if(0x10==(PCON&0x10)){ //如果上电复位标志为1
- PCON&=0xEF; //上电复位标志清零
- }
- else{ //否则判断为外部按键复位,重设管理员密码
- for(x=0;x<4;x++){
- E2Write(initpassword,x*8,6);//强制将初始管理员密码及3组用户密码6个0写入24C02存储
- }
- }
- Write1602_ZiFuChuan(2,1,"Admin Password: ");//第2行第1位显示“管理员密码 ”
- E2Read(CurrentPassword[0],0,6); //读出管理员密码
- while(CurrentPassword[0][0]==0){//判断24c02中的管理员密码是否是0---密码6个0无效 ---目的是停在这里让用户修改管理员密码
- AdminPassword(); //设置管理员密码
- E2Read(CurrentPassword[0],0,6);//读出管理员密码---以便比较设置好了吗
- }
- Write1602_ZiFuChuan(2,1,"password: ");//第2行第1位显示“密码 ”
- N=0; //将输入数据计数器清零,为输入作准备
- }
- //====================设置管理员密码=============================
- void AdminPassword(void){
- unsigned char j,y,z;
- y=KeyDriver(); //读按键的位置码
- if(y!=0){
- z=coding(y); //根据按键的位置将其编码,编码值赋值给NUM
- switch(z){
- case ('A'):;break;
- case ('B'):;break;
- case ('C'): //删除最后一个字符
- if(N>=1) N--; //定位输入的字 加上0的位数
- OneAlam(); //按键提示音
- for(j=N;j<16;j++){
- write_1602com(er+6+j); //第二行已输入的最后一位
- write_1602dat(' '); //显示换成空格
- }
- break;
- case ('D'):;break;
- case ('*'):;break; //取消当前输入
- case ('#'): //确认键
- if(N==6){ //输入满6位
- E2Write(InputData,0,6); //管理员密码EEPROM存储
- TwoAlam(); //成功提示音
- break; //退出循环
- }
- else{ //小于6位报错
- Write1602_ZiFuChuan(2,1," error ");//显示错误
- ThreeAlam(); //错误提示音
- }
- default:{ //如果不是功能键按下时,就是数字键按下
- if(N<6){ //当输入的密码少于6位时,接受输入并保存,大于6位时则无效。
- Write1602_ZiFuChuan(1,1,"====Set Lock====");//第2行第1位显示“管理员密码 ”
- Write1602_ZiFuChuan(2,1,"input: ");//显示输入画面--“输入 ”
- OneAlam(); //按键有效提示音
- InputData[N]=z; //将数字键的码赋值给InputData[]数组暂存
- for(j=0;j<=N;j++){ //显示位数随输入增加而增加
- Write1602(0xc0+6+j,InputData[j]+0x30);//第2行但显示实际数字
- }
- N++; //密码位数加
- }
- else{ //输入数据位数大于6后,忽略输入
- N=6; //密码输入大于6位时,不接受输入
- break;
- }
- }
- }
- }
- }
- //========================设置密码===============================
- void ResetPassword(void){
- unsigned char i;
-
- ReInputCont++; //密码次数计数
- if(ReInputCont==2){ //输入第二次密码时
- for(i=0;i<6;){ //循环比较2次6位密码是否一致
- if(TempPassword==InputData) //将两次输入的新密码作对比
- i++;
- else { //如果两次的密码不同
- Write1602_ZiFuChuan(2,1," error ");//显示错误
- ThreeAlam(); //错误提示音
- ReInputIx=0; //关闭密码重置功能
- ReInputEn=0; //关闭重置输入允许
- ReInputCont=0; //密码次数计数清零
- break;
- }
- }
- if(i==6){ //2次6位密码一致 -----等待存入位置选择 并确认后存入EEPROM
- ReInputBit = 1; //"修改密码第几组标记"标记为第一组
- write_1602com(0x01); //清屏
- Write1602_ZiFuChuan(1,1,"Select location:");//第1行第1位显示“设置位置”--设置储存在第几组位置(共3组)
- Write1602_ZiFuChuan(2,1," [1] [2] [3]");//第2行分别显示 三组供选择
- write_1602com(0xc2); //光标在第一组闪烁
- OneAlam(); //操作有效提示音
- }
- ReInputCont=0; //密码次数计数清零
- }
- else{ //输入一次密码时
- OneAlam(); //操作有效提示音
- write_1602com(0x01); //清屏
- Write1602_ZiFuChuan(1,1,"====Set Lock====");//第1行第1位显示“设置密码”
- Write1602_ZiFuChuan(2,1,"input again: "); //第2行第1位显示“再次输入”
- for(i=0;i<6;i++){
- TempPassword=InputData; //将第一次输入的数据暂存起来
- }
- }
- N=0; //输入数据位数计数器清零
- }
- //============取消所有操作(定时器0专用)不然有警告================
- void Cancel0(void){
- unsigned char i,j;
-
- write_1602com(0x01); //清屏
- for(j=0;j<16;j++){
- Write1602(yi+j,name[j]);//第1行第1位显示“密码锁”
- Write1602(er+j,start_line[j]);//第1行第1位显示“密码锁”
- }
- TwoAlam(); //操作成功提示音
- for(i=0;i<6;i++){
- InputData=0; //将输入密码清零
- }
- LOCK=0; //关闭锁
- ALAM=1; //报警关
- pass=0; //密码正确标志清零
- ReInputEn=0; //重置输入充许标志清零
- ReInputIx=0; //密码重置功能标志清零
- ReInputBit=0; //"修改密码第几组标记"清零
- ErrorCont=0; //密码错误输入次数清零
- ReInputCont=0; //重置密码输入次数清零
- key_disable=0; //锁定键盘标志清零
- N=0; //输入位数计数器清零
- }
- //======================取消所有操作=============================
- void Cancel(void){
- unsigned char i;
-
- write_1602com(0x01); //清屏
- Write1602_ZiFuChuan(1,1,"===Coded Lock===");//第1行第1位显示“密码锁”
- Write1602_ZiFuChuan(2,1,"password: ");//第2行第1位显示“密码 ”
- TwoAlam(); //操作成功提示音
- for(i=0;i<6;i++){
- InputData=0; //将输入密码清零
- }
复制代码
全部资料51hei下载地址:
密码锁仿真.zip
(67.29 KB, 下载次数: 278)
89C52密码锁程序9 24C02 EEPROM.zip
(98.06 KB, 下载次数: 279)
|