Autor Tema: Problema con interrupciones  (Leído 2059 veces)

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

Desconectado Robert76

  • PIC24F
  • *****
  • Mensajes: 561
Problema con interrupciones
« en: 11 de Abril de 2021, 20:38:31 »
Buenas a la comunidad, estuve buscando en el foro, algún tema relacionado pero no encontré algo preciso.
Comento el asunto.
Estoy Armando un código en CCS, que utiliza varias interrupciones, entre ellas uso TMR0, TMR1 y TMR2.
El punto está en que hay una parte del código que no se ejecuta cuándo debe(condición IF) o lo hace de forma aleatoria. He puesto marcas dentro del bucle para debuguear y efectivamente NO entra en esa condición a pesar que se dan las condiciones.
Lo que he notado es que si desactivo las interrupciones, el programa corre de maravillas.
Las he desactivado de a una para ir acercándome al problema, pero no, el problema desaparece cuándo no hay interrupciones en proceso.
Ahora viene la pregunta, será un problema del compilador?
El PIC utilizado es un 18F2550, también probé un 16F819 con los mismos resultados.

Desconectado Eduardo2

  • PIC24F
  • *****
  • Mensajes: 941
Re:Problema con interrupciones
« Respuesta #1 en: 11 de Abril de 2021, 21:19:15 »
Es difícil imaginar qué puede estar pasando, la mayoría de las causas de errores insólitos son insólitas.

Subí un bloque de código que pueda compilarse para ver qué puede ser.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema con interrupciones
« Respuesta #2 en: 11 de Abril de 2021, 22:27:21 »
Intenta recrearlo con lo minimo posible, un cambio de salidas en la interrupciones. Y ese if...

Puede ser el compilador y su efecto de optimizar el código. Si estas usando alguna variable que se comparte, proba ponerle ponerle el "volatile" a las variables que se usen en la interrupción y en el programa, tal ves eso haga cambiar la decisión del compilador de quitarla.

Si podes recrearlo con lo minimo, luego se puede llegar a ver el ASM resultante para ver que paso con esa parte del codigo.
« Última modificación: 11 de Abril de 2021, 22:29:38 por KILLERJC »

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:Problema con interrupciones
« Respuesta #3 en: 12 de Abril de 2021, 04:21:45 »
El if que no se ejecuta, ¿está dentro del handler de interrupción?. 

 ¿Depende de alguna variable local?..   
 
  Prueba desactivando las optimizaciones para intentar descartar que sea por lo que dice KillerJC.
« Última modificación: 12 de Abril de 2021, 04:29:24 por remi04 »

Desconectado Robert76

  • PIC24F
  • *****
  • Mensajes: 561
Re:Problema con interrupciones
« Respuesta #4 en: 12 de Abril de 2021, 07:15:24 »
Gracias por las respuestas, apenas pueda subo el código que es muy simple.
El IF está en la función principal.
Creo que el tema viene por el lado variables. Cómo la memoria de los PICs viene fragmentada, me parece que hay algunas solapadas por error del compilador.
Ya que un array según el tamaño que se lo defina, por ejem a var[64]  aparece otro comportamiento errático en otra variable, que se vuelve cero, y en ningún momento le asigno ese valor. Ahora sí lo defino más pequeño, digamos var[16] no ocurre ese detalle.
« Última modificación: 12 de Abril de 2021, 09:07:21 por Robert76 »

Desconectado Robert76

  • PIC24F
  • *****
  • Mensajes: 561
Re:Problema con interrupciones
« Respuesta #5 en: 12 de Abril de 2021, 10:15:10 »
Aquí les comparto parte del código.
El problema se da en la condición IF en dónde compara la variable rebot==200, la variable se incrementa  aparentemente pero por algún motivo, NO llega al valor 200 o bien lo saltea!


Código: [Seleccionar]

#include <18F2550.h>
//#device adc=10
#fuses NOWDT, HSPLL, NOPUT, PROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT, CPUDIV1, PLL3, NOMCLR, NOVREGEN, RESERVED
#use delay (clock=12000000)
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#zero_ram

///////////////////////////////////////////////////////////////////////////////
static int bufl[1950]; 
static int ptc=1;
static long rebot, x, y, pitch=130;
   
void main(void)
{   
set_tris_a(0b11111111);
set_tris_b(0b00000000);
set_tris_c(0b00000011);

output_b(0);
///////////////////////////////////////////////////////////////////////////////
setup_adc( ADC_CLOCK_DIV_2);
setup_adc_ports(AN0|VREF_VREF); //  VRef_min=A2 Vref_max=A3
set_adc_channel(0);                        // Habilita A0= ent Analog
read_adc(ADC_START_ONLY);
//ADFM=1;
///////////////////////////////////////////////////////////////////////////////
setup_timer_2(T2_DIV_BY_1,255,1);
setup_ccp1(CCP_PWM);
//CCP1CON=0b00001100;
///////////////////////////////////////////////////////////////////////////////
setup_timer_0(T0_INTERNAL|T0_8_BIT|T0_DIV_2);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);
//setup_timer_2(T2_DIV_BY_1,1,1);
///////////////////////////////////////////////////////////////////////////////
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_TIMER1);
disable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);

while(true) 
{
 if(!RC0||!RC1)                                                                // Lee botón  (A4=-) (A4=+)
   {
      if(rebot==200)                            // ===> La variable rebot no se incrementa cuándo debe
        {
       
         ...

        }
        if(rebot<500)rebot++;
   }
else rebot=0;
}
}
 
#INT_GLOBAL
 
void isr_global()
{
  if(TMR0IF)
    {
      TMR0IF=0;                                                                             // Resetea bit interrup           
     ... 
    }
  if(TMR1IF)
    {
      TMR1IF=0;                                                                            // Resetea bit interrup
      ...
     }


« Última modificación: 12 de Abril de 2021, 10:20:59 por Robert76 »

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:Problema con interrupciones
« Respuesta #6 en: 12 de Abril de 2021, 10:38:28 »
Aquí les comparto parte del código.
El problema se da en la condición IF en dónde compara la variable rebot==200, la variable se incrementa  aparentemente pero por algún motivo, NO llega al valor 200 o bien lo saltea!


Código: [Seleccionar]

#include <18F2550.h>
//#device adc=10
#fuses NOWDT, HSPLL, NOPUT, PROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT, CPUDIV1, PLL3, NOMCLR, NOVREGEN, RESERVED
#use delay (clock=12000000)
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#zero_ram

///////////////////////////////////////////////////////////////////////////////
static int bufl[1950]; 
static int ptc=1;
static long rebot, x, y, pitch=130;
   
void main(void)
{   
set_tris_a(0b11111111);
set_tris_b(0b00000000);
set_tris_c(0b00000011);

output_b(0);
///////////////////////////////////////////////////////////////////////////////
setup_adc( ADC_CLOCK_DIV_2);
setup_adc_ports(AN0|VREF_VREF); //  VRef_min=A2 Vref_max=A3
set_adc_channel(0);                        // Habilita A0= ent Analog
read_adc(ADC_START_ONLY);
//ADFM=1;
///////////////////////////////////////////////////////////////////////////////
setup_timer_2(T2_DIV_BY_1,255,1);
setup_ccp1(CCP_PWM);
//CCP1CON=0b00001100;
///////////////////////////////////////////////////////////////////////////////
setup_timer_0(T0_INTERNAL|T0_8_BIT|T0_DIV_2);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);
//setup_timer_2(T2_DIV_BY_1,1,1);
///////////////////////////////////////////////////////////////////////////////
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_TIMER1);
disable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);

while(true) 
{
 if(!RC0||!RC1)                                                                // Lee botón  (A4=-) (A4=+)
   {
      if(rebot==200)                            // ===> La variable rebot no se incrementa cuándo debe
        {
       
         ...

        }
        if(rebot<500)rebot++;
   }
else rebot=0;
}
}
 
#INT_GLOBAL
 
void isr_global()
{
  if(TMR0IF)
    {
      TMR0IF=0;                                                                             // Resetea bit interrup           
     ... 
    }
  if(TMR1IF)
    {
      TMR1IF=0;                                                                            // Resetea bit interrup
      ...
     }



 ¿Y no puede pasar que llegues tarde al if??.

  Si rebot se incrementa por ejemplo en la interrupción puede estar pasando que ya esté a 201 cuando pasas por el if.    En tal caso, ¿te viene mal poner if(rebot>=200) ? Para que tenga en cuenta no solo que llegue a 200, sino que se pase... 

Desconectado Eduardo2

  • PIC24F
  • *****
  • Mensajes: 941
Re:Problema con interrupciones
« Respuesta #7 en: 12 de Abril de 2021, 12:25:05 »
A ese código le agregué unas definiciones para que me compile
Código: [Seleccionar]
#bit TMR0IF=GETENV("SFR:INTCON").2
#bit TMR1IF=GETENV("SFR:PIR1").0 
#bit RC0=GETENV("SFR:PORTC").0
#bit RC1=GETENV("SFR:PORTC").1

y el cambio en un pin para comprobar si pasa.
Código: [Seleccionar]
            if(rebot==200)      // ===> La variable rebot no se incrementa cuándo debe
            {     
                output_toggle(PIN_B0);
                while(!RC0||!RC1) ;
            }

Con este circuito de prueba anda lo mas bien...
 

* test18F.jpg
(26.97 kB, 640x405 - visto 166 veces)


??????

Desconectado Robert76

  • PIC24F
  • *****
  • Mensajes: 561
Re:Problema con interrupciones
« Respuesta #8 en: 12 de Abril de 2021, 13:23:01 »
Respondiendo a REMI04, lo que comentas sobre que la interrupción evita que justo cuándo cuándo cuenta de 200 a 201 llegue tarde, así que reduje la velocidad del timer para hacer las interrupciones más espaciadas, y nada... la cosa sigue igual.
Además una interrupción sólo interrumpe un proceso, NO puede hacer que el programa principal se saltee acciones.
Sólo puedo usar la comparación ==200 ya que debe entrar sólo una vez al IF.
Por otro lado, desde que uso interrupciones, es la 1ra. vez que tengo un problema así.
Voy a analizar el trabajo que te tomaste EDUARDO2, muchas gracias. Luego comentaré. ((:-))
Sospecho en que hay problemas con la versión del compilador, creo tener la 4.02 o algo así.
« Última modificación: 12 de Abril de 2021, 13:27:33 por Robert76 »

Desconectado Eduardo2

  • PIC24F
  • *****
  • Mensajes: 941
Re:Problema con interrupciones
« Respuesta #9 en: 12 de Abril de 2021, 16:24:04 »
Edito lo que estuve escribiendo porque hay cosas que no van  :(

------------Va de nuevo  -------------------

La interrupción global debe ser declarada como #INT_GLOBAL FAST  para que te salve el estado,  pero antes tenes que habilitarlas al principio con #DEVICE HIGH_INTS=TRUE

De lo contrario te vuelve de la interrupción con un RETFIE 0 (no recupera estado)  en lugar de un RETFIE 1 (recupera estado)
« Última modificación: 12 de Abril de 2021, 17:20:43 por Eduardo2 »

Desconectado Robert76

  • PIC24F
  • *****
  • Mensajes: 561
Re:Problema con interrupciones
« Respuesta #10 en: 12 de Abril de 2021, 19:28:20 »
Voy a ver ésto que mencionas.
Ya que es la 1ra. Vez que uso una función global de interrupciones y discrimo cuál se disparó dentro de dicha función.
Gracias Eduardo2.

Desconectado Eduardo2

  • PIC24F
  • *****
  • Mensajes: 941
Re:Problema con interrupciones
« Respuesta #11 en: 13 de Abril de 2021, 09:03:23 »
Ojo que la opción #INT_GLOBAL FAST es para los 18F,  en los 16F hay que salvar y recuperar el estado a mano.

Desconectado Robert76

  • PIC24F
  • *****
  • Mensajes: 561
Re:Problema con interrupciones
« Respuesta #12 en: 13 de Abril de 2021, 22:02:57 »
Hola, estuve chequeando sobre tu recomendación, y el resultado es el mismo.
Estoy simulando y probando en protoboard un 18F.
Probé en otro compilador y la cosa sigue igual.
Eliminé la función GLOBAL, y me remití a usar cada interrupción con su función individual, y el problema persiste.
Así que eliminé todo lo que hay en la función principal y coloqué la sig línea, que no es más que reflejar el estado de B0 en B7.
Increíble tener que llegar a ésto :(

botons=input_b()&1;
if(botons!=1)output_high(pin_B7); else output_low(pin_B7);

Y el programa NO lee el puerto y si lo hace NO provoca cambios. en el puerto B7.
Honestamente he probado casi todo sin resultados favorables.
Pero si desactivo la habilitación de interrupciones globales. La línea de programa trabaja cómo debe.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema con interrupciones
« Respuesta #13 en: 13 de Abril de 2021, 22:30:28 »
Citar
Así que eliminé todo lo que hay en la función principal y coloqué la sig línea, que no es más que reflejar el estado de B0 en B7.

Mientras menos tenga el programa, mejor, pero me gustaria si es posible que me pases el .hex del programa mas sencillo que puedas hacer (con la menor cantidad de lineas de programacion) y que presente ese error

Y luego otro hex, con lo mismo, pero deshabilitando la interrupcion.

Desconectado Robert76

  • PIC24F
  • *****
  • Mensajes: 561
Re:Problema con interrupciones
« Respuesta #14 en: 13 de Abril de 2021, 22:54:10 »
Creo que acabo de arrimarme al problema.
Me doy cuenta que en principio NO sería culpa de las interrupciones.
Lo que hice fue desactivar el almacenamiento de datos de un array que tiene 512 elementos dentro de una función de interrupción.
Y ahora lee el puerto.
Pero... entonces?
Seguramente estoy pisando datos en posiciones de memoria que usa el programa?
Cómo puedo saber que región usar de memoria para datos del programa huésped?
Apenas pueda KILLER te comparto un .hex del problema es cuestión. Ahora estoy escribiendo desde el celular.
« Última modificación: 13 de Abril de 2021, 22:59:04 por Robert76 »