本系统采用以单片机为核心元件的控制方案。由于单片机种类繁多,各种型号都有其一定的应用环境,因此在选用时要多加比较,合理选择,以获得最佳的性价比。一般来说在选取单片机时从下面几个方面考虑:性能、存储器、运行速度、I/O口、定时/计数器、串行接口、模拟电路功能、工作电压、功耗、封装形式、抗干扰性、保密性,除了以上的一些方面外,还有一些最基本的条件,比如:中断源的数量和优先级、工作温度范围、有没有低电压检测功能、单片机内有无时钟振荡器、有无上电复位功能等。在开发过程中还要考虑开发工具、编程器、开发成本、开发人员的适应性、技术支持和服务等因素。基于以上因素本设计选用单片机STC89C516作为本设计的核心元件,利用单片机灵活的编程设计和丰富的I/O端口,及其控制的准确性,实现基本的密码锁功能。在单片机的外围电路外接输入键盘用于密码的输入和一些功能的控制,外接AT24C02芯片用于密码的存储,外接LCD1602显示器用于显示作用。
二、 硬件设计硬件连接如下:
P1 -->矩阵键盘
P20--> EEPROM模块SDA
P21--> EEPROM模块SCL
P22-->继电器模块J15
其他管脚说明:
P0 LCD1602_DATAPINS
P2^7 LCD1602_E;
P2^5 LCD1602_RW;
P2^6 LCD1602_RS;
P1 矩阵键盘
P2^1; 存储模块 24C02 SCL
P2^0 存储模块 24C02 SDA
2.1 主控芯片
2.2存储模块24c02
存储模块的设计是把WP引脚接到GND上因为要让器件进行正常的读/写操作,把SDA串行数据/地址与单片机的P2.0引脚使AT24C02与单片机进行所有数据的发送或接收,把SCL串行时钟引脚与单片机的P2.1引脚相连接,让单片机产生一个AT24C02工作的时钟,使其正常的工作。存储模块电路如图所示。
AT24C02的特点:数据线看门狗定时器;可编程复位门级;高数据传输速率400kHz速率和I2C总线;2.7V至7V电压;低功耗CMOS工艺兼容;16 bespate写缓冲区;反撇写保护芯片;高低电平复位信号输出;100万擦除周期;保存长达100年。
2.3显示模块LCD1602
如果想要了解系统的运行与工作状态显示器是不可缺少的,显示器是一个典型的输出设备并且它的实际应用也是极为广泛的,几乎所有的电子产品都会使用到显示器其差别仅在于显示器的结构类型不同而已。最简单的显示器可以是LED发光二极管或者数码管,它可以给出一个简单的开关信息或者数字显示,而需要显示复杂的完整的信息上述的器件就不能胜任,而液晶的出现就很好的解决了这一问题,它不仅显示内容丰富而且好节约了单片机的管脚资源。本设计采用的是液晶显示LCD1602。LCD1602内部的字符已经储存了不同的字符形式,每一个字符都有一个固定的代码,其代码与标准的ASCII字符代码一致。因此只要写入显示字符的ASCII码即可,这种标准化的设计给使用带来很大的方便。比如英文字母“C”的ASCII代码是01000011(43H),显示时单片机往液晶模块写入显示指令,模块就会把地址为43H中的点阵字符图形识别出,并会在液晶屏相应位置上看到字母“C”。
目前市场字符液晶绝大多数是基于HD44780的液晶芯片,控制原理是完全相同的,因此基于HD44780的写控制程序可以很容易地应用到市场上大部分的字符液晶。LCD1602液晶的几个特性:+5V电压、对比度可调、内含复位电路;提供各种控制命令,如:清屏、字符闪烁、光标闪烁、显示移位等多种功能;有80字节显示数据存储器DDRAM;内建有160个5X7点阵的字型的字符发生器CGROM 8个可由用户自定义的5X7的字符发生器CGRAM。1602的引脚如下所示:
LCD1602采用标准的16脚接口,其中VSS为地电源,VDD接5V正电源,VEE为液晶显示器。RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。RW为读写信号线,高电平1时进行读操作,低电平0时进行写操作。E端为使能端。D0~D7为8位双向数据线。
2.4键盘输入模块
键盘是单片机十分重要的输入设备,是实现人机对话的纽带。键盘是由一组规则排列的按键组成,一个按键实际上就是一个开关元件,即键盘是一组规则排列的开关。根据按键与单片机的连接方式不同,按键主要分为独立式按键和矩阵式按键 ,有了这些按键,对单片机的控制就方便多了。
本设计按键数量较多,所以采用矩阵式按键以节省I/O口线。将16个按键分为4排4列排列好,下图是矩阵键盘硬件结构。当有一个键按下时,通过某一边引脚赋低电平,扫描全部引脚看是否与最初的赋值一样,不一样则根据相应的算法(通过改变后的值与初始值相或,根据结果赋值)确定是哪个键按下。
2.5开锁电路
开锁电路的功能是当输入正确的密码后密码锁将被锁定,既开锁。当单片机P2.2引脚发出信号经三极管放大后,触动电磁阀即会把锁打开。一旦输入密码,单片机便会与初始密码进行比对,如果密码输入3次都与原始密码不相符即会报警。其原理图如图3-11所示
单片机源程序如下:
- /**************************************************************************************
- * 电子密码锁 *
- 实现现象:下载程序输入正确密码,会听到继电器吸合的声音
- 硬件连接:
- P1 -->矩阵键盘
- P20--> EEPROM模块SDA
- P21--> EEPROM模块SCL
- P22-->继电器模块J15
-
- 矩阵键盘:
- 0 1 2 3
-
- 4 5 6 7
-
- 8 9 返回 确定
-
- $ $ $ $
- 注意事项:无
- ***************************************************************************************/
- #include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
- #include "lcd.h"
- #include "key.h"
- #include "i2c.h"
- #define u16 unsigned int //对数据类型进行声明定义
- #define u8 unsigned char
- sbit AS=P2^2; //继电器
- /*****************************************************************************/
- /*****************************************************************************/
- u8 pw_num,Error_Num,PassWord_Length=6;
- u8 PASSWORD[]={6,6,6,6,6,6,6,6,6,6};
- u8 INPUT_PW_Tab[10];
- u8 key_num,Step,Step5,Load_first_flag=0;
- /*****************************************************************************/
- /*******************************************************************************/
- bit result_flag,Input_suc_flag;
- bit List1=0;
- /*****************************************************************************/
- /*******************************************************************************/
- void Step_0();
- void Step_1();
- void Step_2();
- void Step_3();
- void Step_4();
- void Step_5();
- void Step5_0();
- void Step5_1();
- void Step5_2();
- void Step5_3();
- void Step5_4();
- void Step5_5();
- void Step_6();
- /********************************************************************************/
- /*******************************************************************************/
- void CipherComparison();
- void input_password(bit m);
- void Read_Password();
- /*******************************************************************************
- * 函 数 名 : main
- * 函数功能 : 主函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void main()
- {
- u8 data1,a;
- // ShowString(0x00," Pechin Science ");
- // At24c02Write(0,0); //开机显示密码
- LcdWriteCom(0x01); //清屏
- for(data1=0;data1<PassWord_Length+2;data1++)
- {
- a=At24c02Read(data1)+0x30;
- LcdWriteData(a);
- delay(1000);
- }
-
- delay(1000);
- LcdInit();
- delay(1000);
- Step=0;
- Step5=0;
- Error_Num=0x00;
- Read_Password();
-
- //保存 密码长度
- // for(j=0;j<10;j++)
- // {
- // At24c02Write(j,j);
- // delay(100);
- // }
- //
-
- while(1)
- {
- key_num=KeyDown(); //读取输入值
- switch(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;}
-
- }
- }
- }
- /*****************************************************************************/
- /*******************************************************************************/
- void Step_0()
- {
- LcdInit();
- ShowString(0x00," Pechin Science "); //第一行显示Pechin Science
- ShowString(0x10," WELCOME! "); // 第二行显示 WELCOME!
- while(KeyDown()==0xff)Step=1; // 有按键按下进入下一步
- }
- /*****************************************************************************/
- /*******************************************************************************/
- void Step_1()
- {
- LcdWriteCom(0x01); //清屏
- ShowString(0x00,"Unlock");
- ShowString(0x0f,"<"); //1602第一行显示unlock
- ShowString(0x10,"Change Password");
- ShowString(0x1f," "); // 1602第二行显示Change Password
- Step=2; //
- }
- /*****************************************************************************/
- /*******************************************************************************/
- void Step_2()
- {
- if(key_num!=0x0b)
- {
- if((key_num==0x01) ||( key_num==0x09)) //1键或9键按下
- {
- List1=~List1; //Change Password
- if(List1==0)
- {
- ShowString(0x0f,"<"); // Unlock <
- ShowString(0x1f," "); // Change Password
- }
- else
- {
- ShowString(0x0f," "); // Unlock
- ShowString(0x1f,"<"); // Change Password <
- }
- }
- }
- else //确认键按下
- {
- if(List1==0){Step=3;}
- else {Step=5;List1=0;}
- }
- }
- /*****************************************************************************/
- /*******************************************************************************/
- void Step_3() //
- {
- Step=4;
- pw_num=0;
- LcdInit();
- ShowString(0x00,"Pass Word: ");
-
-
- }
- /*****************************************************************************/
- /*******************************************************************************/
- void Step_4()
- {
- input_password(0); //输入密码并以*显示
- if(Input_suc_flag==1){Step=6;} //密码输入完成进入下一步
- Input_suc_flag=0; //清除密码输入完成标志
- }
- /*****************************************************************************/
- /*******************************************************************************/
- 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;
- }
- }
- /*****************************************************************************/
- /*******************************************************************************/
- void Step_6()
- {
- CipherComparison(); //密码比对
- if(result_flag==1) //密码正确
- {
- LcdInit();
- ShowString(0x00," WELCOME!");
- AS=0; //开继电器
- delay(60000);
- delay(60000);
- AS=1; //关继电器
- }
- else //密码错误
- {
- LcdInit();
- ShowString(0x00,"Error 01!");
- }
-
- Step=0;
-
- }
- /****************************************************************************************
- 密码输入函数
- 密码长度:pw_num
- 密码输入完成标志:Input_suc_flag
- *****************************************************************************************/
- void Step5_0()
- {
- LcdWriteCom(0x01); //清屏
- ShowString (0x00,"Input PassWord:"); //1602显示:输入密码
- Step5=1;
- pw_num=0;
- }
- void Step5_1()
- {
- input_password(0); // 输入密码并以*显示
- if(Input_suc_flag==1) //密码输入完成
- {
- Step5=2; //
- Input_suc_flag=0; //清除密码输入完成标志
- }
- }
- void Step5_2() //
- {
- CipherComparison(); //密码比对
- Step5=3;
- }
- void Step5_3() //
- {
- if(result_flag==0) // 密码错误
- {
- if(Error_Num<3) //输出错误次数小于3
- {
- Error_Num++;
- LcdInit();
- ShowString (0x00,"Error 01");
- delay(20000);
- Step5=0;
- }
- else //密码错误次数大于3
- {
- Error_Num=0;
- Step=0;
- }
-
- }
- else //密码正确
- {
- LcdInit();
- ShowString (0x00,"New PassWord:");
- pw_num=0;
- Step5=4;
- }
-
-
- }
- void Step5_4()
- {
- input_password(1); //输入密码并显示
- if(Input_suc_flag==1) //输入完成
- {
- Step5=5;
- Input_suc_flag=0;
- LcdWriteCom(0x01); //清屏
- ShowString (0x00," OK!");
- }
- }
- void Step5_5()
- {
- unsigned char j;
-
- PassWord_Length=pw_num; //读取输入密码长度
- At24c02Write(0,Load_first_flag);
- delay(100);
- At24c02Write(1,PassWord_Length); //保存 密码长度
- delay(100);
- for(j=0;j<PassWord_Length;j++)
- {
- PASSWORD[j]=INPUT_PW_Tab[j]; //读取密码
- At24c02Write(j+2,INPUT_PW_Tab[j]); //保存密码至EEPROM
- delay(100);
- }
- Step5=0;
- Step=0;
- }
- void Read_Password()
- {
- unsigned char j;
- Load_first_flag=At24c02Read(0x00);
- if(Load_first_flag==0) //初次运行
- {
-
- Load_first_flag=1;
- At24c02Write(0,0x01);
- delay(100);
- At24c02Write(1,0x06); //写默认密码长度6至EEPROM
- delay(100);
- for(j=0;j<PassWord_Length;j++)
- {
- At24c02Write(j+2,8); //写默认密码888888至EEPROM
- PASSWORD[j]=INPUT_PW_Tab[j]; //读密码
- delay(100);
- }
- }
-
- Load_first_flag=At24c02Read(0x00);
- PassWord_Length=At24c02Read(0x01); //读取密码长度
- for(j=0;j<PassWord_Length;j++) //读取密码
- {
- PASSWORD[j]=At24c02Read(j+2);
- }
-
- }
- void input_password(bit m)
- {
- unsigned char j;
- if(key_num!=0x0b) //ok键没有按下
- {
- if(key_num<0x0a) //1-9按下
- {
- INPUT_PW_Tab[pw_num]=key_num; //保存至输入密码数组
- pw_num=pw_num+1; //密码长度+1
-
- LcdWriteCom(0xc0);
- for(j=0;j<pw_num;j++)
- {
- if(m==0) {LcdWriteData('*'); } //密码隐藏
- else {LcdWriteData(INPUT_PW_Tab[j]+0x30);} //显示密码
- }
-
- }
- if(key_num==0x0a) //返回键按下
- {
- if(pw_num!=0) {pw_num=pw_num-1;}
- else {Step=0;}
-
-
- // ShowString (0x00,"Pass Word:");
- LcdWriteCom(0xc0);
- for(j=0;j<pw_num;j++)
- {
- if(m==0) {LcdWriteData('*'); } //密码隐藏
- else {LcdWriteData(INPUT_PW_Tab[j]+0x30);} //显示密码
- }
- LcdWriteData(' ');
- }
- }
- else //ok键按下
- {
- if(pw_num==0)
- {
- Step=0;
- LcdWriteCom(0x01);
- ShowString (0x00,"Error 02!");
- delay(10000);
- }
-
- else{
- Input_suc_flag=1;
- }
- //AS=0;
- }
- }
- /*******************************************************
- 密码比对
- ********************************************************/
- void CipherComparison()
- {
- u8 i,j=0;
- if(PassWord_Length==pw_num) //密码长度比对
- {
- for(i=0;i<PassWord_Length;i++) //密码比对
- {
-
- if(PASSWORD[i]!=INPUT_PW_Tab[i])
- {
- result_flag=0;break; //密码错误
- }
- else
- {
- result_flag=1; //密码正确
- }
- INPUT_PW_Tab[i]=0XFF; //清除密码缓存数组
- }
- }
- else
- {result_flag=0;}
-
- }
复制代码
所有程序51hei提供下载:
程序.zip
(63.28 KB, 下载次数: 15)
|