TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: marcelo2112 en 02 de Noviembre de 2010, 17:38:18

Título: Bucle que no continua indefinidamente
Publicado por: marcelo2112 en 02 de Noviembre de 2010, 17:38:18
Hola a todos, estoy haciendo un menu y al entrar en una subrutina deve continuar en alla hasta que una interrupcion externa lo detenga, pero despues de una secuencia de tres veces se detiene y no se porque. Aca dejo la parte del programa:

void menu_uno(void)
{
 
   restart_wdt();

   lcd_putc("\f");
   lcd_gotoxy(1,1);
   lcd_putc("secuencia1");
   
while(TRUE){   
   
output_high(PIN_A0);
delay_ms(300);
output_low(PIN_A0);
output_high(PIN_A1);
delay_ms(300);
output_low(PIN_A1);
output_high(PIN_A2);
delay_ms(300);
output_low(PIN_A2);
output_high(PIN_A3);
delay_ms(300);
output_low(PIN_A3);
}

   
   
  enable_interrupts(GLOBAL);
  enable_interrupts(INT_EXT);
}

Espero que me puedan ayudar. Gracias.
Título: Re: Bucle que no continua indefinidamente
Publicado por: migsantiago en 02 de Noviembre de 2010, 17:53:56
Hola, checa cómo definiste el funcionamiento de tu watchdog.
Título: Re: Bucle que no continua indefinidamente
Publicado por: tannke en 02 de Noviembre de 2010, 17:56:36
veo que la primera instruccion del menu_uno es "restart_wdt();"

y una vez dentro del bucle no restauras mas el wathdog. Seguramente sea eso, que se te esta reiniciando el pic. Un saludo

EDIT. jeje se me adelanto migsantiago
Título: Re: Bucle que no continua indefinidamente
Publicado por: marcelo2112 en 02 de Noviembre de 2010, 22:22:13
entonces pruebo con restart_wdt() dentro del wile?.
Y como hago para  para salir del bucle sin reiniciar el micro?Muchas gracias.
Título: Re: Bucle que no continua indefinidamente
Publicado por: Suky en 02 de Noviembre de 2010, 23:13:14
entonces pruebo con restart_wdt() dentro del wile?.
Y como hago para  para salir del bucle sin reiniciar el micro?Muchas gracias.

Pero, piensas utilizar el wdt? Sino configura adecuadamente los fusibles del microcontrolador.


Saludos!
Título: Re: Bucle que no continua indefinidamente
Publicado por: gera en 02 de Noviembre de 2010, 23:47:29
Otra cosa.. estas activando las interrupciones despues del bucle.. si antes las tenias desactivadas, nunca se van a disparar.
saludos!
Título: Re: Bucle que no continua indefinidamente
Publicado por: marcelo2112 en 03 de Noviembre de 2010, 09:13:18
No pienso usar el wdt, yo lo desactive.
Me di cuanta que deje las interrupciones fuera del bucle y las corregí, pero suguramente tengo mal implementado las declaraciones al inicio del programa, ya que no se como se usan correctamente, es la primera vez que uso interrupciones, buscare un ejemplo. Gracias.
Título: Re: Bucle que no continua indefinidamente
Publicado por: gera en 03 de Noviembre de 2010, 10:45:42
En CCS la interrupcion externa se usa mediante la directiva #INT_EXT. La funcion que venga despues de esa directiva es la que se ejecuta cuando ocurre la interrupcion. Como te dije antes, previamente en tu codigo tenes q habilitar las interrupciones.
saludos!!
Título: Re: Bucle que no continua indefinidamente
Publicado por: marcelo2112 en 03 de Noviembre de 2010, 11:14:31
Gracias, ahora lo tengo asi:

void menu_uno(void)
{
 
   //restart_wdt();

   lcd_putc("\f");
   lcd_gotoxy(1,1);
   lcd_putc("Opcion1");
   
while(TRUE){   

output_high(PIN_A0);
delay_ms(300);
output_low(PIN_A0);
output_high(PIN_A1);
delay_ms(300);
output_low(PIN_A1);
output_high(PIN_A2);
delay_ms(300);
output_low(PIN_A2);
output_high(PIN_A3);
delay_ms(300);
output_low(PIN_A3);
 
  enable_interrupts(GLOBAL);
  enable_interrupts(INT_EXT);
 
}

Pero el bucle continua indefinidamente sin importarle si se presiono el pulsador. Si no pongo el while la secuencia ocurre solo una ves y regrasa aca:

#INT_EXT
void menu()
{

Sin que se haya presionado ningun pulsador.
Título: Re: Bucle que no continua indefinidamente
Publicado por: bmb en 03 de Noviembre de 2010, 11:36:22
Hola marcelo2112, la habilitación de las interrupciones parece seguir mal ubicada como te ha dicho gera.  Además, no se ve la forma en que piensas salir del bucle en la función menu_uno().  Si subes el código completo tal vez sea más fácil ayudarte.

Saludos!
Título: Re: Bucle que no continua indefinidamente
Publicado por: AngelGris en 03 de Noviembre de 2010, 11:42:17
Comparto lo mencionado por los colegas.

  Para ir tirando una idea. La habilitación de las interrupciones debe estar antes del while y no dentro del mismo, ya que si está dentro estás repitiendo una y otra vez lo mismo y no es necesario.

  En la función de la interrupción tendrías que activar un flag y luego en el bucle while testear dicho flag y cuando tome el valor que te interese salís del bucle.

un ejemplillo para el while

Código: C
  1. While (flag == 0)
  2. {
  3.   .....
  4.   .....
  5.   ......
  6. }
Título: Re: Bucle que no continua indefinidamente
Publicado por: marcelo2112 en 03 de Noviembre de 2010, 12:55:49
Gracias, activando un flag funciono correctamente.
Ahora quiero migrar del 18f2550 al 16f886/876 correctamente. Que tengo que tener en cuenta?
Esta es la inicializacion del 2550:

#byte pb       =0xF81
#bit t_ok      =pb.0      // RB0, pin21 (Tecla OK/MENU).
#bit t_up      =pb.1      // RB1, pin22 (Tecla UP).
#bit t_down    =pb.2      // RB2, pin23 (Tecla DOWN).

#byte intcon   =0xFF2
#bit  intf     =intcon.1

Y quiero utilizar todos los pines A como salidas.
Me voy a poner a leer, entiendo poco del C.Gracias.
Título: Re: Bucle que no continua indefinidamente
Publicado por: gera en 03 de Noviembre de 2010, 13:02:43
a ver.. lo q tendrias q hacer es algo parecido a esto:

Código: C
  1. short flag=1;
  2. #INT_EXT
  3. void int_ext_isr()
  4. {
  5.    flag=0;
  6. }
  7.  
  8. void main()
  9. {
  10.   //configurar los puertos, y el pin de la int como entrada
  11.   //configurar la interrupcion externa
  12.   enable_interrupts(GLOBAL);
  13.   enable_interrupts(INT_EXT);
  14.  
  15.   while(flag)
  16.   {
  17.     //tu codigo
  18.   }
  19. }
Título: Re: Bucle que no continua indefinidamente
Publicado por: marcelo2112 en 04 de Noviembre de 2010, 11:37:52
Pregunto otra cosa, cuando entro dentro del bucle; puedo testear el estado de los pulsadores para pasar a la siguiente rutina?
Este es la rutina de chequeo de los pulsadores:

if(testeado==0)       // si la opcion seleccionada es la 0, salimos del menú
   {
     
      intf=0;
      enable_interrupts(GLOBAL);
      enable_interrupts(INT_EXT);
     lcd_putc("\f");
   
      break;
 }
 
   else if(testeado==1){menu_uno1(); lcd_putc("\f");}
   else if(testeado==2){menu_dos1(); lcd_putc("\f");}
   else if(testeado==3){menu_tres1(); lcd_putc("\f");}
   else if(testeado==4){menu_cuatro1(); lcd_putc("\f");}
   else if(testeado==5){menu_cinco1(); lcd_putc("\f");}
      }

Y esto es uno de los bucles:

void menu_uno1(void)
{
 //  restart_wdt();

   lcd_putc("\f");
   lcd_gotoxy(1,1);
   lcd_putc("menu");
   lcd_gotoxy(1,2);
   lcd_putc("1"); 
  while(true)
  {
output_high(PIN_A0);
delay_ms(300);
output_low(PIN_A0);
output_high(PIN_A1);
delay_ms(300);
output_low(PIN_A1);
output_high(PIN_A2);
delay_ms(300);
output_low(PIN_A2);
output_high(PIN_A3);
delay_ms(300);
output_low(PIN_A3);


   
   intf=0;
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_EXT);
}
}

Lo que quiero es pasar directamente a la siguiente rutina sin tener que hacer uso de la interrupcion, ya que con esta vuelvo al menu.
Gracias por su ayuda, sin ustedes me seria imposible avanzar.