Menú y LCD 2 x 16 duda al implementarlo

Menu en lenguaje C usando 16F877A LCD 2X16 Y Keypad


Tengo 5 programas en C y necesito ayuda para crear un menú usando el pic16f877a, lcd 16x2 y keypad 4x4. Las especificaciones son que el lcd muestre un mensaje al inicio (bienvenidos) y después de unos ms muestre seleccione una opción. Después de seleccionar una opción muestre (se está ejecutando :nombre) y aparte en los otros puertos se este ejecutando los programas que se verán con en un display doble y usando pulsadores.
Anexo los programas están para 16f84a pero como es lenguaje c se puede trasladar al 16f877a.
Se necesita un botón del keypad que nos lleve al inicio, como un reset.
En resumen el LCD muestra que opciones tenemos y cual se esta ejecutando , el keypad sirve para seleccionar la opción de 1 a 5 y tendrá un botón de reinicio y aparte las demás funciones se hacen con los pulsadores y el display doble.
Les agradezco su ayuda.
 

Adjuntos

  • programas 5.rar
    1.7 KB · Visitas: 71
Mi problema es realizar un menú usando lenguaje C en Pic C Copiler.
el hardware es un pic16f877a, lcd 16x2 y keypad 4x4abcd.
LCD EN PUERTO D Y KEYPAD PUERTOB y el boton de salida A
Necesito estructurar el menú para 7 opciones y un botón que me regrese a un mensaje de inicio.

El primer mensaje tarda 1500ms después aparece el mensaje seleccione y aparecerán los números del 1 al 7
después de seleccionar cualquiera de los 7 aparecerá un mensaje con el nombre de la opción y ahí se quedara hasta que oprimamos una tecla digamos A.

En cada opción pondré un programa diferente que ya realice pero no logro hacer que salga con un botón es decir, selecciono 1 y aparece selecciono semáforo y estará haciendo lo operación del semáforo todo el rato. ...
 
Este es un ejemplo es LENGUAJE C y necesito como poner default para cuando no sea un numero del 1 al 7 y que regrese al mensaje de bienvenidos usando el botón A, cada opción sera una programación diferente que se estara ejecutando infinitamente

PHP:
void main ()
{
   
   set_tris_a (0b00011111);
   set_tris_b (0b11111111);
   set_tris_c (0b00000000);
   set_tris_d (0b00000000);
   Port_b_pullups (true);
   lcd_init ();
   kbd_init ();
   CHAR k;
   INT8 con, x, uni, dec;
   lcd_gotoxy (3, 1) ;
   printf (lcd_putc, "\nBienvenidos"); Delay_ms (1500);
   lcd_gotoxy (1, 1) ;
   printf (lcd_putc, "Seleccione\n") ;
   printf (lcd_putc, "1 2 3 4 5 6 7\r");

   WHILE (TRUE)
   {
      
      k = kbd_getc ();
      x = k - 48;
      
      IF (k !=  0)
      {
         IF (k == ' * ')
            lcd_putc ("\fpresiono") ;

         
         ELSE
         printf (lcd_putc, "\fpresiono: = % u", x);
      }

      SWITCH (x)
      {
         CASE 1:
         WHILE (true)
         {
            lcd_gotoxy (1, 2) ;
            printf (lcd_putc, "\r F (X) = 3X ^ 2 + 2Y\r");
         }

         CASE 2:
         WHILE (true)
         {
            lcd_gotoxy (1, 2) ;
            printf (lcd_putc, "\r F (X) = X^8 + 2\r");
         }

         CASE 3:
         WHILE (true)
         {
            lcd_gotoxy (1, 2) ;
            printf (lcd_putc, "\r F (X) = 3X ^ 2 + 2Y\r");
         }

      }
   }
}
 
Última edición por un moderador:
Código:
switch (x)
  case 1:
  case 2:
  default:
    (codigo a ejecutar en caso de ser opcion 1, 2 o ninguna)

  case 3:
........

algunos compiladores soportan mutiples selecciones con un mismo codigo como:

Código:
switch (x)
  case 1:
    .....

  case 2:
    .....

........

  default:
    (codigo a ejecutar si no hubo alguna de las opciones anteriores
 
Tu problema es que el programa esta pobremente estructurado.... estas usando whiles infinitos dentro de la sentencia SWITCH - CASE obligando al programa a permanecer atorado una vez que alguien realizo una accion, lo que tienes que hacer es identificar la pulsacion del boton y en base a eso mostrar las acciones

Código:
while (1) {

  if (boton_presionado) {
    switch (x) {

      case 1:
        (acciones de display para caso 1)
        break;

      case 2:
        (acciones de display para caso 1)
        break;

      case 3:
        (acciones de display para caso 3)
        break;

      default:
        (acciones de display para caso otro)
        break;

    }
  } else {
    (mas acciones si no se ha presionado boton)
  }
}
 
Ya veo, si pero es porque se necesitan así por ejemplo para el semáforo, el contador, las compuertas lógicas y los otros 4 por que si no solo harían su acción una ves y ya y ese no es el caso.

Necesito que al sumir un botón me regrese al inicio con mis variables a cero otra ves.
 
No puedes salir de un loop infinito sin violar los principios de la programacion estructurada... necesitas volver a hacerlo desde el principio.. pensando como reorganizar las rutinas y convertirlas en funciones.. para que asi puedas llamarlas dentro de un unico loop infinito... y no varios como tienes ahorita...
 
claro que es posible.. el menu corre en el loop principal... y las interrupciones solo interrumpen al loop principal por momentos y lo que hacen es alterar banderas y variables globales que el loop principal constantemente esta revisando..
 
Buenas tardes, hestoy tratando de hacer un menu con LCD 2x16 y un PIC 16F877A, hasta el momento puedo desplazarme entre las 4 paginas del menu y entrar a cada una de ellas, mediante 4 pulsadores que estan conectadas al AN0, la forma que se utiliza para saber cual boton se oprimió es por variacion de tension. el problema que presento es que al pulsar la tecla 'L' que tengo definida para devolverme al menu principal (estando dentro de alguna de las 4 opciones) no se sale, se queda infinitamente en cada una de las funciones. Agradezco de antemano la ayuda que me puedan brindar, ya que estoy haciendo una de las partes para un robot sumo.
Adjunto el codigo del programa.

Muchas Gracias ...
 

Adjuntos

  • codigoSumo.txt
    4.8 KB · Visitas: 18
Principalmente el problema es que no volves a comprovar si "btn_push" cambia de estado: solo haciendo "while(btn_push != 'L')", siempre te dara true, ya que nunca cambia el valor de btn_push.
Hace una funcion especifica que identifique si algun boton es presionado, y devolve ese valor, luego lo aplicas al while.
Mete en la funcion, lo que hay en el main desde el "medicion = readadc()", y el if que asigna el valor a btn_push, y devolve ese valor.

Otra cosa, no es necesario hacer esto:
"lcd_putc(". ");
lcd_gotoxy(1,1);"
Con solo poner printf(lcd_putc, "\fAca elbtexto de arriba\bY este de abajo");
Ya esta, con el "\f", borras toda la pantalla, y con el "\b", vas a la segunda fila...
 
¿Es necesario que leas las teclas de forma análoga?
¿Lo haces por cuestión de ahorrar pines?
Ya que también puedes usar la técnica de poleo para leer un teclado matricial.

Sin embargo, este ejemplo te puede servir de base para leer una matriz análoga de pulsadores.
Teclado Analógico
 
Yo lo haría así:

Código:
/*Aquí va todo tu código antes del menú*/

byte flag=0;

while (flag == 0)
{
    if (tecla_que_define_la_funcion_salir == Aqui_la_condicion_que_tu_definiste)
    {
         flag=1;  /*Con lo cual saldría del while*/
    }
    /*Aquí va todo tu código del menú*/
}
 
Atrás
Arriba