📄 delay_kbtingle.vhd
字号:
--/*****************************************************************************-- * 源文件: delay_kbtingle.vhd-- * 模块: 键盘控制-- * 版权:-- * Copyright(C) 北京联华众科科技有限公司-- * www.lianhua-zhongke.com.cn-- * 版本: Version 1.0-- * -- * 功能说明:-- * 在键盘扫描有效期间完成下列工作,读取一行按键状态,延时去抖-- * 动,输出按键中断信号。-- *-- * 参数说明:-- * 输出-- * key_data - 8 位按键码-- * key_down - 按键中断信号-- *-- * 输入-- * row_select - 行选择数据-- * row_data - 某行按键状态数据-- * clock - 读取键状态时钟-- * en - 键盘扫描有效-- * reset - 复位信号,低电平有效-- *-- * 参数-- * keyboard_size - 键盘行列宽度为 -- * keyboard_size(行数)*keyboard_size(列数)-- *-- * 变更记录: -- * 2006.01.28, 新建-- *-- *****************************************************************************/LIBRARY ieee;USE ieee.std_logic_1164.all;USE ieee.std_logic_arith.all;USE ieee.std_logic_unsigned.all;ENTITY delay_kbtingle IS GENERIC ( keyboard_size : INTEGER RANGE 0 TO 15:= 4 ); PORT ( key_data : OUT STD_LOGIC_VECTOR(7 downto 0); key_down : OUT STD_LOGIC; row_select : IN STD_LOGIC_VECTOR(keyboard_size-1 downto 0); row_data : IN STD_LOGIC_VECTOR(keyboard_size-1 downto 0); clock : IN STD_LOGIC; en : IN STD_LOGIC; reset : IN STD_LOGIC ); END delay_kbtingle;ARCHITECTURE delay_kbtingle_architecture OF delay_kbtingle IS SIGNAL scan_start : STD_LOGIC:='0'; SIGNAL currentState : STD_LOGIC_VECTOR(3 downto 0):="0000"; SIGNAL nextState : STD_LOGIC_VECTOR(3 downto 0):="0000";BEGIN PROCESS(currentState) VARIABLE previous_row_data : STD_LOGIC_VECTOR(keyboard_size-1 downto 0):=CONV_STD_LOGIC_VECTOR(0, keyboard_size); VARIABLE nz_counter : STD_LOGIC; BEGIN key_down <= '0'; IF (scan_start = '1') THEN --start to read, wait sometime, and then sample key value. IF (currentState = "0000") THEN --start state at clock 0. IF (row_data /= "1111") THEN--key down happened previous_row_data := row_data; nextState <= currentState + 1; ELSE nextState <= "0000"; END IF; ELSIF (currentState = "0001") THEN nextState <= currentState+1; ELSIF (currentState = "0010") THEN nextState <= currentState+1; ELSIF (currentState = "0011") THEN--after delay 2 clock, read again IF (previous_row_data /= row_data) THEN nextState <= "0000"; ELSE nextState <= currentState+1; END IF; ELSIF (currentState = "0100") THEN--read again, again IF (previous_row_data /= row_data) THEN nextState <= "0000"; ELSE nextState <= currentState+1; END IF; ELSIF (currentState = "0101") THEN--read again, again, again IF (previous_row_data /= row_data) THEN nextState <= "0000"; ELSE nz_counter := '0'; CASE previous_row_data IS WHEN "1110" => nz_counter := '0'; WHEN "1101" => nz_counter := '0'; WHEN "1011" => nz_counter := '0'; WHEN "0111" => nz_counter := '0'; WHEN OTHERS => nz_counter := '1'; END CASE; IF (nz_counter = '0') THEN key_down <= '1'; --key_data <= row_select&previous_row_data; key_data(7) <= row_select(3); key_data(6) <= row_select(2); key_data(5) <= row_select(1); key_data(4) <= row_select(0); key_data(3) <= previous_row_data(3); key_data(2) <= previous_row_data(2); key_data(1) <= previous_row_data(1); key_data(0) <= previous_row_data(0); nextState <= currentState+1; ELSE nextState <= "0000"; END IF; END IF; ELSIF (currentState = "0110") THEN key_down <= '1'; nextState <= currentState+1; ELSIF (currentState = "0111") THEN key_down <= '1'; nextState <= currentState+1; ELSIF (currentState = "1000") THEN key_down <= '1'; nextState <= "1111"; ELSIF (currentState = "1111") THEN nextState <= "0000"; ELSE nextState <= "0000"; END IF; ELSE nextState <= "0000"; END IF; END PROCESS; PROCESS(clock, en, reset) BEGIN IF(reset = '0') THEN scan_start <= '0'; currentState <= "0000"; ELSE IF(clock = '1' AND clock'EVENT) THEN IF(en = '1' AND en'EVENT) THEN scan_start <= '1'; END IF; IF (currentState = "1111") THEN scan_start <= '0'; END IF; currentState <= nextState; END IF; END IF; END PROCESS;END delay_kbtingle_architecture;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -