Leitura Assíncrona de Teclado

Leitura Assíncrona de Teclado

{youtube}z-c2xbODBlU|480|320|1{/youtube} 

O projeto a seguir pretende fazer a leitura de um teclado matricial sem a utilização de clock. Basicamente, quando uma tecla é pressionada o circuito identifica qual a linha e coluna correspondente e decodifica a tecla.

O presente artigo apresenta um exemplo de projeto feito em VHDL de um circuito sequencial, o qual foi simulado no Modelsim-Altera®, utilizando como entrada de dados da simulação um testbench.

placa_teclado_2

Animação 1: Ilustração do projeto apresentado

Nesse projeto será utilizado:

Descrição do Funcionamento

O objetivo do projeto, como foi apresentado acima, é fazer a leitura de um teclado matricial de forma assíncrona. Para isso definem-se as linhas como saídas, em nível lógico baixo, e as colunas como entradas, que devido ao pull-up estarão nível lógico alto fraco (em VHDL,"H").

Quando uma tecla é pressionada estabelece uma conexão entre uma linha e coluna (cada botão está associado a uma diferente combinação de linha e coluna). Então, o estado lógico '0' da linha é transmitido para a coluna. Esta condição deve ser detectada para registrar o estado das colunas (e portanto em que coluna se encontra o botão pressionado).

 
Figura 1: transmissão do nivel lógico baixo através do pressionamento do botão.
 
Em seguida, altera-se a condição dos pinos: as colunas passam a ser saída, em nível lógico '0' e as linhas, entradas. Agora, as entradas estarão em nível alto (fraco). Como uma tecla já está pressionada, agora é o '0' da coluna que é transmitido para a linha.   A condição das linhas deve ser registrada.Finalmente, com os registros de linha e de coluna, pode-se determinar a tecla pressionada, em um bloco simples de decodificação.
 
Figura 2: Alteração das condições dos pinos e decodificação da tecla pressionada.
 
Por exemplo, ao se pressionar a tecla '*' a coluna 'F' apresentará nível lógico baixo, então registra-se o valor das colunas como "0HH". Quando ocorre a mudança de saída para entrada, a linha 'G' continua em zero, então, juntando as informações "0HH" e "HHH0", pode-se determinar que a tecla pressionada é '*'.

Descrição em VHDL

No projeto serão utilizados as linhas e colunas como sinais bidirecionais (inout) e um sinal de saída chamado TECLA:

F, E, D, K, J, H, G  :  inout std_logic;
TECLA  :  out std_logic_vector(3 downto 0)

Dentro da architecture se usará um sinal para armazenar os valores das linhas e uma maquina de estados:

signal SEQUENCIA : std_logic_vector (2 downto 0); -- Registrador usado para guardar os valores das colunas
type estados is
( ATIVA_COLUNA, ATIVA_LINHA ); -- criação do tipo para a maquina de estados
signal teclado : estados := ATIVA_COLUNA; -- Declaração da maquina de estado e definição do estado inicial.

O projeto pode ser dividido em três partes: atuação, máquina de estados e decodificação.

O projeto deve atuar quando houver variação no teclado, ou seja, quando houver mudanças em alguma das linhas ou colunas. Dessa forma o processo só precisa ser sensível a variações deles:

-- O processo e sensível a variação no teclado
process (F, E, D, K, J, H, G)

Dentro do processo, a atuação dependerá do estado da máquina de estado, nesse caso chamada de teclado. Caso teclado esteja no estado ATIVA_COLUNA, registra-se o valor das colunas e muda o estado para ATIVA_LINHA. Caso esteja em ATIVA_LINHA, verifica se a tecla foi solta, se sim troca o estado para ATIVA_COLUNA, se não continua em ATIVA_LINHA.

case teclado is
    -- Caso o estado seja ATIVA_COLUNA, grava as colunas em SEQUENCIA e muda o estado
    when ATIVA_COLUNA =>
        if  ( F = '0' or E = '0' or D = '0') then
            SEQUENCIA (2 downto 0) <= F & E & D;
            teclado <= ATIVA_LINHA;
        end if;
     when others =>  -- (ou seja, quando "ATIVA_LINHA")
          -- Verifica se o botão foi solto, se não continua em ATIVA_LINHA
          if  K = 'H' and J = 'H' and H = 'H' and G = 'H' then
                  teclado <= ATIVA_COLUNA;
          end if;
end case;

A máquina de estado definirá, dependendo do estado, se as colunas/linhas serão entradas ou saídas e precisa ser sensível a mudança no valor de teclado:

 process (teclado)
  -- Nesse processo serão selecionados F, E, D, K, J, H, G como entrada ou saída
 begin
 case teclado is
 
    -- Caso o estado seja ATIVA_COLUNA, seleciona F, E, D como entrada e K, H, J, G como saídas
    when ATIVA_COLUNA =>
         K <= '0'; H <= '0'; J <= '0'; G <= '0';
         F <= 'Z'; E <= 'Z'; D <= 'Z';
   -- Caso o estado seja ATIVA_LINHA, seleciona F, E, D, como saida e K, H, J, G como entradas
    when others =>
         K <= 'Z'; H <= 'Z'; J <= 'Z'; G <= 'Z';
         F <= '0'; E <= '0'; D <= '0';
 
 end case;
 end process; 

Por último, o decodificador analisa os valores obtidos e atribui a TECLA o valor correspondente. Note que não é necessário um sinal para registrar o valor das linhas, pois basta tomar diretamente os valores de entrada.

 -- Decodificação das linhas e colunas para o numero correspondente, onde os três primeiros bits (SEQUENCIA) correspondem as
 -- colunas e o quatro últimos (K, J, H, G) as linhas.
 VERIFICA_TECLADO: with SEQUENCIA & K & J & H & G select
 TECLA <= "0001" when "0HH0HHH", -- Linha K, Coluna F -> Tecla '1'
                    "0010" when "H0H0HHH", -- Linha K, Coluna E -> Tecla '2'
                    "0011" when "HH00HHH", -- Linha K, Coluna D -> Tecla '3'
 
                    "0100" when "0HHH0HH", -- Linha J, Coluna F -> Tecla '4'
                    "0101" when "H0HH0HH", -- Linha J, Coluna E -> Tecla '5'
                    "0110" when "HH0H0HH", -- Linha J, Coluna D -> Tecla '6'
 
                    "0111" when "0HHHH0H", -- Linha H, Coluna F -> Tecla '7'
                    "1000" when "H0HHH0H", -- Linha H, Coluna E -> Tecla '8'
                    "1001" when "HH0HH0H", -- Linha H, Coluna D -> Tecla '9'
 
                    "1010" when "0HHHHH0", -- Linha G, Coluna F -> Tecla '*'
                    "0000" when "H0HHHH0", -- Linha G, Coluna E -> Tecla '0'
                    "1011" when "HH0HHH0", -- Linha G, Coluna D -> Tecla '#'
                   "1111" when others; 

Figura 3: Resultado da analise e sintese.

Simulação

Para verificar o funcionamento do projeto, basta simular o pressionamento de alguns botões e averiguar se a saída é a equivalente ao botão apertado. Para isso, pode-se elaborar um testbench (caso você não saiba fazer um testbench clique aqui)  e utilizar o simulador Modelsim-Altera. Abaixo será descrito o código utilizado.

Neste testbench serão simulados as teclas '5', '9', '*'. Note que inicialmente se atribui a todas as linhas e colunas nível lógico alto fraco, para simular o pull-up e para simular o botão solto, após ser pressionado, se atribui novamente 'H' nas coordenadas correspondentes:

 simulando:
  process
  begin
 
   F <= 'H'; E <= 'H'; D <= 'H';
   K <= 'H'; J <= 'H'; H <= 'H'; G <= 'H';
  wait for 15ms;
   -- Simula o acionamento da tecla '5'
   -- (coluna E, linha J)
 E <= '0';
 J <= '0';
 wait for 100 ms;
 E <= 'H'; J <= 'H';
 
 wait for 200 ms;
 
 -- Simula o acionamento da tecla '9'
 -- (coluna D, linha H)
 D <= '0';
 H <= '0';
 wait for 150 ms;
 D <= 'H'; H <= 'H';
-- Simula o acionamento da tecla '*'
 -- (coluna F, linha G)
 F <= '0';
 G <= '0';
 wait for 150 ms;
 F <= 'H'; G <= 'H';
 wait for 25 ms;
 
 wait;
 
 end process simulando; 

O resultado da simulação no Modelsim-Altera é o apresentado na figura a seguir:

Tec_v2_sim

Figura 4: Resultado da simulação no Modelsim-Altera.

Estrutura Física

O projeto é composto pelo módulo do teclado, que será conectado no conector CON2 do Módulo CPLD_7064, e a placa LEDs, que será conectada no CON1, como mostrado na figura 5. Lembrando que o CPLD utilizado é o  EPM7064, da família MAX7000S.


Montagem_3

Figura 5: Montagem do projeto.

Montagem e Roteamento

Como vimos acima, o teclado será colocado no conector CON2. Com base nisso e sabendo a pinagem do teclado pode-se rotear os pinos para a gravação do programa. As linhas K, J, H, G correspondem, respectivamente, aos pinos 21, 24, 25 e 26 e as colunas a F, E, D aos pinos 18, 19, 20.

Figura 6: Conexão entre teclado e o módulo CPLD

A placa de LEDs mostrará o valor do teclado lido pelo CPLD (sinal de saída TECLA). Sabendo da pinagem da placa de LEDs e que será colocada no conector CON1, como mostra a figura 5 (não se esqueça de conferir que o Vcc da placa se conecta ao Vcc do CPLD e da mesma forma o GND),  podemos atribuir, de L3 a L0, respectivamente os pinos 9, 11, 12 e 14. A figura 8 mostra a lista com a atribuição de pinos (pin planer).

Figura 7: Conexão da placa de LEDs no módulo CPLD.

Tec_v2_pins

Figura 8: Atribuição dos pinos do projeto.

Gravação e Teste

Para gravar basta seguir o processo de gravação explicado no tutorial sobre o Quartus II© . Após gravar o código, basta montar o circuito como na figura 5, pressionar os botões e verificar se os LEDs acendem segundo o número binário correspondentes, como mostra o video no inicio da página. 

Arquivos de Projetos