阅读:1395回复:5
我准备实现键盘接口的CPLD方案中源代码的一部分,请大侠指教!
library ieee;
use ieee.std_logic_1164.all; entity key is port( row: out std_logic_vector(3 downto 0) ----行信号线 column: in std_logic_vector(3 downto 0)---列信号线 clk: in std_logic;-----------------时钟信号 db: out std_logic_vector(3 downto 0));----输出数据总线,CPU读入后用来判断哪一个键按下,我设置格式如下:(0:1)位代表被按下键行号,(2:3)位代表被按下键的列号;如db = \"1011\",表示第3行第1列的键被按下 。 end; architecture behavioral of key is type state_t is (s0,s1,s2,s3,s4); signal state,nextstate: state_t; begin process(clk) begin if clk\'event and clk = \'1\' then state <= nextsate; end if; end process; process(state) case state is when s4 => row <= \"0000\"; --首先向所有的行送低电平 if column = \"1111\" then --如果所有的列都是高电平, nextstate <= s4; --则继续以上操作 else --如果发现列不全是低电平 nextstate <= s0; --进行下面的扫描判断工作 end if; when s0 => ---第0行送低电平,查看各列,并对db付相应的数值。 row <= \"1110\" if column = \"1110\" then db <= \"0000\" --被按下的键的坐标(0行,0列) elsif column = \"1101\" then db <= \"0100\";-- 被按下的键的坐标(0行,1列) elsif column <= \"1011\" then db <= \"1000\";--被按下的键的坐标(0行,2列) elsif column <= \"1011\" then db <= \"1100\";--被按下的键的坐标(0行,3列) else nextstate <= s1; end if; when s1 => ---第1行送低电平,查看各行,并对db付相应的数值。 row <= \"1101\" if column = \"1110\" then db <= \"0001\";--被按下的键的坐标(1行,0列) elsif column = \"1101\" then db <= \"0101\";-- 被按下的键的坐标(1行,1列) elsif column <= \"1011\" then db <= \"1001\";-- 被按下的键的坐标(1行,2列) elsif column <= \"1011\" then db <= \"1101\";-- 被按下的键的坐标(1行,3列) else nextstate <= s2 end if; when s2 => ---第2行送低电平,查看各行,并对db付相应的数值。 row <= \"1011\" if column = \"1110\" then db <= \"0010\";--被按下的键的坐标(2行,0列) elsif column = \"1101\" then db <= \"0110\"; --被按下的键的坐标(2行,1列) elsif column <= \"1011\" then db <= \"1010\"; --被按下的键的坐标(2行,2列) elsif column <= \"1011\" then db <= \"1110\"; --被按下的键的坐标(2行,3列) else nextstate <= s3; end if; when s3 => ---第3行送低电平,查看各行,并对db付相应的数值。 row <= \"0111\" if column = \"1110\" then db <= \"0011\" --被按下的键的坐标(3行,0列) elsif column = \"1101\" then db <= \"0111\";--被按下的键的坐标(3行,1列) elsif column <= \"1011\" then db <= \"1011\";--被按下的键的坐标(3行,2列) elsif column <= \"1011\" then db <= \"1111\";--被按下的键的坐标(3行,3列) else nextstate <= s4; end if; end case; end if; end process; end behavioral; [编辑 - 10/5/03 by mysunkeyer] |
|
|
沙发#
发布于:2003-10-05 22:17
没有键盘弹跳消除部分,这样可能出现误码的!
|
|
板凳#
发布于:2003-10-05 23:25
这样好像不行吧……
根据我学过的:一般键盘扫描为了避免接触振荡,要进行多次扫描。(比如连续4次扫描有3次以上为低电平才判断为按下,否则认为未按下)。 |
|
|
地板#
发布于:2003-10-05 23:31
楼上的说的没错!
|
|
地下室#
发布于:2003-10-05 23:36
对于楼上说的4次扫描,3次低电平才判断为低电平,是一种方法,但是有很多情况下的应用都没有这样做,而且也很成功。我的一个同学就按照我的思路实现了,而且很稳定,没有误码,现在他做的东西已经在一家公司量产了。我之所以把键盘接口做在CPLD里面,主要因为如果不这样做,我的CPLD资源比较浪费。
|
|
|
5楼#
发布于:2003-10-06 11:52
买好的按键,问题不大
|
|
|