Página 1 de 1

leitura de teclado matricial 4x3

MensagemEnviado: 25 Jun 2007 15:49
por cristian
galera tem alguma coisa errada nesta rotina pra ler o teclado matricial 4x3 porque acontece o seguinte problemas:

se eu apertar o numero 3 primeiro o programa trava
se press qualquer tecla da linha do ex 4 5 6 e em seguida press o numero 3 aparece o 6
se press qualquer tecla da linha do ex 7 8 9 e em seguida press o numero 3 aparece o 9

ou seja o problema esta na tecla 3 ja revisei tudo e nao achei nada desconfio desta rotina achada na net q deve desviar pra outro local e travar o pic

char const TECLAS[4][3] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};

struct teclado_map {
boolean unused;
boolean coluna1;
boolean coluna2;
boolean coluna3;
boolean linha1;
boolean linha2;
boolean linha3;
boolean linha4;

int data : 8;
} teclado;

#byte teclado = 6

RB_isr() {
char aux, linha, coluna = 0;
ch = '\0';

if (!teclado.linha1 && !teclado.linha2 && !teclado.linha3 && !teclado.linha4)
return;

disable_interrupts(INT_RB);

for (aux=1; aux<4; aux++) {
coluna = aux;

teclado.coluna1 = 0;
teclado.coluna2 = 0;
teclado.coluna3 = 0;

if (aux == 1)
teclado.coluna1 = 1;
else
if (aux == 2)
teclado.coluna2 = 1;
else
teclado.coluna3 = 1;

if (teclado.linha1) {
linha = 1;
break;
}
if (teclado.linha2) {
linha = 2;
break;
}
if (teclado.linha3) {
linha = 3;
break;
}
if (teclado.linha4) {
linha = 4;
break;
}

}


ch = TECLAS[linha-1][coluna-1];
enable_interrupts(INT_RB);
return;

valeu pela obs o teclado é 4x3 e nao 7x8(da onde tirei isso)

MensagemEnviado: 25 Jun 2007 15:59
por fabim
ué.. num seria 4 X 3 ?

MensagemEnviado: 26 Jun 2007 09:52
por andre_luis
Achei um pouco confuso essa rotina.
Eu uso essa aqui de um teclado 4x4, que funciona muito bem pro 8051, mas já a adaptei numa ocasiao pro PIC16F :
Detalhe: Se voce usar resistores pull-down, ao invéz de pull-up, essa rotina fica ainda mais simples, pois nao vai haver necessidade de inverter o valor lido.


Código: Selecionar todos
unsigned char VarreKey ( void )
{
unsigned char TeclaLendo = 0 ;

PORTA_TECLADO = LINHAS                                     ;
Delay(4)                                                   ;
TeclaLendo = (~( PORTA_TECLADO | COLUNAS ))                ;
if ( TeclaLendo )
   {
   PORTA_TECLADO = COLUNAS                                 ;
   Delay(4)                                                ;
   TeclaLendo += (~( PORTA_TECLADO | LINHAS ))             ;     
   return ( TeclaLendo )                                   ;
   }
   else return ( NO_KEY )  ;
}


sendo:

Código: Selecionar todos
#define LINHAS            0x0F
#define COLUNAS         0xF0


A grande vantagem dessa rotina, é que ela permite que voce crie, inclusive, mapeamento para conjuntos de teclas acionadas, tipo SHIFT+TECLA, expandindo a capacidade de leitura do teclado, sem acrescimo no processamento dessa rotina.

+++

MensagemEnviado: 26 Jun 2007 16:14
por cristian
muito simples seu codigo

nao sou tao avançado pra entender vc pode me explicar algumas linhas

TeclaLendo = (~( PORTA_TECLADO | COLUNAS )) qual a funçao de ~
e o que esta rotina faz

é que prefiro aprender a pescar ....

MensagemEnviado: 26 Jun 2007 16:28
por andre_luis
Cristian,

O que essa rotina faz, é ora ler o nibble alto da porta pelo nible baixo, e ora ler o nible baixo da porta pelo nibble alto.

Tendo em vista que o valor default para o 8051 era '1' para todos os pinos, era necessário inverter esse valor para 'somar' o valor lido.

Conforme te falei antes, voce terá de fazer algumas modificacoes para operar com o PIC. Sinceramente nao lembro exatamente do que fiz, mas foram detalhes banais.

+++

MensagemEnviado: 28 Jun 2007 04:01
por icaro51
Eu nao programo em C mas o que eu faco em ASM e muito simples, ativo uma coluna e leio as 4 saidas, outra e outra e assim vai:
Exemplo coluna 1 on 2e3 off leio linha 1,2 e 3, se tiver algo na 1 o valor e 1, se tiver algo na 2 o valor e 4 se tiver algo na 3 o valor e 7, depois disso coloco 1 off 2 on 3 off e faco o mesmo procedimento e assim vai.

MensagemEnviado: 28 Jun 2007 09:08
por andre_luis
Ícaro,

Este método que voce sugeriu é a varredura clássica de teclado.

Ela possui a desvantagem de não conseguir ler simultaneamente mais de 1 tecla, além de ter um consumo de processamento do uC - aparentemente - maior que o da rotinna acima.

A idéia dessa rotina é que, tanto as colunas façam varredura das linhas, como também as linhas façam a varredura da coluna.


+++

MensagemEnviado: 19 Out 2011 23:17
por _blackmore_
andre_teprom

esse seu código eu achei muito interessante, mas eu pergunto ... vc acha necessário um debounce? eu pensei em fazer um com interrupção mas vi esse seu e estou re-pensando essa ideota .. hehehe

MensagemEnviado: 20 Out 2011 20:21
por andre_luis
Olá,



Eu sempre usei debounce por hardware nos meus programas, em parte, por preguiça de raciocinar.
Porém, embora a opção de debounce por software seja mais "elegante", eu considero também o fato de a leitura das teclas consumir proporcionalmente bastante processamento do microcontrolador, e o fato de uma malha R-C representar pouco espaço.

O único caso em que eu preferiria o debounce por firmware, seria se a leitura do teclado fosse disparada por interrupção, ao invéz de varredura constante.
Teve um outro tópico aqui, que uma galera sugeriu um circuito com diodos que possibilitaria essa opção por interrupção.

No final das contas, teria de fazer uma análise de consumo de processamento da aplicação em questão pra saber se isso seria uma preocupação a se considerar.


+++