C51单片机技术应用与实践任务密码锁.docx
《C51单片机技术应用与实践任务密码锁.docx》由会员分享,可在线阅读,更多相关《C51单片机技术应用与实践任务密码锁.docx(31页珍藏版)》请在冰豆网上搜索。
C51单片机技术应用与实践任务密码锁
第3篇单片机接口应用
任务5、电子密码锁模块
问题的提出:
日常生活和工作中,住宅与部门的安全防范、单位的文件档案、财务报表以及一些个人资料的保存多以加锁的办法来解决。
若使用传统的机械式钥匙开锁,人们常需携带多把钥匙,使用极不方便,且钥匙丢失后安全性即大打折扣。
随着科技的发展和社会生活水平的提高,人们对日常生活中的安全保险器件的要求越来越高,电子安全密码锁是基于这一要求的保险器件,用密码代替钥匙。
目前使用的密码锁种类繁多,如指纹锁、红外密码锁、GPS密码锁、卡片锁等,各具特色,其中最为广泛的是键盘式电子密码锁(如图5-1),该产品主要应用于保险箱、保险柜等,还有一部分应用于保管箱和运钞车。
键盘式电子密码在键盘上输入,与打电话差不多,因而易于掌握,其突出优点是“密码”是记在被授权人脑子里的数字和字符,既准确又可靠,不会丢失,难以被窃。
尽管新式电子防盗锁层出不穷,但键盘式电子密码防盗锁不仅在市场上居于主流地位,而且,还经常作为其他类型电子防盗锁的辅助输入手段。
在安全技术防范领域,具有防盗报警功能的电子密码锁逐渐代替了传统的机械式密码锁,电子密码锁具有安全性高、成本低、功耗低、易操作等优点。
图5-1电子密码箱图5-2电子门禁系统
5.1I2C总线的基本原理
I2C总线是英文“InterIntegratedCircuitBus”内部集成电路的缩写,是一种串行的数据总线系统,源于计算机技术,是国际上最先进的大规模数字化集成电路,是通过时钟和数据总线的双向控制进行数据的读写。
现主要用于电视机的各个功能模块(亮度、色度、对比度、音量等)进行有效的跟踪控制,能够提高电视的可靠性,同时方便维修。
5.1.1I2C总线结构
I2C串行总线只有两根信号线,一根是双向的数据线SDA,另一根是双向的时钟线SCL。
所有连接到I2C总线上的芯片的数据引脚SDA都连接到总线的SDA线,各芯片的时钟引脚SCL都连接到总线的SCL线。
典型I2C配置如图5-3所示。
在信息的传输过程中,I2C总线上发送数据的设备称为发送器,而接收数据的设备称为接收器。
能够初始发送、产生时钟、起始信号、停止信号的设备称为主机或主控制器(Multimastering);而被主机寻址的设备称为从机。
主机和从机之间的数据传送,可以由主机发送数据到从机,也可以由从机发送数据到主机。
I2C总线上的每个芯片(例如微控制器、LCD驱动器、存储器或键盘接口)都有唯一的地址,就像电话机一样都有各自唯一的号码,只有被选址的芯片即从机才和主机(例如单片机)通信,就像电话机只有在被拨通各自的号码时才能通话。
图5-3I2C主/从系统结构图
I2C器件的数据线SDA是双向通信的,既可用于向总线上发送数据,也可以接收总线上的数据。
时钟线SCL也是双向的,控制总线数据传送的主机通过时钟线SCL发送时钟信号,同时也要检测SCL上的电平以决定什么时候发送下一个时钟脉冲电平。
作为接收主机命令的从机,要按总线上SCL的信号发出或接收SDA上的信号,也可以向SCL线发出低电平信号以延长总线时钟信号的周期。
由于SDA和SCL均通过上拉电阻连接到5V电源,所以总线空闲时,SDA和SCL线都保持高电平,任一器件输出的低电平都会使相应的总线信号电平变低,即各器件的SDA和SCL都是“与”的关系。
I2C总线最主要的优点是其简单性和有效性。
由于接口直接在芯片上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量。
I2C总线能够以10Kbps的最大传输速率支持40个器件,并支持多个主机,任何能够进行发送和接收的设备都可以成为主机。
主机能够控制信号的传输和时钟频率。
当然,在同一时间段,只能有一个主机。
当有多个主机同时向I2C总线发送起始信号,要求控制总线,将通过仲裁过程,决定哪些主机放弃总线控制权,而仅由一台主机控制总线。
注意:
没有必要在一个系统中指定某个器件作为主机,任何一个发送起始信号和从机地址的器件就成为该次数据传输的主机。
5.1.2I2C总线协议
1)主机—从机和接收器—发送器
I2C总线上的每个器件都可以作为一个发送器或接收器,这由器件的功能决定。
很明显LCD驱动器只是一个接收器,而存储器则既可以接收又可以发送数据。
除了发送器和接收器外,器件在执行数据传输时也可以被看作是主机或从机,见表5-1。
主机是初始化总线的数据传输并产生允许传输的时钟信号的器件。
此时,任何被寻址的器件都被认为是从机。
表5-1I2C总线术语的定义
术语
描述
发送器
发送数据到总线的器件
接收器
从总线接收数据的器件
主机
初始化发送、产生时钟信号和终止发送的器件
从机
被主机寻址的器件
多主机
同时有多于一个主机尝试控制总线,但不破坏数据
主机—从机、接收器—发送器这些关系不是持久的,只由当时数据传输的方向决定。
例如在如下的传输数据的过程中:
(1)微控制器A要发送信息到微控制器B
微控制器A(主机)寻址微控制器B(从机)
微控制器A(主机—发送器)发送数据到微控制器B(从机—接收器)
微控制器A终止传输
(2)如果微控制器A想从微控制器B接收信息
微控制器A(主机)寻址微控制器B(从机)
微控制器A(主机—接收器)从微控制器B(从机—发送器)接收数据
微控制器A终止传输
2)I2C总线位的传输
I2C总线为同步传输总线,总线数据与时钟完全同步。
I2C总线规定时钟线SCL上一个时钟周期只能传送一位数据。
当时钟SCL线为高电平时,对应数据线SDA线上的电平即为有效数据位(高电平为1,低电平为0);在数据传送开始后,SCL为高电平的时候,SDA的数据必须保持稳定,只有当SCL为低电平的时候,才允许SDA上的数据改变。
当SCL发出重复的时钟脉冲时,每次为高电平时,SDA线上对应的电平就是一位一位传送的数据,其中最先传输的是字节的最高位数据,其时序如图5-4所示。
图5-4I2C总线上SDA和SCL的时序关系
3)起始条件和停止条件
在I2C总线中,起始(S)条件和停止(P)条件是根据SDA和SCL线上的电平状态定义的,如图5-5所示。
其中一种情况是在SCL线保持高电平时,SDA线从高电平向低电平切换,即SDA线上出现一个下降沿,这种情况表示一次数据传送的开始。
所有操作均必须由起始条件开始。
出现起始信号以后,总线被认为“忙”。
另一种情况是当SCL保持高电平时,SDA线由低电平向高电平切换,即SDA线上出现一个上升沿,表示停止条件。
出现停止信号后,总线被认为“空闲”。
也就是SCL和SDA都保持高电平,总线就是空闲的。
在连续读写时,如收到—-个“停止条件”。
则所有读写操作将终止,芯片将进入等待模式。
起始条件和停止条件—般由主机产生。
起始条件:
当SCL线为高电平时,SDA线由高到低的转换。
停止条件:
当SCL为线高电平时,SDA线由低到高的转换。
图5-5I2C总线的起始条件和停止条件
4)应答信号
接收数据的芯片在接收到8位数据后,向发送数据的芯片发出特定的低电平脉冲,表示已收到数据。
应答位的时钟脉冲也由主机产生。
发送器在应答时钟脉冲高电平期间,将SDA线拉为高电平,即释放SDA线,转由接收器控制。
接收器在应答时钟脉冲的高电平期间必须拉低SDA线,以使之为稳定的低电平作为有效应答,如图5-6所示。
若接收器不能拉低SDA线,则为非应答信号。
图5-6I2C总线上的应答
发送器向接收器发出一个字节的数据后,等待接收器发出一个应答信号,发送器接收到应答信号后,根据实际情况作出是否继续传递信号的判断。
若未收到应答信号,由判断为接收器出现故障。
5)数据字节的传送
发送到SDA线上的每个字节必须为8位。
每次传输可以发送的字节数量不受限制,但每个字节后必须跟—个应答位,数据传输的顺序是首先传输数据的最高位MSB,然后在每一个SCL线的时钟周期内,传送一位数据,在8个SCL时钟周期后,SDA线上完成一个字节的数据传送。
在传输时,若SCL线为高电平,SDA线上电平需保持稳定不变,只有SCL为低电平时,SDA线上的电平才能改变。
否则,若SCL线为高电平,而SDA线上的电平由高跳变到低,则为起始信号;由低跳变到高,则为停止信号。
SDA线上完成一个字节的数据传送后,在第9个SCL时钟周期,接收器需发出一个应答信号,即在SCL线为高电平时,将SDA线拉低,以使之为稳定的低电平作为有效应答,表明正确收到了发送器发送的数据。
如果接收器要完成一些其他功能后(例如一个内部中断服务程序)才能接收或发送下一个完整的数据字节,可以使时钟线SCL在应答信号后保持低电平迫使发送器进入等待状态,当接收器准备好接收下一个数据字节并释放时钟线SCL(即SCL为高电平)后,继续数据传输。
I2C的数据字节传输如图5-7所示。
图5-7I2C总线上数据的传送
6)一帧完整数据的传送
一次典型的I2C总线数据传输包括一个起始条件(START)、一个地址字节(位7-1:
7位从机地址;位0:
R/W方向位)、一个或多个字节的数据和一个停止条件(STOP)。
每个地址字节和每个数据字节后面都必须用SCL高电平期间的SDA低电平(如图5-6)来应答(ACKNOWLEDGE简写为ACK)。
如果在数据传输了一段时间后,接收器件不能接收更多的数据字节,接收器件将发出一个“非应答”(NACK)信号,这用SCL高电平期间的SDA高电平表示,发送器件读到“非应答”信号后终止传输。
方向位占据地址字节的最低位。
方向位被设置为逻辑1表示这是一个“读”(READ)操作,即主机接收从机发送的数据;方向位为逻辑0表示这是一个“写”(WRITE)操作,即从机接收主机发送的数据。
所有的数据传输都由主器件启动,可以寻址一个或多个目标从机。
主机产生一个起始条件,然后发送地址和方向位。
如果本次数据传输是一个从主机到从机的写操作,则主机每发送一个数据字节后等待来自从机的确认。
如果是一个读操作,则由从机发送数据并等待主机的确认。
在数据传输结束时,主机产生一个停止条件,结束数据交换并释放总线。
图5-8示出了一次典型的I2C总线数据传输过程。
图5-8I2C总线上完整数据的传送
5.1.3I2C总线的传送格式
前面介绍了I2C总线的传送格式为主从式,对系统中的某一器件来说有四种可能的工作方式:
主发送方式、从发送方式、主接收方式、从接收方式。
1)主发送从接收
主机在SDA上发送串行数据,在SCL上输出串行时钟。
首先主机产生一个起始条件,然后发送含有目标从机地址和数据方向位的第一个字节。
该字节内容见表5-2。
表5-2第一个字节的定义
MSB7位从机地址LSB
R/W
最高位最低位
在这种情况下数据方向位(R/W)应为逻辑0,表示这是一个“写”操作。
发送完第一个字节后,主机等待由从机产生的应答信号(ACK)。
收到从机的应答信号(ACK)后,主机发送一个或多个字节的串行数据,并在每发送完一个字节后等待由从机产生的应答信号(ACK)。
最后,为了指示串行传输的结束,主机产生一个停止条件。
典型的主发送从接收时序如图5-9所示。
图5-9典型的主发送从接收时序
2)从发送主接收
主机在SDA上接收串行数据,在SCL上输出串行时钟。
首先主机产生一个起始条件,然后发送含有目标从机地址和数据方向位的第一个字节。
在这种情况下数据方向位(R/W)应为逻辑1,表示这是一个“读”操作。
发送完第一个字节后,主机等待由从机产生的应答信号(ACK)。
收到从机的应答信号(ACK)后,从机开始发送数据,主机每收到一个字节都要发送一个应答信号ACK。
若从机收到的ACK=0有效应答,那么从机继续发送;若ACK=1非有效应答,那么从机停止发送。
最后,为了指示串行传输的结束,主机产生一个停止条件。
典型的主接收从发送时序如图5-10所示。
图5-10典型的主接收从发送时序
5.2AT24CXX
1)引脚介绍
AT24CXX系列E2PROM是支持I2C总线数据传送协议的串行CMOSE2PROM,AT24C02的管脚配置如图5-11所示,采用双列直插DIP-8封装,管脚功能见表5-3。
图5-11管脚配置
表5-3管脚功能描述
管脚名称
功能
A0、A1、A2
器件地址选择
SDA
串行数据/地址信号线
SCL
串行时钟信号线
WP
写保护
VCC、VSS
+1.8~6.0V工作电源、低
SCL:
串行时钟信号线。
用于产生器件所有数据发送或接收的时钟,在写方式,SCL为高电平时,数据必须保持稳定且下降沿送数;
SDA:
串行数据信号线。
用于传送地址和所有数据的发送和接受,仅仅在SCL为低电平时数据才可以改变;
WP:
写保护。
如果WP管脚连接到Vcc,所有的内容都被写保护,只能读而不能写。
此时AT24C02可以接收从机地址和字节地址,但在接收到第一个数据字节后不发送应答信号,从而避免寄存器区域被编程改写。
当WP管脚连接到Vss或悬空,允许AT24C02进行正常的读/写操作。
A0、A1、A2:
器件地址输入端。
这些输入脚用于多个器件级联时设置器件地址,当这些脚悬空时默认值为0。
一个微控制器最大可级联8个AT24C02。
如果系统只有一个AT24C02被总线寻址,这三个地址输入脚A0、A1、A2可悬空或连接到Vss。
AT24C系列E2PROM的型号地址高四位皆为1010,器件地址中的低3位为引脚地址A2、A1、A0,对应器件寻址字节中的D3、D2、D1位,在硬件设计时由连接的引脚电平给定,见表5-4所示。
表5-4AT24C02的地址定义
最高位7位从机地址最低位
1
0
1
0
A2
A1
A0
R/W
D7D6D5D4D3D2D1D0
2)AT24C02的读写操作
(1)AT24C02的写操作
AT24C02的写操作可分为字节写和页写两类。
①字节写。
在字节写模式下,主机发送起始信号和从机地址信息,R/W位置零。
在从机产生应答信号后,主机发送AT24C02的内部字节地址,该地址表明一个字节的数据要写入AT24C02的哪一个字节。
主机在收到从机的另一个应答信号后,再发送数据到AT24C02内部字节地址表明的存储单元。
AT24C02再次应答,并在主机产生停止信号后开始内部数据的擦写。
在内部擦写过程中,AT24C02不再应答主机的任何请求。
字节写时序如图5-12所示。
图5-12字节写时序
②页写
用页写AT24C02可以一次写入8个字节的数据。
页写操作的启动和字节写一样,不同在于传送了一字节数据后并不产生停止信号。
主机被允许再发送7个额外的字节,每发送一个字节数据后,AT24C02产生一个应答信号,并将内部字节地址自动加1。
如果写到此页的最后一个字节,即发送完8个字节数据后,主机继续发送数据,数据将从该页的首地址写入,先前写入的数据将被覆盖,造成数据丢失。
接收到8字节数据和主机发送的停止信号后,AT24C02启动内部写周期将数据写到数据区,所有接收的数据在一个内部写周期内写入AT24C02。
页写时序如图5-13所示。
图5-13页写时序
(2)AT24C02的读操作
AT24C02的读操作可分为立即地址读、选择性读和连续读。
①立即地址读。
AT24C02的地址计数器内容为最后操作字节的地址加1。
也就是说,如果上次读/写的操作地址为N,则立即读的地址从地址N+1开始。
如果N=255,则计数器将翻转到0且继续输出数据。
因为AT24C02的存储容量是256字节。
AT24C02接收到从机地址信号后,R/W位置1,它首先发送一个应答信号,然后发送一个8位字节数据。
主机不需发送一个应答信号,但要产生一个停止信号。
立即地址读时序如图5-14所示。
图5-14立即地址读时序
②选择性读
选择性读操作允许主机对AT24C02寄存器的任意字节进行读操作。
主机首先通过发送起始信号、从机地址和它想读取的字节数据的地址,执行一个伪写操作。
在AT24C02应答之后,主机重新发送起始信号和从机地址,此时R/W位置1,AT24C02响应并发送应答信号,然后输出所要求的一个8位字节数据,主器件不发送应答信号但产生一个停止信号。
选择性读时序如图5-15示。
图5-15选择性读时序
③连续读
连续读操作可通过立即读或选择性读操作启动。
在AT24C02发送完一个8位字节数据后,主机产生一个应答信号来响应,告知AT24C02主器件要求更多的数据,对应每个主机产生的应答信号,AT24C02将发送一个8位数据字节。
当主机不发送应答信号而发送停止信号时结束此操作。
从AT24C02输出的数据按顺序由N到N+1输出。
读操作时地址计数器在AT24C02整个地址内增加,这样整个寄存器区域在可在一个读操作内全部读出。
当读取的字节超过255,计数器将翻转到零并继续输出数据字节。
连续读时序如图5-16所示。
图5-16连续读时序
5.3电子密码锁模块设计
5.3.1目标要求
电子密码锁模块的设计要实现以下功能:
(1)首次开机进行6位密码初始化;
(2)用户可以进行6位密码的修改;
(3)用户输入密码正确按开锁键则开锁;
(4)用户输入密码错误则有提示和报警。
5.3.2问题分析
(1)用户设置密码存放E2PROM24C02中,要弄清24C02的工作原理,编写24C02的多字节读写程序;
(2)密码输入采用4×4行列式键盘,掌握行列式键盘的扫描处理方法;
(3)用户修改密码的时候要进行用户权限的确认。
5.3.3硬件设计
1)电子密码锁模块原理图
电子密码锁模块原理图如图5-17。
图5-17电子密码锁模块原理图
2)电子密码锁模块的主要元器件清单
电子密码锁模块主要元件清单见表5-5。
表5-5电子密码锁模块主要元件清单
元器件名称
参数
数量
元器件名称
参数
数量
单片机
STC89C52
1
排阻
10k
1
IC
AT24C02
1
电位器
10k
1
液晶
1602
1
按钮
-
17
晶振
12MHz
1
电解电容
10uF/16v
1
LED
-
1
瓷片电容
30pF
2
5.3.4软件编程
1)端口分配
密码输入采用4×4行列式键盘,通过单片机STC89C52的P2进行键盘的行列扫描;显示采用1602字符型液晶,P1.0接片选端RS,P1.1接读写选择端R/W,P1.2接使能端E;AT24C02的SDA(串行数据线)接P3.3,SCL(串行时钟线)接P3.2;P1.5口控制LED。
2)程序流程
电子密码锁模块程序主要包括主程序(如图5-18)、AT24C02写多字节数据子程序(如图5-19)、AT24C02读多字节数据子程序(如图5-20),具体如下:
图5-18电子密码锁模块主程序
图5-19AT24C02写多字节数据子程序图5-20AT24C02读多字节数据子程序
2)具体程序
#include
#include
#include
#defineDelay4us();{_nop_();_nop_();_nop_();_nop_();}
#defineucharunsignedchar
#defineuintunsignedint
ucharPre_KeyNo=16,KeyNo=16;
ucharcodeTitle_Text[]="YourPassword...";
charDSY_BUFFER[16]="";
charUserPassword[16]="";
sbitLCD_RS=P1^0;
sbitLCD_RW=P1^1;
sbitLCD_EN=P1^2;
sbitLED_OPEN=P1^5;
sbitSCL=P3^2;
sbitSDA=P3^3;
/*********函数功能:
延时若干毫秒入口参数:
x*********/
voidDelaynms(uintx)
{
uchari;
while(x--)
for(i=0;i<123;i++);
}
/***************关于24C02的程序*******************/
/***************24C02启动信号*******************/
voidStart()
{
SDA=1;
SCL=1;
Delay4us();
SDA=0;
Delay4us();
SCL=0;
}
/***************24C02停止信号*******************/
voidStop()
{
SDA=0;
SCL=1;
Delay4us();
SDA=1;
Delay4us();
SCL=0;
}
/***************24C02IIC初始化*******************/
voidIIC_Init()
{
SCL=0;
Stop();
}
/***************24C02发送应答信号*****************/
voidACK()
{
SDA=0;
SCL=1;
Delay4us();
SCL=0;
SDA=1;
}
/***************24C02发送非应答信号*******************/
voidNO_ACK()
{
SDA=1;
SCL=1;
Delay4us();
SCL=0;
SDA=0;
}
/***************从24C02读取1字节*******************/
ucharRecByte()
{
uchari,rd;
rd=0x00;
SDA=1;
for(i=0;i<8;i++)
{
SCL=1;
rd<<=1;
rd|=SDA;
Delay4us();
SCL=0;
Delay4us();
}
SCL=0;
Delay4us();
returnrd;
}
/***************向24C02发送1字节*******************/
ucharSendByte(ucharwd)
{
uchari;
bitack0;
for(i=0;i<8;i++)
{
SDA=(bit)(wd&0x80);
_nop_();
_nop_();
SCL=1;
Delay4us();
SCL=0;
wd<<=1;
}
Delay4us();
SDA=1;
SCL=1;
Delay4us();
ack0=!
SDA;
SCL=0;
Delay4us();
returnack0;
}
/***************向24C02发送多个字节*******************/
ucharSendString(ucharSlave,ucharSubaddr,uchar*Buffer,ucharN)
{
uchari;