Autor Tema: Tarda en regresar de una interrupción en C30  (Leído 2202 veces)

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

Desconectado alguresusb

  • PIC10
  • *
  • Mensajes: 4
Tarda en regresar de una interrupción en C30
« en: 19 de Octubre de 2011, 18:36:28 »
Buenas tardes.

Les escribo porque estoy desarrollando un código para mi dspic30f4013 en C30 y el código posee una interrupción sencilla: el programa se trata de un semáforo y al detectar un pulso en la interrupción externa INT1, lo pone en intermitente como se ve a continuación:

Código: [Seleccionar]
void __attribute__((__interrupt__)) _INT1Interrupt(void){
while (PORTDbits.RD8==1){
apagado(4);
salir();
retardo(1);
rojo(4);
salir();
retardo(1);
};
};

Técnicamente establece que mientras esté habilitado el pulso, se coloca en intermitencia en rojo. Apagado coloca todos los bits del vector que controla los leds de la fase semafórica en cero. Salir muestra en la salida (por shift register) lo que se escribió en el vector y Retardo(1) produce un retardo de 1 segundo.

Lo cierto es que cuando está el pulso colocado, la rutina ejecuta la intermitencia perfectamente, pero cuando se le quita el pulso, puede tardar de 5 a 20 minutos en regresar al sitio donde estaba en el main si es que regresa.

Espero que me puedan ayudar, saludos!

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: Tarda en regresar de una interrupción en C30
« Respuesta #1 en: 19 de Octubre de 2011, 18:54:20 »
poner un while, y 6 llamadas a funciones en una interrupcion es una muy mala idea.

Ademas, no tienes nada que limpie el flag de la interrupcion.

Algo asi:

void __attribute__((__interrupt__)) _T1Interrupt(void)
{
IFS0bits.T1IF=0; //borra flag de interrupción


pero para el INT1, el cual desconozco cual es el flag.

Desconectado alguresusb

  • PIC10
  • *
  • Mensajes: 4
Re: Tarda en regresar de una interrupción en C30
« Respuesta #2 en: 19 de Octubre de 2011, 19:08:21 »
poner un while, y 6 llamadas a funciones en una interrupcion es una muy mala idea.

Ademas, no tienes nada que limpie el flag de la interrupcion.

Algo asi:

void __attribute__((__interrupt__)) _T1Interrupt(void)
{
IFS0bits.T1IF=0; //borra flag de interrupción


pero para el INT1, el cual desconozco cual es el flag.

Gracias!

Tienes toda la razón, sin embargo no me interesa que salga rápido de la subrutina de interrupción mientras el botón esté presionado, me interesa que se quede todo el tiempo que sea necesario hasta que se suelte el botón.

Ahora bien, gracias al comando (IFS1bits.INT1IF=0;//borra el flag de interrupción) en este caso, logro salir de la interrupción, pero tarda un poco con el rojo estático una vez que cambio el bit de 1 a 0 para regresar al main. Supongo que es lógico, el punto es que debo arreglármelas para hacer que en el momento en que se presione un botón el semáforo cambie de donde estaba a rojo intermitente y al soltarlo regrese a donde estaba sin problemas... no sé si haya una forma más eficiente de hacerlo, aún no estoy muy práctico con lo de las interrupciones :S

Saludos!!!

Desconectado alguresusb

  • PIC10
  • *
  • Mensajes: 4
Re: Tarda en regresar de una interrupción en C30
« Respuesta #3 en: 19 de Octubre de 2011, 19:17:00 »
Traté por los momentos intentando cambiar la función por esta:

Código: [Seleccionar]
void __attribute__((__interrupt__)) _INT1Interrupt(void){
z=5;
IFS1bits.INT1IF=0;//borra el flag de interrupción
};

que lo que hace es poner la variable z (tiempo de verde) en 5. esta variable se ajusta en 20 antes de comenzar a estar en verde el semáforo, así que activo la interrupción luego de que el semáforo se pone en verde para hacer la prueba y resulta que se queda en verde un buen rato y luego es que cambia... como si se quedara guindado en la interrupción un rato... :-S

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: Tarda en regresar de una interrupción en C30
« Respuesta #4 en: 19 de Octubre de 2011, 20:06:26 »
como es tu circuito electrico?? Tienes alguna resistencia pull-down puesta?? Puede que se te quede flotando y por eso no salga. Tambien debes tener en cuenta que los pulsadores tienen un tiempo para estabilizarse, es decir, una vez pulsas te dan 0-1-0-1-0.... durante un tiempo, debido a que es un conector fisico, primero si no tienes resistencia pull-down prueba a ponerla.

Desconectado alguresusb

  • PIC10
  • *
  • Mensajes: 4
Re: Tarda en regresar de una interrupción en C30
« Respuesta #5 en: 20 de Octubre de 2011, 17:45:18 »
Saludos a todos, ya encontré muy por encima cuál era el problema.

Efectivamente estoy consciente de que no era la mejor forma de enfrentar el problema, pero como aún no me quería meter con los timers, tenía que trabajar con retardos y al querer que pasar inmediatamente a una función de intermitencia, me veía obligado a quedarme en la interrupción permanentemente hasta que desapareciera el pulso.

Sin embargo, el problema radicaba en que la función de delay escrita en assembler, tenía alguna complicación al utilizarla dentro de la interrupción. Al cambiarla por una función sencilla pero menos exacta, en C, salía de la interrupción perfectamente al desaparecer el pulso en el puerto INT1 que es el mismo RD8.

Ahora el siguiente paso es trabajar con timers para hacer el programa más eficiente y no ponerlo a trabajar 5 horas en una función de interrupción. Pronto deberé abrir otro hilo donde corresponde para preguntar sobre el uso del timer 1 como RTC en el dsPIC30f4013.

Muchas gracias a todos por sus repuestas.