TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: rogeliogamberro 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
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:
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:
.................... 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;
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.
-
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.
-
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.
-
Prueba así:
#define INTCON 0x0FF2
#define GIE 7
if (bit_test (*INTCON,GIE))
ACTIVA = TRUE;