用 CPLD实现结构简单的键盘控制器

摘要:本文介绍了一种用 CPLD实现键盘控制器的崭新方法。该键盘控制器具有结构简单,通用性强等优点。 
 
1.  引言 
    键盘作为单片机系统的一种主要输入设备被广泛使用,目前用于实现键盘控制的手段有很多,例如采用键盘专用控制芯片或软件扫描查询方式等。本人在制作 MP3 播放器的过程中使用 Altera 公司生产的 CPLD 芯片EPM7128SLC84-15 实现了包括键盘控制器在内的多个系统功能。本键盘控制器具有结构简单器件少、可与 51 系列单片机数据总线连接、能够发出中断请求等功能。经实际验证完全满足设计要求。此外它也可应用在单片机开发实验板、PDA、随身听等设备中。
 
2.  工作原理 
    本键盘控制器的每个键盘输入端口对应一个按键,并与一个独立工作的控制电路相连,每个控制电路由三个D触发器组成。第一个触发器主要用于键盘去抖,同时配合第二个触发器将键码转化为键码脉冲,最后一个触发器负责键码输出和中断请求。单片机响应中断请求后,读取键码并回写任意一个字节作为清除键码和中断请求的信号。键盘控制器与单片机的连接方式如图 1所示。
用 CPLD实现结构简单的键盘控制器_第1张图片 
图 1   键盘控制器与单片机接口原理图

2.1. 键盘去抖
    键盘在被按下和释放时通常会造成持续时间不大于 10ms 的信号抖动,这种抖动使系统无法正确识别按键操作次数。图 2是用D触发器实现键盘去抖功能的示意图。触发器的输入端D与下拉电阻R相连,时钟信号为50Hz,触发器在时钟的上升沿触发。当键盘未按下时,触发器输入端 D被电阻 R 下拉至低电平,触发器在 clk 的上升沿输出低电平。当键盘被按下后,D 变为高电平,触发器在 clk 的上升沿输出高电平。通过时序图可以推断出,在按键过程中可能有三种情况发生。
第一种:抖动发生在时钟信号的某个上升沿,并且此时的输入信号为高电平,则触发器在该上升沿输出高电平。
第二种:抖动同样发生在时钟信号的某个上升沿,但此时的输入信号为低电平,因为一般按键时间在 200ms 以上,所以触发器在下一个上升沿(20ms 后)输出高电平。
第三种:抖动发生在时钟信号的两个相邻上升沿之间,则触发器将在第二个上升沿输出高电平。释放键盘时的情况类似。可见,只要时钟信号周期大于抖动时间且小于按键时间,去抖电路就能正确识读按键次数。
用 CPLD实现结构简单的键盘控制器_第2张图片 
图 2   去抖电路及时序图

2.2. 产生键码脉冲 
    去抖后得到的键码不能直接送到数据总线上等待单片机读取。因为当石英晶体频率为 12MHz 时,单片机AT89C52 可在几十微秒内完成键盘中断程序,在键盘被释放前键盘控制器已发出了多次中断请求,单片机也多次读取了相同的键码,所以要构造一个键码脉冲信号,使每一次按键操作对应一个键码脉冲,键盘控制器根据键码脉冲发出中断请求。如图 3所示,将第一个D触发器的输出作为第二个D触发器的输入,在同一个时钟信号(50Hz)的控制下,两个触发器构成移位寄存器,它们的输出 out1和 out2 相差一个时钟周期 T(20ms)。这两个输出信号经过非门和与门的逻辑组合,得到了脉宽为 20ms 的键码脉冲。
用 CPLD实现结构简单的键盘控制器_第3张图片 
图 3   键码脉冲电路及时序图 

2.3. 键码输出和中断请求 
    异步清除 D触发器在产生键码脉冲后的第一个时钟下降沿锁存键码脉冲信号,等待单片机读取键码,如图 4所示。因为单片机 AT89C52 使用下降沿或低电平触发中断,所以将键码反相后得到的低电平作为中断请求信号int 送出,该信号同时又使时钟信号无法通过与门进入触发器的时钟输入端,触发器保持锁存状态。当单片机响应了中断请求并读取了 out端口输出的键码后,发出中断清除信号给 clr端口,异步清除触发器的输出,中断请求信号 int 回到高电平,与门打开,时钟信号再次进入触发器的时钟输入端。因为在产生键码脉冲的时间内只会遇到一个时钟信号下降沿,触发器只锁存一次键码,并且只产生一次中断请求,所以不会使单片机发生在 1.2 中提到的重读键码问题。
用 CPLD实现结构简单的键盘控制器_第4张图片 
图 4   键码输出电路及时序图

3.  程序设计 
    多数情况下键盘数量不止一个,考虑到还要与单片机数据总线相连,因此必须对上面介绍的单键控制加以改进。首先,键码输出要通过由片选信号(cs)和读信号(rd)控制的三态门连接到数据总线上。其次,锁存的键码经过或非门输出中断请求信号。最后,片选信号(cs)和写信号(wr)相或后产生中断清除信号。下面是键盘控制器的整体原理图、VHDL 程序和单片机程序。
用 CPLD实现结构简单的键盘控制器_第5张图片 
图 5   整体原理图

3.1. 键盘控制器 VHDL程序
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity key_controler is
 port
 (
  clk   :  in std_logic;--时钟信号
  cs   :  in std_logic;--片选信号
  rd   :  in std_logic;--读信号
  wr   :  in std_logic;--写信号
    key_in  :  in std_logic_vector(7 downto 0);--键盘输入
  int   :  out std_logic;--中断请求
  data  :  out std_logic_vector(7 downto 0)--数据输出
 );
end entity;
architecture keyin of key_controler is
 signal key_0   :  std_logic_vector(7 downto 0);
 signal key_1   :  std_logic_vector(7 downto 0);
 signal key_2   :  std_logic_vector(7 downto 0);
 signal key_3   :  std_logic_vector(7 downto 0);
 signal key_4   :  std_logic;
 signal clk_lock  :  std_logic;
 signal read_data  :  std_logic;
 signal int_clr   :  std_logic;
begin
 process(clk)--去抖
 begin
  if rising_edge(clk) then
   key_0<=key_in;
   key_1<=key_0;
  end if;
 end process;
  key_2<=(not key_1) and key_0;--键码脉冲
 process(clk_lock,int_clr)--键码锁存,异步清除
 begin
  if int_clr='0' then
   key_3<="00000000";
  elsif falling_edge(clk_lock) then
   key_3<=key_2;
  end if;
 end process;
  key_4<=not (key_3(7) or key_3(6) or key_3(5) or key_3(4) or key_3(3) or key_3(2) or key_3(1) or key_3(0));
 int<=key_4;--中断请求
  clk_lock<=clk and key_4;
  read_data<=cs or rd;--读键码
 data<=key_3 when read_data='0' else "ZZZZZZZZ";--三态门输出控制
 int_clr<=cs or wr;--清除中断
end architecture;
 
3.2. 单片机读键码程序
#include
#include
unsigned char key_code;
void display(char key_code)
{……}
void main(void)
{
 IT0=1;//int0下降沿触发
 EX0=1;//int0中断允许
 EA=1;//开中断
4/5

 while(1)
 {
  if(key_code!=0x00)
  {
   display_data(key_code);//显示键码
   key_code=0x00;
  }
 }
}
void key_interrupt(void) interrupt 0
{
 key_code=XBYTE[0x7fff];//读键码
 XBYTE[0x7fff]=0x00;//清除键码和中断请求
}

4.  系统仿真和验证 
   键盘控制器 VHDL 程序经 MAX+PLUS II 10 仿真后的结果如图 6 所示。key_in 是键盘输入端口,控制器在按下键盘后的第一下降沿输出中断请求信号(int=0),单片机读键码时(rd=0),数据输出端口 data输出键码,单片机回写数据时(wr=0)清除中断请求(int=1)。经实验证实该设计完全正确。 
 用 CPLD实现结构简单的键盘控制器_第6张图片
图 6   仿真结果

5.  结语 
   本键盘控制器的最大特点就是结构简单。8 个按键的键盘控制器经过 MAX+PLUS II 10 编译后占用 34 个逻辑单元,如果使用 MAX+PLUS II Advanced Synthesis 综合后再编译则占用数量减少到 26个。这样的键盘控制器非常适合应用在一些对键盘数量要求不高的小系统中。

你可能感兴趣的:(用 CPLD实现结构简单的键盘控制器)