TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: SirTonyV en 19 de Marzo de 2015, 02:47:41
-
Hola buenas tardes/noches donde quieran que se encuentren :), este es mi primer post en este tan afamado foro y desearía que me ayudaran a comprender como hacer un menu con submenus para el pic 16f873a y programacion en CCS C
Lo que quiero que haga ese menu es que despliegue en un LCD 16x2 un mensaje que aparescan 3 sub menus por ejemplo
menu1: activacion de sistema
menu2: activacion de subsistema
menu3: temperatura de ambiente
y que una vez presiones el boton 1 te lleve al menu 1 y se hagan todas las funciones que estan ancladas a este menu y para salir de este menu para poder acceder a los demas que se vuelva a presionar denuevo el mismo boton 1 para regresar al menu de los sub menus
Porfavor necesito esta ayuda urgente, ya intente haciendolo con delcaraciones en IF pero solo consigo que acceda a un menu y los demas menus no salgan mas aparte que cuando accedo a ese menu no consigo salir de el para llegar al menu de los submenus :(
-
Para que te puedan ayudar sería bueno que insertes en el mensaje el código que tienes hecho hasta el momento. Porque tal como está escrito el mensaje, da la sensación que quieres que te pasen el programa ya terminado.
-
Yo lo haría con un Switch - case y una variable menu y luego otra variable sub_menu que dentro del primer case trataria, para saber donde estoy, de tal manera que menu = 0 y submenu=0 pantalla principal, y desde hay segun donde estas y lo presionas incrementas y decrementas estas variables.
-
alguien por aca intento hacer lo mismo:
http://www.todopic.com.ar/foros/index.php?topic=44161.0
-
Para que te puedan ayudar sería bueno que insertes en el mensaje el código que tienes hecho hasta el momento. Porque tal como está escrito el mensaje, da la sensación que quieres que te pasen el programa ya terminado.
#include <16f873a.h>
#device adc=10
#include <stdio.h>
#include <stdlib.h>
#define LCD_ENABLE_PIN PIN_B0
#define LCD_RS_PIN PIN_B1
#define LCD_RW_PIN PIN_B2
#define LCD_DATA0 PIN_B4
#define LCD_DATA1 PIN_B5
#define LCD_DATA2 PIN_B6
#define LCD_DATA3 PIN_B7
#use DELAY (CLOCK = 4M)
#include <LCD420.c>
#fuses xt,nowdt,noput,nobrownout,nolvp,noprotect
#DEFINE use_portb_lcd true
#define push0 PIN_a1
#define push1 PIN_a2
#define Push2 PIN_a3
#define pushterm PIN_a0
void main (void)
{
while (true){
lcd_init();
lcd_gotoxy(1,1);
printf (lcd_putc,"Bienvenido a");
delay_ms(1000);
lcd_gotoxy(4,2);
printf (lcd_putc,"GUTRASE");
delay_ms(3000);
printf(LCD_PUTC, "\f");
break;
}
{
int i;
for (i=1;i<=16;++i)
{
lcd_gotoxy(1,1);
printf(LCD_PUTC, "vinculando ..(%02i)",i);
lcd_gotoxy(i,2);
printf(LCD_PUTC, "*");
delay_ms( 500 );
}
printf(LCD_PUTC, "\f");
break;
}
while (true){
lcd_init();
lcd_gotoxy(6,1);
printf (lcd_putc,"MENU");
delay_ms(1000);
printf(LCD_PUTC, "\f");
lcd_gotoxy(1,1);
printf (lcd_putc,"SELECCIONE OPC.");
lcd_gotoxy(1,2);
printf (lcd_putc,"1-activar Guante");
delay_ms(2000);
printf(LCD_PUTC, "\f");
lcd_gotoxy(1,1);
printf (lcd_putc,"2-activar teclado");
lcd_gotoxy(1,2);
printf (lcd_putc,"3-temperatura");
delay_ms(2000);
printf(LCD_PUTC, "\f");
break;
}
while (true){
menu:;
lcd_init();
lcd_gotoxy(1,1);
printf (lcd_putc,"seleccione opc.");
/*QUITE TIEMPO*/
lcd_gotoxy(1,2);
printf (lcd_putc,"1-G 2-T 3-termo");
delay_ms(3000);
break;
}
while (true){
if (input(Push0)==1){
float temper,medicion;
lcd_init();
lcd_putc(" Termometro\n");
lcd_putc(" con LM35");
delay_ms(2000);
lcd_putc("\f");
lcd_putc("Temp actual\n");
lcd_putc(" ");
delay_ms(1000);
lcd_gotoxy(1,2);
lcd_putc("oC");
while (true)
{
lcd_gotoxy(8,2);
lcd_putc(" ");
lcd_gotoxy(8,2);
setup_adc (adc_clock_internal);
setup_adc_ports (all_analog);
set_adc_channel (0);
delay_us (20);
medicion=read_adc ();
setup_adc (adc_off);
temper=medicion*(0.48875);
printf(lcd_putc,"%02.1f",temper);
delay_ms (700);
}
}
}
}
esto es lo que llevo, lo que quiero es crear los menus que aparecen ahi y con los push que ya defini poder presionarlos y llegar a los submenus que estan, por ejemplo ya tengo el sub menu de la temperatura, pero no se como salir del sub menu y regresar al menu de los sub menus :(
ya intente con comando de IF pero sigue sin resultar
-
El mayor problema que tenes, es que tenes demasiados problemas con la programacion en C o no estas entendiendo lo que estas haciendo...
La cantidad de while(true) { .... break; } que hay es impresionante y sin sentido.
Ya que si haces eso es como si lo estuvieras ejecutando 1 sola ves, por lo cual no tiene sentido poner un while
Tenes abierto corchetes sin que exista una funcion... no entiendo por que..
Deberias de identar tu codigo.. sino es inentendible.
Tenes 4 lcd_init() cuando 1 solo al comienzo es suficiente.
Y demasiados delays donde tienen hasta de 3 segundos..
Hay codigo que no corresponde al funcionamiento.. tal como esto:
for (i=1;i<=16;++i)
{
lcd_gotoxy(1,1);
printf(LCD_PUTC
, "vinculando ..(%02i)",i
); lcd_gotoxy(i,2);
delay_ms( 500 );
}
Eso solamente muestra un contador de 1 a 16 haciendo perder 8 segundos, esto es para que quede WOW! pero por ahora no.. si no estas logrando hacer funcionar lo demas.
Reducilo a lo mas simple posible, tambien parecido a eso esta el mensaje de bienvenida.
Como ya te dijeron a un switch case. Ejemplo simple con muchos errores de sintaxis mios pero para referencia.
main() {
lcd_init()
mostrar_menu()
mostrar_menu_corto()
While (true)
{
if (portb & 0x07) {
switch (portb & 0x07)
case 0x01:
Funcion1()
break;
case 0x02:
Funcion2()
break;
case 0x03:
Funcion3()
break;
default:
break;
}
mostrar_menu_corto()
}
}
-
Estuve revisando tu código y estás habilitando todo el puerto A como entradas analógicas. podrias hacer tu menú de esta forma:
#include <16f873a.h>
#device adc=10
#include <stdio.h>
#include <stdlib.h>
#define LCD_ENABLE_PIN PIN_B0
#define LCD_RS_PIN PIN_B1
#define LCD_RW_PIN PIN_B2
#define LCD_DATA0 PIN_B4
#define LCD_DATA1 PIN_B5
#define LCD_DATA2 PIN_B6
#define LCD_DATA3 PIN_B7
#define PORTA 0x05
#use DELAY (CLOCK = 4M)
#include <LCD420.c>
#fuses xt,nowdt,noput,nobrownout,nolvp,noprotect
#DEFINE use_portb_lcd true
#define push0 PIN_a1
#define push1 PIN_a2
#define Push2 PIN_a3
#define pushterm PIN_a0
float temper;
float medicion;
#use standard_io(A)
enum funciones {Temp,acG,acT};
void temperatura(void){ //Función de medir
//algoritmo correspondiente
lcd_putc(" Termometro\n");
lcd_putc(" con LM35");
delay_ms(2000);
lcd_putc("\f");
lcd_putc("Temp actual\n");
lcd_putc(" ");
delay_ms(1000);
lcd_gotoxy(1,2);
lcd_putc("oC");
lcd_gotoxy(8,2);
delay_us (20);
medicion=read_adc ();
temper=medicion*(0.48875);
printf(lcd_putc,"%02.1f",temper);
delay_ms (700);
}
void activarGuante(void){ //Función de calibrar
//algoritmo correspondiente
}
void activarTeclado(void){ //Función de inicializar
//algoritmo correspondiente
}
void run_func(int numfunc){ //Asignación de la función a realizar
//viene dada por la variable "item"
switch(numfunc) {
case Temp:
temperatura();
break;
case acG:
activarGuante();
break;
case acT:
activarTeclado();
break;
}
}
void main() {
set_tris_a(0xff);
setup_adc (adc_clock_internal);
//setup_adc_ports (all_analog);
setup_adc_ports(AN0);
set_adc_channel (0);
char item; //Variables de funciones
char n_menus = 3; //Número de funciones
lcd_init();
lcd_gotoxy(1,1);
printf (lcd_putc,"Bienvenido a");
delay_ms(1000);
lcd_gotoxy(4,2);
printf (lcd_putc,"GUTRASE");
delay_ms(3000);
printf(LCD_PUTC, "\f");
int i;
for (i=1;i<=16;++i)
{
lcd_gotoxy(1,1);
printf(LCD_PUTC, "vinculando ..(%02i)",i);
lcd_gotoxy(i,2);
printf(LCD_PUTC, "*");
delay_ms( 500 );
}
printf(LCD_PUTC, "\f");
lcd_gotoxy(6,1);
printf (lcd_putc,"MENU");
delay_ms(1000);
printf(LCD_PUTC, "\f");
lcd_gotoxy(1,1);
printf (lcd_putc,"SELECCIONE OPC.");
lcd_gotoxy(1,2);
printf (lcd_putc,"1-cambia_OPC");
delay_ms(2000);
printf(LCD_PUTC, "\f");
lcd_gotoxy(1,1);
printf (lcd_putc,"2-enter");
lcd_gotoxy(1,2);
delay_ms(3000);
while (1) {
if (input(push0) == 1) { //Detecta botón de selección
item++; //Si pulsa aumenta la variable
delay_ms(300); //Para evitar rebotes
lcd_putc('\f'); }
if (item > (n_menus-1)) { //Si la variable supera el número de...
item = 0; } //funciones la inicializa
switch (item) {
case 0:
lcd_gotoxy(1,1);
printf(lcd_putc, "temperatura");
lcd_gotoxy(1,1);
break;
case 1:
printf(lcd_putc, "activarGuante");
lcd_gotoxy(1,1);
break;
case 2:
printf(lcd_putc, "activarTeclado");
lcd_gotoxy(1,1);
break;
}
if (input(push1) == 1) //Si se pulsa el botón de selección
{delay_ms(200);
run_func(item);} //se llama a la función correspondiente
}
}
-
Estuve revisando tu código y estás habilitando todo el puerto A como entradas analógicas. podrias hacer tu menú de esta forma:
#include <16f873a.h>
#device adc=10
#include <stdio.h>
#include <stdlib.h>
#define LCD_ENABLE_PIN PIN_B0
#define LCD_RS_PIN PIN_B1
#define LCD_RW_PIN PIN_B2
#define LCD_DATA0 PIN_B4
#define LCD_DATA1 PIN_B5
#define LCD_DATA2 PIN_B6
#define LCD_DATA3 PIN_B7
#define PORTA 0x05
#use DELAY (CLOCK = 4M)
#include <LCD420.c>
#fuses xt,nowdt,noput,nobrownout,nolvp,noprotect
#DEFINE use_portb_lcd true
#define push0 PIN_a1
#define push1 PIN_a2
#define Push2 PIN_a3
#define pushterm PIN_a0
float temper;
float medicion;
#use standard_io(A)
enum funciones {Temp,acG,acT};
void temperatura(void){ //Función de medir
//algoritmo correspondiente
lcd_putc(" Termometro\n");
lcd_putc(" con LM35");
delay_ms(2000);
lcd_putc("\f");
lcd_putc("Temp actual\n");
lcd_putc(" ");
delay_ms(1000);
lcd_gotoxy(1,2);
lcd_putc("oC");
lcd_gotoxy(8,2);
delay_us (20);
medicion=read_adc ();
temper=medicion*(0.48875);
printf(lcd_putc,"%02.1f",temper);
delay_ms (700);
}
void activarGuante(void){ //Función de calibrar
//algoritmo correspondiente
}
void activarTeclado(void){ //Función de inicializar
//algoritmo correspondiente
}
void run_func(int numfunc){ //Asignación de la función a realizar
//viene dada por la variable "item"
switch(numfunc) {
case Temp:
temperatura();
break;
case acG:
activarGuante();
break;
case acT:
activarTeclado();
break;
}
}
void main() {
set_tris_a(0xff);
setup_adc (adc_clock_internal);
//setup_adc_ports (all_analog);
setup_adc_ports(AN0);
set_adc_channel (0);
char item; //Variables de funciones
char n_menus = 3; //Número de funciones
lcd_init();
lcd_gotoxy(1,1);
printf (lcd_putc,"Bienvenido a");
delay_ms(1000);
lcd_gotoxy(4,2);
printf (lcd_putc,"GUTRASE");
delay_ms(3000);
printf(LCD_PUTC, "\f");
int i;
for (i=1;i<=16;++i)
{
lcd_gotoxy(1,1);
printf(LCD_PUTC, "vinculando ..(%02i)",i);
lcd_gotoxy(i,2);
printf(LCD_PUTC, "*");
delay_ms( 500 );
}
printf(LCD_PUTC, "\f");
lcd_gotoxy(6,1);
printf (lcd_putc,"MENU");
delay_ms(1000);
printf(LCD_PUTC, "\f");
lcd_gotoxy(1,1);
printf (lcd_putc,"SELECCIONE OPC.");
lcd_gotoxy(1,2);
printf (lcd_putc,"1-cambia_OPC");
delay_ms(2000);
printf(LCD_PUTC, "\f");
lcd_gotoxy(1,1);
printf (lcd_putc,"2-enter");
lcd_gotoxy(1,2);
delay_ms(3000);
while (1) {
if (input(push0) == 1) { //Detecta botón de selección
item++; //Si pulsa aumenta la variable
delay_ms(300); //Para evitar rebotes
lcd_putc('\f'); }
if (item > (n_menus-1)) { //Si la variable supera el número de...
item = 0; } //funciones la inicializa
switch (item) {
case 0:
lcd_gotoxy(1,1);
printf(lcd_putc, "temperatura");
lcd_gotoxy(1,1);
break;
case 1:
printf(lcd_putc, "activarGuante");
lcd_gotoxy(1,1);
break;
case 2:
printf(lcd_putc, "activarTeclado");
lcd_gotoxy(1,1);
break;
}
if (input(push1) == 1) //Si se pulsa el botón de selección
{delay_ms(200);
run_func(item);} //se llama a la función correspondiente
}
}
Esta demasiado bueno tu codigo ((:-)) ((:-)), el unico defecto que encontre es que necesito que la temperatura siempre este en while para que cuente a tiempo real la temperatura, en lo que me estas pasando solo la capta una vez y se regresa a los submenus, no hay forma para que el menu se quede estatico pero de igual modo puedas salir de ese menu??
-
Hola SirTonyV
Yo he estado realizando con ayuda del foro un menú con sub menú muy similar similar y tengo ese mismo problema en mis códigos pero de pronto alguno te pueda servir, yo ya los había publicado pero a qui se los dejo para que los revises.
-
Puedes modificar la funcion temperatura con un while asi:
void temperatura(void){ //Función de medir
//algoritmo correspondiente
lcd_putc(" Termometro\n");
lcd_putc(" con LM35");
delay_ms(2000);
lcd_putc("\f");
lcd_putc("Temp actual\n");
lcd_putc(" ");
delay_ms(1000);
lcd_gotoxy(1,2);
lcd_putc("oC");
do{
lcd_gotoxy(8,2);
delay_us (20);
medicion=read_adc ();
temper=medicion*(0.48875);
printf(lcd_putc,"%02.1f",temper);
}while((input(push0) == 0));
}espero te sirva.
-
Puedes modificar la funcion temperatura con un while asi:void temperatura(void){ //Función de medir
//algoritmo correspondiente
lcd_putc(" Termometro\n");
lcd_putc(" con LM35");
delay_ms(2000);
lcd_putc("\f");
lcd_putc("Temp actual\n");
lcd_putc(" ");
delay_ms(1000);
lcd_gotoxy(1,2);
lcd_putc("oC");
do{
lcd_gotoxy(8,2);
delay_us (20);
medicion=read_adc ();
temper=medicion*(0.48875);
printf(lcd_putc,"%02.1f",temper);
}while((input(push0) == 0));
}espero te sirva.
Muchisimas gracias amigo, me vino de maravilla tu ayuda :) :) :) :) :) :)