Dentre as várias maneiras de interagirmos com o hardware em uma IHM (Interface Homem Máquina) uma das formas mais comuns é através do pressionamento de chaves e botoeiras para que o programa possa então executar uma tarefa específica.
Hoje vamos interfacear um teclado matricial, como o encontrado em telefones celulares e calculadoras, onde temos várias chaves conectadas ao microcontrolador de maneira eficiente a fim de não despediçarmos pinos do hardware.
Para efetuar a conexão de uma tecla ao microcontrolador, podemos citar a maneira mais simples que utiliza apenas uma tecla e um resistor de Pull-up ou Pull-down conforme o nível de tensão que desejarmos quando ocorrer o pressionamento da tecla.
Porém nesta configuração precisamos um pino para cada tecla conectada ao microcontrolador, o que caracteriza o desperdício de hardware, porém isto pode ser resolvido com implementação de uma simples matriz, onde conseguimos maximizar a utilização dos pinos de forma eficiente.
No esquema abaixo podemos observar a utilização das linhas e colunas que formam a matriz.
O número máximo de chaves para esta implementação pode ser obtida através da equação abaixo:
N°teclas = Colunas x Linhas
O funcionamento do teclado matricial consiste em energizar apenas uma única linha por vez e efetuar a leitura das colunas para verificar o pressionamento de alguma das teclas, quando detectado um nível alto em alguma das colunas durante o rastreamento se torna possível a identificação da tecla pressionada. Para que não haja erros de leituras durante este processo, se faz necessário o uso de resistores de pull-down para garantir um nível baixo nas colunas que não estão sendo ativas pelo pressionamento de tecla.
Função para escaneamento de teclado
Para efetuar a leitura do teclado matricial, vamos criar uma função que retornará o valor da tecla pressionada em hexadecimal ou o valor 0xFF caso nenhuma tecla tenha sido pressionada.No nosso exemplo utilizaremos um teclado matricial de [4x3] que foi adquirido através do site www.goodluckbuy.com.
Assim que a função é chamada, colocamos um nivel alto na primeira linha e efetuamos a leitura das quatro colunas, caso alguma coluna responda nivel alto, retornamos da função com o valor correspondente a matrizagem, vejamos como fica o código:
#define Coluna_1 PORTD.B0
#define Coluna_2 PORTD.B1
#define Coluna_3 PORTD.B2
#define Linha_1 PORTD.B6
#define Linha_2 PORTD.B5
#define Linha_3 PORTD.B4
#define Linha_4 PORTD.B3
char Le_Teclado() // Função que efetua a leitura do teclado matricial
{
Coluna_1 = 1;
Coluna_2 = 0;
Coluna_3 = 0;
Delay_ms(1);
if(Linha_1) return 1;
if(Linha_2) return 4;
if(Linha_3) return 7;
if(Linha_4) return 10;
Coluna_1 = 0;
Coluna_2 = 1;
Coluna_3 = 0;
Delay_ms(1);
if(Linha_1) return 2;
if(Linha_2) return 5;
if(Linha_3) return 8;
if(Linha_4) return 0;
Coluna_1 = 0;
Coluna_2 = 0;
Coluna_3 = 1;
Delay_ms(1);
if(Linha_1) return 3;
if(Linha_2) return 6;
if(Linha_3) return 9;
if(Linha_4) return 11;
return 255;
}
Este código mostra como efetuar uma leitura “simples” do teclado matricial, porém dependendo do hardware utilizado pode apresentar problemas de estabilidade efetuando leituras falsas ou deixando de apresentar um pressionamento.
MikroC PRO
O compilador MikroC PRO, possui internamente uma biblioteca própria para uso com teclados matriciais e que torna o processo de escaneamento uma tarefa simples. Podem ser utilizadas as configurações [4x1] , [4x2] , [4x3] ou [4x4].
Keypad_Init()
Efetua a inicialização do teclado matricial, esta função requer que seja declarado anteriormente uma variável chamada keypadPort que define o PORT onde será conectado o nosso hardware do teclado.
char keypadPort at PORTD;
Keypad_Key_Press()
Efetua a leitura de uma tecla pressionada, retornando o valor da tecla (1 –16) ou 0 caso nenhuma tecla seja pressionada.
Keypad_Key_Click()
Efetua a leitura de uma tecla pressionada, retornando o valor da tecla (1 –16) ou 0 caso nenhuma tecla seja pressionada, porém é uma função com propriedades de bloqueio, ou seja, quando chamada, aguarda o pressionamento da tecla, bloqueando o processo do programa durante a espera do pressionamento da tecla.
Notem que esta biblioteca do MikroC PRO, embora nos ajude a interfacear o teclado não retorna o valor direto das teclas e sim a posição dela na matriz.
Vejamos como ficou o nosso código completo utilizando o compilador MikroC PRO.
/******************************************************************************
JL Audio – www.esquemas .org
Data: 04/2012
Autor: Jean Carlos
Projeto: Teclado Matricial
Microprocessador: PIC18F4550
Clock do processador: 48MHz
Estação de desenvolvimento: PK2Lab V 1.1
Compilador: MikroC PRO V 4.60.0.0
Versão atual: 1.0
Descrição:
Implementação de leitura de teclado matricial na
placa PK2Lab, através de biblioteca do MikroC PRO.
*******************************************************************************/
// Inicialização do teclado no PORTD
char keypadPort at PORTD;
// Configuração do LCD da placa PK2Lab V.1.1
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
//******************************************************************************
// Variáveis Globais
char tecla, tecla_antiga = 0;
//******************************************************************************
// Rotinas Auxiliares
//******************************************************************************
//Rotina Principal
void main()
{
TRISA = 0b00000000;
PORTA = 0b00000000;
TRISB = 0b00000000;
PORTB = 0b00000000;
TRISC = 0b00000000;
PORTC = 0b00000000;
PORTD = 0b00000000;
TRISE = 0b00000000;
PORTE = 0b00000000;
ADCON1 = 0X0F; // Entradas digitais.
Keypad_Init(); // Inicializa o Teclado Matricial
Lcd_Init();
Lcd_Cmd(_Lcd_Cursor_Off);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"*** PK2Lab ***");
Lcd_Out(2,2,"Tecla Press:");
Delay_ms(100);
while(1)
{
tecla = Keypad_Key_Press(); // Efetua leitura do teclado
if(tecla != 0)
{
switch (tecla) // Efetua conversão para impressão
{
case 1: tecla = 49; break; // 1
case 2: tecla = 50; break; // 2
case 3: tecla = 51; break; // 3
case 4: tecla = 65; break; // A
case 5: tecla = 52; break; // 4
case 6: tecla = 53; break; // 5
case 7: tecla = 54; break; // 6
case 8: tecla = 66; break; // B
case 9: tecla = 55; break; // 7
case 10: tecla = 56; break; // 8
case 11: tecla = 57; break; // 9
case 12: tecla = 67; break; // C
case 13: tecla = 42; break; // *
case 14: tecla = 48; break; // 0
case 15: tecla = 35; break; // #
case 16: tecla = 68; break; // D
}
if(tecla != tecla_antiga) // Atualiza a ultima tecla pressionada
{
tecla_antiga = tecla;
}
Lcd_Chr(2,15,tecla); // Imprime a tecla pressionada no LCD
}
}//while(1)
}//main
Abaixo o vídeo do projeto funcionando!
Bom projetos a todos e até a próxima!