Autor Tema: Ejemplito 16F876A: Rastreando un Teclado Matricial 4x4 y enviando a la RS232  (Leído 21531 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5362
    • Picmania by Redraven
En este nuevo ejemplito hace exactamente lo que dice su titulo: rastrea un teclado matricial de 16 teclas y envía la tecla pulsada al puerto RS232 del PC para monitorizarla.

Lo que aporta este ejemplito es una pequeña modificación del KBD.C de CCS que podeis encontrar en el directorio drives del mismo, y que he tenido que adaptar a mi hardware concreto, ya que este KBD.C usa un teclado de 3 columnas y 4 filas mientras que el mío dispone de una columna más. Aquí os pego el esquema de conexión de mi teclado:



Podéis comparar la libreria tal como yo la he dejado con la original para ver las diferencias, pero realmente lo único interesante está en las líneas #define del Keypad conection en las que puedes colocar qué pines usan cada fila y columna del teclado. Además he añadido una COL3 en todos los sitios donde acababa en COL2.

La librería queda como sigue (he marcado en negrita los cambios realizados por mi):

Codigo:

///////////////////////////////////////////////////////////////////////////
////                     KBD_LIB.C by Redraven                         ////
////                                                                   ////
////                     Derived from KBDD.C                           ////
////                  Generic keypad scan driver                       ////
////                                                                   ////
////  kbd_init()   Must be called before any other function.           ////
////                                                                   ////
////  c = kbd_getc(c)  Will return a key value if pressed or /0 if not ////
////                   This function should be called frequently so as ////
////                   not to miss a key press.                        ////
////                                                                   ////
///////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,1997 Custom Computer Services            ////
//// This source code may only be used by licensed users of the CCS C   ////
//// compiler.  This source code may only be distributed to other       ////
//// licensed users of the CCS C compiler.  No other use, reproduction  ////
//// or distribution is permitted without written permission.           ////
//// Derivative programs created using this software in object code     ////
//// form are not restricted in any way.                                ////
////////////////////////////////////////////////////////////////////////////

////////////////// The following defines the keypad layout on port D

// Un-comment the following define to use port B
#define use_portb_kbd TRUE

// Make sure the port used has pull-up resistors (or the LCD) on
// the column pins


#if defined(__PCH__)
#if defined use_portb_kbd
   #byte kbd = 0xF81              // This puts the entire structure
#else
   #byte kbd = 0xF83              // This puts the entire structure
#endif
#else
#if defined use_portb_kbd
   #byte kbd = 6                  // on to port B (at address 6)
#else
   #byte kbd = 8                  // on to port D (at address 8)
#endif
#endif

#if defined use_portb_kbd
   #define set_tris_kbd(x) set_tris_b(x)
#else
   #define set_tris_kbd(x) set_tris_d(x)
#endif

//Keypad connection:   (for example column 0 is B0)

#define COL0 (1 << 0) // PIN_B0
#define COL1 (1 << 1) // PIN_B1
#define COL2 (1 << 2) // PIN_B2
#define COL3 (1 << 3) // PIN_B3

#define ROW0 (1 << 4) // PIN_B4
#define ROW1 (1 << 5) // PIN_B5
#define ROW2 (1 << 6) // PIN_B6
#define ROW3 (1 << 7) // PIN_B7


#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)


#define ALL_PINS (ALL_ROWS|COL0|COL1|COL2|COL3)


// Keypad layout:

char const KEYS[4][4] = {{"1","2","3","A"},
                         {"4","5","6","B"},
                         {"7","8","9","C"},
                         {"*","0","#","D"}};


#define KBD_DEBOUNCE_FACTOR 33    // Set this number to apx n/333 where
                                  // n is the number of times you expect
                                  // to call kbd_getc each second

void kbd_init() {
}

char kbd_getc( ) {
   static byte kbd_call_count;
   static short int kbd_down;
   static char last_key;
   static byte col;

   byte kchar;
   byte row;

   kchar="";
   if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) {
       switch (col) {
         case 0   : set_tris_kbd(ALL_PINS&~COL0);
                    kbd=~COL0&ALL_PINS;
                    break;
         case 1   : set_tris_kbd(ALL_PINS&~COL1);
                    kbd=~COL1&ALL_PINS;
                    break;
         case 2   : set_tris_kbd(ALL_PINS&~COL2);
                    kbd=~COL2&ALL_PINS;
                    break;
        case 3   : set_tris_kbd(ALL_PINS&~COL3);
                    kbd=~COL3&ALL_PINS;
                    break;
 
     }

       if(kbd_down) {
         if((kbd & (ALL_ROWS))==(ALL_ROWS)) {
           kbd_down=false;
           kchar=last_key;
           last_key="";
         }
       } else {
          if((kbd & (ALL_ROWS))!=(ALL_ROWS)) {
             if((kbd & ROW0)==0)
               row=0;
             else if((kbd & ROW1)==0)
               row=1;
             else if((kbd & ROW2)==0)
               row=2;
             else if((kbd & ROW3)==0)
               row=3;
             last_key =KEYS[row][col];
             kbd_down = true;
          } else {
             ++col;
            if(col==4)
               col=0;
          }
       }
      kbd_call_count=0;
   }
  set_tris_kbd(ALL_PINS);
  return(kchar);
}



Este código lo he salvado en el disco con el nombre de KBD_LIB.C y es el que incluyo en mi programa:

Codigo:

#include <16f876a.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use fast_io(b)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#include "kbd_lib.c"

void main(){
   char mitecla=0;

   kbd_init();
   printf("Keyboard 4x4 monitor"Giño;
   do {
      mitecla=kbd_getc();
      if(mitecla!=0){
         putc(mitecla);
      }
   } while (TRUE);
}



Como véis es muy simple, a la par que elegante Muchas risas

Y por último la foto de los resultados sobre el monitor RS232:



Y esto es todo, amigos.
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado RaDoN

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1498
RE: Ejemplito 16F876A: Rastreando un Teclado Matricial 4x4 y enviando a la RS232
« Respuesta #1 en: 30 de Diciembre de 2005, 15:59:00 »
Aver si termino la rutina que ando haciendo para el terminal-rs232, se trata de usar el teclado matricial de forma como se escribe en el movil y tal.

El principal problema que el encuentro a la rutina KBD de CCS es que no se puede usar con las interrupciones RB del PIC. RollEyes
Si juegas contra el mejor, pierdes como los demás.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5362
    • Picmania by Redraven
RE: Ejemplito 16F876A: Rastreando un Teclado Matricial 4x4 y enviando a la RS232
« Respuesta #2 en: 30 de Diciembre de 2005, 16:12:00 »
Amigo Radón:

Ayer me di cienes de cabezazos intentando hacerlo con la INT_RB4a7 y al final tiré la toalla desesperado desquiciado ... no comprendía lo que me ocurría desquiciado ... asi que lo dejé por el momento ... desquiciado

Pero ¡que tiemble el Keypad! porque le tengo el ojo echado encima y no me se vá a escapar con la INT_RB4a7 Fumador

Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado microcarsil

  • PIC10
  • *
  • Mensajes: 44
RE: Ejemplito 16F876A: Rastreando un Teclado Matricial 4x4 y enviando a la RS232
« Respuesta #3 en: 30 de Diciembre de 2005, 16:15:00 »
Muy buen programa RedPic  Giño me puede servir mucho ya que tengo pensado implementar una especie de calculadora sencilla, felicidades y a seguir programando... Fumador
Microcarsil

Desconectado microcarsil

  • PIC10
  • *
  • Mensajes: 44
RE: Ejemplito 16F876A: Rastreando un Teclado Matricial 4x4 y enviando a la RS232
« Respuesta #4 en: 30 de Diciembre de 2005, 16:24:00 »
Hola quiza este post te pueda servir es un ejemplo que hice para manejar un teclado ps/2 por medio de interrupcion, hechale un vistaso y a darle a ese Keypad Muchas risas , ya que seria bueno como dijo radon que fuera por medio de interrupciones.

http://miarroba.com/foros/ver.php?foroid=46840&temaid=4627644
Microcarsil

Desconectado RaDoN

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1498
RE: Ejemplito 16F876A: Rastreando un Teclado Matricial 4x4 y enviando a la RS232
« Respuesta #5 en: 31 de Diciembre de 2005, 02:53:00 »
Creo que hay que rehacer de otra forma la libreria para que se pueda usar en las interrupciones, por cierto carsil, muy buen enlace, no lo conocia Sonrisa Gigante
Si juegas contra el mejor, pierdes como los demás.

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2565
Re: Ejemplito 16F876A: Rastreando un Teclado Matricial 4x4 y enviando a la RS232
« Respuesta #6 en: 15 de Abril de 2006, 09:12:00 »
Os pongo lo que he hecho respecto al teclado por interrupcion:

Código: C
  1. #include <16F876.h>
  2.  
  3. #fuses XT,NOWDT,NOPROTECT,NOLVP
  4.  
  5. #use delay (clock=4000000)  
  6.  
  7. #include <lcd_ind.c>
  8. #include <Teclado3.c>
  9.  
  10. char k;
  11. int1 bandera,aux;
  12.        
  13. // RUTINA DE INTERRUPCIÓN DEL PUERTO B (parte alta)
  14.    
  15. #INT_RB
  16. TECLADO_INTERRUPT()
  17. {
  18.         delay_ms(50);                   //Antirebotes
  19.        
  20.         if(!RB4 || !RB5 || !RB6 ||      !RB7)   //Para no leer el teclado al "soltar" la tecla
  21.         {      
  22.                 aux=!aux;               //Para debug, nos avisa que se entra en la interrupcion
  23.                 bandera=1;
  24.                 k= kbd_getc(); 
  25.                 RB0=RB1=RB2=RB3=0;    //Hay que anularlas tanto aquí como al final de Teclado3.c de lo contrario en la colúmna 1,6,7,* se activan los números al soltar la tecla ¿?
  26.         }
  27. }
  28.  
  29. main()
  30. {
  31.         lcd_init();
  32.         lcd_gotoxy(1,1);       
  33.         lcd_erase_line(16);
  34.         lcd_gotoxy(1,2);       
  35.         lcd_erase_line(16);    
  36.         lcd_gotoxy(1,1);
  37.         lcd_putc("Tecla pulsada:");
  38.  
  39.         set_tris_b(0xF0);               //RB0..RB3 salidas a teclado, RB4..RB7 entradas de teclado
  40.  
  41.         RB0=RB1=RB2=RB3=0;      //Esta línea y la siguiente son para detectar el cambio de estado RB0=RB1=RB2=RB3=0 a RB4=RB5=RB6=RB7=1;
  42.         port_b_pullups(true);                  
  43.                        
  44.        enable_interrupts ( INT_RB );                 
  45.        enable_interrupts ( GLOBAL );           
  46.        
  47.       while(1)
  48.       {
  49.                 if(bandera==1)
  50.                 {
  51.                         set_tris_b(0x0F);       //Activar salidas a la LCD (RB4..RB7) y programar RB0..RB4 como entradas para que no hayan cortocircuitos con las salidas RB5..RB7
  52.                         lcd_gotoxy(16,1);
  53.                         lcd_putc(k);
  54.                         lcd_gotoxy(7,2);
  55.                         printf(lcd_putc,"aux=%u",aux);
  56.                         bandera=0;                     
  57.                         set_tris_b(0xF0);                       //Activar teclado
  58.                         RB0=RB1=RB2=RB3=0;              //Fundamental, ya que al estar activadas las pullups se queda todo el PORTB a 1
  59.                 }              
  60.   }    
  61. }
  62.  

En PROTEUS funciona perfectamente, faltaria probarlo fisicamente. Aquí debajo os dejo todos los archivos del Teclado por interrupción.

Un saludo
« Última modificación: 24 de Abril de 2006, 07:02:06 por pocher »

Desconectado julietgolf

  • PIC10
  • *
  • Mensajes: 15
    • Mi Página (aún está en construcción...)
Re: Ejemplito 16F876A: Rastreando un Teclado Matricial 4x4 y enviando a la RS232
« Respuesta #7 en: 18 de Octubre de 2007, 17:54:12 »
hola sres... llego con más de un año de atraso del ultimo mens en este post (espero q aun esté vivo) pero hoy día me atañe este tema del teclado...
he estado tratando de utilizar la lib propuesta por redpic, pero sin ni un solo resultado satisfactorio...
escribo aqui porq he tirado la toalla, ya no puedo hacerlo andar ni siquiera el ejemplo propuesto por redpic... estoy simulandolo en proteus, aun no lo he probado fisicamente porq no me han traído aun el teclado...
ESPERO ALGUNA AYUDITA DE ALGUIEN.... GRACIAS!

si no logro de esta forma, trataré de hacer una lib mía, pero llevará más tiempo aún...

adjunto tambien los archivos en cuestion, por si desean verlos...
...::: Un feliz usuario de Debian Linux (e17) y amante de los PIC :::...

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5425
    • Electrónica Didacta
Re: Ejemplito 16F876A: Rastreando un Teclado Matricial 4x4 y enviando a la RS232
« Respuesta #8 en: 29 de Abril de 2008, 12:23:58 »
pocher, estoy estudiando el programa de arriba que amablemente publicaste  :wink:

Código: C
  1.  
  2. ...
  3. #INT_RB
  4. TECLADO_INTERRUPT()
  5. {
  6. delay_ms(50); //Antirebotes
  7. if(!RB4 || !RB5 || !RB6 || !RB7)
  8. ...
  9.  
  10.  

respecto al delay de 50ms dentro de la interrupción:

¿como es posible una validación de una tecla después de 50ms si el flag RB[7-4] sigue activo?

asumiendo un falso contacto, el estado de dichos pines no cambiará y se tomará como una pulsación

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2565
Re: Ejemplito 16F876A: Rastreando un Teclado Matricial 4x4 y enviando a la RS232
« Respuesta #9 en: 29 de Abril de 2008, 15:49:00 »
Hola Pedro.

No acabo de entender la conexión que quieres establecer entre el bit RBIF y el delay_ms(50) ¿Te refieres al flag RBIF?

El funcionamiento de la interrupción es:

Al pulsar una tecla alguno de los bits RB4..RB7 pasan a 0, se entra en la interrupción, se espera a que la tecla se estabilice y siga siendo 0 y entonces pasados 50ms se entrará en el if leyendo el valor de la tecla pulsada. Por último se saldrá de la interrupción y se mostrará en la LCD.

Sin embargo una vez fuera de la interrupción al soltar la tecla se crea de nuevo un cambio de estado con lo que indeseadamente se vuelve a entrar en la interrupción, sin embargo si ahora nos esperamos 50ms todos los valores de RB4..RB7 son 1 con lo que no entrará en el if y abandonará rápidamente la interrupción.

No sé si con esto te vale. Ya me cuentas Pedro.

Un saludo

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5425
    • Electrónica Didacta
Re: Ejemplito 16F876A: Rastreando un Teclado Matricial 4x4 y enviando a la RS232
« Respuesta #10 en: 29 de Abril de 2008, 17:05:44 »
...Al pulsar una tecla alguno de los bits RB4..RB7 pasan a 0, se entra en la interrupción, se espera a que la tecla se estabilice y siga siendo 0 y entonces pasados 50ms se entrará en el if leyendo el valor de la tecla pulsada. ...

ajá, pero se supone que GIE se limpia cuando sale de la interrupción, mientras no importa si RB[7-4] cambian  entonces el retardo de nada servirá.

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2565
Re: Ejemplito 16F876A: Rastreando un Teclado Matricial 4x4 y enviando a la RS232
« Respuesta #11 en: 30 de Abril de 2008, 01:32:27 »
¿Es esto lo que deseas?: quieres quitar el retardo para que no esté tanto tiempo en la interrupción y el programa pueda atender a otras cosas.

Posiblemente al quitar el retardo no pase nada, lo único que debido a los rebotes la tecla será leida varias veces ... habría que probarlo físicamente.

Sigo sin ver la interconexión entre el retardo y el bit GIE ... y es que la edad no perdona. :-)

Un saludo

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5425
    • Electrónica Didacta
Re: Ejemplito 16F876A: Rastreando un Teclado Matricial 4x4 y enviando a la RS232
« Respuesta #12 en: 30 de Abril de 2008, 11:49:00 »
ah ah ah ya resolví la incognita.   :-/

no tomé en cuenta que a pesar de la interrupción, RB[7-4] sigue en su condición de entrada y puede cambiar en cualquier momento, aún estando GIE=0, esos 4 pines pines cambian su valor, si cambia el switche (asumiendo que tecleemos mucho dentro de los 50ms)

yo creo que ese programa se le puede hacer una adaptación, como por ejemplo:

- al entrar a la interrupción RB, capturar el valor de RB[7-4] y guardarlo en un registro (llamemoslo flanco_RB)
- hacer el retardo por timer, salir de la interrupción inmediatamente.
- volver al bucle principal y seguir haciendo otras cosas.
- al pasar los 50ms, ir a una función y validar si sigue intacto flanco_RB y ejecutar la parte del programa que tu metiste en la interrupción.

ya me pongo a ello.





La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado jeison

  • PIC10
  • *
  • Mensajes: 19
Re: Ejemplito 16F876A: Rastreando un Teclado Matricial 4x4 y enviando a la RS232
« Respuesta #13 en: 10 de Agosto de 2015, 13:33:46 »
hola podrías colocar de nuevo el esquematico o si depronto te es posible enviaarmelo al correo que mi pc no lo puede mostrar  :(
mi correo es jeisonalejo666@gmail.com
muchas gracias