📄 elec_lock.vhd
字号:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL ;
USE IEEE.STD_LOGIC_UNSIGNED.ALL ;
LIBRARY altera;
USE altera.maxplus2.ALL;
--*********************************************
ENTITY elec_lock IS
PORT (
CLK_4M : IN STD_LOGIC ; --system original clock 4M
CLK_SCAN : OUT STD_LOGIC_VECTOR (3 downto 0) ; --scan sequence
KEY_IN : IN STD_LOGIC_VECTOR (2 downto 0) ; --KEY IN button code
FLAG_NUMB : OUT STD_LOGIC ;
FLAG_FUNC : OUT STD_LOGIC ;
LED_COM : OUT STD_LOGIC ; -- for LP-2900 only
CLEAR : OUT STD_LOGIC ; --**
ENLOCK : OUT STD_LOGIC ; --1:LOCK, 0:UNLOCK
NUMB_CNT : OUT STD_LOGIC_VECTOR (2 DOWNTO 0) ;
BCD_CODE : OUT STD_LOGIC_VECTOR (15 DOWNTO 0) ;
SELOUT : OUT STD_LOGIC_VECTOR (1 DOWNTO 0) ; --FIT TO LP-2900
SEGOUT : OUT STD_LOGIC_VECTOR(6 DOWNTO 0) -- SEG7 Display
);
END elec_lock ;
--*********************************************
ARCHITECTURE a OF elec_lock IS
component debouncing
port( d_in : IN STD_LOGIC ;
clk : IN STD_LOGIC ;
d_out : OUT STD_LOGIC ) ;
end component ;
SIGNAL CLK : STD_LOGIC ;
SIGNAL CLK_KEYBOARD : STD_LOGIC_VECTOR(1 downto 0) ;
SIGNAL CLK_DEBOUNCE : STD_LOGIC ;
SIGNAL CLK_DISPLAY : STD_LOGIC_VECTOR(1 downto 0) ;
SIGNAL C : STD_LOGIC_VECTOR(2 downto 0) ;
SIGNAL N : STD_LOGIC_VECTOR(3 downto 0) ;
SIGNAL F : STD_LOGIC_VECTOR(3 downto 0) ;
SIGNAL FN : STD_LOGIC ;
SIGNAL FF : STD_LOGIC ;
SIGNAL SEL : STD_LOGIC_VECTOR (3 downto 0) ;
SIGNAL OUT_NUMB : STD_LOGIC_VECTOR(3 downto 0) ;
SIGNAL OUT_FUNC : STD_LOGIC_VECTOR(3 downto 0) ;
SIGNAL ACC : STD_LOGIC_VECTOR (15 DOWNTO 0) ;
SIGNAL REG : STD_LOGIC_VECTOR (15 DOWNTO 0) ;
SIGNAL RR2 : STD_LOGIC ; -- ** RR2 = Clear
SIGNAL QA, QB, BB : STD_LOGIC ;
SIGNAL NC : STD_LOGIC_VECTOR (2 DOWNTO 0) ;
SIGNAL DB : STD_LOGIC_VECTOR( 3 DOWNTO 0);-- Number TO Display
SIGNAL SEG : STD_LOGIC_VECTOR( 6 DOWNTO 0);-- SEG7 Display Signal
BEGIN
--******************************************* 连接模块
-- CONNECTION
OUT_NUMB <= N ;
OUT_FUNC <= F ;
FLAG_NUMB <= FN ;
FLAG_FUNC <= FF ;
CLK_DEBOUNCE <= CLK ;
NUMB_CNT<= NC ; ----????
SEGOUT(6 DOWNTO 0) <= SEG; -- Seven Segment Display
SELOUT <= CLK_DISPLAY ;
LED_COM <= '1' ; --For LP-2900 only
--********************************************* 时钟模块
-- scan signal generator
counter : block
Signal Q : STD_LOGIC_VECTOR(22 DOWNTO 0);
Signal S : STD_LOGIC_VECTOR(1 DOWNTO 0) ; --keyboard scan about 15Hz ***
SIGNAL SEL : STD_LOGIC_VECTOR (3 downto 0);
BEGIN
PROCESS (Clk_4M) --各种时钟产生
Begin
IF CLK_4M'Event AND CLK_4M = '1' then
Q <= Q+1;
END IF;
END PROCESS;
CLK <= Q(0) ; --CLK = CLK_DEBOUNCE
CLK_KEYBOARD <= Q(5 DOWNTO 4) ; -- ***00-01-10-11 ----- 32分频
CLK_DISPLAY <= Q(5 DOWNTO 4) ;
-- To generate keyboard scan sequence 1110->1101->1011->0111 对应一,二,三,四行
SEL <= "1110" WHEN CLK_KEYBOARD=0 ELSE
"1101" WHEN CLK_KEYBOARD=1 ELSE
"1011" WHEN CLK_KEYBOARD=2 ELSE
"0111" ;
CLK_SCAN <= SEL ;
end block counter ;
--*********************************************
--debounuing ckt
debounuing : block ----消抖处理模块 难点!!!!
begin
U1: debouncing PORT MAP (
d_in => key_in(0) ,
d_out => C(0) ,
clk => CLK
);
U2: debouncing PORT MAP (
d_in => key_in(1),
d_out => C(1) ,
clk => CLK
);
U3: debouncing PORT MAP (
d_in => key_in(2) ,
d_out => C(2) ,
clk => CLK
);
END block debounuing ;
--******************************************************
--key_decoder
key_decoder : block --按键译码 模块
signal Z : std_logic_VECTOR(4 downto 0) ; --KEY POSITION
SIGNAL R1, R0 : STD_LOGIC ;
begin
PROCESS(clk)
begin
Z <= CLK_KEYBOARD & C ; ----CLK_KEYBOARD表示键盘行值 见时钟模块
IF CLK'EVENT AND CLK = '1' THEN ----C为处理消抖后键盘列值
case Z is ----译码
when "11101" => N <= "0000" ;--0 0111 101
when "00011" => N <= "0001" ;--1 1110
when "00101" => N <= "0010" ;--2 1110
when "00110" => N <= "0011" ;--3 1110
when "01011" => N <= "0100" ;--4 1101
when "01101" => N <= "0101" ;--5 1101
when "01110" => N <= "0110" ;--6 1101
when "10011" => N <= "0111" ;--7 1011
when "10101" => N <= "1000" ;--8 1011
when "10110" => N <= "1001" ;--9 1011
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 <= ( NOT F(3) AND F(2) AND NOT F(1) AND NOT F(0)) OR (NOT F(3)AND NOT F(2)AND NOT F(1) AND F(0) ) ;
--To generate clear signal for ACC 16位 为输入
PROCESS (CLK)
BEGIN
IF CLK'EVENT AND CLK = '1' THEN
R1 <= R0 ; R0 <= FF ; --R0为开或关锁标志
END IF ;
RR2 <= R1 AND NOT R0 ; --功能标志为0且R1输出为1,表示功能执行完成
CLEAR <= RR2 ; --开放信号由此而得
END PROCESS ;
end block key_decoder ;
--*****************************************************
--KEYIN /// BACK /// ALL CLEAR ---键盘输入处理模块
KEYIN_PROCESS :BLOCK
SIGNAL RST,D0,D1: STD_LOGIC ;
BEGIN
PROCESS(CLK,FN,RST)
BEGIN
IF RST = '1' THEN
ACC <= "0000000000000000" ; --CLEAR INPUT
NC <= "000" ; ---表示显示位数
ELSE
IF FN'EVENT AND FN = '1' THEN
IF NC < 4 THEN ---表示显示位数
ACC <= ACC(11 DOWNTO 0) & N ; ---实现左移
BB <= '0' ;
NC <= NC + 1 ;
ELSE
BB <= '1' ; ---位数大于四的标志
END IF ;
END IF ;
END IF ;
END PROCESS ;
RST <= RR2 ;
END BLOCK KEYIN_PROCESS ;
--*********************************************
LOCK_PROCESS : BLOCK ---控制模块
BEGIN
PROCESS(CLK,F)
BEGIN
IF (CLK'EVENT AND CLK = '1') THEN
IF NC = 4 THEN
IF F(2) = '1' THEN --LOCK
REG <= ACC ; ---------密码存储
QA <= '1' ; QB <= '0'; ---------置关锁标志位
ELSIF F(0) = '1' THEN --UNLOCK
IF REG = ACC THEN --CHECK PIN CODE
QB <= '1' ; QA<= '0'; ----------置开锁标志位
END IF ;
ELSIF ACC = "0010010110000000" THEN -----------源始密码开锁
--To set "2580" is the Universal. pin number
QB <= '1' ; QA<= '0';
END IF ;
END IF;
END IF ;
END PROCESS ;
END BLOCK LOCK_PROCESS ;
ENLOCK <= QA AND NOT QB ; -----锁的标志位 1关锁,0打开
BCD_CODE <= ACC ; -----数据以BCD码输出
--**********************************************
MULTIPLEXER : BLOCK ---多路显示控制处理模块
BEGIN
DB <= ACC(15 DOWNTO 12) WHEN CLK_DISPLAY = 0 ELSE
ACC(11 DOWNTO 8) WHEN CLK_DISPLAY = 1 ELSE
ACC(7 DOWNTO 4) WHEN CLK_DISPLAY = 2 ELSE
ACC(3 DOWNTO 0) WHEN CLK_DISPLAY = 3 ELSE
"1111" ;
End Block MULTIPLEXER ;
--**********************************************
SEVEN_SEGMENT : Block -- Binary Code -> Segment 7 Code ---显示模块
Begin
--gfedcba
SEG <= "0111111" WHEN DB = 0 ELSE
"0000110" WHEN DB = 1 ELSE
"1011011" WHEN DB = 2 ELSE
"1001111" WHEN DB = 3 ELSE
"1100110" WHEN DB = 4 ELSE
"1101101" WHEN DB = 5 ELSE
"1111101" WHEN DB = 6 ELSE
"0000111" WHEN DB = 7 ELSE
"1111111" WHEN DB = 8 ELSE
"1101111" WHEN DB = 9 ELSE
"1111111";
End Block SEVEN_SEGMENT;
END a;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -