一、概述
1.1 电子密码锁的现状
随着我国对外开放的不断深入,高档建筑发展很快,高档密码锁具市场的前景乐观。我国密码锁具行业对密码锁具高新技术的投入正逐年增大,高档密码锁的市场需求也逐年增加。在安防工程中,锁具产品是关系到整个系统安全性的重要设备,所以锁具产品的优劣也关系了整个安防工程的质量和验收。
目前,市场上比较先进的智能电子密码锁分别有:IC卡电子密码锁、射频卡式电子密码锁、红外遥控电子密码锁、指纹识别电子密码锁和瞳孔识别电子密码锁等。IC卡电子密码锁成本低,体积小,卡片本身无须电源等优点占领了一定的市场份额,但是由于有机械接触,会产生接触磨损,而且使用不太方便,在一定程度上限制了它的应用;射频卡式电子密码锁是非接触式电子密码锁,成本也不太高,体积跟IC卡密码锁相当,卡片使用感应电源,重量很轻,技术成熟,受到了广泛的欢迎,但是与IC卡电子密码锁相比,成本偏高;指纹识别电子密码锁和瞳孔识别电子密码锁可靠性很高,安全性是目前应用系统中最高的,但是成本高昂,还没进入大众化使用阶段。
在国外,美国、日本、德国的电子密码锁保密性较好,并结合感应卡技术,生物识别技术,使电子密码锁系统得到了飞跃式的发展。这几个国家的密码锁识别的密码更复杂,并且综合性比较好,已经进入了成熟期,出现了感应卡式密码锁,指纹式密码锁,虹膜密码锁,面部识别密码锁,序列混乱的键盘密码锁等各种技术的系统,它们在安全性,方便性,易管理性等方面都各有特长,新型的电子密码锁系统的应用也越来越广。
基于FPGA的电子密码锁是新型现代化安全管理系统,它集微机自动识别技术和现代安全管理措施为一体,它涉及电子,机械,计算机技术,通讯技术,生物技术等诸多新技术。它是解决重要部门出入口实现安全防范管理的有效措施,适用各种场合,如银行、宾馆、机房、军械库、机要室、办公间、智能化小区、工厂、家庭等。
在数字技术网络技术飞速发展的今天,电子密码锁技术得到了迅猛的发展。它早已超越了单纯的门道及钥匙管理,逐渐发展成为一套完整的出入管理系统。它在工作环境安全、人事考勤管理等行政管理工作中发挥着巨大的作用。在该系统的基础上增加相应的辅助设备可以进行电梯控制、车辆进出控制,物业消防监控、餐饮收费、私家车库管理等,真正实现区域内一卡智能管理。
目前使用的电子密码锁大部分是基于单片机技术, 以单片机为主要器件,
其编码器与解码器的生成为软件方式。在实际应用中, 由于程序容易跑飞, 系统的可靠性能较差。基于FPGA的电子密码锁已经是现代生活中经常用到的工具之一,用于各类保险柜、房门、防盗门等等。用电子密码锁代替传统的机械式密码锁,克服了机械式密码锁密码量少、安全性能差的缺点。由于采用的是可编程逻辑器件FPGA,使得系统有相当大的灵活性,随时可以进行硬件升级、扩展,而且系统设计完善以后还可以将主控的FPGA固化成一片ASIC,那么这块ASIC就可以作为专用的数字密码锁芯片。而且由于硬件可升级,还可随时增加密码位数或增加新的功能,使得密码锁有更高的安全性、可靠性和方便性。
1.2 论文主要完成的工作
课题主要解决系统硬件和软件两方面的问题。硬件方面要解决FPGA可编程器件与其外围电路的接口设计的问题;软件方面主要问题是利用Verilog HDL 语言完成基于FPGA的电子密码锁的编程问题。除此之外,程序还要完成基本的密码开锁功能,并通过扬声器长时间鸣叫报警。本设计是由FPGA可编程逻辑器件编程实现的控制电路,具体有按键指示、输入错误提示、密码有效指示、控制开锁、控制报警等功能。它具有安全可靠、连接方便、简单易用、结构紧凑、系统可扩展性好等特点。
二、系统硬件设计
2.1 系统设计方案
2.1.1 系统功能需求分析
本系统主要集中在以FPGA以核心外围扩展设计,整个电路主要电子锁具的组成框图是以可编程逻辑器件(FPGA)为核心,配以相应硬件电路,设计一个密码锁,密码为一个4位的十进制数,密码固化在锁内,用户输入密码正确,则开锁(绿灯亮);若不正确,则报警(红灯亮)若用户输入密码不正确,可以按复位键重新输入密码。
2.1.2 系统实现方案的论证比较
方案一:采样台湾凌阳科技有限公司推出的以凌阳自主研发的SPCE061A 芯片为主控芯片,用一条下载线连接到计算机就可以实现在线仿真、在线调试、在线下载,低廉的价格保证了系统可靠开发;此外,61板具有SOC概念、DSP 功能和语音特色,为电子密码锁的语音报警提供了方便,但是基于单片机设计的
密码锁外围电路比较复杂,系统可靠性差,密码的数量少,尤其是系统的程序不够稳定,功率较大,需要专门的电源供电,所以不采用这个方案。
方案二:设计一种基于FPGA的电子密码锁的设计,用FPGA设计的系统已经是现代生活中经常用到的工具之一,通过键盘输入密码,用FPGA作为主控芯片,用数码管显示输入的数字,如果出现错误便通过报警电路发出报警,主控芯片又可分为按键处理部分、控制部分和译码显示部分用电子密码锁代替传统的机械式密码锁。由于采用的是可编程逻辑器件FPGA,使得系统有相当大的灵活性,随时可以进行硬件升级、扩展。而且系统设计完善以后还可以将主控的FPGA固化成一片ASIC,那么这块ASIC就可以作为专用的数字密码锁芯片。
方案的论证比较
在实际应用中, 由于程序容易跑飞, 系统的可靠性能较差,而基于FPGA设计的电子密码锁克服了基于单片机设计密码锁的缺点。基于上述比较以上两种方案,根据系统设计要求,采用方案二。
2.1.3 系统方案的总体设计
系统原理框图
本系统由主控芯片(FPGA),键盘,显示电路,报警电路和开/关门电路组成,而主控芯片又可分为按键处理部分,控制部分和译码显示部分。系统原理框系统原理框图如图2.1.3所示:
图2.1.3 系统总体框架
总体设计原理
本系统有8个按键,K0,K1,K2,K3,K4,K5代表数字0-9共10个数字和1个确认键,1个复位键。密码长度为四位,并且固化在锁内,输入正确密码后,
按确认键即可开门,本系统设置为绿灯亮。在输入密码的过程中,当用户键入错误密码时,报警灯红灯亮。按下复位键,可使报警停止,同时清除所有密码显示。每输入一位数字,密码在数码管上的显示左移一位。即上电后,按确认键即可开门。门开后可通过锁门按钮关门,门关上后要再次输入密码才能开门。在输入密码的过程中,当用户键入错误密码时,系统就会报警,由扬声器发出报警声,当连续三次出现密码错误时,则系统会长时间报警不止,这时必须按警报复位键方可停止。
2.2 主控模块
2.2.1 主控芯片EP4CE6E22C8的介绍
主控芯片采用ACEX1K 系列的EP4CE6E22C8。Cyclone IV系列是当今Altera CPLD 中应用前景最好的器件系列之一,该系列的FPGA 由逻辑阵列块LAB (Logic array block)、嵌入式阵列块EAB(embedded array block)、快速互联以及IO 单元构成,每个逻辑阵列块包含8 个逻辑单元LE(logic element)和一个局部互联。每个逻辑单元则由一个4 输入查找表(LUT)、一个可编程触发器、快速进位链、级连链组成,多个LAB 和多个EAB 则可通过快速通道互相连接[3]。EAB 是Cyclone IV系列器件在结构设计上的一个重要部件,他是输入端口和输出端口都带有触发器的一种灵活的RAM 块,其主要功能是实现一些规模不太大的 FIFO、ROM、RAM 和双端口RAM 等。
2.3 键盘模块
按键方式分为8个独立按键,K0,K1,K2,K3,K4,K5代表数字0-9共10个数字和1个确认键,1个复位键。考虑到按键数目不够,采用了一位按键作为功能转换按键;即前5位按键输入0~4,同时按下功能转换按键时,按键0~4即转换为按键5~9,这就弥补了按键数目的不足。最后两位按键设定为确认输入按键和复位按键。密码输入完成后可以按确认键检验密码的正误,报警、输入错误或者其他情况可以按复位按键重新输入。按键上拉,当IO口被拉高电平,当IO口检测到高电平时,表示按键按下。部分按键控制电路如图2.3所示:
图2.3
2.4 显示模块
LED显示块是由发光二极管显示字段的显示器件。在单片机应用系统中通常使用的是7段LED,本设计将采用共阳极。共阳极LED显示块的发光二极管与阳极并接。
数码管显示块中共有8个发光二极管,其中7个发光二极管构成七笔字形“8”,1个发光二极管构成小数点。7段显示块与FPGA接口非常容易。只要将一个8位并行输出与显示块的发光二极管引脚相连即可。8位并行输出口输出不同的字节数据即可获得不同的数字或字符,如表5.1所示。通常将控制发光二极管的8位字节数据称为段选码。共阳极与共阴极的段选码互为补数。
表2.4 LED显示块功能表
三、芯片主控设计
3.1 FPGA有限状态机
本设计是通过FPGA有限状态机来实现,设计有限状态机最开始的工作时要确定电路,包括哪些状态,比如某个电路包括四个状态,S0,S1,S2,S3。然后对所有状态给出一个状态编码,比如为状态S0赋予编码00,为状态S1赋予编码01,为状态S2赋予编码10,为状态S3赋予编码11。状态编码是状态的标识,保存在寄存器当中,对于此编码形式,只需一个2位的寄存器就可以了。
FSM Encoding Style 主要有: Binary Encoding One Hot Encoding Gray Encoding
二进制与一位热码的特性比较:
表3.1 二进制与一位热码的特性比较
状态机可以认为是组合逻辑和寄存器逻辑的特殊租户,它一般包括两个部分:组合逻辑部分和寄存器逻辑部分。寄存器用于存储状态,组合电路用于状态译码和产生输出信号。状态机的下一个状态及输出,不仅与输入信号有关,而且还有寄存器当前所处的状态有关。
根据输出信号产生方法的不同,状态机可以分成两类:Mealy型和Moore型。Moore型状态机的输出只是当前状态的函数,而Moore型状态机的输出只是当前状态的函数,而Mealy型状态机的输出则是当前状态和当前输入状态的函数。其
原理如下两图:
3.2 设计流程
本次密码锁的设计,有限状态机应该包括以下状态:密码为输入前的等待状态、输入密码时的等待状态、输入密码正确时的通过状态、输入密码错误时的警报状态。
图3.3 主有效状态机的状态转换图
其中当密码输入时又可包括以下状态,正常输入状态、异常输入状态(包括命令状态)、输入确认状态。
下面的图(图是在程序编译后,tools->Netlist_Vewers->RTL Vewer得到的)表示了密码输入的时候的次状态机,表示了4个密码输入的顺序状态,以及输入完成后的等待确认状态。
图3.4次有效状态机的状态转换
3.3 系统软件设计总RTC级图
3.4 状态编码
状态编码主要有二进制编码、格雷编码和一位独热编码等方式。格雷编码时,相邻状态每次只有一个比特位产生变化,这样减少了瞬变的次数,也减少了产生毛刺和一些状态的可能。
采用一位独热编码,虽然多用了触发器,当可以有效节省和简化组合电路。对于寄存器数量多而逻辑相对缺乏的FPGA器件来说,采用一位独热编码可以有效提高电路的速度和可靠性,也有利于提高器件资源的利用率。
将产生状态的组合逻辑电路和用于保存状态的寄存器分别写在不同的
always块中。其中主要包括:输出控制部分、警报计时部分、锁打开后的计时部分、比较密码部分、记录密码部分和记录错误次数的部分
3.5 密码的输入
本次密码锁的密码输入采用FPGA芯片上的8位单个按键,考虑到按键数目不够,采用了一位按键作为功能转换按键;即前5位按键输入0~4,同时按下功能转换按键时,按键0~4即转换为按键5~9,这就弥补了按键数目的不足。最后两位按键设定为确认输入按键和复位按键。密码输入完成后可以按确认键检验密码的正误,报警、输入错误或者其他情况可以按复位按键重新输入。
另外由于按键的时候同时会引起状态机的转换,所以如果按键的时候对按键判断次数过多会产生状态的过快转换,记录的密码和数码管的显示就同时会出现错误,因此在按键部分加入了消除多重按键的程序,只检测一次按键的下降沿,解决了这个问题。
3.6 密码的记录与比较
程序设定了一个寄存器用来记录输入的密码。当次有效状态机(即密码输入的状态机)发生转换并且有密码输入时,程序会记录下输入的密码在寄存器的其中4位里面,最后次有效状态转换到确认密码的状态时,会将记录下的密码与固化在锁内的密码进行对比,正确即将主状态机转换到通过阶段,错误则将状态机转换到报警阶段。其中正确错误的状态转换是通过控制相应的标志位实现的。
3.7 密码的显示
密码显示采用数码管动态扫描显示,初始时显示密码为4位0,当输入密码后数码管的第一位、第二位、第三位、第四位会依次显示输入的密码,错误后复位可以重新输入。密码显示采用的是记录密码的寄存器的数据,显示扫描的扫描时间设置为1ms左右,这样显示不会出现闪烁或者残影。
四、程序仿真
下前面的输入cmd的编码:
//输入的数字编码 0~9,enter,cancel
one=4'b0001, two=4’b0010,three=4'b0011,four=4'b0100,five=4'b0101, six=4'b0110,seven=4'b0111,eight=4'b1000,nine=4'b1001,
zero=4'b1000,enter=4'b1010,cancel=4'b1011;
可以看到,在复位以后,输入第1,2,3,4个密码(依次为1111)后,passed 变成高电平
当过了一定的时间后,passed变成低电平,重新计入键盘读入值,进行下一轮的密码辨别。
五、结论
本次课题设计完成的是基于FPGA的密码锁设计,通过一个多星期的不断努力、克服各种困难,最终实现了任务目标。本次设计解决的主要问题是是利用verilog HDL语言完成基于FPGA的电子密码锁的编程问题。
设计是理论知识与实践的完美结合,对于现代大学生的实践能力是个很好的培养。
短短的一个星期的时间的设计虽然短暂,但是它给我的收获确实难忘,不仅仅在智能仪器方面有了很大的进步,而且在FPGA、Quartus软件等方面也学到了不少在上课学不到的知识。这段时间我查阅到很多关于课程设计的书籍,对我帮助也很大。我觉得自己以前的盲目,现在明白了很多。也对我们专业动手实践的兴趣提高了很多。有了这些经历对于我日后工作一定会有很大帮助。相信这次设计中学到的种种东西一定会存在我的脑海里,令我终身受益。
在课程设计的过程中也可以看到我的不足,如原理知识掌握不实,曾经学过的知识如今却不会应用,软件的应用也不熟练,希望日后提供给我们更多的锻炼机会来培养我们的实践能力。
参考文献
[1] 高移南.遥控变号电子锁[J].电子世界,1994,07:15
[2] 许琦.基于FPGA 的电子密码锁设计[J ]. 中国科技信息, 2007 (1) : 240-241
[3] 刘韬,楼兴华.FPGA数字电子系统设计与开发实例导航[M].人民邮电出版社,2005.
[4] 王金明.数字系统设计与Verilog HDL
附录
程序清单:
module passwd_lock(
clk0, //时钟 pin_23
passed, //开锁灯与警报灯
zero1, //按键0 pin_84
one1, //按键1 pin_85
two1, //按键2 pin_86
three1, //按键3 pin_87
four1, //按键4 pin_88
change, //功能选择键pin_89
yes, //确认按键pin_90
resetb, //重输按键pin_91
seg, //数码管段选【7:0】
dig //数码管位选【3:0】
);
input one1,two1,three1,four1,zero1,change;
reg zero,one,two,three,four;
input yes;
input resetb;
input clk0; //输入时钟信号
output [7:0] passed; //输出信号 //为何要是8位??实际只用了2位
//output [1:0] passed; //输出信号
output [7:0] seg;//////段选
output [3:0] dig;//////位选
reg [3:0] key; //按键存储器
reg RXBuf0,RXBuf1,RXBuf2,RXBuf3,RXBuf4; //缓存器,可用于按键消抖
//display
reg clk0_div;
reg [2:0] digyi;////////////哪一位亮,用于数码管数字移位
reg [3:0] dig;/////////////位选
reg [3:0] seg0;/////////////存储按键按下的数字
reg [7:0] seg; /////////段选
reg [12:0] CNT_R0;
reg [18:0] CNT_R1;
reg clk1;
reg [21:0] CNT_R2;
reg clk2;
reg [7:0] passed; //pass 8b'1000 0000 alarm 8b'0000 0001 waits
8b'0000 0000
/*输入与输出的声明部分,其中,clk0为输入的时钟信号,resetb为密码复位的输入信号,
key为输入命令,
需注意的时,key并不是总在表示密码,也表示密码的间隔,如当输入4位密码后需要一个确认“enter”信号,
当密码输入错误时,需要取消“cancel”信号,这些信号之间在设计中通过有限状态转换机
实现。*/
parameter PASSWORD=16'b0001001100010100;//盛放密码的参数
reg [15:0] password;//输入数值盛放寄存器
//输入的数字编码
always @( posedge clk1 ) begin //检测线路的下降沿
RXBuf1 <= one1;
one <= ~(RXBuf1 & ( ~one1 ));
// RXFall1<=RXFall;
end
//消除多重按键
always @( posedge clk1 ) begin //检测线路的下降沿
RXBuf0 <= zero1;
zero <= ~(RXBuf0 & ( ~zero1 ));
// RXFall1<=RXFall;
end
//消除多重按键
always @( posedge clk1 ) begin //检测线路的下降沿
RXBuf2 <= two1;
two <= ~(RXBuf2 & ( ~two1 ));
// RXFall1<=RXFall;
end
//消除多重按
always @( posedge clk1 )
begin //检测线路的下降沿
RXBuf3 <= three1;
three <= ~(RXBuf3 & ( ~three1 ));
// RXFall1<=RXFall;
end
//消除多重按键
always @( posedge clk1 )
begin //检测线路的下降沿
RXBuf4 <= four1;
four <= ~(RXBuf4 & ( ~four1 ));
// RXFall1<=RXFall;
end
//消除多重按键
reg [2:0] main_state;//主状态
reg [2:0] next_state;//下一个状态
//主有限状态转换机的三个状态:waits、pass、alarm
parameter waits=3'b001, pass=3'b010, alarm=3'b100; //3个状态编码
reg [2:0] sub_state; //从状态机现状态
reg [2:0] next_sub_state; //从状态机下一个状态
//从有限状态转换机的五个状态:first、second、third、fourth、finish parameter
first=3'b000,second=3'b001,third=3'b010,fourth=3'b011,finish=3'b100;
//通过计时寄存器
reg [7:0] pass_count; //pass计时完后回到wait状态
//警报计时寄存器
reg [10:0] alarm_count; //alarm计时完后回到wait状态
//尝试次数寄存器
reg [1:0] try_count;
//输入状态寄存器:error和correct
reg error;
reg correct;
reg key_pressed_flag; // 键盘按下标志
//以上为中间状态的一些寄存器和一些所用到的参数
//主机状态机部分
always @(posedge clk0)
begin
CNT_R2 <= CNT_R2 + 1'b1;
if(CNT_R2 < 4000000)
begin
clk1 <= 1;
end
else
begin
clk1 <= 0;
end
end
always@(main_state or correct or error) //3位主状态寄存器,1位输入状态寄存器correct,error
case(main_state) //判断主状态寄存器
waits: //3b'001
if(correct==1) begin//由waits转换到pass的条件
next_state=pass; end//3位next_state寄存器写入等待状态
else if(error==1&&try_count==1) begin
next_state=alarm; end//由waits转换到alarm的条件
else begin
next_state=waits; end
pass:
if(pass_count[7]==1) begin//由pass转换到waits的条件计时器时间到,由通过状态变成等待状态
next_state=waits; end
else begin
next_state=pass; end
alarm:
if(alarm_count[10]==1) begin// 由alarm转换到waits的条件警告时间到达时变成等待状态
next_state=waits; end
else begin
next_state=alarm;end//否则继续警告
default://默认状态:waits
next_state=waits;
endcase
end
//状态转换
always@(posedge clk1 or negedge resetb)
begin
if(!resetb)
main_state<=waits;
else
main_state<=next_state;
end
//输出控制部分
always@(posedge clk1 or negedge resetb)
begin
if(!resetb)//复位时,开锁输出与警报输出都为零
begin
passed<=8'b10000001;
//passed<=2b'11;
else if(main_state==pass)//当主机状态为pass时,开锁
begin
passed<=8'b00000001;
//passed<=2'b01;
end
else if(main_state==alarm)//当主机状态为alarm时,警报
begin
passed<=8'b10000000;
//passed<=2'b10;
end
else//其它状态复位
begin
passed<=8'b10000001;
//passed<=2b'11;
end end
//alarm一段时间后,自动进入waits状态
//alarm定时器
always@(posedge clk1 or negedge resetb)
begin
if(!resetb)
alarm_count<=0;
else if(main_state==alarm)//alarm状态计时器alarm定时器加1
alarm_count<=alarm_count+1;
else
alarm_count<=0;
end
//锁pass以后计数开始,当规定的时间到达后自动上锁,并进入waits状态//pass定时器
always@(posedge clk1 or negedge resetb)
begin
if(!resetb)
pass_count<=0;
else if(main_state==pass) //pass状态计时器pass定时器加1
pass_count<=pass_count+1;
else
pass_count<=0;
end
//从状态机,用于输入4位密码
always@(posedge clk1 or negedge resetb)
begin
if(!resetb)
sub_state<=first;
else
sub_state<=next_sub_state;
end
always@(!zero||!one||!two||!three||!four||!yes or sub_state)
//always@(key or sub_state)
begin
if(key_pressed_flag||!yes)
if(!yes)//4个密码输完时,进行确认
next_sub_state=first;
//default为输入了某位密码,输入完自动将状态转入下一位
else if (!zero||!one||!two||!three||!four) //zero1,one1,two1,three1,four1
case(sub_state)
first:
next_sub_state=second;
second:
next_sub_state=third;
third:
next_sub_state=fourth;
fourth:
next_sub_state=finish;
//当输入完4位密码以后状态保持不变,等待输入enter命令
finish:
next_sub_state=finish;
default: next_sub_state=sub_state;
endcase
else
next_sub_state=sub_state;
end
//比较密码,产生正确或者错误信息
always@(posedge clk1 or negedge resetb)
begin
if(!resetb) begin
correct<=0;
error<=0;
end
else if(!key_pressed_flag&&!yes)
if(password==PASSWORD)//密码正确时
begin
correct<=1;
error<=0;
end
else//密码错误时
begin
error<=1;
correct<=0;
end
else begin
correct<=0;
error<=0;
end
end
//记录密码
always@(posedge clk1 or negedge resetb)
begin
if(!resetb) begin
password<=0;
end
else if(!zero||!one||!two||!three||!four) begin case(sub_state)
first:
password[15:12]<=key;
second:
password[11:8]<=key;
third:
password[7:4]<=key;
fourth:
password[3:0]<=key;
default:
password<=password;
endcase
end
else begin
password<=password;
end
end
//记录错误次数
always@(posedge clk1 or negedge resetb)
begin
if(!resetb) begin
try_count<=0;