TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: maxluis en 08 de Enero de 2017, 01:27:46

Título: En XC8 No se como leer un array.
Publicado por: maxluis en 08 de Enero de 2017, 01:27:46
Estimados...tratando de aprender xc8, el arreglo char dato[] lo defino = "a1010", pero al leerlo en el main y preguntar si es igual a el mismo,con el if, no se me prende el led en la simulacion del proteus.......que estoy haciendo mal....que alguien tienda una mano.



Este es el main.c ----me compila bien.
//bits de configuración del PIC16F873A
#pragma config FOSC = XT        // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit S
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits
#pragma config CP = OFF         // Flash Program Memory Code Protection bit
 
#define _XTAL_FREQ 4000000


#include <xc.h>
#include <string.h>
#include <stdlib.h>
#include "rs2322.h"
 

void main(void)
{
     char dato[]="a1010";
   
    TRISB =0b00000000;//portb comosalida
    ADCON1 =0b00000111; //todo digital port a
    //__delay_ms(500);
    iniciar_usart2();//inicia el módulo USART PIC
    while(1)
    {
        if(dato=="a1010")
        {
        PORTBbits.RB1=1;
        }
        else
            PORTBbits.RB1=0;
    }
    }
Título: Re:En XC8 No se como leer un array.
Publicado por: KILLERJC en 08 de Enero de 2017, 02:08:09
Tu problema no es XC8, tu problema es un problema de C directamente. Voy a explicar el concepto, y vas a ver que es erroneo lo que hiciste.

Para leer un array lo haces de esta forma:

Código: C
  1. dato[0]

Dandole el indice. El 0 te va a dar el primer elemento que es la 'a', al ser una string ( las comillas dobles) tiene 1 elemento mas que es el caracter nulo o 0 al final para indicar que termino el string. Es decir estas 2 insrtucciones son equivalentes:

Código: C
  1. char dato[] = "a1010"
  2. char dato[] = {'a','1','0','1','0',0x00};

Es importante que veas que el array anterior tiene 6 datos o lugares ( cualquiera de ambos ).
Si tus datos provienen desde la UART vas a ir cargandolo 1 por 1 ( letra por letra ) a no ser que tengas alguna funcion que cargue cierta cantidad de elementos.

Entonces... ¿ Como comparo 2 palabras/strings?
En C lo tenes que hacer elemento a elemento, en C++ podrias pero esto no se trata de C++.
Suponete que lo que me llega a la UART lo guardo en un array que se llame buffer. Y lo quiero comparar con el array dato ( es decir dato es el valor fijo). Podria crear un programa que compare los mismos de esta forma:

Código: C
  1. short int i;
  2. bool resultado=1;
  3. for(i=0;i<5;i++) // 6 elementos del array menos el ultimo que es el caracter nulo.
  4. {
  5.    if( dato[i] != buffer[i] )
  6.    {
  7.        resultado = 0;    // Si entro aca es porque es distinto, por lo tanto cargo que es distinto y salgo
  8.        break;
  9.    }
  10. }
  11.  
  12. if(resultado == 1)
  13. {
  14.     // Aca coincide
  15. }
  16. else
  17. {
  18.    // Aca ejecuta cuando no coincide
  19. }

¿Hay alguna forma mas facil?

Si, pero lo anterior es para que entendieras eso. C provee unas librerias que hacen lo anterior. En la libreria string.h que tenes incluido tenes un funcion que hace lo mismo que hicimos, y esa es la funcion strncmp()

http://www.cplusplus.com/reference/cstring/strncmp/

Usando el mismo ejemplo que antes ahora vamos a escribirlo con strncmp, nuevamente en el array buffer vamos a tener lo que llego de la UART.

Código: C
  1. if(strncmp(buffer,"a1010",5) == 0)   // Nuevamente los 5 letras nomas
  2. {
  3.     // Aca coincide
  4. }
  5. else
  6. {
  7.    // Aca ejecuta cuando no coincide
  8. }

Si es igual a 0 es que coincide. Ahora si es mucho mas facil de hacer. Si reemplazas este codigo en el tuyo, te vas a dar cuenta que siempre va a quedar en 1, ya que el array dato siempre va a tener el valor "a1010" y por lo tanto la comparacion siempre va a coincidir.[/code]
Título: Re:En XC8 No se como leer un array.
Publicado por: maxluis en 08 de Enero de 2017, 08:36:25
Estimado  KILLERJC: Muchas gracias¡¡........mi problema no es el C++, ni el XC8, ni los strings.....son los 60 y pico años que todo me lo van poniendo Lento y confuso.....esto de querer hacer una "puta" comunicación rs232 entre dos pic 16f873a en xc8 se me a puesto tan condicionado como invitar a mi viejita a una "enesima" luna de miel.

Gracias por su tiempo estimado Señor....ya aprenderé.
Maxluis.
Título: Re:En XC8 No se como leer un array.
Publicado por: maxluis en 08 de Enero de 2017, 08:57:41
Ya me estaba asustando strncmp ¡= strcmp (xc8) ya no me estaba compilando, esta prueba si funcionó en el simulador ahora voy por, como tomar un string que llega por rs232 y meterlo en un string buffer para compararlo....si alguien sabe de alguna pista aqui en este gran FORO que me ilumine.

adjunto lo que me funcionó gracias al Sr. Killerjc:

//bits de configuración del PIC16F873A
#pragma config FOSC = XT        // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit S
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits
#pragma config CP = OFF         // Flash Program Memory Code Protection bit
 
#define _XTAL_FREQ 4000000


#include <xc.h>
#include <string.h>
#include <stdlib.h>
#include "rs2322.h"
 

void main(void)
{
     char dato[]={'a','1','0','1','0',0x00};
     char datin[]="a1010";
   
    TRISB =0b00000000;//portb comosalida
    ADCON1 =0b00000111; //todo digital port a
    //__delay_ms(500);
    iniciar_usart2();//inicia el módulo USART PIC
    while(1)
    {
        if ( strcmp(dato,datin)== 0 )
        {
        PORTBbits.RB1=1;
        }
        else
            PORTBbits.RB1=0;
    }
    }
Título: Re:En XC8 No se como leer un array.
Publicado por: KILLERJC en 08 de Enero de 2017, 13:52:07
Acabo de darme cuenta que mi post por culpa de un corchete no salio el codigo del strncmp,, ahi lo arregle.

Respecto a recibir datos por la UART lo podes hacer de 2 formas.

La primera es hacerlo en el while,
Esto puede traer problemas o no. ¿Por que traeria problemas? Si en tu while utilizas delays o si tu codigo necesita bastante tiempo para ejecutarse, esto puede llegar a acarrear que 2 datos lleguen a la UART mientras esta haciendo otra cosa, al ocurrir esto significa que un dato se pierde y ya vas a tener que reiniciar la UART por que tenes un error de Overrun.
Si tu while simplemente no demora no tendrias problema de leerlo ahi.
Nuevamente aca vas a ir recibiendo uno por uno los valores.

La segunda opcion y la mejor es usar interrupciones.
Me refiero a la interrupcion de la recepcion de la UART, en el cual va a entrar cada ves que reciba un caracter. En ese momento vas a tomar ese valor que llego y guardarlo en un array, mientras recordas el numero de indice. En codigo seria algo asi ( voy a inventar el nombre de los bits y registros pero es referencial nomas ):

Código: C
  1. short int indice=0;
  2. char buffer[10];
  3. volatile bool completado = false;
  4.  
  5. void interrupt Interrrupciones(void)
  6. {
  7.    if(PIR1bits.RXUART)
  8.    {
  9.       buffer[indice] = RXREG;   // Del registro que esta el dato recibido al array buffer
  10.       indice++;
  11.       if( (buffer[indice-1] == 0) )      // Si llego el caracter nulo, Fin de linea
  12.       {
  13.            completado = true;             // Llego toda la trama
  14.            indice = 0;                          // Pongo a 0 el indice
  15.       }
  16.       else if( indice == 9 )
  17.       {
  18.             indice = 0;                          // LLego al maximo del array y no aparecio el caracter nulo?, sigo escribiendo en el array.
  19.       }
  20.       // Sino ocurrio nada de lo anterior es un caracter comun por lo tanto salgo normalmente
  21.    }
  22. }
  23.  
  24. void main(void)
  25. {
  26.    // Aca el setup
  27.    while(1)
  28.    {
  29.       if(completado)
  30.       {
  31.           completado = 0;
  32.           //Aca comparo los string de buffer y lo que quiero
  33.       }
  34.    }
  35. }

Un solo cuidado con este codigo que es que al comparar no se tarde demasiado o que el transmisor no envie rapidamente otro dato. Ya que sino estaria sobreescribiendo buffer y no vas a poder comparar correctamente.
La otra opcion seria usar 2 arrays en ves de 1, asi mientras uno se llena el otro se lee.

PD: usa strncmp en ves de strcmp, la diferencia entre ambos es que strcmp solamente se detiene cuando detecta un caracter nulo, es decir un 0d ( 0x00 ), mientras que el otro se limita a la cantidad de datos que se le pasa.
El problema lo tendrias si tenes un array que no esta cerrado correctamente, suponete que uso esto:

buffer[4] = {'1','0','1','0'};

strcmp va a continuar luego del '0' por que no posee un caracter de fin de linea, 0x00, Y terminaria leyendo otra memoria que no tiene nada que ver con buffer.
Título: Re:En XC8 No se como leer un array.
Publicado por: centrino_ en 02 de Mayo de 2017, 18:29:36
Hola, antes que nada quiero decir que soy nuevo en el foro, así que cualquier error en la consulta será tenido en cuenta para mejorar la misma.

Buscando temas que concuerden con la consulta que me concierne, me parece que este es el lugar mas adecuado donde plasmarla.

Estoy trabajando con el PIC18f67j50, y comunicándome con un módulo bluetooth HC-05 a través de la USART del pic, la interfaz utilizada es el MPLAB v3.45 y el compilador el XC8 (v1.34).

Puntualmente el problema consiste en la comparación de los caracteres recibidos desde la USART y almacenados en un arreglo (Rxdata[]), con un caracter constante, es decir, comparo cada uno de los elementos de Rxdata[], con un caracter.

Adjunto aquí la porción de código en donde realizo la comparación.

Código: [Seleccionar]
...
       char *PRxdata;
       char *Pconst;
       const char mas = '+';
       PRxdata = Rxdata;
       Pconst = &mas;
       WriteCmdXLCD(0b00000001);  // Clear LCD
       SetDDRamAddr(0x00);
       putrsXLCD("Dato Recibido");
       while(i<300){
           
           if(*PRxdata == *Pconst){
              //Acción a realizar
           }
           PRxdata++;
           i++;
       }
       WriteCmdXLCD(0b00000001);  // Clear LCD
       SetDDRamAddr(0x00);
       putrsXLCD("Comparación Hecha");
...

El problema es que cuando dentro del "if" donde dice "//Acción a realizar" introduzco una acción, el micro se "tilda" o entra en un estado que no conozco, ya que en el LCD se borran la lineas que tenía escritas anteriormente, y no escribe nada (si todo anduviera de manera correcta se tendría que mostrar "Comparación Hecha").
Si no introduzco ninguna acción, el programa continua normalmente, algo que me desconcierta.

Cabe aclarar que en un principio intenté realizar la comparación de manera mas sencilla como KILLERJC lo mostró:

Código: [Seleccionar]
...
for(i=0;i<5;i++) // 6 elementos del array menos el ultimo que es el caracter nulo.
{
   if( dato[i] != buffer[i] )
   {
       resultado = 0;    // Si entro aca es porque es distinto, por lo tanto cargo que es distinto y salgo
       break;
   }
}...

y tampoco funciono.

Otro dato que quizás sirva es que la recepción de datos de la USART la debo hacer caracter a caracter, como muestro en el siguiente código:

Código: [Seleccionar]
...
       while(Busy2USART());
       while(DataRdy2USART()==0){};
       Rxdata[0] = Read2USART(); //Recieve 1 byte
       if(Rxdata[0]=='K'){}
       while(Busy2USART());
       while(DataRdy2USART()==0){break;}
       Rxdata[1] = Read2USART();
       if(Rxdata[1]=='K'){break;}
...

si esta recepción la hacía en un bucle, la misma no andaba y el micro entraba en el mismo estado (creo) que el que comenté anteriormente.

Espero se entienda la duda, y desde ya muchas gracias al que responda. El tema me tiene bastante desconcertado.
Título: Re:En XC8 No se como leer un array.
Publicado por: KILLERJC en 02 de Mayo de 2017, 20:07:58
En tu primer codigo, estas seguro que i es de 16 bits ?, falta que sea de 8 bits y pase de 255 a 0 lo cual nunca llegaria a los 500.
Igual no deberia borrarte el LCD.

Citar
Otro dato que quizás sirva es que la recepción de datos de la USART la debo hacer caracter a caracter, como muestro en el siguiente código:

Ese codigo donde lo tenes puesto? En una interrupcion? No me parece correcto el codigo, ademas el ultimo break del if no se que for/while/do..while estaras intentando salir, ya que del if no sale.
Título: Re:En XC8 No se como leer un array.
Publicado por: centrino_ en 03 de Mayo de 2017, 16:28:51
Estimado KILLERJC:

En tu primer codigo, estas seguro que i es de 16 bits ?...

en principio si, "i" es de 16 bits, además, cuando no pongo ninguna condición en el "if"(//acción a realizar), el micro recorre el while (i<300), sale y escribe "Comparación Hech" en el LCD, creo que si la variable "i" no llegara a 300, no debería salir nunca del while, y si así fuera, no debería borrar el LCD tampoco.

Ese codigo donde lo tenes puesto? En una interrupcion? No me parece correcto el codigo, ademas el ultimo break del if no se que for/while/do..while estaras intentando salir, ya que del if no sale.

Está todo en el mismo código, no lo inserté completo porque es muy extenso, la idea es receptar 300 caracteres del módulo, pero el mismo puede o no enviarme los 300 caracteres, es decir, lo máximo que me envía son 300 caracteres, por ello Rxdata[300].

El if(Rxdata[xx]=='K'){break;} lo que hace es comparar el caracter recibido, con el caracter "K" ("K" es el último caracter que envía el módulo). Si es así, sale de un while que contiene la recepción de datos. Una vez almacenados los caracteres recibidos en Rxdata[xx], necesito comparar cada uno de ellos con un caracter (en este caso "+"). Ahí es donde estoy teniendo el problema.

Para aclarar un poco adjunto la porción de código mejor explicada.

Código: [Seleccionar]
...
while(condicion)
{
       while(Busy2USART());
       while(DataRdy2USART()==0){};
       Rxdata[0] = Read2USART();
       if(Rxdata[0]=='K'){break;}
       while(Busy2USART());
       while(DataRdy2USART()==0){};
       Rxdata[1] = Read2USART();
       if(Rxdata[1]=='K'){break;}
...
...
...
       while(Busy2USART());
       while(DataRdy2USART()==0){};
       Rxdata[298] = Read2USART();
       if(Rxdata[298]=='K'){break;}
       while(Busy2USART());
       while(DataRdy2USART()==0){};
       Rxdata[299] = Read2USART();
       condición cumplida;
}

 char *PRxdata;
 char *Pconst;
 const char mas = '+';
 PRxdata = Rxdata;
 Pconst = &mas;
 WriteCmdXLCD(0b00000001);  // Clear LCD
 SetDDRamAddr(0x00);
 putrsXLCD("Dato Recibido");
 while(i<300){
           
     if(*PRxdata == *Pconst){
        //Acción a realizar
     }
     PRxdata++;
     i++;
 }
 WriteCmdXLCD(0b00000001);  // Clear LCD
 SetDDRamAddr(0x00);
 putrsXLCD("Comparación Hecha");
...

Título: Re:En XC8 No se como leer un array.
Publicado por: KILLERJC en 03 de Mayo de 2017, 17:40:45
Primero que 300 es MUCHISIMO!, lo bajaria a 200 , ( mas que nada porque el compilador puede tener problemas con el tema de pasarse de los 8bits, es decir arrays mas grande de 255 bytes )

Esto:

Código: C
  1. while(condicion)
  2. {
  3.        while(Busy2USART());
  4.        while(DataRdy2USART()==0){};
  5.        Rxdata[0] = Read2USART();
  6.        if(Rxdata[0]=='K'){break;}
  7.        while(Busy2USART());
  8.        while(DataRdy2USART()==0){};
  9.        Rxdata[1] = Read2USART();
  10.        if(Rxdata[1]=='K'){break;}
  11. ...
  12. ...
  13. ...
  14.        while(Busy2USART());
  15.        while(DataRdy2USART()==0){};
  16.        Rxdata[298] = Read2USART();
  17.        if(Rxdata[298]=='K'){break;}
  18.        while(Busy2USART());
  19.        while(DataRdy2USART()==0){};
  20.        Rxdata[299] = Read2USART();
  21.        condición cumplida;
  22. }

Lo podrias haber realizado asi:

Código: C
  1. for(i =0; i<200; i++)
  2. {
  3.        while(Busy2USART());
  4.        while(!DataRdy2USART());
  5.        Rxdata[i] = Read2USART();
  6.        if(Rxdata[i]=='K'){break;}
  7. }

Pero es absurdo esperar SI o SI una 'K', el problema es que si no responde una K, eso se queda para siempre ahi. Por lo cual vas a tener que implementar un Timeout. O creo que devuelve \r\n el comando, es decir "OK\r\n", de eso no estoy muy seguro, pero estaria bueno si podes averiguarlo. De esa forma esperas un \n y se simplifica mucho mas la operacion.

Por la otra parte, no nos compliquemos demasiado. No hay ninguna necesidad de usar punteros en ese caso.

Código: C
  1. WriteCmdXLCD(0b00000001);  // Clear LCD
  2.  SetDDRamAddr(0x00);
  3.  putrsXLCD("Dato Recibido");
  4.  
  5.  for(i=0;i<200;i++){
  6.            
  7.      if(Rxdata[i] == '+'){
  8.         //Acción a realizar
  9.         break;
  10.      }
  11.  }
  12.  
  13.  WriteCmdXLCD(0b00000001);  // Clear LCD
  14.  SetDDRamAddr(0x00);
  15.  putrsXLCD("Comparación Hecha");
Título: Re:En XC8 No se como leer un array.
Publicado por: centrino_ en 03 de Mayo de 2017, 18:16:19
Estimado KILERJC:

Primero que 300 es MUCHISIMO!, lo bajaria a 200...

El tema es que puedo llegar a recibir hasta 300 caracteres.
La parte de la recepción de los datos funciona bien de la manera que la estoy realizando.

...
Lo podrias haber realizado asi:

Código: C
  1. for(i =0; i<200; i++)
  2. {
  3.        while(Busy2USART());
  4.        while(!DataRdy2USART());
  5.        Rxdata[i] = Read2USART();
  6.        if(Rxdata[i]=='K'){break;}
  7. }
...

Lo intenté de esa manera, no funcionó. Por ello lo hice de la forma que mostré.


Pero es absurdo esperar SI o SI una 'K', el problema es que si no responde una K, eso se queda para siempre ahi. Por lo cual vas a tener que implementar un Timeout. O creo que devuelve \r\n el comando, es decir "OK\r\n", de eso no estoy muy seguro, pero estaria bueno si podes averiguarlo. De esa forma esperas un \n y se simplifica mucho mas la operacion.


Lo resolví de esa manera ya que el módulo, luego de enviar la información que necesito, envía un OK siempre. Podría implementar el tmimeout a modo de seguridad. Igual la recepción de datos esta resuelta y funciona.

Por la otra parte, no nos compliquemos demasiado. No hay ninguna necesidad de usar punteros en ese caso.

En el primer post que realicé, aclaré que había intentado realizarlo de la manera que recomiendas, y estaba teniendo el mismo problema.

Cabe aclarar que en un principio intenté realizar la comparación de manera mas sencilla como KILLERJC lo mostró:

Código: [Seleccionar]
...
for(i=0;i<5;i++) // 6 elementos del array menos el ultimo que es el caracter nulo.
{
   if( dato[i] != buffer[i] )
   {
       resultado = 0;    // Si entro aca es porque es distinto, por lo tanto cargo que es distinto y salgo
       break;
   }
}...

y tampoco funciono.
Es por ello que estoy bastante perdido.
De todas formas, puede ser que al manipular un arreglo de esa magnitud (300), el compilador entre en conflicto?
Muchas gracias KILLERJC por estar ayudándome.



Título: Re:En XC8 No se como leer un array.
Publicado por: KILLERJC en 03 de Mayo de 2017, 20:06:03
Citar
La parte de la recepción de los datos funciona bien de la manera que la estoy realizando.
Lo intenté de esa manera, no funcionó. Por ello lo hice de la forma que mostré.

Lo que hiciste... con lo hecho con el for es lo mismo, debería funcionar correctamente. Si no funciona entonces es algún otro problema con otra parte del código tenes. En ves de repetir 300 veces lo mismo, hice un bucle para que repita esas 300 veces, nada mas.

Citar
De todas formas, puede ser que al manipular un arreglo de esa magnitud (300), el compilador entre en conflicto?

Para algunos PICs si, los de gama baja y base, pero ahora que veo es un PIC18 lo cual no tenes limite ( solo la RAM entera). No habia visto el PIC que estabas usando.

Citar
El tema es que puedo llegar a recibir hasta 300 caracteres.

Desde la parte del bluetooth imagino ( datos ) , Y espero que los datos recibidos ninguno tenga una 'K', sino seria un problema.

-----------------

Hasta ahora el unico problema que puede suceder con el codigo pasado ( no se las demas partes), es que no estas recibiendo por una interrupcion, lo cual podes tener un error de overrun al llegar 2 caracteres mientras estas haciendo otra cosa.
Todo codigo que pasaste no veo problema en el mismo, si ineficiencia como la parte de preguntar 300 veces lo mismo.
Todo codigo que pase deberia funcionar correctamente.

Una sola cosa, sacaria el Busy2USART() del for, ya que eso es para cuando trasmitis, no hay bit que indique que estas a mitad de una recepcion, sino que hay un bit para cuando recibiste el dato, quedando simplemente:

Código: C
  1. for(i =0; i<300; i++)
  2. {
  3.        while(!DataRdy2USART());
  4.        Rxdata[i] = Read2USART();
  5.        if(Rxdata[i]=='K'){break;}
  6. }

De todas formas, tengo mis dudas respecto a la condicion de que sea una 'K', y si o si deberias agregar un timeout ( un simple contador, aunque reformaria el bucle). En fin... En el codigo que pasaste/pase no veo error alguno, seguramente debe estar en otro lado.

En MPLAB podes simular las cosas, crea un nuevo proyecto con el mismo micro, crea un array de 300 lugares y hacerles pasar ese codigo. Ejemplo:

Ejemplo aca siempre saltaria el While como si tuviera caracteres recibidos, guardaria el mismo valor que el indice (en tu codigo seria lo que hay en RCREG) y cuando llegue a 200 ( tu 'K' de mentira para este ejemplo) deberia salir de ese bucle. Si lo simulas deberia hacer eso (podes crear un proyecto aparte de prueba, y vas a ver )

Tambien lo podes hacer pasar por el otro codigo para comprobar que funcione.

Código: C
  1. // Todo esto dentro de un while(1)
  2.  
  3. for(i =0; i<300; i++)
  4. {
  5.        while(0);
  6.        Rxdata[i] = i;
  7.        if(Rxdata[i]==200)
  8.        {
  9.            break; //breakpoint aca
  10.        }
  11. }
  12.  
  13. for(i=0;i<300;i++){
  14.            
  15.      if(Rxdata[i] == 150){
  16.         Rxdata[299] = 0; // Poner un breakpoint aca y ver si entra
  17.         break;
  18.      }
  19.  }

En fin, aprovecha que podes simular en el MPLAB, podes simular los perifericos ( UART/I2C/etc) pero hacelo simple no dependas de ellos y vas a ver que los codigos pasados son correctos.
Título: Re:En XC8 No se como leer un array.
Publicado por: centrino_ en 04 de Mayo de 2017, 10:35:34
Estimado KILLERKC:

Lo que hiciste... con lo hecho con el for es lo mismo, debería funcionar correctamente...

Haciendolo con un for, con un while o con un do while no funciona. Lo probé y lo volví a probar, se que es lo mismo (que preguntar 300 veces) pero no funciona. Por eso mi desconcierto. Te repito, de la única forma que puedo recibir es de la manera que lo hice. Mi duda es, por que con un for, while, do while no funciona si debería funcionar.

Hasta ahora el unico problema que puede suceder con el codigo pasado ( no se las demas partes), es que no estas recibiendo por una interrupcion, lo cual podes tener un error de overrun al llegar 2 caracteres mientras estas haciendo otra cosa....

En principio no pensé hacer la recepción de datos por medio de una interrupción ya que el micro no está realizando ninguna acción mientras espera que el módulo envíe los datos. Pero voy a pobar igualmente hacerlo de esta manera. Aunque repito, de la manera que realicé la recepción, funciona. Tendría que funcionar con un for, pero no lo hace.

Desde la parte del bluetooth imagino ( datos ) , Y espero que los datos recibidos ninguno tenga una 'K', sino seria un problema.

No, no estoy recibiendo datos desde otro transmisor bluetooth, lo que recibo es el RSSI de la señal junto con el addres del dispositivo bluetooth que esté encendido, todos estos valores son hexadecimales por ende no hay nunguna caracter 'K' y no va a haber conflicto alguno con la lógica planteada.

Todo codigo que pase deberia funcionar correctamente.

Debería, pero no funciona correctamente y ahí está mi duda. Porque algo que debería andar correctamente, no lo hace.

Muchas Gracias
Título: Re:En XC8 No se como leer un array.
Publicado por: manwenwe en 04 de Mayo de 2017, 10:44:00
¿Están las optimizaciones encendidas?.
Título: Re:En XC8 No se como leer un array.
Publicado por: centrino_ en 04 de Mayo de 2017, 11:08:55
Estimado manwenwe:

¿Están las optimizaciones encendidas?.

La verdad que no sabría responderte. Optimizaciones del compilador?
Título: Re:En XC8 No se como leer un array.
Publicado por: manwenwe en 04 de Mayo de 2017, 12:41:37
Sí. Click derecho en el proyecto ==>> propiedades ==>> XC8 ==>> Xc8-gcc (o el compilador que sea) ==>>optimization ==>optimization level.

Si no está a '0' es que están encendidas. Eso puede dar lugar a que el compilador "desordene" algunas instrucciones...
Título: Re:En XC8 No se como leer un array.
Publicado por: manwenwe en 04 de Mayo de 2017, 15:22:59
Perdón: quise decir que "desordene" algunas sentencias en C, las instrucciones en código máquina está claro que van una detrás de otras después de haber sido generado el código...
Título: Re:En XC8 No se como leer un array.
Publicado por: centrino_ en 04 de Mayo de 2017, 16:15:59
Sí. Click derecho en el proyecto ==>> propiedades ==>> XC8 ==>> Xc8-gcc (o el compilador que sea) ==>>optimization ==>optimization level.

Si no está a '0' es que están encendidas. Eso puede dar lugar a que el compilador "desordene" algunas instrucciones...

El compilador que estoy utilizando tengo entendido que es el XC8 v1.34, y dentro de "Optimization" no tengo ningun indicador de "Optimization level"

Te comento la información que tengo:

Generated Assembler Code (tildado)
Assembler Files (tildado)
Speed (no tildado)
Debug (no tildado)
Instuction Invariant Mode (no tildado)
Code Pointer Size (N/A) (sin posibilidad de modificarlo)
Address qualifiers (Ignore) (Opciones: Request - Require - Reject)
Operation Mode (Free) (Opciones: Standard - PRO)

Título: Re:En XC8 No se como leer un array.
Publicado por: KILLERJC en 04 de Mayo de 2017, 16:18:05
Yo tambien lo tengo asi, pero cuando compilo me aparece:

Citar
You have compiled in FREE mode.
Using Omnicient Code Generation that is available in PRO mode,
you could have produced up to 60% smaller and 400% faster code.
See http://www.microchip.com/MPLABXCcompilers for more information.
Título: Re:En XC8 No se como leer un array.
Publicado por: manwenwe en 04 de Mayo de 2017, 16:20:14
Es MPLABX?

(http://img.fenixzone.net/i/MwgKBJ3.png)

Lo siento pero no tengo ejemplo con XC8 (este es XC32)
Título: Re:En XC8 No se como leer un array.
Publicado por: KILLERJC en 04 de Mayo de 2017, 16:30:24
Eso es XC32 manwewe, el de XC8 difiere un poco

Imagen de internet:
(http://www.microchip.co.jp/support/images/faq_com-ass_pic02.jpg)

El tema es que podes tenerlo seleccionado como "PRO" pero si no tenes la licencia en la compilacion te dice que te lo programo como FREE ( sin optimizaciones ).

Acabo de simular el codigo y funciona correctamente.
Lo que resume el problema en:

- O es tema de optimizaciones lo cual no creo
- o es otro problema el que posee el con otra parte del codigo.
- O tal ves sean las librerias de la UART, las cuales son faciles de reemplazar.
Título: Re:En XC8 No se como leer un array.
Publicado por: manwenwe en 04 de Mayo de 2017, 16:34:27
Gracias KILLERJC! Algo nuevo que aprendo. Sólo comenté porque a mi cuando me pasan "cosas inexplicables" la mitad de las veces es porque tengo las optimizaciones encendidas...
Título: Re:En XC8 No se como leer un array.
Publicado por: centrino_ en 05 de Mayo de 2017, 17:43:23
Estimados:

Intentando ver por donde puede llegar a venir el problema, hice otro proyecto en el cual, no uso el USART, sino que cargo manualmente un arreglo de 30 y lo recorro para compararlo con un caracter, y estoy teniendo el mismo problema.

Adjunto todo el código para ver si se puede hallar el problema.

fuses.h
Código: [Seleccionar]
// CONFIG1L
#pragma config WDTEN = OFF      // Watchdog Timer Enable bit (WDT disabled (control is placed on SWDTEN bit))
#pragma config PLLDIV = 1       // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable bit (Reset on stack overflow/underflow enabled)
#pragma config XINST = ON       // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode enabled)

// CONFIG1H
#pragma config CPUDIV = OSC1    // CPU System Clock Postscaler (No CPU system clock divide)
#pragma config CP0 = OFF        // Code Protection bit (Program memory is not code-protected)

// CONFIG2L
#pragma config FOSC = ECPLL     // Oscillator Selection bits (EC Oscillator with PLL, CLKO on RA6, ECPLL used by USB)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)
#pragma config IESO = ON        // Two-Speed Start-up (Internal/External Oscillator Switchover) Control bit (Two-Speed Start-up enabled)

// CONFIG2H
#pragma config WDTPS = 32768    // Watchdog Timer Postscaler Select bits (1:32768)

// CONFIG3L

// CONFIG3H
#pragma config CCP2MX = DEFAULT // ECCP2 MUX bit (ECCP2/P2A is multiplexed with RC1)
#pragma config MSSPMSK = MSK7   // MSSP Address Masking Mode Select bit (7-Bit Address Masking mode enable)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

//Variables
    unsigned char Rxdata[] = {"+INQ:9000:4E:EA6EC7,3E010C,7FFF,+OK"};
    unsigned int NewLineIndex[9],i=0,j=0;

test.c
Código: [Seleccionar]
#include <stdio.h>
#include <stdlib.h>
#include <pic18f67j50.h>
#include <xc.h>
#include "fuses.h"
#include "delays.h"
#include <xlcd.h>

#define _XTAL_FREQ 8000000

#define UP PORTDbits.RD0

void DelayFor18TCY(void);
void DelayPORXLCD(void);
void DelayXLCD(void);
int main(int argc, char** argv){
//Oscilator configuration
    OSCCONbits.IDLEN = 0;
    OSCCONbits.IRCF = 0b111;
    OSCCONbits.OSTS = 0;
    OSCCONbits.SCS = 0b00;

//Pin configuration
    TRISDbits.RD0=1; //Superior
    TRISDbits.RD3=1; //Inferior
//LCD Configuration
  OpenXLCD(FOUR_BIT & LINES_5X7); // A 4 bit o I/O y a 5x7
  while(BusyXLCD());             // Esperamso a que el Lcd este disponible
 /* Table of LCD's posittion
 *  ===============================================
 * |00|01|02|03|04|05|06|07|08|09|0A|0B|0C|0D|0E|0F|
 *  ===============================================
 * |40|41|42|42|44|45|46|47|48|49|4A|4B|4C|4D|4E|4F|
 *  ===============================================
*/  WriteCmdXLCD(0b00000001);  // Clear LCD
    SetDDRamAddr(0x00);        // Address 04
    putrsXLCD("USART v4.4");
    SetDDRamAddr(0x40);        // Address 04
    putrsXLCD("RSSIDataBase");

WriteCmdXLCD(0b00000001);  // Clear LCD
SetDDRamAddr(0x00);
putrsXLCD("Presione el");
SetDDRamAddr(0x40);
putrsXLCD("superior");

while(1){
   
   if(UP == 1){   
        while(UP == 1){};
       WriteCmdXLCD(0b00000001);  // Clear LCD
       SetDDRamAddr(0x00);
       putrsXLCD("PELOTUDO");
               while(i<40){
           
           if(Rxdata[i] == '+'){
               NewLineIndex[j]=i;
               j++;
           }
           i++;
       }
       WriteCmdXLCD(0b00000001);  // Clear LCD
       SetDDRamAddr(0x00);
       putrsXLCD("Comparacion Hech");

    }
   
}
    return (EXIT_SUCCESS);
}
// Delays for LCD's driver
void DelayFor18TCY(void)
{
 Delay10TCYx(120);
}
void DelayPORXLCD(void)
{
 Delay1KTCYx(180);
 return;
}
void DelayXLCD(void)
{
 Delay1KTCYx(60);
 return;
}
Título: Re:En XC8 No se como leer un array.
Publicado por: KILLERJC en 05 de Mayo de 2017, 20:18:43
Apenas lo pruebe edito esto, pero intenta desactivar el set extendido de instrucciones:

Código: [Seleccionar]
#pragma config XINST = ON       // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode enabled)
La otra pregunta.. es External Clock ? es decir le estas dando una señal de clock ahi o pusiste un cristal?

Como te decia, apenas tenga un tiempo pruebo el codigo, quitando la parte del LCD, si funciona entonces es problema de la libreria del LCD entonces imagino.

PD: Trata de quitar la parte del LCD y para ver si termino y lo encontro activa alguna salida.
Título: Re:En XC8 No se como leer un array.
Publicado por: centrino_ en 06 de Mayo de 2017, 11:36:09
SOLUCIONADOO!!!!

Estimado KILERJC, al desactivar el set extendido de instrucciones el problema se solucionó. La verdad no tengo mucho conocimiento sobre que es eso, pero me voy a poner a investigar... Desde ya, muchísimas gracias. Me has dado una ayuda enorme!
Título: Re:En XC8 No se como leer un array.
Publicado por: KILLERJC en 06 de Mayo de 2017, 11:48:43
SOLUCIONADOO!!!!

Estimado KILERJC, al desactivar el set extendido de instrucciones el problema se solucionó. La verdad no tengo mucho conocimiento sobre que es eso, pero me voy a poner a investigar... Desde ya, muchísimas gracias. Me has dado una ayuda enorme!

El set extendido de instrucciones agrega mas instrucciones, pero ademas le cambia el funcionamiento a las instrucciones que estaban antes, este set hace que el manejarse con arrays sea mucho mas simple por ende utilizar menos instrucciones en el PIC, el tema esta en que si no me equivoco debes si o si activar una opcion en el MPLAB indicando que use el set extendido de instrucciones, asi lo compila para este ( ya que como dije cambia la forma de algunas de las instrucciones "base").

Peeero. XC8 no soporta el set extendido, el unico que lo soporta es C18, ya que cuando compran HITECH estos compiladores no soportaban el set extendido, y de hacerlo se presentan otros problemas como registros no accesibles al compilador lo cual dificulta la generacion de codigo y tambien un compilador mas (ya que el set es totalmente disitnto) a mantener, como todo lo que se puede hacer con el set extendido se puede lograr con las instrucciones base no se traslado a XC8.
Asi que el set extendido es solo un adorno para decir "tiene esto", el unico caso donde lo use fue en ASM para probar un par de cosas, pero nada mas, y lo veo util para el caso de arrays, para todo lo demas por ahi es "engorroso" que con instrucciones simples seria mas facil.