Varredura de um teclado matricial
O projeto apresentado abaixo tem o objetivo de ler um teclado matricial pelo processo de varredura, ou seja, testar linha por linha ou coluna por coluna para determinar a tecla pressionada. Neste projeto, como mostra a animação, são atribuídos valores as linhas de forma a uma linha estar em nível lógico baixo e as outras em nível lógico alto.
Esse artigo é um exemplo de projeto descrito em VHDL, o qual foi simulado no Modelsim-Altera®, tendo como entrada de comandos um testbench, também escrito em VHDL.
Para a implementação do projeto são necessários:
- 1x Módulo CPLD_7064;
- 1x Módulo de teclado numérico;
- 1x Placa de LEDs, para visualizar o valor da tecla apertada.
Detalhamento do Princípio de Funcionamento
Como explicado acima, o projeto tem por objetivo ler um teclado matricial, usando a varredura de linha. Para isto, defini-se as linhas como saídas e as colunas como entradas. A varredura das linha é feita rotacionando um nível lógico baixo pelas linhas, de forma a uma linha estar em ‘0’ e as outras em ‘1’. Dessa forma, quando um botão estiver pressionado e a linha correspondente estiver em ‘0’, o nível lógico da linha é transmitido para a coluna e pode-se então ler a tecla pressionada.
Animação 1: Ilustração do projeto a ser implementado.
Por exemplo, se a tecla “ * ” esta pressionada no momento em que a quarta linha (G) está em nível lógico baixo, este nível é transmitido à coluna correspondente (F), enquanto as demais colunas ficam em nível alto, devido ao “pull up” resistivo. Abaixo segue a explicação do projeto e no final da página você encontra os arquivos de projetos para baixar.
Descrição em VHDL
No projeto serão utilizados como entradas o clock, o resetn (“reseta” quando em nível lógico baixo) e as colunas. Como saída serão utilizadas as linhas e o sinal TECLA (Valor correspondente a tecla pressionada).
1 2 3 4 5 6 7 8 9 |
entity teclado is port ( CLOCK : in std_logic; F, E, D : in std_logic; K, J, H, G : out std_logic; TECLA : out std_logic_vector(3 downto 0) ); end entity teclado; |
O projeto pode ser dividido em três blocos: Envio e recebimento de dados, Contador e Decodificador.
O envio e recebimento de dados utiliza um sinal auxiliar de 7 bits chamado SEQUENCIA, em que os 4 bits menos significativos correspondem aos valores enviados as linhas e os 3 bits mais significativos aos valores recebidos das colunas. Como mostrado abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
-- Sequencia recebe os valores das colunas SEQUENCIA (6) <= F; SEQUENCIA (5) <= E; SEQUENCIA (4) <= D; -- Sequencia envia valores para as linhas K <= SEQUENCIA (3); J <= SEQUENCIA (2); H <= SEQUENCIA (1); G <= SEQUENCIA (0); |
O contador, apresentado no código abaixo, vai rotacionar os bits da saída, enviando nível lógico baixo a uma linha por vez. Quando há uma coluna em ‘0’ (tecla pressionada) a rotação pára até que a tecla seja solta.
1 2 3 4 5 6 7 8 9 10 11 12 |
ACIONA_LINHA: process(CLOCK, SEQUENCIA) begin if CLOCK'event and CLOCK = '1' and SEQUENCIA (6 downto 4) = "HHH" then case SEQUENCIA(3 downto 0) is when "0111" => SEQUENCIA(3 downto 0) when "1011" => SEQUENCIA(3 downto 0) when "1101" => SEQUENCIA(3 downto 0) when others => SEQUENCIA(3 downto 0) end case; end if; end process; |
O decodificador que seleciona o valor da TECLA a partir do valor do sinal SEQUENCIA.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
VERIFICA_TECLADO: with SEQUENCIA select TECLA Tecla '1' "0010" when "H0H0111", -- Linha K, Coluna E -> Tecla '2' "0011" when "HH00111", -- Linha K, Coluna D -> Tecla '3' "0100" when "0HH1011", -- Linha K, Coluna F -> Tecla '4' "0101" when "H0H1011", -- Linha K, Coluna E -> Tecla '5' "0110" when "HH01011", -- Linha K, Coluna F -> Tecla '6' "0111" when "0HH1101", -- Linha K, Coluna F -> Tecla '7' "1000" when "H0H1101", -- Linha K, Coluna F -> Tecla '8' "1001" when "HH01101", -- Linha K, Coluna F -> Tecla '9' "1010" when "0HH1110", -- Linha K, Coluna F -> Tecla '#' "0000" when "H0H1110", -- Linha K, Coluna F -> Tecla '0' "1011" when "HH01110", "1111" when others; |
Figura 1: 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 e utilizar o simulador Modelsim-Altera. Abaixo será descrito o código utilizado.
O testbench foi dividido em dois blocos, o primeiro gera o clock e o segundo emula uma tecla pressionada.
O gerador de clock nada mais é do que um for em que o clock passa 5 ms em nível lógico 1 e 5 ms em nível lógico baixo.
1 2 3 4 5 6 7 8 9 10 |
-- Processo: Geracao de clock: gera_clock: process begin for cont in 0 to 1000 loop CLOCK <= '1'; wait for 5 ms; CLOCK <= '0'; wait for 5 ms; end loop; wait; end process gera_clock; |
Para emular uma tecla pressionada, basta atribuir 0 a uma coluna no momento em que a linha correspondente está em 0, como o feito no código abaixo (lembrando que ‘H’ significa nível lógico alto fraco):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
-- Processo com os estímulos para a UUT: simulando: process begin -- Inicialmente, as colunas estao em nivel alto -- (devido ao "pull up") F <= 'H'; E <= 'H'; D <= 'H'; -- Simulando o acionamento do botao 2 wait for 200 ms; while K /= '0' loop wait for 2ms; end loop; E <= '0'; wait for 200ms; E <= 'H'; wait; end process simulando; |
Utilizando este testbench pôde-se observar as formas de onda abaixo. Perceba que o nível lógico baixo vai rotacionando nas linhas e no momento em que há uma tecla pressionada essa rotação pára até que a tecla seja solta.
Figura 2: Simulação do projeto
Estrutura Física
O projeto é composto pela placa de teclado matricial, a placa de LEDs e o kit CPLD_7064. A placa de LEDs será responsável por apresentar o valor do signal TECLA, ou seja, o valor da tecla pressionada. O teclado será conectado no conector CON2 do CPLD_7064 e a placa LEDs no conector CON1, como mostrado na figura abaixo. O CPLD utilizado foi o EPM7064, da família MAX7000S.
Figura 3: 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 4: 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 6 mostra a lista com a atribuição de pinos (pin planer), lembrando que o clock padrão do módulo CPLD_7064 é no pino 43.
Figura 5: Conexão da placa de LEDs no módulo CPLD.
Figura 6: 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 3, pressionar os botões e verificar se os LEDs acendem segundo o número binário correspondentes, como no vídeo apresentado no inicio deste artigo.