文章目录
- 一、课程设计内容
- 功能阐述
- 二、开发板原理图与设计流程图
- 三、设计思路和方法
- 1、EEPROM初始化
- 2、LCD1602初始化
- 3、矩阵按键扫描
- 4、输入密码
- 5、密码比对
- 四、源代码附录
- 五、经验总结与体会
- 1、遇到问题及解决方法
一、课程设计内容
选用单片机开发板STC89C52作为本设计的核心元件,利用编程设计、I/O端口及其板上的各种硬件电路,设计电子密码锁功能
功能阐述
选用单片机开发板STC89C52作为本设计的核心元件,利用编程设计、I/O端口及其板上的各种硬件电路,设计密码锁功能,以自创的代码将功能实现,并形成项目报告。利用单片机的矩阵键盘用于密码的输入和一些功能的控制,利用EEPROM用于密码的存储,外接LCD1602液晶显示器用于显示作用。
二、开发板原理图与设计流程图
三、设计思路和方法
设计思路:初始化从EEPROM中读取密码,单片机通电即显示首页,按任意键进入功能选择界面,可通过按键移动光标选择直接输入密码登录,或者进行修改密码操作。①直接输入密码登录:通过矩阵按键输入6位数字密码,并存入数组,然后通过该数组与EEPROM读取的密码进行比对,从而判断密码是否正确,如果密码正确则显示登录成功并触发流水灯反馈结果,如果密码错误则显示输入错误并触发蜂鸣器警告,当输入密码次数超过3次则直接返回首页。②进行修改密码操作:提示输入原密码,键入6位密码并判断,当输入密码正确时提示输入新密码,键入6位新密码后存入EEPROM,重启或重新登录时从EEPROM读取密码,此时使用为新密码。
1、EEPROM初始化
将51单片机的头文件和i2c.h的头文件包含进来,对24C02芯片进行读写操作,调用At24c02Write函数将变量、数据写入到对应的地址内,调用 At24c02Read 函数进行读取操作,将从对应地址内读取的值存储在变量中。
2、LCD1602初始化
LCD1602驱动的底层协议中几个常用的函数:
① LcdWriteCom():写命令函数,通过此函数向LCD1602写命令。比如:清屏LcdWriteCom(0x01); 设置数据指针起LcdWriteCom(0x80)。
② LcdWriteData():显示函数,在写数据之前需要通过LcdWriteCom()函数告诉要写数据的地址,LCD1602的第一行的16个显示位地址是0x80到0x8f;第二行的地址是0xc0到0xcf。比如在1602的第一行第一位显示数字8:LcdWriteCom(0x80)或LcdWriteData(‘8’)。
③ showString (unsigned char Coordinate,char *ptr):ShowString (首地址,字符串)函数在需要显示字符串时使用。比如在第二行第3位开始显示hello:ShowString (0x13,”hello”)。其中首地址的高四位为0则表示在第一排显示,为“1”则在第二排显示。低四位为0则在第0位显示。
3、矩阵按键扫描
矩阵按键P1口的低四位接的4*4矩阵键盘的行,高四位接的矩阵键盘的列。检测矩阵键盘是否有按键按下时:先将P1端口的低四位置1,高四位清零,检测P1端口的状态,如果高四位不为零,则表示有按键按下,并且可以知道是x0-x3哪一列有按键按下,比如P1=0x1f;则第一列有按键按下。此时我们在将P1口第四位清零,高四位置1;检测P1的状态,就知道y0-y3哪一行有按键按下。结合xy就可以知道具体是哪个按键按下。
4、输入密码
检测按键’0’~'9’的按下,将键入数字信息保存至输入密码数组,+‘0’因为需要存入的是ASCII码,显示密码在Lcd显示屏第2行,可修改传入值m改变密码显示形式,m=0密码以’*'显示,m=1密码直接显示,按下return键时返回一步,按下OK键时结束输入。
5、密码比对
先判断密码长度,如果不为6位直接跳转密码错误反馈,满足密码位数,再逐位与EEPROM内存的密码进行比对,逐一对应则跳转密码成功反馈,否则跳转密码错误反馈。
四、源代码附录
/**************************************************************************************Course application design : Electronic code lock
Function design: download program and input correct password, receive double lights rolling; input wrong password, receive buzzer alarm
Hardware connection:P1 -- > keyboard matrixP20 - > EEPROM module SDAP21 - > EEPROM module SCLMatrix keyboard position corresponding information:S1 S2 S3 S4 0 1 2 3S5 S6 S7 S8 4 5 6 7--->S9 S10 S11 S12 8 9 return OKS13 S14 S15 S16 × × × ×
***************************************************************************************/
#include "reg52.h" //This file defines some special function registers of MCU
#include "lcd.h"
#include "key.h"
#include "i2c.h"
#include<intrins.h> //The header file required by the left and right shift function#define u16 unsigned int //Declarative definition of data types
#define u8 unsigned charsbit beep=P2^5; //define beep# define LCD_LINE1 0x00 //Define the first line of the LCD display
# define LCD_LINE2 0xc0 //Define the second line of the LCD display u8 pw_num,Error_Num,PassWord_Length=6; //The password length is 6
u8 PASSWORD[]={'8','8','8','8','8','8'}; //The initial password is 888888
u8 INPUT_PW_Tab[10] = {'-', '-', '-', '-', '-', '-'};//Defines an array to hold passwords
u8 key_num,Step,Step5,Load_first_flag;bit result_flag = 0,List1=0,Input_suc_flag;void Step_0(); //Step 0: home page display
void Step_1(); //Step 1: display function: input password or modify password
void Step_2(); //Step 2: Select function: input password or modify password
void Step_3(); //Step 3: display prompt: input password
void Step_4(); //Step 4: input the password void Step_5(); //Step 5: change the password
void Step5_0(); //Modify password function: step 0: display prompt: input the original password
void Step5_1(); //Password modification function: Step 1: enter the password
void Step5_2(); //Password modification function: Step 2: password comparison
void Step5_3(); //Password modification function: Step 3: processing after password comparison
void Step5_4(); //Password modification function: Step 4: enter a new password
void Step5_5(); //Password modification function: Step 5: read the new password and save it in EEPROM void Step_6(); //Step 6: the password comparison result is correct or wrong, feedback the corresponding result void CipherComparison(); //Function of password comparison
void input_password(bit m); //Function to enter password
void init_Password(); //Initialization password: read password from EEPROM
void light_run(); //Water lamp: feedback function after inputting correct password
void beep_run(); //Beep: feedback function after inputting wrong password/*******************************************************************************/
void main()
{ u8 data1,a;beep=1;LcdInit();// At24c02Write(0, 0);
/*Clear the memory, initialize and reset the password to 888888. This statement is used to write illegal characters to EEPROM during debugging. When the password cannot be modified again, this statement can be used to initialize the password.*/delay(1000);Step=0;Step5=0;Error_Num=0x00;init_Password();while(1){ key_num=KeyDown(); //Read input valueswitch(Step){case 0:{Step_0();break;}case 1:{Step_1();break;}case 2:{Step_2();break;}case 3:{Step_3();break;} case 4:{Step_4();break;} case 5:{Step_5();break;} case 6:{Step_6();break;} }}
}
/*****************************************************************************/
//Step 0: home page display
void Step_0()
{char dis[16];int i;//For debugging convenience, the current password is displayed on the home page. dis[0] = Load_first_flag + '0';dis[1] = ':';for(i = 0; i < 6; i++)dis[2 + i] = PASSWORD[i] ;dis[8]=0;LcdInit();if(result_flag == 0) //First time login {ShowString(LCD_LINE1, " Need to Log in "); //The first line shows " Need to Log in " ShowString(LCD_LINE2, dis); //The second line shows the current password }else{ShowString(LCD_LINE1, " Welcome! "); //The first line shows " Welcome! " ShowString(LCD_LINE2, dis); //The second line shows the current password}while(KeyDown()==0xff)Step=1; //Press the detection button to enter the next step
}
/*****************************************************************************/
//Step 1: display function: input password or modify password
void Step_1()
{LcdWriteCom(0x01); //Clear screenShowString(0x00,"Input Password"); //The first line of LCD1602 displays "Input Password"ShowString(0x0f,"<"); //Display indicator cursor "<" ShowString(0x10,"Change Password"); //The second line of LCD1602 displays change passwordShowString(0x1f," "); Step=2; //Go to step 2
}
/*****************************************************************************/
//Step 2: Select function: input password or modify password
void Step_2()
{if(key_num!=0x0b) {if((key_num==0x01) ||( key_num==0x09)) //When 1 key or 9 key is pressed: switch cursor position - > Select function {List1=~List1; //Change Passwordif(List1==0){ ShowString(0x0f,"<"); // Input Password <ShowString(0x1f," "); // Change Password }else{ShowString(0x0f," "); // Input Password ShowString(0x1f,"<"); // Change Password <}}}else //When the OK key is pressed{if(List1==0){Step=3;} //When input password is selected, go to step 3 else {Step=5;List1=0;} //When change password is selected, go to step 5 }
}
/*****************************************************************************/
//Step 3: display prompt: input password
void Step_3()
{Step=4;pw_num=0;LcdInit();ShowString(0x00,"Pass Word: ");
}
/*****************************************************************************/
//Step 4: input the password
void Step_4()
{input_password(1); //Input the password and display itif(Input_suc_flag==1){Step=6;} //Enter the password and go to the next stepInput_suc_flag=0; //Clear the password input complete flag
}
/*****************************************************************************/
//Step 5: change the password
void Step_5()
{switch(Step5){case 0: {Step5_0();} break;case 1: {Step5_1();} break;case 2: {Step5_2();} break;case 3: {Step5_3();} break;case 4: {Step5_4();} break;case 5: {Step5_5();} break;}
}
/*****************************************************************************//*****************************************************************************/
//Step 6: the password comparison result is correct or wrong, feedback the corresponding result
void Step_6()
{CipherComparison(); //Password comparisonif(result_flag==1) //If the password is correct{LcdInit();ShowString(0x00," SUCCESS!"); //Display "success!" and trigger the water lamplight_run(); }else //If the password is error{LcdInit();ShowString(0x00,"Error!"); //Display "error!" and trigger buzzer beep_run();}Step=0;
}/****************************************************************************/
//Modify password function: step 0: display prompt: input the original password
void Step5_0()
{LcdWriteCom(0x01); //Clear screenShowString (0x00,"Input PassWord:");//The first line of LCD1602 displays "Input Password"Step5=1; //Go to the next step pw_num=0;
}
//Password modification function: Step 1: input the password
void Step5_1()
{input_password(1); //Input the password and display itif(Input_suc_flag==1) //When the password is entered{Step5=2; //Go to the next step Input_suc_flag=0; //Clear password input complete flag}
}
//Password modification function: Step 2: password comparison
void Step5_2()
{CipherComparison(); //Password comparisonStep5=3; //Go to the next step
}
//Password modification function: Step 3: processing after password comparison
void Step5_3()
{if(result_flag==0) //Input password error{if(Error_Num<3) //The number of input errors is less than 3{Error_Num++;LcdInit();ShowString (0x00,"Error"); //If the password is wrong, diaplay "Error"delay(20000);Step5=0;}else //The number of input errors is more than 3{Error_Num=0;Step=0;} }else //Input password correctly{LcdInit();ShowString (0x00,"New PassWord:");//If the password is correct, diaplay "New PassWord:" pw_num=0;Step5=4; //Go to the next step}
}
//Password modification function: Step 4: input the new password
void Step5_4()
{input_password(1); //Input the password and display itif(Input_suc_flag==1) //When the password is entered{ Step5=5; //Go to the next step Input_suc_flag=0;LcdWriteCom(0x01); //clear screenShowString (0x00," OK!");}
}
//Password modification function: Step 5: read the new password and save it in EEPROM
void Step5_5()
{unsigned char j;Load_first_flag = 1;At24c02Write(0,Load_first_flag); delay(100); for(j=0;j<PassWord_Length;j++) {PASSWORD[j]=INPUT_PW_Tab[j]; //Read passwordAt24c02Write(j+1,INPUT_PW_Tab[j] - '0');//Save password to EEPROMdelay(100);}Step5=0;Step=0;
}
/****************************************************************************/
//Initialization password: read password from EEPROM
void init_Password()
{unsigned char j;Load_first_flag=At24c02Read(0);if(Load_first_flag!=0) {for(j=0;j<PassWord_Length;j++) //Read password{PASSWORD[j]= At24c02Read(j + 1)+'0';}}
}//Function to enter password
void input_password(bit m)
{unsigned char j;if(key_num!=0x0b) //When the OK key is not pressed{if(key_num<0x0a) //Keys 1-9 are pressed{INPUT_PW_Tab[pw_num]=key_num + '0'; //Save to the input password array. Using +'0' because it needs to store ASCII code pw_num=pw_num+1; //Password length + 1LcdWriteCom(LCD_LINE2); //Display the password on line 2 of LCD display for(j=0;j<pw_num;j++){if(m==0) {LcdWriteData('*'); } //The input value m can be modified to change the password display. M = 0, the password is displayed as' * '. M = 1 password direct display else {LcdWriteData(INPUT_PW_Tab[j]);} //display the password}}if(key_num==0x0a) //When the return key is pressed{if(pw_num!=0) {pw_num=pw_num-1;}else {Step=0;}LcdWriteCom(LCD_LINE2); for(j=0;j<pw_num;j++){if(m==0) {LcdWriteData('*'); } //Using '*' to hide the passwordelse {LcdWriteData(INPUT_PW_Tab[j]);}//Display password directly }LcdWriteData(' '); }} else //When the OK key is pressed{if(pw_num==0) //When the password number is wrong, it will be judged as wrong password directly {Step=0;LcdWriteCom(0x01);ShowString (0x00,"Error!");delay(10000);}else{ Input_suc_flag=1; } }
}
/***************************************************************/
//Function of password comparison
void CipherComparison()
{ u8 i;if(PassWord_Length==pw_num) //Password length comparison{for(i=0;i<PassWord_Length;i++) //Password comparison{if(PASSWORD[i]!=INPUT_PW_Tab[i]){result_flag=0;return; //Password error}}result_flag=1;}elseresult_flag=0;
}//Water lamp: feedback function after inputting correct password
void light_run()
{u8 i;for(i=0;i<8;i++){P2=~(0x03<<i); //Move the i bit to the right, and then assign the result to the P2 port. The first light of ~0x03 is D1 and D2 delay(100000); //delay }
}//Beep: feedback function after inputting wrong password
void beep_run()
{u8 i;for(i=0;i<100;i++){beep=~beep;delay(1000);}
}
五、经验总结与体会
1、遇到问题及解决方法
①实验调试过程中,由于密码固定为6位数的数字密码,矩阵键盘键入数值为int型,而密码数组为字符型,录入密码再从EEPROM读取时会发现出现非预期字符或无法显示的空白字符,解决方法是在录入和读取密码时统一为字符型例如:
char PASSWORD[]={‘8’,‘8’,‘8’,‘8’,‘8’,‘8’}; //The initial password is 888888
char INPUT_PW_Tab[10] = {’-’, ‘-’, ‘-’, ‘-’, ‘-’, ‘-’}; //Defines an array to hold passwords
录入EEPROM:
At24c02Write(j+1,INPUT_PW_Tab[j] - ‘0’); //Save password to EEPROM
从EEPROM读取:
PASSWORD[j]= At24c02Read(j + 1)+‘0’;
②实验调试过程中,由于数据的录入和显示会出现各种状况,在实现修改密码功能的调试过程中,由于统一使用字符型,需要与int型进行转换,可能会出现密码录入EEPROM后出现矩阵键盘无法输入的字符或其他非法字符,此时由于无法输入正确密码而需要反复调试将会增加很多麻烦,此时解决方法可以使用语句:
At24c02Write(0, 0);
清除内存,初始化,将密码重置到888888,用于调试时可对EEPROM存入密码初始化。调试成功后可将此语句注释,恢复单片机重启后依然可以读取上次录入的新密码的功能。