La lectura de una matriz de caracteres proporciona diferentes resultados dentro y fuera de ISR

4

Tengo problemas para leer una matriz de caracteres dentro de un ISR. Estoy usando la versión 3.41 del compilador PIC18F4680 y C18.

La matriz tiene varios elementos que se rellenan a partir de los datos leídos de un RTC y deben usarse más adelante para generar datos en otra matriz que luego se usará para controlar una pantalla de 5x7.

Mi problema es que cuando leo los elementos de la matriz, obtengo un conjunto de valores en el ISR y otro fuera del ISR.

Aquí está el resultado de lo que estoy obteniendo:

 1  1
 0  0
 0  0     

 1  1
 0  0
 0  0     

 1  1
 0  0
 0  0     

 ******************* 
 1  7
 0  0
 0  0    


 ******************* 
 1  1
 0  0
 0  0     

 1  1
 0  0
 0  0     

 1  1
 0  0
 0  0

La línea superior es segundos, la segunda línea es minutos y la tercera línea son horas desde que se inició el sistema. Las tres líneas con estrellas arriba y debajo de ellas fueron enviadas desde el ISR. Como podemos ver, el valor de segundos fue 11 antes de ISR, 17 en ISR y 11 después de ISR. También he notado que esto nunca ocurre durante los primeros 10 segundos después de comenzar un minuto o durante los últimos 10 segundos de un minuto. En otras ocasiones, los cambios parecen ocurrir al azar.

Aquí está el código relevante:

k=0;//this is a sort of critical section
data[0]=from_seconds (data[0]);
data[1]=from_minutes (data[1]);
data[2]=from_hours (data[2]).time;
k=1;//if it's zero, ISR won't read the data

for (i=0;i<3;i++)
//I made sure here that the counter variable isn't used anywhere else
            {
              WriteUSART ( (data[i]/10)+48 );//Converting decimal into ASCII
              putrsUSART (" ");
              WriteUSART ( (data[i]%10)+48 );
              putrsUSART ("\r\n");
            }
            putrsUSART ("\r\n");
            putrsUSART ("\r\n");
            putrsUSART ("\r\n");
            putrsUSART ("\r\n");

Aquí está el ISR:

 if (INTCON3bits.INT1IF)
{
      if(k)//I know that I'll miss the interrupt if the k is zero, but I'll fix that later
        {
          fill_matrix (data[2],data[1], data[0]);

          putrsUSART ("\r\n");
          putrsUSART ("\r\n");
          putrsUSART ("*******************");
          putrsUSART ("\r\n");

          for (j=0;j<3;j++)
            {
              WriteUSART ( (data[j]/10)+48 );
              putrsUSART (" ");
              WriteUSART ( (data[j]%10)+48 );
              putrsUSART ("\r\n");
            }
            putrsUSART ("\r\n");
            putrsUSART ("\r\n");
            putrsUSART ("\r\n");
            putrsUSART ("*******************");
            putrsUSART ("\r\n");
        }
        INTCON3bits.INT1IF=0;
}

¿Alguna idea de lo que podría estar pasando aquí?

ACTUALIZACIÓN:

Sobre el comentario de tcrosley: La parte separada por signos de exclamación se lee con el ISR de lectura y la parte separada con estrellas se escribe con el ISR de escritura.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   0  0  0  0  0
   0  0  0  0  0
   0  0  0  0  0
   0  0  0  0  0
   0  0  0  0  0
   0  0  0  0  0
   0  0  0  0  0



 !!!!!!!!!!!!!!!!!!!!!!!! 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   0  0  0  0  0
   0  0  0  0  0
   0  0  0  0  0
   0  0  0  0  0
   0  0  0  0  0
   0  0  0  0  0
   0  0  0  0  0



 !!!!!!!!!!!!!!!!!!!!!!!! 


 ******************* 
   1  [  _  [  1
   t  @  4  0  [
   „  0  4  1  Z
   t  1  _  1  Z
   t  0  5  0  Z
   t  0  5  0  Z
   0  t  _  Z  0



 ******************* 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   1  [  _  [  1
   t  @  4  0  [
   „  0  4  1  Z
   t  1  _  1  Z
   t  0  5  0  Z
   t  0  5  0  Z
   0  t  _  Z  0



 !!!!!!!!!!!!!!!!!!!!!!!! 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   1  [  _  [  1
   t  @  4  0  [
   „  0  4  1  Z
   t  1  _  1  Z
   t  0  5  0  Z
   t  0  5  0  Z
   0  t  _  Z  0



 !!!!!!!!!!!!!!!!!!!!!!!! 

 ******************* 
   Q  ›    ›  Q
   t  @  ґ  0  ›
   „  0  ґ  Q  љ
   t  1    Q  љ
   t  0  Х  0  љ
   t  0  Х  0  љ
   0  t    љ  0



 ******************* 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   Q  ›    ›  Q
   t  @  ґ  0  ›
   „  0  ґ  Q  љ
   t  1    Q  љ
   t  0  Х  0  љ
   t  0  Х  0  љ
   0  t    љ  0



 !!!!!!!!!!!!!!!!!!!!!!!! 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   Q  ›    ›  Q
   t  @  ґ  0  ›
   „  0  ґ  Q  љ
   t  1    Q  љ
   t  0  Х  0  љ
   t  0  Х  0  љ
   0  t    љ  0



 !!!!!!!!!!!!!!!!!!!!!!!! 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   Q  ›    ›  Q
   t  @  ґ  0  ›
   „  0  ґ  Q  љ
   t  1    Q  љ
   t  0  Х  0  љ
   t  0  Х  0  љ
   0  t    љ  0



 !!!!!!!!!!!!!!!!!!!!!!!! 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   Q  ›    ›  Q
   t  @  ґ  0  ›
   „  0  ґ  Q  љ
   t  1    Q  љ
   t  0  Х  0  љ
   t  0  Х  0  љ
   0  t    љ  0



 !!!!!!!!!!!!!!!!!!!!!!!! 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   Q  ›    ›  Q
   t  @  ґ  0  ›
   „  0  ґ  Q  љ
   t  1    Q  љ
   t  0  Х  0  љ
   t  0  Х  0  љ
   0  t    љ  0



 !!!!!!!!!!!!!!!!!!!!!!!! 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   Q  ›    ›  Q
   t  @  ґ  0  ›
   „  0  ґ  Q  љ
   t  1    Q  љ
   t  0  Х  0  љ
   t  0  Х  0  љ
   0  t    љ  0



 !!!!!!!!!!!!!!!!!!!!!!!! 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   Q  ›    ›  Q
   t  @  ґ  0  ›
   „  0  ґ  Q  љ
   t  1    Q  љ
   t  0  Х  0  љ
   t  0  Х  0  љ
   0  t    љ  0



 !!!!!!!!!!!!!!!!!!!!!!!! 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   Q  ›    ›  Q
   t  @  ґ  0  ›
   „  0  ґ  Q  љ
   t  1    Q  љ
   t  0  Х  0  љ
   t  0  Х  0  љ
   0  t    љ  0



 !!!!!!!!!!!!!!!!!!!!!!!! 


 ******************* 
   P  ћ    ћ  P
   „  1  ±  0  ћ
   …  0  ±  P  ћ
   „  0    P  ћ
   „  0  С  0  ћ
   „  0  С  0  ћ
   0  „    ћ  0



 ******************* 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   P  ћ    ћ  P
   „  1  ±  0  ћ
   …  0  ±  P  ћ
   „  0    P  ћ
   „  0  С  0  ћ
   „  0  С  0  ћ
   0  „    ћ  0



 !!!!!!!!!!!!!!!!!!!!!!!! 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   P  ћ    ћ  P
   „  1  ±  0  ћ
   …  0  ±  P  ћ
   „  0    P  ћ
   „  0  С  0  ћ
   „  0  С  0  ћ
   0  „    ћ  0



 !!!!!!!!!!!!!!!!!!!!!!!! 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   P  ћ    ћ  P
   „  1  ±  0  ћ
   …  0  ±  P  ћ
   „  0    P  ћ
   „  0  С  0  ћ
   „  0  С  0  ћ
   0  „    ћ  0



 !!!!!!!!!!!!!!!!!!!!!!!! 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   P  ћ    ћ  P
   „  1  ±  0  ћ
   …  0  ±  P  ћ
   „  0    P  ћ
   „  0  С  0  ћ
   „  0  С  0  ћ
   0  „    ћ  0



 !!!!!!!!!!!!!!!!!!!!!!!! 


 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
   P  ћ    ћ  P
   „  1  ±  0  ћ
   …  0  ±  P  ћ
   „  0    P  ћ
   „  0  С  0  ћ
   „  0  С  0  ћ
   0  „    ћ  0



 !!!!!!!!!!!!!!!!!!!!!!!! 

Por lo que veo, el ISR de lectura siempre obtiene los datos correctos de la matriz, incluso después de varias decenas de segundos.

    
pregunta AndrejaKo

1 respuesta

4
k=0;//this is a sort of critical section
data[0]=from_seconds (data[0]);
data[1]=from_minutes (data[1]);
data[2]=from_hours (data[2]).time;
k=1;//if it's zero, ISR won't read the data

¿De dónde obtienen los datos [0] su valor inicial? Los comentarios OP implican que primero se carga con datos RTC, luego se convierte aquí en un formato diferente. Pero, ¿dónde se cargan los datos de RTC?

Para reutilizar la matriz, tanto la carga de datos RTC como la conversión deben realizarse dentro de la "sección crítica". De lo contrario, sería posible que el ISR se dispare entre la carga de datos RTC y la conversión. En general, desapruebo la reutilización de matrices de datos como esa, especialmente con los ISR, porque un ISR hará todo lo posible para disparar en el peor momento posible.

En su lugar, debería funcionar más en una filosofía de handshaking. En primer lugar, cargue una matriz que de otra manera no se use con los datos RTC. Luego, haz la conversión dentro de la sección crítica. Esto garantiza que en cualquier momento posible que el ISR pueda activarse, los valores en la matriz de datos siempre serán correctos.

Como beneficio adicional, recomendaría este tipo de enfoque de sección crítica. En cambio, si necesita este tipo de funcionalidad, configure INTCON3bits.INT1IE = 0 para que solo se enmascare esta interrupción. La bandera de interrupción aún se establecerá, y cuando configure INTCON3bits.INT1IE = 1 más adelante, la interrupción se activará como se esperaba.

    
respondido por el ajs410

Lea otras preguntas en las etiquetas