Autor Tema: Interrupción dentro de interrupción  (Leído 3653 veces)

0 Usuarios y 3 Visitantes están viendo este tema.

Desconectado c4_esp_VR

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 735
    • www.muchotrasto.com
Interrupción dentro de interrupción
« en: 05 de Septiembre de 2011, 11:39:58 »
Hola compañeros foreros,

Tengo una ligera duda de concepto...mi memoría me dice que no es bueno llamar a una interrupción dentro de una interrupción, pero no estoy seguro de ello. Os comento tengo un timer que me lleva a la ISR (interrupt service routine) de éste cuando se derborda. De tal forma que cuando se derborda, dentro de la ISR del timer, llamo al ADC y este al ser llamado va al ISR del ADC...

A modo de seudo-código.

Código: [Seleccionar]
uint dato=0;
bool isDato=false:
void ADC_isr()
{
//Leemos dato del registro
dato=registroADC(0);
//Activamos flag
isDato=true;
}

void timer_isr()
{
//Activamos captura del ADC (Sample&Hold)
adc_start(0);
}

vod main()
{
timer_preconfigure(1000);//Desborda cada 1ms
timer_start();
while (true)
{
if (isDato==true)
{
isDato = false;
printf("%i\r\n",dato);
}

}
}

¿Es esto bueno?, de no ser así, ¿qué otras formas serían posibles?.

Como siempre muchas gracias.

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Interrupción dentro de interrupción
« Respuesta #1 en: 05 de Septiembre de 2011, 12:16:01 »
se supone que no debes realizar muchas operaciones dentro de una interrupcion, esto incluye otra interrupcion, lo recomendable es que cuando entres a una interrupcion actives una bandera para que la funcion que deseas se realice dentro del main y asi quedas libre para poder atender a otra interrupcion
"Nada es imposible, no si puedes imaginarlo"

Desconectado c4_esp_VR

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 735
    • www.muchotrasto.com
Re: Interrupción dentro de interrupción
« Respuesta #2 en: 05 de Septiembre de 2011, 12:21:12 »
Citar
se supone que no debes realizar muchas operaciones dentro de una interrupcion, esto incluye otra interrupcion, lo recomendable es que cuando entres a una interrupcion actives una bandera para que la funcion que deseas se realice dentro del main y asi quedas libre para poder atender a otra interrupcion

Hola,

Efectivamente eso es lo que solía hacer, pero tengo que asegurarme que el valor que adquiero en el ADC esté dentro del ton(led encendido) del PWM generado con el pulso, de lo contrario puede que adquiriese un valor en el ADC que esté en el toff(led apagado), es por ello el requerimiento de esto y más teniendo en cuenta que el ton es de 50us y el toff de 950us...

A ver si se nos ocurre algo más.

Muchas gracias.

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Interrupción dentro de interrupción
« Respuesta #3 en: 05 de Septiembre de 2011, 12:25:19 »
me parece que si te daria tiempo de ralizar la lectura en cuanto tengas la activacion del ton, ya que la conversion tarda entre 2 y 4 us, y las instrucciones duran menos de 1 us cada una(aunque dependen de tu cristal). y tu tienes 50 us de tiempo para realizar esto, me parece suficiente tiempo
"Nada es imposible, no si puedes imaginarlo"

Desconectado mtristan

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 395
Re: Interrupción dentro de interrupción
« Respuesta #4 en: 05 de Septiembre de 2011, 12:33:38 »
.


Como los pic tienen un solo vector de interrupción en su memoria de programa, no permiten atender más de 1 interrupción a la vez. Lo que pasaría si estuvieras dentro de la interrupción del timer y luego se activara la del adc, sería que la bandera de este último se activaría, pero recién se accedería a la interrupción del adc cuando se salga de la del timer.
Podrías probar con esto:
 (Dentro de la int. del timer):
 - Borrar la bandera del timer y del adc.
 - Activar la lectura del adc
 - Esperar a que se active la bandera de la int. del adc
 - Salir de la int.
E inmediatamente entraría en la int. del adc. También hay que tener en cuenta que las banderas de interrupción se activan siempre que ocurra su evento de disparo (por ej, el desborde del timer) independientemente del estado del bit GIE y de los respectivos bits de habilitación de int. individuales.

Espero que se me entienda lo que quiero decir  :tongue:

Saludos.

« Última modificación: 05 de Septiembre de 2011, 12:46:10 por mtristan »
When you see a good move, look for a better one (Emanuel Lasker)

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Interrupción dentro de interrupción
« Respuesta #5 en: 05 de Septiembre de 2011, 12:46:25 »
Citar
Como los pic tienen un solo vector de interrupción en su memoria de programa,

En la serie 16f es asi, pero en la serie 18f creo que los hay con dos vectores de interrupcion, y uno de ellos tiene prioridad sobre el otro. no soy un gran experto en la serie 18f pero estoy casi seguro que es asi.

Una interrupcion no deberia tardar mas de 50us, o hacer lo posible para que asi sea.

Desconectado mtristan

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 395
Re: Interrupción dentro de interrupción
« Respuesta #6 en: 05 de Septiembre de 2011, 12:50:05 »
.


Bueno, en realidad los de la serie 16F tienen también el vector de reset, que puede considerarse una interrupción. Desconozco totalmente la linea 18F, pero me imaginaba que tenían algo así.

Saludos.

When you see a good move, look for a better one (Emanuel Lasker)

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Interrupción dentro de interrupción
« Respuesta #7 en: 05 de Septiembre de 2011, 13:51:59 »
En los 16F nunca atenderás una interrupción mientras estas en otra. Existe un solo vector de interrupción, y en el caso de estar atendiendo a una ocurre otra, termina de ejecutar la actual, sale de la interrupción y entra de nuevo.

En los 18F si se puede, ya que dispone de 2 vectores (alta y baja prioridad). Así que si estas atendiendo una interrupción de baja prioridad y ocurre una de alta prioridad, atiende esta última y luego sigue con la de baja prioridad.

En los PIC24 ya es otro cantar, hay 7 niveles de prioridad  :tongue:

Como se estructuran las isr en CCS puede llegar a confundir el concepto de interrupción para cada arquitectura  :?


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: Interrupción dentro de interrupción
« Respuesta #8 en: 05 de Septiembre de 2011, 14:39:53 »
Creo que esto se refiere a que no es bueno utilizar una funcion dentro de una interrupcion, no es que sea bueno, es que si llamas a una funcion dentro de la interrupcion los registros se modifican, entonces al volver al codigo normal puede haber algun registro corrupto (sobrescrito). En el CSS no se como ira, se que en el C18 puedes elegir que datos salvar para que cuando salgas de la interrupcion estos se restauren, aun asi lo hace automaticamente. Supongo que en el CSS tambien lo hara asi, el problema es que entre mas datos tenga que guardar, mas tardara tu interrupcion, y tu codigo no sera efectivo en caso de que requieras precision de tiempos.

Creo recordar que si utilizabas una funcion dentro de una interrupcion, te salia una advertencia al compilar o algo asi no? O si utilizabas divisiones/multiplicaciones. Es por esto mismo

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Interrupción dentro de interrupción
« Respuesta #9 en: 05 de Septiembre de 2011, 15:17:48 »
En los 16F nunca atenderás una interrupción mientras estas en otra. Existe un solo vector de interrupción, y en el caso de estar atendiendo a una ocurre otra, termina de ejecutar la actual, sale de la interrupción y entra de nuevo.

Esto es técnicamente incorrecto. Una vez ocurrida una interrupción y dentro del vector, podrías volver a habilitar el bit INTCON,GIE y si al menos alguna bandera de alguna interrupción habilitada está activa, se volverá a interrumpir la mismísima subrutina de ISR.

Es un procedimiento algo complejo. Te recomendaría que intentes hacerlo sin tener que recurrir a esta técnica. Probablemente sea más sencillo pasarse a un 18F o superior, que ya poseen más de un vector de interrupciones y más de una prioridad.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Interrupción dentro de interrupción
« Respuesta #10 en: 05 de Septiembre de 2011, 15:30:04 »
En los 16F nunca atenderás una interrupción mientras estas en otra. Existe un solo vector de interrupción, y en el caso de estar atendiendo a una ocurre otra, termina de ejecutar la actual, sale de la interrupción y entra de nuevo.

Esto es técnicamente incorrecto. Una vez ocurrida una interrupción y dentro del vector, podrías volver a habilitar el bit INTCON,GIE y si al menos alguna bandera de alguna interrupción habilitada está activa, se volverá a interrumpir la mismísima subrutina de ISR.

Si, lo iba a indicar como caso aparte, extra de lo propio de CCS  ;-)
No contesto mensajes privados, las consultas en el foro

Desconectado AKENAFAB

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3227
Re: Interrupción dentro de interrupción
« Respuesta #11 en: 05 de Septiembre de 2011, 20:24:04 »
Si estas usando CCS  revisa el tiempo que demora en atender la interrpción.

Hace mucho alboroto con solo entrar a la interrupción y salir de ella,por lo menos con los pic16F y menores;dependiendo también de la velocidad de tu uC puede que esto te afecte o no para el tratamiento de tus datos.

Saludos!

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Interrupción dentro de interrupción
« Respuesta #12 en: 05 de Septiembre de 2011, 23:17:19 »
En los 16F nunca atenderás una interrupción mientras estas en otra. Existe un solo vector de interrupción, y en el caso de estar atendiendo a una ocurre otra, termina de ejecutar la actual, sale de la interrupción y entra de nuevo.

Esto es técnicamente incorrecto. Una vez ocurrida una interrupción y dentro del vector, podrías volver a habilitar el bit INTCON,GIE y si al menos alguna bandera de alguna interrupción habilitada está activa, se volverá a interrumpir la mismísima subrutina de ISR.

Si, lo iba a indicar como caso aparte, extra de lo propio de CCS  ;-)

Bien! Siempre en todos los detalles!  :D :D
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Interrupción dentro de interrupción
« Respuesta #13 en: 05 de Septiembre de 2011, 23:57:57 »
En los 16F nunca atenderás una interrupción mientras estas en otra. Existe un solo vector de interrupción, y en el caso de estar atendiendo a una ocurre otra, termina de ejecutar la actual, sale de la interrupción y entra de nuevo.

Esto es técnicamente incorrecto. Una vez ocurrida una interrupción y dentro del vector, podrías volver a habilitar el bit INTCON,GIE y si al menos alguna bandera de alguna interrupción habilitada está activa, se volverá a interrumpir la mismísima subrutina de ISR.

Si, lo iba a indicar como caso aparte, extra de lo propio de CCS  ;-)

Bien! Siempre en todos los detalles!  :D :D

Y claro, no eres el "único"  :D :D :D
No contesto mensajes privados, las consultas en el foro

Desconectado NoSepComo

  • PIC18
  • ****
  • Mensajes: 305
Re: Interrupción dentro de interrupción
« Respuesta #14 en: 06 de Septiembre de 2011, 04:00:22 »
Lo único que pasaba con eso era el tema de anidarlas correctamente, pero si lo haces en un compilador avanzado te da todo igual, porque lo hace por ti todo el compilador. Lo único el tema de los tiempos que ya han comentado algunos, ya que al final las interrupciones son saltos en el flujo de programa que destrozan el pipeline del ciclo de instrucción. Pero vamos, que tiene que ser un periférico muy lento para que te retarde mucho la ejecución. Yo lo he hecho más de una vez y va bien, haciendolo siempre como te indicó suky.