Autor Tema: Funcion interrupt_active()  (Leído 2263 veces)

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

Desconectado rogeliogamberro

  • PIC10
  • *
  • Mensajes: 34
Funcion interrupt_active()
« en: 07 de Julio de 2009, 03:27:45 »
Hola a Todos!

Hace algun tiempo publique este post consultando por una funcion que me indique el estado de las interrupciones:http://www.todopic.com.ar/foros/index.php?topic=26171.0

En mi busqueda de lograr guardar el estado de las interrupciones de los timer (por no poder deshabilitar el global ni el int_RDA) para luego poder restauralos, encontre una falla en la funcion interrupt_active() en CCS 4.084 y PIC18F4620. Esta es la prueba que realice:

1) Cuento con estas funciones

Código: [Seleccionar]

void Guarda_Interrupciones (void)
{
 int i;
 ESTADO_DE_INTERRUPCIONES [0] = interrupt_active(GLOBAL);
 ESTADO_DE_INTERRUPCIONES [1] = interrupt_active(int_TIMER0);
 ESTADO_DE_INTERRUPCIONES [2] = interrupt_active(int_TIMER1);
 ESTADO_DE_INTERRUPCIONES [3] = interrupt_active(int_TIMER2);
 ESTADO_DE_INTERRUPCIONES [4] = interrupt_active(int_TIMER3);
 ESTADO_DE_INTERRUPCIONES [5] = interrupt_active(int_RDA);
 for (i = 0; i < 6; i++)
   {
    if (ESTADO_DE_INTERRUPCIONES [i])
     putc (0x22);
    else
     putc (0xEE);}
}

void Restaura_Interrupciones (void)
{
 int i;
 for (i = 0; i < 6; i++)
   {
    if (ESTADO_DE_INTERRUPCIONES [i])
     putc (0x11);
    else
     putc (0xFF);
   }

if (ESTADO_DE_INTERRUPCIONES [1])
   enable_interrupts(int_TIMER0);
else
   disable_interrupts(int_TIMER0);
   
if (ESTADO_DE_INTERRUPCIONES [2])
   enable_interrupts(int_TIMER1);
else
   disable_interrupts(int_TIMER1);

if (ESTADO_DE_INTERRUPCIONES [3])
   enable_interrupts(int_TIMER2);
else
   disable_interrupts(int_TIMER2);

if (ESTADO_DE_INTERRUPCIONES [4])
   enable_interrupts(int_TIMER3);
else
   disable_interrupts(int_TIMER3);

if (ESTADO_DE_INTERRUPCIONES [5])
   enable_interrupts(int_RDA);
else
   disable_interrupts(int_RDA);
   
   if (ESTADO_DE_INTERRUPCIONES [0])
   enable_interrupts(GLOBAL);
else
   disable_interrupts(GLOBAL);
}

void Deshabilita_Interrupciones (void)
{
   disable_interrupts(GLOBAL);
   disable_interrupts(int_TIMER0);
   disable_interrupts(int_TIMER1);
   disable_interrupts(int_TIMER2);
   disable_interrupts(int_TIMER3);
   disable_interrupts(int_RDA);
}

void Habilita_Interrupciones (void)
{
   enable_interrupts(GLOBAL);
   enable_interrupts(int_TIMER0);
   enable_interrupts(int_TIMER1);
   enable_interrupts(int_TIMER2);
   enable_interrupts(int_TIMER3);
   enable_interrupts(int_RDA);
}


2) En la funcion main realice lo siguiente luego de la configuracion:

Código: [Seleccionar]

   Deshabilita_Interrupciones ();
   Guarda_Interrupciones ();
   Habilita_Interrupciones ();
   Restaura_Interrupciones ();
   
   Habilita_Interrupciones ();
   Guarda_Interrupciones ();
   Deshabilita_Interrupciones ();
   Restaura_Interrupciones ();


3) Los datos recibidos por el monitor de puerto serie fueron:

EE EE EE EE EE EE
FF FF FF FF FF FF
EE EE EE EE EE EE
FF FF FF FF FF FF

4) Lo que querria decir que enable_interrupts() esta siempre devolviendo un FALSE

La decompilacion de una instruccion es la siguiente:

Código: [Seleccionar]
....................  ESTADO_DE_INTERRUPCIONES [0] = interrupt_active(GLOBAL);
*
01646:  MOVLB  4
01648:  BCF    x19.0
0164A:  BTFSC  00.0
0164C:  BSF    x19.0



1) Tambien hice esta prueba utilizando int1 EstT1, EstT1;

Código: [Seleccionar]

Deshabilita_Interrupciones ();
 EstT1 = interrupt_active(int_TIMER1);
 EstT2 = interrupt_active(int_TIMER2);
 if (EstT1)
   putc (0xFF);
 else 
   putc (0xAA);
 if (EstT2)
   putc (0xFF);
 else 
   putc (0xAA);
 Habilita_Interrupciones ();
 delay_ms (5000); // demora para observar el funcionamiento de los timers
 EstT1 = interrupt_active(int_TIMER1);
 EstT2 = interrupt_active(int_TIMER2);
 if (EstT1)
   putc (0xFF);
 else 
   putc (0xAA);
 if (EstT2)
   putc (0xFF);
 else 
   putc (0xAA);


2) Por el Puerto se recibieron los siguiente resultados:

AA AA
Demora 5 seg sin observar funcionamiento de timers
AA AA

Lo que indicaria que esta funcion siempre devuelve FALSE.

Si alguien sabe como se soluciona u como puedo implementar esto se lo agradeceria.


Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Funcion interrupt_active()
« Respuesta #1 en: 07 de Julio de 2009, 11:55:23 »
Tu primer programa tiene una falla...

   Deshabilita_Interrupciones (); //Apaga las interrupciones, NO guarda sus ESTADOS
   Guarda_Interrupciones (); //Guarda los ESTADOS APAGADOS de las interrupciones
   Habilita_Interrupciones (); //Prende las interrupciones, NO guarda sus ESTADOS
   Restaura_Interrupciones (); //desactiva interrupciones con los ESTADOS APAGADOS guardados en Guarda_interrupciones

El problema de tu programa es que...

- Apagas las interrupciones
- Guardas sus estados apagados
- Prendes las interrupciones
- Vuelves a apagarlas porque lo haces según el contenido de ESTADOS

En tu segundo programa sí veo el problema. Asegúrate de que las funciones Deshabilita y Habilita realmente contengan disables y enables respectivamente. Si son correctas entonces usa defines con minúsculas y no los mezcles... int_rda en vez de int_RDA.

Si el problema persiste entonces publica por favor tu segundo programa completo.

Desconectado rogeliogamberro

  • PIC10
  • *
  • Mensajes: 34
Re: Funcion interrupt_active()
« Respuesta #2 en: 07 de Julio de 2009, 15:09:57 »
Gracias por responder migsantiago!

En otros microcontroladores (18F452 y 18F877) la funcion interrupt_active funcionaba correctamente... pero en este no. La idea del primer ejemplo es correcta y era:

1) fase: deshabilitar interrupciones, guardar su estado,  deshabilita interrupciones, ver el primer estado (que el resultado fue correcto)
2) face: habilitar interrupciones, guardar su estado, deshabilita interrupciones, ver el primer estado (resultado incorrecto)

Conclusion: Siempre interrupt_active () devuelve false!!!!!!!

otra prueba que realice fue la siguiente:

#define INTCON 0x0FF2
#define GIE 7

if (bit_test (INTCON,GIE))
 ACTIVA = TRUE;

pero esta no compila. Estimo que esto debe ser por la ubicacion del INTCON en 0x0FF2.


Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Funcion interrupt_active()
« Respuesta #3 en: 07 de Julio de 2009, 15:16:23 »
Prueba así:

Código: [Seleccionar]
#define INTCON 0x0FF2
#define GIE 7

if (bit_test (*INTCON,GIE))
 ACTIVA = TRUE;