TODOPIC

Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: stark_xlii en 13 de Octubre de 2021, 05:14:58

Título: almacenamiento de datos array con TMR
Publicado por: stark_xlii en 13 de Octubre de 2021, 05:14:58
Hola buenos dias, estoy realizando un seguidor de linea con un array de 16 sensores multiplexados. Para realizar la lectura utilizo un un timer en el PIC18F57q43 (placa curiosity) en concreto1.6Khz.
En la funcion de interrupcion hago lo siguiente,:
Tengo una variable contador y otra variable data[16], la variable contador empieza en 0, cuando se ejecuta la primera interrupcion escribo por el puerto A (LATA = cont), la siguiente linea almaceno el valor del sensor (data[cont]=PORTAbits.RA4); y finalmente incremento con cont++.
Pues el problema biene cuando veo el debug y lo que me encuentro es que la primera lectura la guarda en las posiciones del array 0 y 1 y no se por que.
Porr ejemplo si tengo en los 3 primeros sensores 011, el software me alamcena en el array 0011, me desplaza una posicion los datos. (ver imagenes) sin embargo si escribo la lectura (data[cont-1]=PORTAbits.RA4), funciona correctamente.
Código: [Seleccionar]
#include "mcc_generated_files/mcc.h"
#include "LiquidCristalPIC.h"
#include <stdio.h>
#include <stdint.h>


                         //Main application
 
int cont = 0 ;
char data[16];
int error = 0;
char buffer[4];

void __interrupt() TMR_0 (){
  if (PIR3bits.TMR0IF) {
     
  if(cont == 16){   
   cont = 0;                        // CUANDO EL CONTADOR LLEGA A 16, ESTE SE PONE A 0
  }
   LATA = cont;                     //ESCRIBE POR EL PUERTO A EL NUMERO QUE REPRESENTA CONT
   data[cont]=DATA_GetValue();      // GUARDA EL VALOR LEIDO EN LA POSICION CONT DEL ARRAY
   cont ++;                          // AUMENTA EN UNO EL CONTADOR 
  }
 PIR3bits.TMR0IF = 0;              // BAJAMOS LA BANDERA DE INTERRUPCION
 TMR0H = 155;                     // RECARGAMOS DE NUEVO EL VALOR DEL TEMPORIZADOR 155
 
 
}

void main(void)
{
   
    SYSTEM_Initialize();
   
   
    LED_SetLow();
    __delay_ms(2000);
    LED_SetHigh();
    __delay_ms(2000);
    // If using interrupts in PIC18 High/Low Priority Mode you need to enable the Global High and Low Interrupts
    // If using interrupts in PIC Mid-Range Compatibility Mode you need to enable the Global Interrupts
    // Use the following macros to:

    // Enable the Global Interrupts
    INTCON0bits.GIE=1;          // HABILITACION INTERRUPCIONES GLOBALES
    PIE3bits.TMR0IE = 1;        // hABILITACION INTERRUPCION POR DESBORDAMIENTO DEL TMR0
    T0CON0bits.EN =0;           // TIMER DESABILITADO
    T0CON0bits.MD16 = 0;        //8 bit mode
    T0CON0bits.OUTPS = 0;       // POSTSCLAER 1:1
   
    T0CON1bits.CS = 0b010;      // CLOCK SOURCE FOSC/4
    T0CON1bits.ASYNC = 0;       //SINCRONIZED FOSC/4
    T0CON1bits.CKPS = 0b0101;   // PRESCALER 0b0101
    TMR0H = 155;                // CARGA VALOR PARA 62.5 US 16KHZ 155
    TMR0L = 0;                  // MODO 8 BITS PARTE BAJA ES 0
         
   
   
    __delay_ms(500);
     Lcd_Init();
     
     Lcd_Text("SensorLine16");
     __delay_ms(2000);
     Lcd_Clear();
   
      T0CON0bits.EN =1;          //HABILITA EL TIMER0
    while (1)
    {
       
        Lcd_Set_Cursor(1,1);    //POSICIONA EL CURSOR EN 1FILA 1 COLUMNA
        for(int i = 0; i<16; i++){     //HACE UN BARRIDO DESDE 0 A 15 PARA MOSTRAR EN PANTALLA LOS VALORES DE LOS 16 SENSORES
           
       
           if (data[i] == 0){           //SI DETECTA EL FONDO BLANCO LA PANTALLA MUESTRA UN CARACTER PIXELADO
                 Lcd_Write_Char(0xff);
            }
           else{
             Lcd_Write_Char(' ');       //SI DETECTA LA LINEA NEGRA LA PANTALLA MUESTRA UN ESPACIO EN BLANCO
              }
           
         }
        //CALCULO DEL ERROR//
        error = (data[0]*(-8)+data[1]*(-7)+data[2]*(-6)+data[3]*(-5)+data[4]*(-4)+data[5]*(-3)+data[6]*(-2)+data[7]*(-1)+data[8]*(1)+data[9]*(2)+data[10]*(3)+data[11]*(4)+data[12]*(5)+data[13]*(6)+data[14]*(7)+data[15]*(8));
         sprintf(buffer,"%d",error);
        Lcd_Set_Cursor(2,1);
        Lcd_Text("   ");
        Lcd_Set_Cursor(2,1);
        Lcd_Text(buffer);     
    }
}

Agradeceria que alguien le echara un vistazo y me dijera que hay mal porque ya no se que puede ser. Enun procipio creia que era la pantalla lcd pero al ver el array en el debug lo descaré.
un saludo. Muchas gracias


Título: Re:almacenamiento de datos array con TMR
Publicado por: DominusDRR en 13 de Octubre de 2021, 09:16:18
Parece que PORTAbits.RA4 no es de tipo byte y por eso te escribe en 2 espacios del arreglo (algo raro)

Y si haces esto?:

Código: C
  1. data[cont]=(0x01 & PORTAbits.RA4);
Título: Re:almacenamiento de datos array con TMR
Publicado por: stark_xlii en 13 de Octubre de 2021, 09:27:53
Gracias por la respuesta.
Esto solamente pasa en las 2 primeras cuentas y no entiendo por que. Me explico, si el sensor fisicamente tiene una lectura de 01011, el array almacena 001011.
si pongo esto funciona correctamente, cosa que no entiendo por que.
Código: [Seleccionar]
data[cont-1]=PORTAbits.RA4;
un saludo
Título: Re:almacenamiento de datos array con TMR
Publicado por: DominusDRR en 13 de Octubre de 2021, 09:30:18
Gracias por la respuesta.
Esto solamente pasa en las 2 primeras cuentas y no entiendo por que. Me explico, si el sensor fisicamente tiene una lectura de 01011, el array almacena 001011.
un saludo
La otra opción sería así:

Código: C
  1. if (PORTAbits.RA4)
  2. {
  3.     data[cont]= 0x01;
  4. }
  5. else
  6. {
  7.    data[cont]= 0x00;
  8. }
  9. cont++;
Título: Re:almacenamiento de datos array con TMR
Publicado por: stark_xlii en 13 de Octubre de 2021, 09:34:00
escribir esto seria correcto?

data[cont-1]=PORTAbits.RA4;

ademas probando tambien funciona con :

 LATA = cont +1
Título: Re:almacenamiento de datos array con TMR
Publicado por: DominusDRR en 13 de Octubre de 2021, 09:40:30
escribir esto seria correcto?

data[cont-1]=PORTAbits.RA4;

(cont -1) deberías cuidar que siempre sea mayor o igual que cero, pero por lo que parece que PORTAbits.RA4 utiliza dos bytes, te escribiría en cont -1 y en cont -2, pero si cont -1 es cero, te escribiría en data[0x00] y en data[0xFF], y por eso parecería que funciona para data[0]
Título: Re:almacenamiento de datos array con TMR
Publicado por: stark_xlii en 13 de Octubre de 2021, 09:58:02
el registro PORT segun datasheet es de 8 bits por lo que no deberia ocupar 2 bytes no?
Título: Re:almacenamiento de datos array con TMR
Publicado por: DominusDRR en 13 de Octubre de 2021, 10:02:41
el registro PORT segun datasheet es de 8 bits por lo que no deberia ocupar 2 bytes no?

Da clic derecho sobre RA4 y ve a donde está definido o anda al manual de tu compilador y te llevarás una sorpresa. Una cosa es en el hardware y otra es como se crea las variables propias del compilador
Título: Re:almacenamiento de datos array con TMR
Publicado por: DominusDRR en 13 de Octubre de 2021, 10:06:46
el registro PORT segun datasheet es de 8 bits por lo que no deberia ocupar 2 bytes no?

Algo así debes hacer como en la imagen adjunta, en tu caso debe ser de uint16, la imagen es de un microcontrolador de 32 bits (Ya no trabajo con los de 8 hace mucho tiempo)
Título: Re:almacenamiento de datos array con TMR
Publicado por: Robert76 en 13 de Octubre de 2021, 10:11:34
Hola, me parece que el array se está solapando. Entonces añade un espacio más, data[17].
Título: Re:almacenamiento de datos array con TMR
Publicado por: stark_xlii en 13 de Octubre de 2021, 14:47:12
Gracias por vuestra respuesta.
 En el caso que me menciona DominusDRR, adjunto una imagen con lo que a mi me aparece, no veo el tamaño que asigna el compilador.
He probado a definir int8_t, int16_t y sigue desplazando el valor leido.

El caso que me dice el compañero  Robert76, data[17], tampoco funciona.

un saludo
Título: Re:almacenamiento de datos array con TMR
Publicado por: Robert76 en 13 de Octubre de 2021, 15:07:51
Si ignoras la posición data[0] y sólo utilizas desde la sig. en adelante, se manifiesta el problema?
Título: Re:almacenamiento de datos array con TMR
Publicado por: DominusDRR en 13 de Octubre de 2021, 15:32:15
Gracias por vuestra respuesta.
 En el caso que me menciona DominusDRR, adjunto una imagen con lo que a mi me aparece, no veo el tamaño que asigna el compilador.
He probado a definir int8_t, int16_t y sigue desplazando el valor leido.

El caso que me dice el compañero  Robert76, data[17], tampoco funciona.

un saludo

Mira en ensamblador lo que está haciendo tu código para comprender lo que pasa.
Título: Re:almacenamiento de datos array con TMR
Publicado por: DominusDRR en 13 de Octubre de 2021, 15:36:12
Hola buenos dias, estoy realizando un seguidor de linea con un array de 16 sensores multiplexados. Para realizar la lectura utilizo un un timer en el PIC18F57q43 (placa curiosity) en concreto1.6Khz.
En la funcion de interrupcion hago lo siguiente,:
Tengo una variable contador y otra variable data[16], la variable contador empieza en 0, cuando se ejecuta la primera interrupcion escribo por el puerto A (LATA = cont), la siguiente linea almaceno el valor del sensor (data[cont]=PORTAbits.RA4); y finalmente incremento con cont++.
Pues el problema biene cuando veo el debug y lo que me encuentro es que la primera lectura la guarda en las posiciones del array 0 y 1 y no se por que.
Porr ejemplo si tengo en los 3 primeros sensores 011, el software me alamcena en el array 0011, me desplaza una posicion los datos. (ver imagenes) sin embargo si escribo la lectura (data[cont-1]=PORTAbits.RA4), funciona correctamente.
Código: [Seleccionar]
#include "mcc_generated_files/mcc.h"
#include "LiquidCristalPIC.h"
#include <stdio.h>
#include <stdint.h>


                         //Main application
 
int cont = 0 ;
char data[16];
int error = 0;
char buffer[4];

void __interrupt() TMR_0 (){
  if (PIR3bits.TMR0IF) {
     
  if(cont == 16){   
   cont = 0;                        // CUANDO EL CONTADOR LLEGA A 16, ESTE SE PONE A 0
  }
   LATA = cont;                     //ESCRIBE POR EL PUERTO A EL NUMERO QUE REPRESENTA CONT
   data[cont]=DATA_GetValue();      // GUARDA EL VALOR LEIDO EN LA POSICION CONT DEL ARRAY
   cont ++;                          // AUMENTA EN UNO EL CONTADOR 
  }
 PIR3bits.TMR0IF = 0;              // BAJAMOS LA BANDERA DE INTERRUPCION
 TMR0H = 155;                     // RECARGAMOS DE NUEVO EL VALOR DEL TEMPORIZADOR 155
 
 
}

void main(void)
{
   
    SYSTEM_Initialize();
   
   
    LED_SetLow();
    __delay_ms(2000);
    LED_SetHigh();
    __delay_ms(2000);
    // If using interrupts in PIC18 High/Low Priority Mode you need to enable the Global High and Low Interrupts
    // If using interrupts in PIC Mid-Range Compatibility Mode you need to enable the Global Interrupts
    // Use the following macros to:

    // Enable the Global Interrupts
    INTCON0bits.GIE=1;          // HABILITACION INTERRUPCIONES GLOBALES
    PIE3bits.TMR0IE = 1;        // hABILITACION INTERRUPCION POR DESBORDAMIENTO DEL TMR0
    T0CON0bits.EN =0;           // TIMER DESABILITADO
    T0CON0bits.MD16 = 0;        //8 bit mode
    T0CON0bits.OUTPS = 0;       // POSTSCLAER 1:1
   
    T0CON1bits.CS = 0b010;      // CLOCK SOURCE FOSC/4
    T0CON1bits.ASYNC = 0;       //SINCRONIZED FOSC/4
    T0CON1bits.CKPS = 0b0101;   // PRESCALER 0b0101
    TMR0H = 155;                // CARGA VALOR PARA 62.5 US 16KHZ 155
    TMR0L = 0;                  // MODO 8 BITS PARTE BAJA ES 0
         
   
   
    __delay_ms(500);
     Lcd_Init();
     
     Lcd_Text("SensorLine16");
     __delay_ms(2000);
     Lcd_Clear();
   
      T0CON0bits.EN =1;          //HABILITA EL TIMER0
    while (1)
    {
       
        Lcd_Set_Cursor(1,1);    //POSICIONA EL CURSOR EN 1FILA 1 COLUMNA
        for(int i = 0; i<16; i++){     //HACE UN BARRIDO DESDE 0 A 15 PARA MOSTRAR EN PANTALLA LOS VALORES DE LOS 16 SENSORES
           
       
           if (data[i] == 0){           //SI DETECTA EL FONDO BLANCO LA PANTALLA MUESTRA UN CARACTER PIXELADO
                 Lcd_Write_Char(0xff);
            }
           else{
             Lcd_Write_Char(' ');       //SI DETECTA LA LINEA NEGRA LA PANTALLA MUESTRA UN ESPACIO EN BLANCO
              }
           
         }
        //CALCULO DEL ERROR//
        error = (data[0]*(-8)+data[1]*(-7)+data[2]*(-6)+data[3]*(-5)+data[4]*(-4)+data[5]*(-3)+data[6]*(-2)+data[7]*(-1)+data[8]*(1)+data[9]*(2)+data[10]*(3)+data[11]*(4)+data[12]*(5)+data[13]*(6)+data[14]*(7)+data[15]*(8));
         sprintf(buffer,"%d",error);
        Lcd_Set_Cursor(2,1);
        Lcd_Text("   ");
        Lcd_Set_Cursor(2,1);
        Lcd_Text(buffer);     
    }
}

Agradeceria que alguien le echara un vistazo y me dijera que hay mal porque ya no se que puede ser. Enun procipio creia que era la pantalla lcd pero al ver el array en el debug lo descaré.
un saludo. Muchas gracias

Empecé a revisar tu código y no veo lo que dices:

Código: C
  1. data[cont]=PORTAbits.RA4;


Lo que hay es:
Código: C
  1. data[cont]=DATA_GetValue();

Me imagino que DATA_GetValue() es equivalente a = PORTAbits.RA4, ¿Puedes compartir esa función para verla?
Título: Re:almacenamiento de datos array con TMR
Publicado por: stark_xlii en 13 de Octubre de 2021, 15:52:25
Gracias a todos de nuevo, respecto a verificar el código ensamblador, tengo que decir que no tengo ni zorra idea de ensamblador.

La función que observa, Getvalue la genera MCC es equivalente a PORTAbits.RA4.

 De que forma realizarían ustedes el código que he escrito, por si se me pasase algo por alto o no declarase bien alguna variable.

Lo que no me explico es que dean la posición 0 y 1, las 14 restantes las guarda corelativamente.

Gracias, un saludo
Título: Re:almacenamiento de datos array con TMR
Publicado por: DominusDRR en 13 de Octubre de 2021, 15:59:04
Gracias a todos de nuevo, respecto a verificar el código ensamblador, tengo que decir que no tengo ni zorra idea de ensamblador.

La función que observa, Getvalue la genera MCC es equivalente a PORTAbits.RA4.

 De que forma realizarían ustedes el código que he escrito, por si se me pasase algo por alto o no declarase bien alguna variable.

Lo que no me explico es que dean la posición 0 y 1, las 14 restantes las guarda corelativamente.

Gracias, un saludo

Deberías intentar aprender ensamblador, sobre todo para PIC16 y PIC18 es muy sencillo, de esa manera podrías analizar tu problema y darte cuenta que está pasando, a parte de comprender mucho mejor la arquitectura del microcontrolador.

Gracias a eso me di cuenta que PICC escribe a veces absurdos y tonterías, claro eso fue como hace unos 10 años o más, tal vez ahora es mucho mejor.

Si puedes mírale con es en ensamblador y publica el código para intentar analizar que pasa.
Título: Re:almacenamiento de datos array con TMR
Publicado por: Robert76 en 13 de Octubre de 2021, 16:19:45
En lo personal, no he usado mucho la declaración de variables en formato Char.
Prueba declararla como int8.
Título: Re:almacenamiento de datos array con TMR
Publicado por: stark_xlii en 15 de Octubre de 2021, 18:04:15
Gracias a todos de nuevo.
He estado peleándome con el asunto y no consigo hacerlo funcionar de manera normal, la única manera que he podido conseguirlo es ignorando la posición 0 del array y empezar desde la posicion 1, de esa manera funciona perfecto.

Se os ocurre alguna otra cosa, porque yo ya no sé que más comprobar, he hecho todo lo que me habéis dicho y nada.
Un saludo