TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: antoniojdobarro en 07 de Febrero de 2011, 19:02:03

Título: Lectura de teclado
Publicado por: antoniojdobarro en 07 de Febrero de 2011, 19:02:03
Supongamos quiero leer una pulsación:

Leo teclado.------
Si la tecla pulsada es 2-----Acción 1
Si latecla pulsada es 3-----Acción 2.
-----
----

Y si no detecto ninguna pulsación----Accion 7.

Com puedo hacer esta última condición, es decir si no pulso ninguna tecla ejecutar esa acción.
Título: Re: Lectura de teclado
Publicado por: MGLSOFT en 07 de Febrero de 2011, 19:18:20
Usa una comparación del tipo switch-case.

Es decir algo así:

Código: C
  1. switch (cmd) {
  2.  
  3.     case tecla0:(hago algo);
  4.            break;
  5.  
  6.     case tecla1:(hago algo distinto);
  7.            break;
  8.  
  9.     default:(no es ninguna tecla, hago esto otro);
  10.  
  11.             break; }

Se entiende??

Título: Re: Lectura de teclado
Publicado por: antoniojdobarro en 07 de Febrero de 2011, 19:41:53
Bien, lo tenía construido con If, else if, else, lo que ocurre es que no puedo poner un break, quiero que lo repita siempre, son entradas del teclado que van cambiando, luego tengo tambien do-while. Todo funcionaba perfectamente cuando tenía entradas independientes en el pic (si había tensión en A1 pues haz esto, si en A2 pues lo otro, el problema es cuando quiero que lo haga a partir de caracteres ya que las entradas son de RS232 luego han de ser caracteres, y no funciona como debería, se corta o traba a partir de virtual terminal).

void main(void) {
do{
switch(getchar())
{
case '2':avance();
case '3':giro_derecha();

case '5':retroceso();

default: detencion();
}

}
while(x<10);


El problema es que si no es 2 ni 3 ni 5 no tiene por que ejecutar detencion() ya que el caso contrario a esos es cualquier letra a,b,c, y yo quiero que detecte como caso contrario ninguna pulsación
Título: Re: Lectura de teclado
Publicado por: pajaro en 07 de Febrero de 2011, 20:06:53
Hola amigo
cuando quieres que salga?

verifica antes del switch que letra pueden entrar ,
y en caso contrario actue como si fuese sordo a ellas.

Un saludo.
Título: Re: Lectura de teclado
Publicado por: AngelGris en 07 de Febrero de 2011, 20:30:53
  Lo que creo tendrías que hacer antes de entrar al switch, sería testear si realmente hay un caracter a la espera de ser leído. Porque creo que getchar() se queda ahí esperando a que ingrese un caracter. ¿Qué compilador estás usando?

  Básicamente para saber si hay algún caracter en el registro RCREG basta con testear el bit RCIF. Entonces podrías hacer algo así....

Código: C
  1. if (RCIF == 1) // si me llego un caracter ejecuto esta parte
  2. {
  3.   swicth (getchar())
  4.   {
  5.     .........
  6.     .........
  7.     .........
  8.   }
  9. }
  10. else // si no llego caracter ejecuto esta parte
  11. {
  12. .........
  13. }
Título: Re: Lectura de teclado
Publicado por: antoniojdobarro en 08 de Febrero de 2011, 03:41:46
Esta  última estructura tiene muy buena pinta, y puede ser mi solución, pero no me reconoce el comando RCIF.

Puede ser debido a utilizar CCS C PCW?
Título: Re: Lectura de teclado
Publicado por: MGLSOFT en 08 de Febrero de 2011, 08:21:03
El comando kbhit() hace ese testeo en CCS, igual eso no te dice si es un carácter o un numero, vas a tener que testearlo fuera del switch case y filtrarlo antes de entrar en el mismo.
Título: Re: Lectura de teclado
Publicado por: antoniojdobarro en 08 de Febrero de 2011, 08:40:05
Bien, copio la estructura:

void main(void) {

do{
if (kbhit()){

char entrada;
entrada=getchar();

if (entrada=='2')
avance();

else if (entrada=='5')
retroceso();


}
else detencion();
}
while(x<10);
}


El problema es que en virtual console de proteus una vez que pulso 2 o 5, luego la única manera de detenerlo es pulsando una tecla que no sea una de esas dos. Es como si kbhit no funcionase, ya que si fuese cero debería irse directamente a detención y solamente entrar en la sentencia if si hubiese algún botón presionado.
Título: Re: Lectura de teclado
Publicado por: bmb en 08 de Febrero de 2011, 08:43:27
Hola, como adición a lo dicho por MGLSOFT, kbhit() debe ser llamado frecuentemente; si has presionado una tecla te devuelve su valor, y si no has presionado nada te devuelve /0.  Del encabezado de la librería KBD.C de CCS:
Citar
////  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.                                      ////
El uso de este comando de la librería KBD.C lo puedes ver en el ejemplo EX_LCDKB.C

Saludos!
Título: Re: Lectura de teclado
Publicado por: MGLSOFT en 08 de Febrero de 2011, 08:44:31
Una vez que comparas deberías poner la variable entrada en 0, asi no te molesta, ya que la variable mantiene el valor aun después y el if vuelve a entrar, por eso se ejecuta continuamente.
Título: Re: Lectura de teclado
Publicado por: AngelGris en 08 de Febrero de 2011, 09:31:22
Una vez que comparas deberías poner la variable entrada en 0, asi no te molesta, ya que la variable mantiene el valor aun después y el if vuelve a entrar, por eso se ejecuta continuamente.

  Pero en teoría no debería volver a entrar porque está el kbhit() con anterioridad.

  Digo yo especulando un poco porque en realidad no se como trabaja CCS con eso.
Título: Re: Lectura de teclado
Publicado por: antoniojdobarro en 08 de Febrero de 2011, 11:58:14
El problema de kbhit() es que una vez que se pulsa una tecla se pone a -1. Luego alguien sabe como resetearlo?

Toco la solución pero...
Título: Re: Lectura de teclado
Publicado por: bmb en 08 de Febrero de 2011, 16:51:00
El problema de kbhit() es que una vez que se pulsa una tecla se pone a -1. Luego alguien sabe como resetearlo?

Toco la solución pero...

Hola antoniojdobarro, el problema es que no estás usando correctamente la función kbhit().  Leiste el post #8 de este hilo?

EDITO: Perdón lo estaba confundiendo con otra función....

Saludos!
Título: Re: Lectura de teclado
Publicado por: AngelGris en 08 de Febrero de 2011, 17:05:10
El problema de kbhit() es que una vez que se pulsa una tecla se pone a -1. Luego alguien sabe como resetearlo?

Toco la solución pero...

Hola antoniojdobarro, el problema es que no estás usando correctamente la función kbhit().  Leiste el post #8 de este hilo?

Saludos!

  Perdón por mi ignorancia pero esta función (kbd_getc(c)) no se utiliza para leer un teclado? Antoniojdobarro quiere leer del RS232
Título: Re: Lectura de teclado
Publicado por: bmb en 08 de Febrero de 2011, 17:06:28
Si AngelGris perdón, es que confundi las funciones...


Saludos!
Título: Re: Lectura de teclado
Publicado por: pajaro en 08 de Febrero de 2011, 22:42:41
Bien, copio la estructura:

Código: C++
  1. void main(void) {
  2.  
  3. do{  //hacer..
  4.     if (kbhit()){  // si pulso tecla
  5.  
  6.          char entrada;       //declara variable
  7.          entrada=getchar();  //capturas el caracter y lo guardas en variable
  8.  
  9.            // aqui deberia de verificar o filtar con un while que quieres que pase por el if.
  10.  
  11.            if (entrada=='2') avance();
  12.  
  13.            else if (entrada=='5') retroceso();
  14.  
  15.      }//fin de if
  16.      else detencion(); //haces la detencion pero seguiras dentro del  bucle si no lo rompes
  17.    }
  18. while(x<10);
  19. }
El problema es que en virtual console de proteus una vez que pulso 2 o 5, luego la única manera de detenerlo es pulsando una tecla que no sea una de esas dos. Es como si kbhit no funcionase, ya que si fuese cero debería irse directamente a detención y solamente entrar en la sentencia if si hubiese algún botón presionado.

Otra cosa:

le dice :
hacer cosa mietras x<10.
   despues dice si pulsas tecla, carga la tecla en varible
   si esa tecla es 2 avanza
   si esa tecla es 5 retrocede
si no es 2 o 5 detines

//si no pulsaras tecla se te detendra de inmediato(no se si te da tiempo a pulsar tecla)  y se quedaria en el blucle
 que sino incrementas la x, sera infinito nunca saldra del bucle y si detencion no te saca del bucle sera infinito tambien-------

Título: Re: Lectura de teclado
Publicado por: antoniojdobarro en 09 de Febrero de 2011, 04:18:31
No incremento la x ya que no quiero salir nunca del bucle, quiero que esté atento a las pulsaciones.

El problema es que kbhit() una vez que se pulsa tiene valor -1 luego nunca más sale del if.

Luego el problema es como resetear kbhit()
Título: Re: Lectura de teclado
Publicado por: AngelGris en 09 de Febrero de 2011, 09:16:28
  Se supone que sólo entraría en el if si kbhit() fuera 1 o TRUE pero con -1 no debería entrar. Ya que no se cumpliría con la condición " kbhit() verdadero "

  Si nunca querés salir del loop conviene escribirlo como

Código: C
  1. do
  2. {
  3. ...
  4. ...
  5. ...
  6. }
  7. while (TRUE);

  Eso sería un loop infinito y no presta lugar a confusiones.

  Podés buscar en CCS el .h  del PIC que estés utilizando y ver como llama al registro donde se encuentre el bit RCIF. Luego buscar la manera de testear dicho bit en forma manual sin hacer uso de kbhit() para ver que pasa.
  Me parecío haber leído en algunos post que CCS tiene la función bit_test, con ella podrías testear el bit RCIF.

  Sería llegar a poner algo así....

Código: C
  1. while (TRUE)
  2. {
  3.   if (bit_test(PIR1,RCIF) == 1)
  4.   {
  5.     // todo lo que quieras hacer si se pulsa una tecla
  6.   }
  7.   else
  8.   {
  9.     detencion();
  10.   }
  11. }

  Tal vez hay algún bug en el compilador y por ello el fallo