⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elec_lock.vhd

📁 本程序是用VHDL语言实现电子密码锁功能,整个系统分为三大模块,一为控制模块,二为键盘显示模块,三为处理模块
💻 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 + -