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

📄 delay_kbtingle.vhd

📁 数码管显示Vhdl实现
💻 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;
--scan_start0 : OUT STD_LOGIC;
--currentState0 : OUT STD_LOGIC_VECTOR(3 downto 0);

		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 en_scan_start : STD_LOGIC:='0';
	--SIGNAL clock_scan_start : STD_LOGIC:='0';
	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;
				
				--scan_start0 <= scan_start;
				--currentState0 <= currentState;
				
				currentState <= nextState;
			END IF;
		END IF;
	END PROCESS;

END delay_kbtingle_architecture;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -