电子密码锁 密码锁输入电路程序
--KEYBOARD.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY KEYBOARD IS
PORT(CLK_1K:IN STD_LOGIC; --系统原始时钟脉冲(1 kHz)
KEY_IN:IN STD_LOGIC_VECTOR(2 DOWNTO 0);--按键输入
CLK_SCAN:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--仿真时用键盘扫描序列
DATA_N:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--数字输出
DATA_F:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--功能输出
FLAG_N:OUT STD_LOGIC;
FLAG_F:OUT STD_LOGIC;
CLK_CTR:OUT STD_LOGIC;
CLK_DEBOUNCE:OUT STD_LOGIC
);
END ENTITY KEYBOARD;
ARCHITECTURE ART OF KEYBOARD IS
COMPONENT DEBOUNCING IS
PORT(D_IN:IN STD_LOGIC;
CLK:IN STD_LOGIC;
D_OUT:OUT STD_LOGIC);
END COMPONENT DEBOUNCING;
SIGNAL CLK:STD_LOGIC; --电路工作时钟脉冲
SIGNAL C_KEYBOARD:STD_LOGIC_VECTOR(1 DOWNTO 0);--键扫信号“00-01-10-11”寄存器
SIGNAL C_DEBOUNCE:STD_LOGIC; --去抖时钟信号
SIGNAL C:STD_LOGIC_VECTOR(2 DOWNTO 0); --键盘输入去抖后的寄存器
SIGNAL N,F:STD_LOGIC_VECTOR(3 DOWNTO 0); --数字、功能按键译码值的寄存器
SIGNAL FN,FF:STD_LOGIC; --数字、功能按键标志值数字、功能按键
SIGNAL SEL:STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
--内部连接
DATA_N<=N;
DATA_F<=F;
FLAG_N<=FN;
FLAG_F<=FF;
CLK_CTR<=CLK;
--扫描信号发生器
COUNTER:BLOCK IS
SIGNAL Q:STD_LOGIC_VECTOR(5 DOWNTO 0);
SIGNAL SEL:STD_LOGIC_VECTOR(3 DOWNTO 0); --1110-1101-1011-0111
BEGIN
PROCESS(CLK_1K)IS
BEGIN
IF CLK_1K'EVENT AND CLK_1K='1'THEN
Q<=Q+1;
END IF;
C_DEBOUNCE<=Q(2); --去抖时钟信号,大约123Hz
C_KEYBOARD<=Q(6 DOWNTO 5); --产生键扫信号***“00-01-10-11”,大约16Hz
C_DEBOUNCE<=Q(1);
C_KEYBOARD<=Q(5 DOWNTO 4);
CLK<=Q(0);
END PROCESS;
CLK_DEBOUNCE<=C_DEBOUNCE;
SEL<="1110"WHEN C_KEYBOARD=0 ELSE
"1101"WHEN C_KEYBOARD=1 ELSE
"1011"WHEN C_KEYBOARD=2 ELSE
"0111"WHEN C_KEYBOARD=3 ELSE
"1111";
CLK_SCAN<=SEL;
END BLOCK COUNTER; --键盘去抖
DEBOUNUING:BLOCK IS
BEGIN
U1:DEBOUNCING PORT MAP(D_IN=>KEY_IN(0),D_OUT=>C(0),
CLK=>C_DEBOUNCE);
U2:DEBOUNCING PORT MAP(D_IN=>KEY_IN(1),D_OUT=>C(1),
CLK=>C_DEBOUNCE);
U3:DEBOUNCING PORT MAP(D_IN=>KEY_IN(2),D_OUT=>C(2),
CLK=>C_DEBOUNCE);
END BLOCK DEBOUNUING; --键盘译码
KEY_DECODER:BLOCK
SIGNAL Z:STD_LOGIC_VECTOR(4 DOWNTO 0); --按键位置
BEGIN
PROCESS(CLK)
BEGIN
Z<=C_KEYBOARD&C;
IF CLK'EVENT AND CLK='1' THEN
CASE Z IS
WHEN"11101"=>N<="0000"; --0
WHEN"00011"=>N<="0001"; --1
WHEN"00101"=>N<="0010"; --2
WHEN"00110"=>N<="0011"; --3
WHEN"01011"=>N<="0100"; --4
WHEN"01101"=>N<="0101"; --5
WHEN"01110"=>N<="0110"; --6
WHEN"10011"=>N<="0111"; --7
WHEN"10101"=>N<="1000"; --8
WHEN"10110"=>N<="1001"; --9
WHEN OTHERS=>N<="1111";
END CASE;
END IF;
IF CLK'EVENT AND CLK='1' THEN
CASE Z IS
WHEN"11011"=>F<="0100";--*_LOCK
WHEN"11110"=>F<="0001";--#_UNLOCK
WHEN OTHERS=>F<="1000";
END CASE;
END IF;
END PROCESS;
FN<=NOT(N(3) AND N(2) AND N(1) AND N(0));
FF<=F(2) OR F(0);
END BLOCK KEY_DECODER;
END ARCHITECTURE ART;