Autor Tema: Lectura de teclado matricial  (Leído 9634 veces)

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

Desconectado FrAnderGround

  • PIC10
  • *
  • Mensajes: 6
Lectura de teclado matricial
« en: 15 de Febrero de 2007, 13:58:29 »
MUY BUENAS A TODOS!!!

soy nuevo en este foro, y weno el caso es q tengo un problemilla a la hora de tomar valores desde un teclado matricial 4x4, os explico:


Trabajo con un PIC16f876 y el compilador CCS de C y conectando el teclado al puerto b, tengo ke conseguir introducir un valor de dos numeros (ej:12 o 45 o 36 o...) y al pulsar la tecla A que me lo almacene en una cadena, de forma que luego, con un atoi pueda coger esos dos datos de la cadena y hacer un entero, es decir:

si pulso en el teclado 1,2 y luego A, kiero ke la cadena corresponda a :   

char cadena[2]={'1','2'};

para luego con otra variable haga:

int valor= atoi (cadena);
y obtenga=> valor=12

lo que necesito es saber como hacer que el teclado me asigne el 1 y el 2 a esa cadena, que no encuentro al forma.

la libreria de teclado es la siguiente:


__________________________________________________________________________________________________
/*-------------------------------------------*\

 |  KBD2.C                                   |

 |  Autor: Pedro Mª Jiménez                  |

 |  (c) Microsystems Engineering (Bilbao)    |

\*-------------------------------------------*/



// Funciones para la gestión del teclado de la Trainer PLUS.



// char kbd_getc( )Devuelve el código ASCII de la tecla pulsada.

//Si no se pulsó ninguna, devuelve 0.





// Conexiones del teclado.

/*

            RB0 RB1 RB2 RB3

             ^   ^   ^   ^

             |   |   |   |

           |---|---|---|---|

  RB4 ---> | 1 | 2 | 3 | F |

           |---|---|---|---|

  RB5 ---> | 4 | 5 | 6 | E |

           |---|---|---|---|

  RB6 ---> | 7 | 8 | 9 | D |

           |---|---|---|---|

  RB7 ---> | A | 0 | B | C |

           |---|---|---|---|

*/



// Caracteres ASCII asociados a cada tecla:

char const KEYS[4][4] = {{'1','2','3','F'} ,

                         {'4','5','6','E'} ,

                         {'7','8','9','D'} ,

                         {'A','0','B','C'} };



#byte kbd_port_b = 6





char kbd_getc( )

{

  char tecla=0;

  int f,c,t,i,j;



  port_b_pullups(true);

  set_tris_b(0b00001111); // RB7-RB4 salidas, RB3-RB0 entradas



  for(f=0x10, i=0; i<4; f<<=1, i++)

  {

    for(c=0x01, j=0; j<4; c<<=1, j++)

    {

      kbd_port_b = ~f;

      delay_cycles(1);

      t = kbd_port_b & 0x0F;

      t = ~(t | 0xF0 );

      if(t == c)

      {

        delay_ms(20);

        tecla=KEYS[i ][j ];

        while(t==c)

        {

          restart_wdt( );

          t = kbd_port_b & 0x0F;

          t = ~(t | 0xF0) ;

        }

        break;

      }

    }

    if(tecla)

      break;

  }



  port_b_pullups(false);

  return tecla;

}
____________________________________________________________________________________________________

Si alguien me puede aceralguna sugerencia os lo agradeceria...

Muchas gracias de antemano, un saludo!!!!!

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
Re: Lectura de teclado matricial
« Respuesta #1 en: 15 de Febrero de 2007, 14:40:24 »
Código: C++
  1. cadena[0] = kbd_getc( );
  2. while(cadena[0] = 0)
  3.   {
  4.    cadena[0] = kbd_getc( ); // captura las decenas
  5.   }
  6. cadena[1] = kbd_getc( );
  7. while(cadena[1] = 0)
  8.   {
  9.    cadena[1] = kbd_getc( ); // captura las unidades
  10.   }

Si lo haces por interrupción,cosa que te recomiendo,no necesitarás usar los bucles,basta con que hagas el volcado sobre "cadena" en la rutina de interrupción,controlando la inhibición de esta para que no se dispare cuando no interese,y siempre llevando el control de a qué dígito corresponde la pulsación (unidades o decenas)
« Última modificación: 15 de Febrero de 2007, 14:49:09 por Modulay »

Desconectado FrAnderGround

  • PIC10
  • *
  • Mensajes: 6
Re: Lectura de teclado matricial
« Respuesta #2 en: 15 de Febrero de 2007, 17:16:05 »
pero eso me permitiria luego hacer el "atoi" con cadena pa meter el numero en la variable entera?

y si eso me guarda el valor, como podria luego salir al pulsar 'A' en el teclado?

yo tenia una idea mas o menos asi...(aplicando lo ke me has dicho...)

//*****************************************************************\
//Pongamos que si pulsas la tecla B del teclado,     *
//se inicia la secuencia para asignar a la variable    *
//'valor' el numero pulsado                                   *
//*****
************************************

char cadena[2];
int valor;
char c;

c= kbd_getc();
while(c=='B'){

cadena[0] = kbd_getc( );

while(cadena[0] = 0){
                                cadena[0] = kbd_getc( ); // captura las decenas
                               }

cadena[1] = kbd_getc( );

while(cadena[1] = 0){
                                cadena[1] = kbd_getc( ); // captura las unidades
                               }
valor= atoi (cadena);     //paso el valor de las decenas y el de las unidades para obtener el entero en la variable valor.

break;                          //terminamos con el bucle para volver al programa principal       
}

***************************************************************************

Asi realizaria bien la secuencia? y almacenaria en valor lo pulsado saliendo de alli con el A? o existe algun fallo en mi estructura?

Gracias de antemano y gracias por la contestacion anterior....

Un saludo!!!!!!

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
Re: Lectura de teclado matricial
« Respuesta #3 en: 15 de Febrero de 2007, 18:19:43 »
En este caso para que la función "atoi" trabaje correctamente deberás asegurarte de que el último carácter de "cadena" es null (valor numérico 0).
Esto puedes hacerlo declarando el array de tamaño 3 y poniéndole un cero que quedará de forma permanente en la última posición.

char cadena[3];
cadena[2] = 0;
...
...
valor = atoi(cadena);

Otra forma más casera de hacerlo,si no te fuera bien con el atoi sería a partir de los valores ascii de los dígitos correspondientes...

tabla ascii

...es decir,cogemos el valor ascii del carácter en cuestión y le restamos el valor ascii del carácter '0',que es 48...así obtendrás de forma directa cada dígito en formato numérico:

decenas = cadena[0] - 48;
unidades = cadena[1] - 48;
valor = decenas*10 + unidades;

En cuanto al bucle,lo que pusiste no funcionará.
Te explico por qué:
Lo primero que haces es capturar la tecla pulsada (si no hay pulsación,la función devuelve 0).En dicho caso no entrarás en el bucle.
En el caso de que diera la casualidad de que se pulsara la tecla B justo cuando cuando haces la llamada a kbd_getc() (una posibilidad bastante remota) si se ejecutaría el bucle de forma correcta,pero en la práctica difícilmente será así,ya que kbd_getc() rastrea el teclado en busca de pulsación una única vez cuando la invocas,devolviendo el carácter null (valor ascii 0) en caso de que no haya detectado pulsación en alguna tecla.Es por esto por lo que se hace una invocación iterativa,comprobando cada vez lo que se tiene.
Así que,si tu condición de entrada a la secuencia es que se pulse "B",simplemente precede a la captura de los dígitos con un buclecillo como este,que te mantenga ahí dando vueltas hasta que se detecte la "B"

c = kbd_getc();
while(c != 'B') 
{
c = kbd_getc();
}

Después iría tu código y por último otro buclecillo idéntico para no salir hasta que no se pulse la 'A'

Resumiendo

Código: C++
  1. char cadena[3];
  2. int valor;
  3. char c;
  4.  
  5. cadena[2] = 0;
  6.  
  7. c = kbd_getc();
  8. while(c != 'B')  
  9. {
  10. c = kbd_getc();
  11. }
  12.  
  13. cadena[0] = kbd_getc( );
  14. while(cadena[0] = 0)
  15.   {
  16.    cadena[0] = kbd_getc( ); // captura las decenas
  17.   }
  18. cadena[1] = kbd_getc( );
  19. while(cadena[1] = 0)
  20.   {
  21.    cadena[1] = kbd_getc( ); // captura las unidades
  22.   }
  23.  
  24. valor= atoi (cadena);
  25.  
  26. c = kbd_getc();
  27. while(c != 'A')  
  28. {
  29. c = kbd_getc();
  30. }
« Última modificación: 15 de Febrero de 2007, 18:30:57 por Modulay »

Desconectado FrAnderGround

  • PIC10
  • *
  • Mensajes: 6
Re: Lectura de teclado matricial
« Respuesta #4 en: 16 de Febrero de 2007, 06:08:15 »
no funciona bien la secuencia que asigna el valor a cadena[0] y cadena[1],

necesitamos insertar la decena y seguidamente la unidad, y que las almacene  los dos, pero de forma secuencial, es decir, si pulso  B, primero hasta ke no pulse una tecla no se asigna su valor a Cadena[0], y luego hasta ke no pulse otra tecla no se almacene el siguiente valor en cadena[1] y una vez almacenado al pulsar A se guarda en valor y se sale de la funcion.

nuestro programa es el siguiente, (siempre siguiendo tu idea de cadena, pero ke no nos va...)

*---------------------------------------------------------------------------------------------------------------------*

main()
{

int c;                           
char temp[3];                   

while(1){

c = kbd_getc();
while(c !='B') 
{
lcd_init();
printf (lcd_putc , "pulse B");            //mientras no se pulse B piude ke se pulse.
c = kbd_getc();
}
while(c=='B')                                //al pulsar B se entra en el bucle que configurara los dos digitos.
{
//aki iria el proceso de lectura y almacenamiento de datos en Cadena[0] y cadena [1] que es el ke falla.
c = kbd_getc();
while(c !='A') 
{
c = kbd_getc();
}
while(c =='A')  //al puslar la tecla A
{
valor=atoi(cadena);       //se guarda en la variable valor el dato correspondiente
break;                          //se sale de la funcion para ke si se desea volver a consfigurar haya ke volver a pulsar B
}
}

}
}

***************************************************************************

asi ke nose que hay ke poner para q espere a ke pulse la tecla para ke lo guarde en decenas y luego espere a ke pulses para que lo guarde en unidadesy ya se kde almacenado en cadena. en ese momento de la secuencia....

Gracias por la atencion. Un saludo!!!!

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
Re: Lectura de teclado matricial
« Respuesta #5 en: 16 de Febrero de 2007, 09:04:04 »
Como va a funcionar si has hecho un lío tremendo con los bucles :D
Copia y pega el código tal y como te lo pongo y pruébalo

Código: C++
  1. char cadena[3];
  2. int valor;
  3. char c;
  4.  
  5. cadena[2] = 0;
  6.  
  7. lcd_init();   // el lcd sólo se inicializa una vez (mejor que coloques esto en el programa principal)
  8. printf (lcd_putc , "pulse B");  // esto también basta con ejecutarlo una vez y no dentro de un bucle
  9.  
  10. c = kbd_getc();
  11. while(c != 'B')  
  12.   {
  13.    c = kbd_getc();    // nos mantenemos aquí dentro hasta que se pulse B
  14.   }
  15. printf (lcd_putc , "/f");   // una vez se ha pulsado B y hemos salido del bucle borramos la pantalla del lcd
  16.  
  17. cadena[0] = kbd_getc( );
  18. while(cadena[0] = 0)
  19.   {
  20.    cadena[0] = kbd_getc( ); // esperamos pulsación para capturar las decenas
  21.   }
  22. printf (lcd_putc , "%c",cadena[0]);  // una vez se ha producido pulsación y hemos salido del bucle representamos la 1ª tecla capturada
  23.  
  24. cadena[1] = kbd_getc( );
  25. while(cadena[1] = 0)
  26.   {
  27.    cadena[1] = kbd_getc( );   // esperamos pulsación para capturar las unidades
  28.   }
  29. printf (lcd_putc , "%c",cadena[1]);  // una vez se ha producido la 2ª pulsación y hemos salido del 2º bucle representamos la 2ª tecla capturada
  30.  
  31. valor= atoi (cadena);  // llegados aquí, aquí hacemos la conversión
  32.  
  33. c = kbd_getc();
  34. while(c != 'A')  
  35. {
  36. c = kbd_getc();  // no salimos de aquí hasta que se pulse A
  37. }

Desconectado FrAnderGround

  • PIC10
  • *
  • Mensajes: 6
Re: Lectura de teclado matricial
« Respuesta #6 en: 16 de Febrero de 2007, 10:48:05 »
a ok ok, lo unico es q con atoi usando una cadena de 3 datos,  si pongo cadena[2] a 0, me daria si cadena[0] y cadena[1] valen 1 y 2 respectivamente, me asigna a int valor el numero 120.


Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
Re: Lectura de teclado matricial
« Respuesta #7 en: 16 de Febrero de 2007, 11:01:25 »
No debería ¿lo has probado o lo presupones?
El 0 no es un carácter normal,es el carácter null (de valor ascii 0).La función atoi lo interpreta como el fin de la cadena,no como un carácter que forme parte de ella.Siguiendo el ejemplo que dices al fnal de la ejecución debería quedar:

cadena[0] = '1' (valor ascii 49)
cadena[1] = '2' (valor ascii 50)
cadena[2] = null (valor ascii 0)

Desconectado FrAnderGround

  • PIC10
  • *
  • Mensajes: 6
Re: Lectura de teclado matricial
« Respuesta #8 en: 16 de Febrero de 2007, 11:21:39 »
lo probe poniendo cadena[3]={'1','2','0'};

y luego aciendo el atoi para ver como funcionaba, y me sacaba el 120....

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
Re: Lectura de teclado matricial
« Respuesta #9 en: 16 de Febrero de 2007, 12:38:40 »
A ver.
Aunque el lenguaje te permita crear variables de tipo carácter,éstas,en definitiva,son números.Se almacenan como números,que es lo único que sabe manejar y entender un sistema digital (unos y ceros).
Cuando tu creas un array de caracteres y escribes en él el carácter '0',lo que estás haciendo es escribir el valor numérico 48,que se corresponde con el código ascii del carácter '0'.El 49 es el código ascii del '1',el 50 del '2',etc...
Y el código ascii 0 (CERO NUMERICO)  se corresponde con el carácter "null",que es el que debemos usar como fin de cadena para que "atoi" trabaje como debe.
Presta más atención al código que te he puesto y míralo con detenimiento.

cadena[2] = 0;  // esta es la forma correcta,el carácter null

no es lo mismo que

cadena[2] = '0';  // así no

Desconectado FrAnderGround

  • PIC10
  • *
  • Mensajes: 6
Re: Lectura de teclado matricial
« Respuesta #10 en: 17 de Febrero de 2007, 13:18:16 »
ok muchas gracias, si surge alguna duda mas ya preguntare, gracias por las respuestas y por la atencion, un saludo!!!!!!