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

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

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Problema con interrupciones
« Respuesta #15 en: 14 de Abril de 2021, 08:41:43 »
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.

Mas que el .hex convendría el fuente, pero uno que haga la falla.  Lo que subiste antes tenía la interrupcion vacía.

Desconectado Robert76

  • PIC24F
  • *****
  • Mensajes: 577
Re:Problema con interrupciones
« Respuesta #16 en: 14 de Abril de 2021, 09:26:46 »
Por eso a tí te funcionó en la simulación, porque no escribía ningún dato en la RAM.
Estoy investigando cómo poder reservar y usar RAM sin que solape con registros de uso interno.
Porque ahí está el tema.

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Problema con interrupciones
« Respuesta #17 en: 14 de Abril de 2021, 10:15:47 »
Por esas casualidades...  Cuando escribís la RAM lo hacés antes o después de resetear TMR0IF ?

Desconectado Robert76

  • PIC24F
  • *****
  • Mensajes: 577
Re:Problema con interrupciones
« Respuesta #18 en: 14 de Abril de 2021, 12:01:50 »
Lo intenté de ambas maneras. Es decir al principio de la función y también antes de salir.
Pero no hubo cambios.
El programa lo que hace es muestrear audio, y almacenarlo en un buffer de 512 bytes.
Pero luego de reproducirlo, veo que aparecen pequeños picos en el audio reproducido.
Y probando de usar un buffer más chico, por ejem. la mitad, esos picos desaparecen.
Por lo que también me lleva a pensar que el buffer que almacena los datos está usando registros del programa, y ahí se arma la tosca!
La solución a todos esos males, es buscar la manera de organizar la RAM para evitar esos conflictos,(que por cierto en muchas oportunidades he tenido problemas anómalos, y veo que todo tiene que ver con eso)
Estoy investigando sobre la organización de la RAM, hay una directiva llamada #reserved, que nunca usé. Voy a ver que hace exactamente.
« Última modificación: 14 de Abril de 2021, 12:05:41 por Robert76 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema con interrupciones
« Respuesta #19 en: 14 de Abril de 2021, 16:42:48 »
Mas que el .hex convendría el fuente, pero uno que haga la falla.  Lo que subiste antes tenía la interrupcion vacía.

Es que no poseo el compilador CCS, y siendo muy sencillo el programa, deberia ser facil localizar la variable que se compara con 200 o un valor fijo

Desconectado Robert76

  • PIC24F
  • *****
  • Mensajes: 577
Re:Problema con interrupciones
« Respuesta #20 en: 14 de Abril de 2021, 23:10:47 »
Que tal KILLER? Paso a contar sobre el detalle.
Después de tantos intentos, el problema viene por la forma en que el compilador asigna el espacio de RAM a los arrays del programa.
Ayer comencé a desactivar uno a uno, hasta que de repente, el programa lee los dos puertos que tiene asignado a un botón cada uno.
Leyendo un poco encontré info. cómo manipular la RAM.
Y encuentro la directiva #reserve, pero sólo sirve para asignar locaciones para uso exclusivo del compilador, listo eso terminó ahí.
Continué buscando el problema y veo que según el tamaño que asigne a los arrays el problema se daba o no.
Entonces empecé a dimensionar los arrays con valores múltiplos de 2, más específicamente de 256 en 256, de esa manera no hubo problemas, por ejem. 1023, 1535 o 1791.
Luego he intentado provocar la falla, y no lo he conseguido, probé con los valores cercanos a los que usé, y no hubo forma, desconcertándome aún más :shock:  :shock:
En conclusión, al asignar un array tipo short  var[1500] o similar, me apareció el problema. Estimo que el array estaba pisando algún valor de algún registro de uso interno cómo lo mencioné antes.
Además añadiendo la línea
#DEVICE HIGH_INTS=TRUE ,( muy bien sugerida por Eduardo2), el programa trabaja estable.

Espero le sirva a alguien más, aunque NO encontré el problema en si, pero funciona cómo debe. Veo que muchos han tenido problemas similares al mío, al trabajar con arrays de gran tamaño en los pic 18F.
Gracias por la colaboración!!!👏👏👏
« Última modificación: 14 de Abril de 2021, 23:25:07 por Robert76 »

Desconectado Robert76

  • PIC24F
  • *****
  • Mensajes: 577
Re:Problema con interrupciones
« Respuesta #21 en: 15 de Abril de 2021, 12:19:59 »
Hola gente, bueno, les comparto parte del código (sólo por curiosidad, ya que pude hacerlo funcionar)en dónde manifiesta error en los puertos, según el tamaño del array llamado
bufl[].

Si dicho array tiene 100 elementos por ejem. todo funciona cómo debe, ahora si lo dimensionamos a 300 elementos, aparecen la falla de que no actualiza los puertos de salida, o no lee un pin de entrada etc.
La única prueba que me quedó pendiente de hacer fue, escribir los datos del array, por referencia a la función, aún así debería funcionar de cualquier modo.

Código: [Seleccionar]
#include <18F2550.h>
#device HIGH_INTS = TRUE
#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
#byte ADRESH = 0xFC4                                                                       // Registro Almacenamiento valor ADC0
#byte CCPR1L = 0xFBE
#byte CCPR1H = 0xFBF
#byte CCP1CON = 0xFBD
#byte TMR0L = 0xFD6
#byte TMR0H = 0xFD7
#byte TMR1L = 0xFCE
#byte TMR1H = 0xFCF
#bit TMR0IF = 0xFF2.2
#bit TMR1IF = 0xF9E.0
#bit ADFM = 0xFC0.7
#bit RB4 = 0xF81.4
#bit RB5 = 0xF81.5
///////////////////////////////////////////////////////////////////////////////



static int bufl[300];  //==============================================> Genera en puerto RC error según tamaño del array
static int ptc=1;
static long rebot[5], x, y, pitch=130;
   
void main(void)
{   
set_tris_a(0b11111111);
set_tris_b(0b00110000);
set_tris_c(0b00000000);

output_b(0);
///////////////////////////////////////////////////////////////////////////////
setup_adc( ADC_CLOCK_DIV_2);
setup_adc_ports(AN0_TO_AN3|VSS_VDD);
set_adc_channel(2);                                                                       
read_adc(ADC_START_ONLY);
ADFM=0;
///////////////////////////////////////////////////////////////////////////////
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);
///////////////////////////////////////////////////////////////////////////////
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_TIMER1);   
enable_interrupts(GLOBAL);   
while(true)   
{                                                               
 if(!RB4||!RB5)                                                               
   {
      if(rebot[2]==200)
        {
         if(!RB4)if(ptc>0)ptc--;                                               
         if(!RB5)if(ptc<2)ptc++;                                               
         output_c(ptc);
            switch(ptc)
                  {
                   case 0:pitch=2;break; case 1:pitch=130;break; case 2 :pitch=200;break;
                  }     
        }
        if(rebot[2]<500)rebot[2]++;
   }
else rebot[2]=0;
}
}
 
#INT_GLOBAL
 
void isr_global()
{
  if(TMR0IF)
    {
      TMR0IF=0;                                                                                         
    }
  if(TMR1IF)
    {
      TMR1L=130;
      TMR1H=255; 
      bufl[x]=ADRESH;                                                       
      read_adc(ADC_START_ONLY);
      if(x<99)x++;else x=0;
      TMR1IF=0;                                                                           

     }

}



« Última modificación: 15 de Abril de 2021, 12:29:01 por Robert76 »

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Problema con interrupciones
« Respuesta #22 en: 15 de Abril de 2021, 13:58:39 »
Hola gente, bueno, les comparto parte del código (sólo por curiosidad, ya que pude hacerlo funcionar)en dónde manifiesta error en los puertos, según el tamaño del array llamado
bufl[].
Si dicho array tiene 100 elementos por ejem. todo funciona cómo debe, ahora si lo dimensionamos a 300 elementos, aparecen la falla de que no actualiza los puertos de salida, o no lee un pin de entrada etc.
...

Te había comentado que debe declararse #DEVICE HIGH_INTS=TRUE  al principio e  #INT_GLOBAL FAST  para que termine la interrupción con un RETFIE 1 , de lo contrario lo hace con RETFIE 0  y no recupera el estado.

Agregando el FAST lo pruebo con 2000 elementos y anda todo bien (al menos en el Proteus :) )


Desconectado Robert76

  • PIC24F
  • *****
  • Mensajes: 577
Re:Problema con interrupciones
« Respuesta #23 en: 15 de Abril de 2021, 16:04:46 »
Bueno, faltó aclarar ese detalle. Tuve que quitar el FAST, porque la versión que tengo 4.012(creo) daba error al compilar.
En otra PC, tengo una versión más reciente y soporta el argumento FAST, pero aún así no funcionaba.
Lo que me deja con la espina es que, sin argumento FAST, debería fallar de cualquier forma. Y no porque según el tamaño del arrays dependa el funcionamiento.
De todos modos tu aporte me sirvió para definir las cosas cómo debe hacerse.
Gracias por tu ayuda! Quedó todo ok ((:-)) ((:-))
« Última modificación: 15 de Abril de 2021, 16:10:32 por Robert76 »

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Problema con interrupciones
« Respuesta #24 en: 15 de Abril de 2021, 16:38:45 »
El atributo FAST te da error si no lo habilitaste antes con #DEVICE HIGH_INTS=TRUE 

Puede que sea un bug de esa versión, yo uso la 5.091.
Podés probar con el salvado de estado "a mano" que propone Microchip

Código: [Seleccionar]
#byte STATUS = getenv("SFR:STATUS") ;
#byte BSR    = getenv("SFR:BSR")    ;

byte W_TEMP,STATUS_TEMP,BSR_TEMP    ;

//EXAMPLE 9-1: SAVING STATUS, WREG AND BSR REGISTERS IN RAM

    #ASM
        MOVWF W_TEMP                ; W_TEMP is in virtual bank
        MOVFF STATUS, STATUS_TEMP   ; STATUS_TEMP located anywhere
        MOVFF BSR, BSR_TEMP         ; BSR_TMEP located anywhere
    #ENDASM

    //
    // USER ISR CODE
    //

    #ASM
        MOVFF BSR_TEMP, BSR         ; Restore BSR
        MOVF W_TEMP, W              ; Restore WREG
        MOVFF STATUS_TEMP, STATUS   ; Restore STATUS
    #ENDASM

El problema que aparentemente tenés es que la interrupción te cambia el banco de memoria (el registro BSR) y no se restaura.

« Última modificación: 15 de Abril de 2021, 16:41:03 por Eduardo2 »

Desconectado Robert76

  • PIC24F
  • *****
  • Mensajes: 577
Re:Problema con interrupciones
« Respuesta #25 en: 15 de Abril de 2021, 19:04:55 »
Excelente!!! Gracias por el dato. :-/
Estuve haciendo más pruebas en la versión 5.0XX de CCS, que si soporta el argumento FAST.
Y vuelve a fallar al leer o accionar puertos, cuándo declaro una variable short de 1700 elementos.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema con interrupciones
« Respuesta #26 en: 15 de Abril de 2021, 19:23:51 »
Resumen: Problema del compilador  :D

Desconectado Robert76

  • PIC24F
  • *****
  • Mensajes: 577
Re:Problema con interrupciones
« Respuesta #27 en: 15 de Abril de 2021, 23:01:06 »
No queda otra que aprender a vivir con Bugs.
Peor es casarse me dijeron. :P


 

anything