Autor Tema: Temporizar una función dentro de interrupcion  (Leído 2512 veces)

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

Desconectado jnavarro

  • PIC10
  • *
  • Mensajes: 33
Temporizar una función dentro de interrupcion
« en: 06 de Junio de 2008, 11:33:58 »
Hola,

Me encuentro haciendo un programita y tengo una pequeña duda.

En un cierto momento me aparece una interrupcion y voy a tratarla. Dentro del tratamiento de la interrupcion, llamo a varias funciones hechas por mi, pero me surje el problema, de que, en algunas ocasiones, estan funciones se quedan "colgadas", en concreto, se quedan esperando unos datos por rs232 que nunca llegan porque la electronica ha fallado, luego no sale nunca de esa función.

He pensado en hacer un temporizador, para que cuando se pase mas de X segundos dentro de esa función, se salga de ella a la fuerza. El problema, es que si ya estoy dentro de una interrupcion, no se me ejecutará otra.

¿teneis alguna idea?
__El conocimiento humano pertenece al mundo__

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: Temporizar una función dentro de interrupcion
« Respuesta #1 en: 06 de Junio de 2008, 11:48:45 »
Saludos jnavarro!
Ese tema se ha tratado en otro hilos, y la conclusión ha sido que se debe tratar en lo posible de minimizar la cantidad de código dentro de la rutina de interrupción... una alternativa es "setear" banderas que luego te servirán para tratar condicionales y ejecutar código dentro del main, y no en la rutina de interrupción. Me parece que es lo que tú puedes hacer también en este caso.
Ok nos leemos!  :mrgreen:
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado Micro23

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 226
Re: Temporizar una función dentro de interrupcion
« Respuesta #2 en: 06 de Junio de 2008, 11:56:21 »
Hola jnavarro para lo que tu quieres hacer se combiene utilizar el watchdog timer.
Saludos
El pesimista se queja del viento
El optimista espera que cambie
El realista ajusta las velas

Desconectado jnavarro

  • PIC10
  • *
  • Mensajes: 33
Re: Temporizar una función dentro de interrupcion
« Respuesta #3 en: 06 de Junio de 2008, 12:09:11 »

Ya habia pensado en el watchdog, pero cuando este ocurra reseteará al micro, y no quiero que ocurra eso, sino que simplemente salga de la función.
__El conocimiento humano pertenece al mundo__

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Temporizar una función dentro de interrupcion
« Respuesta #4 en: 06 de Junio de 2008, 12:20:34 »
¿ Podrías poner una de esas funciones que estan dentro de la interrupción "esperando" RS232 ? ¿de qué interrupción se trata?

Desconectado jnavarro

  • PIC10
  • *
  • Mensajes: 33
Re: Temporizar una función dentro de interrupcion
« Respuesta #5 en: 06 de Junio de 2008, 13:28:00 »
A ver, pongo un trozo y lo explico porque el programa entero es bastante largo.

En este codigo, cuando recibo desde el ordenador un FF llamo a una funcion comunicarseConOtroPIC() en la que en primer lugar le envio una trama a ese pic, y me quedo esperando su contestacion, una vez ha llegado la contestacion, veo como es y salgo de la funcion, y logicamente termina la interrupcion provocada por el ordenador.

El problema es que en algunas ocasiones, el otro PIC no contesta, y me quedo encerrado esperando su contestacion. Por ese motivo queria programa un Timer, el cual, si en por ejemplo 1 segundo, no se recibe contestacion, pues que saliera de la funcion.


#int_ext
void ext_isr(){
   
   if(kbhit(Canal_PC) && fgetc(Canal_PC) == 0xFF){

         comunicarseConOtroPIC();
   }
}


comunicarseConOtroPIC(){

   //Envio una trama al otro PIC
   for(i=0;i<14;i++){
      fputc(trama,Canal_WC);
   }

   //Espero contestacion del otro PIC y capturo su contestacion
   do{
      if(kbhit(Canal_WC)){     
         bufferRecepWC[posBuffWC] = fgetc(Canal_WC);
         if(bufferRecepWC[0] == 0xFF){
            posBuffWC++;
         }   
      }
   }while(bufferRecepWC[posBuffWC - 1]!=0x02);
   posBuffWC=0;
   do{
      longitud = fgetc(Canal_WC);
   }while(longitud == 0xFF || longitud == 0x02); //Para que no se me cuele un FF ó 02 como longitud
   do{
         bufferRecepWC[posBuffWC] = fgetc(Canal_WC);
         posBuffWC++;
      }while(posBuffWC<(longitud-1));
   posBuffWC=0;   
   finTrama = fgetc(Canal_WC);

  //...
  //Una vez recibida toda la trama, la trato, viendo lo que me ha llegado, y salgo de la función.
  //...

}
__El conocimiento humano pertenece al mundo__

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: Temporizar una función dentro de interrupcion
« Respuesta #6 en: 06 de Junio de 2008, 13:47:54 »
Creo que esto puede ayudarte:



Aparece en el manual del CCS 4, bajo la sentencia #use rs232...
Fíjate en la opcion "TIMEOUT=x"... me parece que es justamente lo que necesitas.
Ok saludos, nos leemos!  :mrgreen:
« Última modificación: 06 de Junio de 2008, 14:02:53 por firepic »
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado Gonzalo_BlackHawk

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 519
Re: Temporizar una función dentro de interrupcion
« Respuesta #7 en: 06 de Junio de 2008, 15:17:48 »
Hola jnavarro, Fire ya me ha ganado de mano (como siempre :D) y te ha dado la respuesta más sencilla. Puedes utilizar el timeout del RS232.

El unico problema del timeout es que el PIC se queda esperando ese tiempo a ver si llegaron datos y son milisegundos de procesamiento que se pierden, uno a veces no puede darse tal lujo.
A lo que yo apuntaria es ha utilizar la interrupción del UART en conjuncion con la interrupcion externa y además habilitar el envio de datos a la PC a traves de una bandera y no llamando a la función directamente.

Habria que ver el ASM, pero al llamar al procedimiento comunicarseConOtroPIC() desde la interrupción (y si no es llamada en ninguna otra parte del código) CCS la compila como una sola función y entonces todo el código de transmisión y recepción se ejecutaría en realidad dentro de la interrupción. Puedes indicarle con el preprocesador #separate que el compilador coloque la función y la interrupción en dos niveles de stack distintos, es decir que las trate como rutinas separadas, pero esto aunque dejaria libre a la interrupción para que pueda llamarse de nuevo, no es óptimo pues estamos apilando funciones.

Te dejo el pseudocódigo para que se termine de entender mi idea:

Código: [Seleccionar]
#int_ext
void ext_isr(){
   
   if(kbhit(Canal_PC) && fgetc(Canal_PC) == 0xFF){
         Flag_Com = 1 ;
         enable_interrupts(INT_RDA);
   }
}

#int_rda
void Uart_isr(){
   
    RECIBIR DATOS!

    disable_interrupts(INT_RDA);
}

EN EL MAIN EN UN WHILE INFINITO VA LO SIGUIENTE:

If (Flag_Com){

    ENVIO DE DATOS!

    Flag_Com = 0;
}

Obviamente si no te importa perder algunos milisegundos y si el PIC no necesita hacer mas que esperar te sugiero que implementes la idea que te ha dado Firepic. Esperamos tus resultados.

Saludos.

"Siempre piensa si el jugo vale la exprimida..."

"La muerte esta tan segura de vencer que nos da toda una vida de ventaja."

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Temporizar una función dentro de interrupcion
« Respuesta #8 en: 07 de Junio de 2008, 04:32:54 »
Aporto mi pequeño grano.

Estas usando la int_ext y int_rda para recibir datos: ¿ has puesto en el main: ext_int_edge(H_TO_L) ? para que se pueda establecer la comunicación.

Si quieres mirar como es el proceso con un ejemplo mírate el ejemplo de CCS: EX_ENCRY.c

Un saludo

Desconectado jnavarro

  • PIC10
  • *
  • Mensajes: 33
Re: Temporizar una función dentro de interrupcion
« Respuesta #9 en: 07 de Junio de 2008, 16:44:27 »
Fire, excelente solucion  :-/  Gracias !!

El lunes en llegar al trabajo lo probaré.

Si, porsupuesto que tengo activado ext_int_edge(H_TO_L), las comunicaciones las recibo perfectamente, el unico problema que se me planteó es el que os he explicado, que en ciertos momento, me quedo esperando que el otro PIC me conteste, cuando este en realidad no me va a contestar, puesto que esta realizando otras tareas mas importantes.
__El conocimiento humano pertenece al mundo__


 

anything