1、数字电子密码锁一、 设计目的与要求:目的:掌握矩阵式键盘的工作原理、设计方法;掌握译码器的应用;掌握状态机的设计方法,掌握数码管的控制。要求:设计一个数字电子密码锁,密码为3 位,密码锁由键盘控制,显示采用数码管及LED灯。功能:1、 密码输入:每按下一个数字键,要求在数码管上显示,并依次左移;输入错误时,按退格键,清除前一个输入的数字;输入完毕,按确认键。2、 开锁:按开锁键,检查输入的密码是否正确,正确才开锁,成功。3、 上锁:按上锁键,可以直接上锁或者设定新密码上锁。 4、 密码修改:按下修改键,必须先核对原密码,正确后可以输入3位数字,设为新的密码。5、 报警:开锁输入密码,连续错误三
2、次,则禁止输入密码,并发出报警信号,用红灯一直亮表示。6、 解除报警:按复位键,解除报警状态,实际应用中复位键设置在其他部位,不可设置在键盘上。7、 万能密码:电锁维护者使用,在程序中暂时统一设置为999。8、 其他要求:输入键盘为矩阵式,不使用直接式;条件允许时可以使用语音模块代替指示灯的表示。二、 电路组成:为达到以上功能,可将数字电子密码锁分为以下几个模块:1、键盘接口电路:键盘矩阵、键盘扫描、键盘消抖、键盘译码及按键存储。2、密码锁控制电路:数字按键输入、存储及清除;功能按键的设计:退格键、确认键、开锁键、上锁键、修改键、解除报警键;密码清除、修改与存储。密码锁的上锁与开锁。3、输出显
3、示电路BCD译码、动态扫描电路、指示灯电路(或者为语音控制电路)。三、功能电路的设计:1、键盘接口电路:图1(1)矩阵式键盘工作原理:矩阵式键盘是一种常见的输入装置,在计算机、电话、手机、微波炉等各工电子产品中被广泛应用。如图2所示为一44 矩阵式键盘。矩阵式键盘以行、列形式排列,图中为4 行4 列,键盘上的每一个按键盘其实是一个开关电路,当某键被按下时,该按键所对应的位置就呈现逻辑0的状态,键盘的扫描可以以行扫或列扫方式进行,图中为行扫方式,KEYR3 KEYR0 为扫描信号,其中的某一位为0即扫描其中的一行,具体见表1。7 8 9开 锁 键4 5 6上 锁 键1 2 3密 码 修 改 键0
4、#退格键确 认 键清 抖 电 路 键 盘 译 码 按 键 存 储键 盘 扫 描图1C P L D7 8 9开 锁 键4 5 6上 锁 键1 2 3密 码 修 改 键0#退格键确 认 键经 上 拉 电 阻 接 V C C图 2K E Y C 3 . . 0K E Y R 3 . . 0键盘扫描表1 键盘扫描与其对应的键值的关系KEYR3.0 KEYC3.0 对应的按键 KEYR3.0 KEYC3.0 对应的按键0111 7 0111 11011 8 1011 21101 9 1101 301111110 开锁键11011110 密码修改键0111 4 0111 01011 5 1011 #110
5、1 6 1101 退格键10111110 上锁键11101110 确认键键盘扫描信号KEYR3与第一行相连,KEYR2与第二行相连,依此类推。很显然,扫描信号的变化顺序为:0111、1011、1101、1110,周而复始。在扫描的过程中,当有键按下时,对应的键位就为逻辑0 状态,从而从KEYC3.0 读出的键值相应列为0,具体情况如表1 所示。若从KEYC3.0 读出的值全为 1 时,表示没有键被按下,则不进行按键的处理。如果的键被按下,则将KEYC3.0 读出的送至键盘译码电路进行译码。(2)时钟产生电路在一个系统的设计中,往往需要多种时钟信号,最方便的方法是利用一个自由计数器来产生各种需要
6、的频率。本电路需要:系统主时钟CLK、扫描状态产生时钟clkouta和动态扫描时钟clkoutb,其中系统主时钟CLK为输入时钟,由20MHZ 晶振产生。程序清单:LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL ;USE IEEE.STD_LOGIC_UNSIGNED.ALL ;ENTITY clkdiv ISPORT (CLK: IN STD_LOGIC ;clkouta,clkoutb: OUT STD_LOGIC);END clkdiV ;ARCHITECTURE rtl OF clkdiV IS
7、SIGNAL CLKA:STD_LOGIC;BeginPROCESS (CLK)VARIABLE S:INTEGER RANGE 200 DOWNTO 0;BeginIF CLKEvent AND CLK=1 thenIF SSCAN_OUTSCAN_OUTSCAN_OUTSCAN_OUTSCAN_OUT=“1000“THENCOUNTout_numbout_numbout_numbout_numbout_numbout_numbout_numbout_numbout_numbout_numbout_numbout_numbout_numbout_numbout_numbout_numb= “
8、1111“ ;end case ;END IF ;end process ;END a;说明:键盘译码电路根据键盘输入数据d_IN和扫描状态S进行译码out_numb,数字键为:0、1、2、3、4、5、6、7、8、9,功能键为:退格键、确认键、修改键、上锁键和解锁键,out_numb=“1111”表示无任何操作。仿真波形:(6)按键存储电路键盘译码后,可以看出,译码值不等于“1111” 时表示有按键动作发生,当译码值等于长时间“1111”时,表示无按键动作发生,所以可以根据译码值产生按键动作发生的标示信号和按键的译码值。程序清单:LIBRARY ieee;USE ieee.std_logic_
9、1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL ;USE IEEE.STD_LOGIC_UNSIGNED.ALL ;ENTITY num_or_fun_DEC ISPORT (clkSCAN : IN STD_LOGIC ;in_num: IN STD_LOGIC_VECTOR (3 downto 0);change_clk: out STD_LOGIC;out_num : OUT STD_LOGIC_VECTOR(3 downto 0);END num_or_fun_DEC ;-*ARCHITECTURE a OF num_or_fun_DEC ISsignal
10、temp_num:STD_LOGIC_VECTOR(3 downto 0);BEGINPROCESS(clkSCAN)variable count,counta:std_logic_vector(2 downto 0);beginIF CLKSCANEVENT AND CLKSCAN = 1 THENif in_num=“1111“thenif count7 then count:=count+1;else change_clk=0;count:=“111“;counta:=“000“;end if; elsetemp_num=in_num;count:=“000“;if(counta3)th
11、encounta:= counta+1;elsecounta:=“011“;change_clk=1; end if;end if;END IF ;end process ;out_num=temp_num;END a;说明:当按键译码值in_num不等于“1111”时,按键发生标示信号change_clk=1 ,按键译码输出值out_num等于按键译码值。仿真波形:2、电锁控制电路设计电锁控制电路是整个电路的控制中心,主要完成如下功能:1、 数字按键输入部分如果输入数字键,第一个数字会从显示器的最右端开始显示,此后每新按一个数字时,显示器上的数字必须往左移动一位。若想要更改输入的数字,可按退
12、格键来清除前一个输入的数字,或按清除键清除输入的所有数字,再重新输入3位数字。既然设计的是三位电子密码锁,当输入的数字键超过3 位时,电路不应理会。2、 功能键输入部分退格键:清除前一个输入的数字,如果数字全部清除,则回到前一个状态(例如上锁或者解锁等)。密码核对:在密码更改,开锁之前必须先核对密码。密码修改:按下此键先输入原密码,核对后将新输入的数字设定为新的密码。上锁:按上锁键可以直接上锁。解锁:检查输入的密码是否正确,正确才开锁。万用密码:电锁维护者使用。程序清单:三位电子密码锁LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE IEEE.STD_L
13、OGIC_ARITH.ALL ;USE IEEE.STD_LOGIC_UNSIGNED.ALL ;ENTITY control ISPORT (reset,d_clk:in std_logic;d_in: IN STD_LOGIC_VECTOR (3 downto 0); led_alarm:out std_logic;led_flag,leda,ledb,ledc: inout STD_LOGIC_VECTOR (3 downto 0);END control ;-*ARCHITECTURE a OF control ISTYPE STATE_TYPE IS (lock_idle,lock,
14、unlock_idle,unlock,modify,new_num,alarm,num_one,num_two,num_three);SIGNAL state: STATE_TYPE;signal lock_rega,lock_regb,lock_regc:std_logic_vector(3 downto 0);signal locked,unlock_modify_flag:std_logic;BEGINPROCESS (reset,state,d_in,d_clk)variable alarmcnt:std_logic_vector(1 downto 0);BEGINif reset=0 then