TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Prototipe88 en 28 de Marzo de 2014, 14:05:59

Título: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 28 de Marzo de 2014, 14:05:59
Hola a todos. Estoy desarrollando una aplicación y al compilar tengo uno errores en el programa. Vamos hay un poco de todo. Explicaré el programa para que sepáis qué hace exactamente.

Desde otro PIC master yo enviaré una solicitud para pedir una lectura del ADC. En esa solicitud especificaré la dirección de mi PIC slave y también el canal del que deseo obtener la información. La trama a enviar por puerto serie desde el PIC master hacia mi PIC slave será la siguiente: "$ADQ,P01,CHx," donde [ x ] será un valor del 0 al 5 (referente al canal de lectura).

Una vez reciba la trama por el puerto serie de mi PIC slave primero de todo tendré que comprobar si la dirección recibida coincide con la del PIC slave. La dirección de éste PIC slave es la siguiente: "$ADQ,P01,". Comprobaré si coincide con la recibida y posteriormente miraré qué canal de lectura hay que leer. La cadena de caracteres a obtener de la trama recibida es solamente "CHx" para saber qué canal hay que leer. Para éstas dos cosas defino unos strings para guardar la direccion recibida y el canal recibido.

Una vez sepa el canal realizo la lectura y lo guardo en una variable. Es evidente que para cambiar de un valor Numérico a un String tengo que hacer una conversión. Hay unas funciones como por ejemplo itoa() pero prefiero hacerlo manualmente.

Una vez convierto éste valor del ADC a string concateno unos strings para obtener mi dato a devolver por puerto serie. El dato a devolver es el siguiente: "$DAT,P01,CHx,xxxxxxxxxx" donde xxxxxxxxxx es el valor del ADC de 10 bits del PIC 16F88.


Quiero comprobar que todo esté bien definido ya que obtengo errores al compilar y no tengo ni idea... llevo muy poco con CCS. Ya sé que el programa quizás es un poco largo pero si alguien pudiera repasarlo. Cualquier duda respecto al funcionamiento que quiero hacer puedo responder.

Muchas gracias

#include <16F88.h>
#include <stdio.h>
#include <string.h>

#device adc=10 //INDICO EL NÚMERO DE BITS DEL ADC
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_B5, rcv=PIN_B2) //*CONFIGURO PUERTO SERIE

char DireccionPIC[10]= "$ADQ,P01,"; //Es la direccion del PIC
char DireccionPICrespuesta[10]="$DAT,P01,"

int strcmp(const char *cadena1, const char *cadena2); //Definicion funcion STRCMP creo que es obligatorio

#INT_RDA
void INT_UART() {

//Definición de variables
int ValorADC=0; //Variable para lectura ADC
int i=0; //Variable para ciclos for
int Maskara=0; //Variable para obtencion de bits '0' o '1'
char StringValorADC[12]={0};//Cadena de caracteres para guardar valor ADC en Carcteres
char PreDatoSalida[15]={0};
char DatoEntrada[15]={0}; //String para guardar el dato de entrada por UART
char DatoSalida[24]={0}; //String para guardar lo que envio por UART
char DireccionRecibida[10]={0}; //Variable para guardar direccion entrada
char CanalRecibido[6]={0}; //Variable para guardar canal ADC a leer


DatoEntrada=fgets();

for(i=0;i<10;i++){ //Con éste for obtengo la direccion recibida por UART
DireccionRecibida=DatoEntrada;
}
i=0;
DireccionRecibida[10]='/0'; //Pongo caracter nulo para que sea string

if(strcmp(DireccionRecibida, DireccionPIC)==0){ //Comparo si la direccion recibida coincide con la del PIC

for(i=0;i<5;i++){
CanalRecibido=DatoEntrada[i+9]; //Si coincide obtengo el canal de lectura del ADC
}
i=0;
variable2[5]='/0'; //Pongo caracter nulo para que sea string

if(strcmp(CanalRecibido,"CH0")==0){ //voy comparando para ver qué canal he obtenido y leo CHX
set_adc_channel(0); //SELECCIONO CANAL 0 (PIN A0) DEL ADC PARA A LEER.
}

else if(strcmp(CanalRecibido,"CH1")==0){
set_adc_channel(1);
}

else if(strcmp(CanalRecibido,"CH2")==0){
set_adc_channel(2);
}

else if(strcmp(CanalRecibido,"CH3")==0){
set_adc_channel(3);
}

else if(strcmp(CanalRecibido,"CH4")==0){
set_adc_channel(4);
}

else if(strcmp(CanalRecibido,"CH6")==0){
set_adc_channel(5);
}

delay_us(20); //retardo para leer ADC
ValorADC=read_adc(); //lectura ADC

for(i=0;i<10;i++){ //Con un for recorreré solo 10 posiciones del resultado ValorADC (ADC 10 bits)

CopiaValorADC=ValorADC; //Realizo una copia del valor numérico del ADC para no perderlo
Maskara=CopiaValorADC>>i; //Quiero tener el bit "i" a la derecha del todo
Maskara=Maskara&0x0000000000000001; //realizo una AND para ver si tengo un [1] o un
  • .

if(Maskara==1){
StringValorADC[10-i]='1'; //Meto los bits (en forma de caracter) en el String StringValorADC
}
else{
StringValorADC[10-i]='0';
}
}

StringValorADC[0]=','; //Pongo una ',' al principio del resultado
StringValorADC[11]='/0'; //Por último pongo el caracter nulo (para que sea String)

PreDatoSalida=strcat(DireccionPICrespuesta,CanalRe cibido); //Concateno DireccionPICrespuesta y el canal "CHX")

DatoSalida=strcat(PreDatoSalida,StringValorADC);//concateno String anterior y Valor del ADC

puts(DatoSalida); //Envio un solo String con la direccion, canal CHX y el resutado del PIC por UART.

} //ya he enviado por UART: "$ADQ,P01,CHx,xxxxxxxxxx"


void main(){

enable_interrupts(GLOBAL); //HABITILRO TODAS LAS INTERRUPCIONES GLOBALES
enable_interrupts(INT_RDA); //HABILITO LA INTERRUPCIÓN UART
setup_adc_ports(sAN0,sAN1,sAN2,sAN3,sAN4,sAN5); //INDICO EL PIN A0/A1/A2/A3/A4/A5 COMO ENTRADA ANALÓGICA
setup_adc(ADC_CLOCK_INTERNAL); //CLOCK INTERNO PARA CONVERSIÓN ADC
return(0);
}
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 28 de Marzo de 2014, 14:25:29
bueno donde pone CH6 es en realidad CH5
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 28 de Marzo de 2014, 14:35:06
te marca error al compilar? o en la ejecución del programa?
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 28 de Marzo de 2014, 14:41:43
te marca error al compilar? o en la ejecución del programa?

Hola de nuevo rivale! Pues me marca digamos los errores siguientes:


*** Error 23 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 5(8,9): Can not change device type this far into the code
*** Error 48 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 5(9,12): Expecting a (
*** Error 43 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 5(13,15): Expecting a declaration
*** Error 36 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 13(5,8): Expecting a ; or ,
*** Error 43 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 13(11,12): Expecting a declaration
*** Error 46 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 13(31,32): Expecting an =
*** Error 46 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 13(52,53): Expecting an =
*** Error 43 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 13(53,54): Expecting a declaration
*** Error 49 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 31(1,12): Expecting LVALUE such as a variable name  or  * expression
*** Error 45 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 37(23,25): Subscript out of range
*** Error 5 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 37(27,29): Character constant constructed incorrectly
*** Error 5 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 37(30,32): Character constant constructed incorrectly
*** Error 12 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 45(5,14): Undefined identifier   variable2
*** Error 5 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 45(18,20): Character constant constructed incorrectly
*** Error 5 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 45(21,23): Character constant constructed incorrectly
*** Error 51 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 51(4,8): A numeric expression must appear here
*** Error 51 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 55(4,8): A numeric expression must appear here
*** Error 51 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 59(4,8): A numeric expression must appear here
*** Error 51 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 63(4,8): A numeric expression must appear here
*** Error 51 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 67(3,7): A numeric expression must appear here
*** Error 5 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 88(20,22): Character constant constructed incorrectly
*** Error 5 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 88(23,25): Character constant constructed incorrectly
*** Error 76 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 90(1,14): Expect ;
*** Error 49 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 92(1,11): Expecting LVALUE such as a variable name  or  * expression
*** Error 51 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 99(1,5): A numeric expression must appear here
*** Error 58 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 103(26,27): Expecting a close paren
*** Error 127 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 105(1,7): Return value not allowed in void function
*** Error 79 "D:\Documents and Settings\Administrador.DESKTOP\Mis documentos\Programa PIC\project1.c" Line 108(0,1): Expect }
      28 Errors,  0 Warnings.
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 28 de Marzo de 2014, 14:43:24
Alguna variable no estaba definida pero ya lo solventé.
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 28 de Marzo de 2014, 15:00:03
Alguna variable no estaba definida pero ya lo solventé.
ya lo corregiste?. por lo que veo te faltan ; en algunas lineas por eso te marca varios errores, puedes picarle en el error y te envía a la linea correspondiente
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 28 de Marzo de 2014, 17:18:57
Alguna variable no estaba definida pero ya lo solventé.
ya lo corregiste?. por lo que veo te faltan ; en algunas lineas por eso te marca varios errores, puedes picarle en el error y te envía a la linea correspondiente

Le doy al error pero en principio veo que tengo los ";"
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 28 de Marzo de 2014, 17:24:20
¿Me podrías repasar un poco la definición de las funciones y las ideas que estoy plasmando en el programa? Me sería de grandísima ayuda ya que no sé si plasmo correctamente lo que pienso en C (CCS)
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 28 de Marzo de 2014, 17:33:37
viendo tu código encuentro algunos errores:

-dentro del main debes tener un ciclo infinito para que tu pic no se resetee.
-dentro de la interrupción lo ideal es que no realices muchas operaciones, puedes activar una bander y posteriormente realizar lo que desees dentro del main o mandando a llamar a una función
-la función  strcmp no es necesario que la definas, esta ya esta definida dentro de las librerias string.h

Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 28 de Marzo de 2014, 18:38:25
viendo tu código encuentro algunos errores:

-dentro del main debes tener un ciclo infinito para que tu pic no se resetee.
-dentro de la interrupción lo ideal es que no realices muchas operaciones, puedes activar una bander y posteriormente realizar lo que desees dentro del main o mandando a llamar a una función
-la función  strcmp no es necesario que la definas, esta ya esta definida dentro de las librerias string.h





Vale rivale ya he corregido ésto. Adjunto de nuevo el programa.



#include <16F88.h>
#include <stdio.h>
#include <string.h>


#device adc=10 //INDICO EL NÚMERO DE BITS DEL ADC
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_B5, rcv=PIN_B2) //CONFIGURO PUERTO SERIE

#define TRUE 1
#define FALSE 0

char DireccionPIC[10]= "$ADQ,P01,"; //Es la direccion del PIC
char DireccionPICrespuesta[10]="$DAT,P01,"

//Definición de variables

int ValorADC=0; //Variable para lectura ADC
int CopiaValorADC;
int i=0; //Variable para ciclos for
int Maskara=0; //Variable para obtencion de bits '0' o '1'
char StringValorADC[12]={0};//Cadena de caracteres para guardar valor ADC en Carcteres
char PreDatoSalida[15]={0};
char DatoEntrada[15]={0}; //String para guardar el dato de entrada por UART
char DatoSalida[24]={0}; //String para guardar lo que envio por UART
char DireccionRecibida[10]={0}; //Variable para guardar direccion entrada
char CanalRecibido[6]={0}; //Variable para guardar canal ADC a leer
int FlagUART

#INT_RDA
void INT_UART() {

DatoEntrada=fgets();
FlagUART=TRUE;

} //ya he enviado por UART: "$ADQ,P01,CHx,xxxxxxxxxx"


void main(){

enable_interrupts(GLOBAL); //HABITILRO TODAS LAS INTERRUPCIONES GLOBALES
enable_interrupts(INT_RDA); //HABILITO LA INTERRUPCIÓN UART
setup_adc_ports(sAN0,sAN1,sAN2,sAN3,sAN4,sAN5); //INDICO EL PIN A0/A1/A2/A3/A4/A5 COMO ENTRADA ANALÓGICA
setup_adc(ADC_CLOCK_INTERNAL); //CLOCK INTERNO PARA CONVERSIÓN ADC

while(1){

if(FlagUART==TRUE){

FlagUART=FALSE;

for(i=0;i<10;i++){  //Con éste for obtengo la direccion recibida por UART
    DireccionRecibida=DatoEntrada;
}
    i=0;
    DireccionRecibida[10]='/0'; //Pongo caracter nulo para que sea string

if(strcmp(DireccionRecibida, DireccionPIC)==0){ //Comparo si la direccion recibida coincide con la del PIC

   for(i=0;i<5;i++){
      CanalRecibido=DatoEntrada[i+9]; //Si coincide obtengo el canal de lectura del ADC
   }
    i=0;
    variable2[5]='/0';   //Pongo caracter nulo para que sea string

   if(strcmp(CanalRecibido,"CH0")==0){ //voy comparando para ver qué canal he obtenido y leo CHX
     set_adc_channel(0); //SELECCIONO CANAL 0 (PIN A0) DEL ADC PARA A LEER.
   }

   else if(strcmp(CanalRecibido,"CH1")==0){
      set_adc_channel(1);
   }
  
   else if(strcmp(CanalRecibido,"CH2")==0){
      set_adc_channel(2);
   }

   else if(strcmp(CanalRecibido,"CH3")==0){
      set_adc_channel(3);
   }
  
   else if(strcmp(CanalRecibido,"CH4")==0){
      set_adc_channel(4);
   }
  
  else if(strcmp(CanalRecibido,"CH5")==0){
      set_adc_channel(5);
   }

delay_us(20); //retardo para leer ADC
ValorADC=read_adc(); //lectura ADC

for(i=0;i<10;i++){ //Con un for recorreré solo 10 posiciones del resultado ValorADC (ADC 10 bits)

    CopiaValorADC=ValorADC; //Realizo una copia del valor numérico del ADC para no perderlo
    Maskara=CopiaValorADC>>i; //Quiero tener el bit "i" a la derecha del todo
    Maskara=Maskara&0x0000000000000001;  //realizo una AND para ver si tengo un [1] o un
  • .

    if(Maskara==1){
       StringValorADC[10-i]='1';  //Meto los bits (en forma de caracter) en el String StringValorADC
    }
    else{
       StringValorADC[10-i]='0';
    }
}

StringValorADC[0]=','; //Pongo una ',' al principio del resultado
StringValorADC[11]='/0'; //Por último pongo el caracter nulo (para que sea String)

PreDatoSalida=strcat(DireccionPICrespuesta,CanalRecibido); //Concateno DireccionPICrespuesta y el canal "CHX")

DatoSalida=strcat(PreDatoSalida,StringValorADC);//concateno String anterior y Valor del ADC

puts(DatoSalida); //Envio un solo String con la direccion, canal CHX y el resutado del PIC por UART.

   }
 
  }

 }

}

Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 28 de Marzo de 2014, 18:42:56
ya te compila y funciona como lo esperabas?
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 28 de Marzo de 2014, 18:52:35
ya te compila y funciona como lo esperabas?


No me funciona bien aún... hay algo que no estoy haciendo bien... puse ";" en FlafUART; y tambien lo de variable2 que la cambie por otra.
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 28 de Marzo de 2014, 19:03:44
otro error en esta linea

 DireccionRecibida=DatoEntrada;

debes ir copiando los elementos del vector, debe ser así

DireccionRecibida=DatoEntrada;

 
Código: C
  1. DireccionRecibida[i]=DatoEntrada[i];

también en esta linea, del lado de canal recibido no estas asignando un elemento del vector
Código: C
  1. CanalRecibido[i]=DatoEntrada[i+9];
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 28 de Marzo de 2014, 19:07:44
una sugerencia para hacer mas facil la selección del canal es que solo tomes en cuenta el caracter que corresponde al canal

"$ADQ,P01,CHx,"

esta en la posición 11, entonces podrias leer solo ese character, restarle 0x30 y tienes directamente el canal que tienes que leer.
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 28 de Marzo de 2014, 19:31:29
una sugerencia para hacer mas facil la selección del canal es que solo tomes en cuenta el caracter que corresponde al canal

"$ADQ,P01,CHx,"

esta en la posición 11, entonces podrias leer solo ese character, restarle 0x30 y tienes directamente el canal que tienes que leer.


Pues no sé por qué razón lo de los vectores no se copió bien. Pero a corregí de nuevo eso de DatoRecibido:

CORRECIÓN1:

for(i=0;i<10;i++){  //Con éste for obtengo la direccion recibida por UART
    DireccionRecibida[ i ]=DatoEntrada[ i ];
}
    i=0;
    DireccionRecibida[10]='/0'; //Pongo caracter nulo para que sea string


CORRECIÓN2:

for(i=0;i<5;i++){
      CanalRecibido[ i ]=DatoEntrada[i+9]; //Si coincide obtengo el canal de lectura del ADC
   }
    i=0;
    CanalRecibido[5]='/0';   //Pongo caracter nulo para que sea string
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 28 de Marzo de 2014, 19:34:35
haaa, no habia visto que en mi comentario también desaparecieron los corchetes y no se ve la corrección

deberia ser así

Código: C
  1. DireccionRecibida[i]=DatoEntrada[i];

Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 28 de Marzo de 2014, 19:39:12
ya encontré tu error

Código: C
  1. for(i=0;i<10;i++){ //Con éste for obtengo la direccion recibida por UART
  2. DireccionRecibida[i]=DatoEntrada[i];
  3. }

estas copiando los caracteres desde la posición 0 hasta la posición 9, es decir, estas copiando 10 caracteres, no 9
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 29 de Marzo de 2014, 06:28:23
ya encontré tu error

Código: C
  1. for(i=0;i<10;i++){ //Con éste for obtengo la direccion recibida por UART
  2. DireccionRecibida[i]=DatoEntrada[i];
  3. }

estas copiando los caracteres desde la posición 0 hasta la posición 9, es decir, estas copiando 10 caracteres, no 9


Vale eso ya lo acabo de cambiar. Otra cosa rivale. cuando realizo algo de éste estilo:

FlagString=strcmp(CanalRecibido,"CH2");
   else if(FlagString==0){
      set_adc_channel(2);
   }


me da un error diciendo lo siguiente:

A numeric expression must appear here


Y bueno cuando cambio "CH2" por el array de caracteres CH2 (ya que CH2[4]="CH2") también me da error al compilar.
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 29 de Marzo de 2014, 10:26:28
Hola, probe compilar tu código y tenia varios errores, le corregi todo lo que no dejaba compilar, aunque no cambié la lógica, checa si ya lo puedes compilar  hace lo que quieres, entonces ya podemos revisar la lógica


Código: C
  1. #include <16F88.h>
  2. #device adc=10 //INDICO EL NÚMERO DE BITS DEL ADC
  3. #include <stdio.h>
  4. #include <string.h>
  5.  
  6. #fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
  7. #use delay(clock=8000000)
  8. #use rs232(baud=9600, xmit=PIN_B5, rcv=PIN_B2) //CONFIGURO PUERTO SERIE
  9.  
  10.  
  11. char can0[5]="CH0";
  12. char can1[5]="CH1";
  13. char can2[5]="CH2";
  14. char can3[5]="CH3";
  15. char can4[5]="CH4";
  16. char can5[5]="CH5";
  17.  
  18. char DireccionPIC[10]= "$ADQ,P01,"; //Es la direccion del PIC
  19. char DireccionPICrespuesta[30]="$DAT,P01,";
  20.  
  21. //Definición de variables
  22.  
  23. int ValorADC=0; //Variable para lectura ADC
  24. int CopiaValorADC;
  25. int i=0; //Variable para ciclos for
  26. int Maskara=0; //Variable para obtencion de bits '0' o '1'
  27. char StringValorADC[12]={0};//Cadena de caracteres para guardar valor ADC en Carcteres
  28. char PreDatoSalida[15]={0};
  29. char DatoEntrada[15]={0}; //String para guardar el dato de entrada por UART
  30. char DatoSalida[24]={0}; //String para guardar lo que envio por UART
  31. char DireccionRecibida[10]={0}; //Variable para guardar direccion entrada
  32. char CanalRecibido[6]={0}; //Variable para guardar canal ADC a leer
  33. int FlagUART;
  34.  
  35. #INT_RDA
  36. void INT_UART() {
  37.  
  38. gets(DatoEntrada);
  39. FlagUART=TRUE;
  40.  
  41. }
  42.  
  43.  
  44. void main(){
  45.  
  46. enable_interrupts(GLOBAL); //HABITILRO TODAS LAS INTERRUPCIONES GLOBALES
  47. enable_interrupts(INT_RDA); //HABILITO LA INTERRUPCIÓN UART
  48. setup_adc_ports(sAN0|sAN1|sAN2|sAN3|sAN4|sAN5); //INDICO EL PIN A0/A1/A2/A3/A4/A5 COMO ENTRADA ANALÓGICA
  49. setup_adc(ADC_CLOCK_INTERNAL); //CLOCK  INTERNO PARA CONVERSIÓN ADC
  50.  
  51. while(1){
  52.  
  53. if(FlagUART==TRUE){
  54.  
  55. FlagUART=FALSE;
  56.  
  57. for(i=0;i<9;i++){  //Con éste for obtengo la direccion recibida por UART
  58.     DireccionRecibida[i]=DatoEntrada[i];
  59. }
  60.     i=0;
  61.     DireccionRecibida[9]=0; //Pongo caracter nulo para que sea string
  62.  
  63. if(strcmp(DireccionRecibida, DireccionPIC)==0){ //Comparo si la direccion recibida coincide con la del PIC
  64.  
  65.    for(i=0;i<4;i++){
  66.       CanalRecibido[i]=DatoEntrada[i+9]; //Si coincide obtengo el canal de lectura del ADC
  67.    }
  68.     i=0;
  69.     CanalRecibido[4]=0;   //Pongo caracter nulo para que sea string
  70.  
  71.    if(strcmp(CanalRecibido,can0)==0){ //voy comparando para ver qué canal he obtenido y leo CHX
  72.      set_adc_channel(0); //SELECCIONO CANAL 0 (PIN A0) DEL ADC PARA A LEER.
  73.    }
  74.  
  75.    else if(strcmp(CanalRecibido,can1)==0){
  76.       set_adc_channel(1);
  77.    }
  78.  
  79.    else if(strcmp(CanalRecibido,can2)==0){
  80.       set_adc_channel(2);
  81.    }
  82.  
  83.    else if(strcmp(CanalRecibido,can3)==0){
  84.       set_adc_channel(3);
  85.    }
  86.  
  87.    else if(strcmp(CanalRecibido,can4)==0){
  88.       set_adc_channel(4);
  89.    }
  90.  
  91.   else if(strcmp(CanalRecibido,can5)==0){
  92.       set_adc_channel(5);
  93.    }
  94.  
  95. delay_us(20); //retardo para leer ADC
  96. ValorADC=read_adc(); //lectura ADC
  97.  
  98. for(i=0;i<10;i++){ //Con un for recorreré solo 10 posiciones del resultado ValorADC (ADC 10 bits)
  99.  
  100.     CopiaValorADC=ValorADC; //Realizo una copia del valor numérico del ADC para no perderlo
  101.     Maskara=CopiaValorADC>>i; //Quiero tener el bit "i" a la derecha del todo
  102.     Maskara=Maskara&0x0000000000000001;  //realizo una AND para ver si tengo un [1] o un
  103.    if(Maskara==1){
  104.        StringValorADC[10-i]='1';  //Meto los bits (en forma de caracter) en el String StringValorADC
  105.     }
  106.     else{
  107.        StringValorADC[10-i]='0';
  108.     }
  109. }
  110.  
  111. StringValorADC[0]=','; //Pongo una ',' al principio del resultado
  112. StringValorADC[11]=0; //Por último pongo el caracter nulo (para que sea String)
  113.  
  114. strcat(DireccionPICrespuesta,CanalRecibido); //Concateno DireccionPICrespuesta y el canal "CHX")
  115.  
  116. strcat(DireccionPICrespuesta,StringValorADC);//concateno String anterior y Valor del ADC
  117.  
  118. puts(DireccionPICrespuesta); //Envio un solo String con la direccion, canal CHX y el resutado del PIC por UART.
  119.  
  120.    }
  121.  
  122.   }
  123.  
  124.  }
  125.  
  126. }
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 29 de Marzo de 2014, 10:29:58
yo cambiaria esta parte del código

Código: C
  1. if(strcmp(CanalRecibido,can0)==0){ //voy comparando para ver qué canal he obtenido y leo CHX
  2.      set_adc_channel(0); //SELECCIONO CANAL 0 (PIN A0) DEL ADC PARA A LEER.
  3.    }
  4.  
  5.    else if(strcmp(CanalRecibido,can1)==0){
  6.       set_adc_channel(1);
  7.    }
  8.  
  9.    else if(strcmp(CanalRecibido,can2)==0){
  10.       set_adc_channel(2);
  11.    }
  12.  
  13.    else if(strcmp(CanalRecibido,can3)==0){
  14.       set_adc_channel(3);
  15.    }
  16.  
  17.    else if(strcmp(CanalRecibido,can4)==0){
  18.       set_adc_channel(4);
  19.    }
  20.  
  21.   else if(strcmp(CanalRecibido,can5)==0){
  22.       set_adc_channel(5);
  23.    }


por algo así



Código: [Seleccionar]
set_adc_channel(canalreibido[2]-0x30);


como ves, quitas muchas comparaciones si solo tomas en cuenta el elemento 2 de tu vector CHX, y le restas 0x30 para que el '0' lo vuelva 0 y el '1' lo vuelva 1 y así con los demás valores

Saludos
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 30 de Marzo de 2014, 07:51:44
Código nuevo por si lo quieres revisar abajo expongo algunas dudas en el siguiente post:

Código: [Seleccionar]
#include <16F88.h>
#device ADC=10 //INDICO EL NÚMERO DE BITS DEL ADC

#include <stdio.h>
#include <string.h>

#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_B5, rcv=PIN_B2) //CONFIGURO PUERTO SERIE

char DireccionPIC[10]= "$ADQ,P01,"; //Es la direccion del PIC
char DireccionPICrespuesta[10]="$DAT,P01,";

//Definición de variables

int ValorADC=0; //Variable para lectura ADC
//int CopiaValorADC=0;
int i=0; //Variable para ciclos for
//int Maskara=0; //Variable para obtencion de bits '0' o '1'
char StringValorADC[12]={0};//Cadena de caracteres para guardar valor ADC en Carcteres
char DatoEntrada[13]={0}; //String para guardar el dato de entrada por UART
char DatoSalida[24]={0}; //String para guardar lo que envio por UART
char DireccionRecibida[10]={0}; //Variable para guardar direccion entrada
char CanalRecibido[4]={0}; //Variable para guardar canal ADC a leer
int FlagUART=0;
int FlagString=1;

#INT_RDA
void INT_UART() {

for(i=0;i<12;i++){
DatoEntrada[i]=getc();
 }

DatoEntrada[12]='\0';
i=0;
FlagUART=1;

} //ya he enviado por UART: "$ADQ,P01,CHx,n"


void main(){

enable_interrupts(GLOBAL); //HABITILRO TODAS LAS INTERRUPCIONES GLOBALES
enable_interrupts(INT_RDA); //HABILITO LA INTERRUPCIÓN UART
setup_adc_ports(sAN0|sAN1|sAN2|sAN3|sAN4|sAN5); //INDICO EL PIN A0/A1/A2/A3/A4/A5 COMO ENTRADA ANALÓGICA
setup_adc(ADC_CLOCK_INTERNAL); //CLOCK INTERNO PARA CONVERSIÓN ADC

while(1){

if(FlagUART==1){

FlagUART=0;

for(i=0;i<9;i++){  //Con éste for obtengo la direccion recibida por UART
    DireccionRecibida[i]=DatoEntrada[i];
}
    i=0;
    DireccionRecibida[9]='\0'; //Pongo caracter nulo para que sea string

FlagString=strcmp(DireccionRecibida, DireccionPIC);
   
if(FlagString==0){ //Comparo si la direccion recibida coincide con la del PIC

 for(i=0;i<3;i++){
      CanalRecibido[i]=DatoEntrada[i+9]; //Si coincide obtengo el canal de lectura del ADC
   }
 i=0;
 CanalRecibido[3]='\0';   //Pongo caracter nulo para que sea string


   if((FlagString=strcmp(CanalRecibido,(char*)"CH0"))==0){ //voy comparando para ver qué canal he obtenido y leo CHX
     
    set_adc_channel(0); //SELECCIONO CANAL 0 (PIN A0) DEL ADC PARA A LEER.
   }

   else if((FlagString=strcmp(CanalRecibido,(char*)"CH1"))==0){

      set_adc_channel(1); 
   }
 
   else if((FlagString=strcmp(CanalRecibido,(char*)"CH2"))==0){
      set_adc_channel(2);
   }

   else if((FlagString=strcmp(CanalRecibido,(char*)"CH3"))==0){
      set_adc_channel(3);
   }

   else if((FlagString=strcmp(CanalRecibido,(char*)"CH4"))==0){
      set_adc_channel(4);
   }

  else if((FlagString=strcmp(CanalRecibido,(char*)"CH5"))==0){
      set_adc_channel(5);
   }

delay_us(20); //retardo para leer ADC
ValorADC=read_adc(); //lectura ADC

////for(i=0;i<10;i++){ //Con un for recorreré solo 10 posiciones del resultado ValorADC (ADC 10 bits)
//
//    CopiaValorADC=ValorADC; //Realizo una copia del valor numérico del ADC para no perderlo
//    Maskara=CopiaValorADC>>i; //Quiero tener el bit "i" a la derecha del todo
//    Maskara=Maskara&0x0000000000000001;  //realizo una AND para ver si tengo un [1] o un [0].
//    if(Maskara==1){
//       StringValorADC[10-i]='1';  //Meto los bits (en forma de caracter) en el String StringValorADC
//    }
//    else{
//       StringValorADC[10-i]='0';
//    }
//}
//

sprintf(StringValorADC,",%d",ValorADC); //pongo en StringValorADC el ValorADC pero en formsto string

//StringValorADC[0]=','; //Pongo una ',' al principio del resultado
//StringValorADC[11]='\0'; //Por último pongo el caracter nulo (para que sea String)

strcat(DatoSalida,DireccionPICrespuesta); //Concateno DireccionPICrespuesta y el canal "CHX")
strcat(DatoSalida,CanalRecibido);
strcat(DatoSalida,StringValorADC);//concateno String anterior y Valor del ADC

printf("%s", DatoSalida); //Envio un solo String con la direccion, canal CHX y el resutado del PIC por UART.

   }
 
  }

 }

}
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 31 de Marzo de 2014, 09:04:48
Bueno, respecto a la cadena de caracteres que tengo que recibir por puerto serie lo modifiqué por ésto:
Tengo que recibir por puerto serie una cadena de 12 caracteres (12bytes + 1byte de caracter nulo [ '\0' ] ).

Código: [Seleccionar]
char DatoEntrada[13]={0};

          for(i=0;i<12;i++){
          DatoEntrada[i]=getc();
          }

         DatoEntrada[12]='\0'; //ya tengo un string con el string del puerto serie recibido

Creo que la función getc() permite obtener solo un carácter del puerto serie (1byte) con lo cual si sé que voy a recibir 12bytes (el byte del caracter nulo no lo tengo en cuenta) pues realizo un FOR para ir metiendo esos caracteres en un array de caracteres que para que se convierta en string le inserto por último el caracter nulo '\0'


Luego la duda que tengo es, al final del código,  para convertir un valor de INT a STRING realizo lo siguiente (en el anterior post lo hice de una forma un poco rara pero creo que ésta es mejor):

Código: [Seleccionar]
sprintf(StringValorADC,",%d",ValorADC);
Es decir que el ValorADC que es un INT le pongo una coma delante y lo guardo en StringValorADC en forma de string ya que el caracter nulo lo pone automáticamente esa función.

Es decir que tendré algo así: si ValorADC=750 entonces StringValorADC=",750"


Luego otra cosa es:


Código: [Seleccionar]
strcat(DatoSalida,DireccionPICrespuesta);
La función STRCAT permite concatenar srings de diferentes longitudes siempre y cuando el string de destino (en mi caso DatoSalida) sea suficientemente grande. Bien pues imaginad que tengo lo siguiente:

Código: [Seleccionar]
DatoSalida[15]="HolaMundo"
DireccionPICrespuesta[3]="001"

Cuando realizo la concatenación se hará justo despues del último caracter del DatoSalida? es decir tendré esto?

DatoSalida[15]="HolaMundo001" + el caracter nulo ?
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 31 de Marzo de 2014, 11:17:36
Citar
Creo que la función getc() permite obtener solo un carácter del puerto serie (1byte) con lo cual si sé que voy a recibir 12bytes (el byte del caracter nulo no lo tengo en cuenta) pues realizo un FOR para ir metiendo esos caracteres en un array de caracteres que para que se convierta en string le inserto por último el caracter nulo '\0'

esto es correcto, con getc solo obtienes un caracter


Citar
Es decir que el ValorADC que es un INT le pongo una coma delante y lo guardo en StringValorADC en forma de string ya que el caracter nulo lo pone automáticamente esa función.

Es decir que tendré algo así: si ValorADC=750 entonces StringValorADC=",750"

correcto


Citar
Cuando realizo la concatenación se hará justo despues del último caracter del DatoSalida? es decir tendré esto?

DatoSalida[15]="HolaMundo001" + el caracter nulo ?

también es correcto
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 31 de Marzo de 2014, 11:42:25
MUCHÍSIMAS GRACIAS rivale. Eres todo una máquina  :)

Respecto a los if: if((FlagString=strcmp(CanalRecibido,(char*)"CH0"))==0) por qué razón me da Warnings?

Igualmente voy a mirar de implementarlo como tu decias. Voy a intentar realizarlo.

También me acaba de surgir una pequeña duda. Si yo realizo:

Código: [Seleccionar]
output_high(PIN_B1);
output_high(PIN_B0);

El compilador ya sabe que se trata de salidas y no tengo que especificarle nada no? Es que he leído algo sobre #use standard_io(PUERTO) que ya está definida por defecto en el compilador y hace ésto de averiguar que pines los utilizamos como salidas y cuales como entrada.
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 02 de Abril de 2014, 12:57:24
Hola, no habia visto que habias actualizado tu último post.

el warning que te sale supongo que es porque estas haciendo una declaracion dentro de un if, y no debe ser así.

en cuanto a los outputs, por default el compilador esta en standard_io, y cada que usas un output, se ponen como salidas los pines correspondientes y cada que usas un input se ponen como entradas, sin embargo, te recomiendo que configures propiamente tus entradas y salidas, ya que si despúes quieres programar en otro lenguaje o usar algun otro tipo de micro, te vas a quedar con la costumbre de que se configuran solos los puertos.


Saludos
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 02 de Abril de 2014, 15:42:21
Hola, no habia visto que habias actualizado tu último post.

el warning que te sale supongo que es porque estas haciendo una declaracion dentro de un if, y no debe ser así.

en cuanto a los outputs, por default el compilador esta en standard_io, y cada que usas un output, se ponen como salidas los pines correspondientes y cada que usas un input se ponen como entradas, sin embargo, te recomiendo que configures propiamente tus entradas y salidas, ya que si despúes quieres programar en otro lenguaje o usar algun otro tipo de micro, te vas a quedar con la costumbre de que se configuran solos los puertos.


Saludos



La duda que me surge es: Si utilizo un oscilador de cuarzo (es decir un oscilador externo) para el clock del micro debo utilizar las entradas RB6 y RB7 referentes al PIC 16F88. Si defino entradas y salidas previamente como debo configurar las del clock referentes al puerto B?

Es decir haria los iguiente?

#use standard_io(B)

y en la funcion del void main() definiría las entradas y salidas del puerto así? set_tris_B(0x)? (pero los RB6 y  RB7 si son del clock los configuro como entradas?
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 02 de Abril de 2014, 15:55:16
cuando usas un oscilador externo no importa como configures los pines correspondientes, puedes verlo en la página 55 y 56 de la hoja de especificaciones
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 02 de Abril de 2014, 18:29:10
cuando usas un oscilador externo no importa como configures los pines correspondientes, puedes verlo en la página 55 y 56 de la hoja de especificaciones

 :) Gracias rivale! estoy aprendiendo muchísimo gracias a tu ayuda.
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 03 de Abril de 2014, 17:35:30
Ya casi ando acabando el programa. Quisiera con consultar una de éstas dudas que investigando no consigo resolver.

Una vez leo el ADC (de 10 bits del PIC) mediante ValorADC=adc_read() parece evidente que si la variable ValorADC es de tipo INT si mi valor de ADC lee 1000 pues ValorADC=1000 y si el ADC lee 900 pues ValorADC=900.

Yo quiero enviar por puerto serie una trama FIJA de X bytes. Si mi valor de ADC es 900 o 1000 parece evidente que la cantidad de bytes a enviar por puerto serie cambia. Yo necesito enviar algo fijo independientemente del valor del ADC. Yo para intentar resolver ésto realizo lo siguiente:


Código: [Seleccionar]
if(ValorADC<1000){

sprintf(StringValorADC,".0%d",ValorADC); //pongo en StringValorADC el ValorADC pero en formsto string

}

else if(ValorADC<100){

sprintf(StringValorADC,".00%d",ValorADC); //pongo en StringValorADC el ValorADC pero en formsto string

}

else if(ValorADC<10){

sprintf(StringValorADC,".000%d",ValorADC); //pongo en StringValorADC el ValorADC pero en formsto string

}


Como lo ves rivale? hay alguna solución mejor?
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 03 de Abril de 2014, 17:44:04
Recuerda que en ccs el tipo int es de 8 bits, por lo que solo puedes guardar hasta 127 en numeros signados, para leer 10 bits necesitas usar un tipo long, que es un entero de 16 bits

no necesitas verificar si es mayor o menor a 1000, la forma correcta sería la siguiente:

Código: C
  1. printf ("%04l",ValorADC );


lo que vas a imprimir es un long, entonces es %l, y para que sea fija la cantidad de caracteres a mostar usas %04l:

donde el numero que sigue al % es con lo que va a rellenar, en este caso un 0, y el siguiente numero es la cantidad fija de dijitos que quieres mostrar, 4 en este caso.


Espero te sirva, Saludos
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 03 de Abril de 2014, 17:50:56
Recuerda que en ccs el tipo int es de 8 bits, por lo que solo puedes guardar hasta 127 en numeros signados, para leer 10 bits necesitas usar un tipo long, que es un entero de 16 bits

no necesitas verificar si es mayor o menor a 1000, la forma correcta sería la siguiente:

Código: C
  1. printf ("%04l",ValorADC );


lo que vas a imprimir es un long, entonces es %l, y para que sea fija la cantidad de caracteres a mostar usas %04l:

donde el numero que sigue al % es con lo que va a rellenar, en este caso un 0, y el siguiente numero es la cantidad fija de dijitos que quieres mostrar, 4 en este caso.


Espero te sirva, Saludos


Es decir que si utilizo sprintf(StringValorADC,".%04l",ValorADC); siempre voy a tener ValorADC=.0004 ó .0010 ó .0100 ó .1023 etc. Si en vez de un 0 introduzco un 1 el valor restante para completar los 4 dígitos los rellenaría con un 1?

Muchas grasias!
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 03 de Abril de 2014, 17:56:12


Es decir que si utilizo sprintf(StringValorADC,".%04l",ValorADC); siempre voy a tener ValorADC=.0004 ó .0010 ó .0100 ó .1023 etc. Si en vez de un 0 introduzco un 1 el valor restante para completar los 4 dígitos los rellenaría con un 1?

Muchas grasias!

exacto, el primer digito indica con que va a completar para que impriman los caracteres faltantes
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 03 de Abril de 2014, 17:57:28
Me da un error de formato en el sprintf su pongo que para ésta función no le gusta el %04l. Necesito guardar el valor del ADC en forma de string dentro de una variable para luego concatenarla con otro string. Se puede hacer? (lo de concatenar ya lo hago con el strcat pero lo de guardar el valor del ADC dentro de otro string pero ya en formato string sin sprintf no se hacerlo)
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 03 de Abril de 2014, 18:00:57
intenta con ld, en lugar de l
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 03 de Abril de 2014, 18:02:30
intenta con ld, en lugar de l

Ahora PERFERCTO.  :) :) :) :) :) :) Qué diferencia hay?
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 03 de Abril de 2014, 18:14:11
ld es para imprimir "longs" signados y con lu imprimes no signados
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 03 de Abril de 2014, 18:35:26
ld es para imprimir "longs" signados y con lu imprimes no signados

:) ahora lo entiendo.
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 10 de Abril de 2014, 12:10:32
rivale he utilizado el entorno de programación MPLAB y el compilador CCS. Entonces dispodré en poco tiempo del ICD2 de Microchip. Una vez compilo el programa (sin errores y solo unos warnings) debo utilizar el MPLAB ICD2 Setup Wizard para la programación del micro cierto? o hay que realizar un paso previo como el generar el archivo .hex para introducirlo en algún lugar antes? muchas gracias!
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 11 de Abril de 2014, 10:45:17
rivale he utilizado el entorno de programación MPLAB y el compilador CCS. Entonces dispodré en poco tiempo del ICD2 de Microchip. Una vez compilo el programa (sin errores y solo unos warnings) debo utilizar el MPLAB ICD2 Setup Wizard para la programación del micro cierto? o hay que realizar un paso previo como el generar el archivo .hex para introducirlo en algún lugar antes? muchas gracias!
no tengo el ICD2, yo tengo el pickit3 y el programador de ccs(no recuerdo como se llama), pero en general en mplab escoges el programador a usar y solo le pones grabar, para el pickit 3 tenias que activarle el voltaje de salida para que se pudiera programar el micro usando como fuente el usb, pero creo que para el icd2 esto no es necesario
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 26 de Abril de 2014, 10:06:00
He conseguido programar con el ICD2 pero tengo un problema en el funcionamiento del programa. Cuando realizo la siguientes concatenaciones. El PIC mio se queda como colgado... es como si no le gustara la función STRCAT.


    
Código: [Seleccionar]
strcat(dato_salida, (char*)"$");
    strcat(dato_salida, tipo_dato); //tipo_dato es un string
    strcat(dato_salida, (char*)",");
    strcat(dato_salida, direccion_pic); // direccion_pic es un string
    strcat(dato_salida, (char*)"\r");
    strcat(dato_salida, (char*)"\n");
    printf("%s", dato_salida);


En cambio cuando pongo solo:

Código: [Seleccionar]
printf("$ADQ,P00,CH0\r);

me lo hace sin problema. A qué puede ser debido? El programa no me da errores ni warnings respecto a ésto. Y compila bien al igual que al programarlo. He añadido también la libreria string.h pero no sé a qué puede ser debido éste fallo en el funcionamiento...


Te adjunto el codigo completo por si quieres hecharle un vistazo:


Código: [Seleccionar]
#include <16f88.h>
#device ADC=10 //INDICO EL NÚMERO DE BITS DEL ADC

#include <stdio.h>
#include <string.h>


#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_B5, rcv=PIN_B2) //CONFIGURO PUERTO SERIE


//**VARIABLES PARA GESTIONAR LA TRAMA RECIBIDA Y LA TRAMA A ENVIAR POR PUERTO SERIE**//

long valor_adc=0; //Variable para lectura ADC

int P_W=0; //puntero escritura
int P_R=0; //puntero lectura

int i=0; //puntero bucle for
int j=0;

int inicio=0;
int final=0;

char string_valor_adc[6]={0};//Cadena de caracteres para guardar valor ADC en Carcteres
char trama_entrada[91]={0}; //String para guardar el dato de entrada por UART
char direccion_pic[4]={0};
char tipo_dato[4]={0};
char canal[4]={0};
char dato_salida[19]={0}; //String para guardar lo que envio por UART
char dato[13]={0};

short flag=0;
short flag_permiso=0;
short flag_tst=0;


void lectura(){

 for(P_R=0; P_R<91; P_R++){

  if(trama_entrada[P_R]==(char*)"$"){

  inicio=P_R;
  
  for(P_R=inicio; P_R<91; P_R++){
 
   if(trama_entrada[P_R]==(char*)"\r"){

   P_W=0;
   final=P_R;
   flag_permiso=1;
   break;

    }
 
   }
   break;
  }

 }

}


void escritura(){

for(i=inicio; i<=final; i++){
  
dato[j]=trama_entrada[i];
j++;

  }

i=0;
j=0;

}


void procesamiento(){

for(i=0; i<3; i++){

direccion_pic[i]=dato[i+5];

}


if((flag=strcmp(direccion_pic, (char*)"P01")==0)){

for(i=0; i<3; i++){

tipo_dato[i]=dato[i+1];

}

if((flag=strcmp(tipo_dato, (char*)"ADQ")==0)){

for(i=0; i<3; i++){

canal[i]=dato[i+9];

}


if((flag=strcmp(canal,(char*)"CH1"))==0){
      set_adc_channel(1);  
   }
  
   else if((flag=strcmp(canal,(char*)"CH2"))==0){
      set_adc_channel(2);
   }

   else if((flag=strcmp(canal,(char*)"CH3"))==0){
      set_adc_channel(3);
   }

   else if((flag=strcmp(canal,(char*)"CH4"))==0){
      set_adc_channel(4);
   }

  else if((flag=strcmp(canal,(char*)"CH5"))==0){
      set_adc_channel(5);
   }


delay_us(20);//retardo para leer ADC
valor_adc=read_adc();//lectura ADC

 }

else if((flag=strcmp(tipo_dato, (char*)"TST")==0)){

flag_tst=1;

}

}

}

void enviar(){

switch(flag_tst){

case 0:

    sprintf(string_valor_adc,",%04ld",valor_adc);

    strcat(dato_salida, (char*)"$");
    strcat(dato_salida, tipo_dato);
    strcat(dato_salida, (char*)",");
    strcat(dato_salida, direccion_pic); //Concateno DireccionPICrespuesta y el canal "CHX")
    strcat(dato_salida, (char*)",");
    strcat(dato_salida, canal);
    strcat(dato_salida, string_valor_adc);//concateno String anterior y Valor del ADC
    strcat(dato_salida, (char*)"\r");
    strcat(dato_salida, (char*)"\n");


    output_high(PIN_B0);

    printf("%s", dato_salida); //Envio un solo String con la direccion, canal CHX y el resutado del PIC por UART.

    output_high(PIN_B0);

    flag_permiso=0;

    break;

case 1:

    strcat(dato_salida, (char*)"$");
    strcat(dato_salida, tipo_dato);
    strcat(dato_salida, (char*)",");
    strcat(dato_salida, direccion_pic); //Concateno DireccionPICrespuesta y el canal "CHX")
    strcat(dato_salida, (char*)"\r");
    strcat(dato_salida, (char*)"\n");

    output_high(PIN_B0);

    printf("%s", dato_salida); //Envio un solo String con la direccion, canal CHX y el resutado del PIC por UART.

    output_high(PIN_B0);

    flag_permiso=0;
    flag_tst=0;

    break;

}

}


#INT_RDA

void INT_UART() {

trama_entrada[P_W]=getc();
P_W++;
 
}


void main(){

output_low(PIN_B0);

enable_interrupts(GLOBAL); //HABIlLITO TODAS LAS INTERRUPCIONES GLOBALES
enable_interrupts(INT_RDA); //HABILITO LA INTERRUPCIÓN UART
setup_adc_ports(sAN0|sAN1|sAN2|sAN3|sAN4|sAN5); //INDICO EL PIN A0/A1/A2/A3/A4/A5 COMO ENTRADA ANALÓGICA
setup_adc(ADC_CLOCK_INTERNAL); //CLOCK INTERNO PARA CONVERSIÓN ADC

 while(1){

 lectura();

if(flag_permiso==1){
 escritura();
 procesamiento();
 enviar();
  }
 }
}
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: rivale en 26 de Abril de 2014, 12:15:26
Hola, porque no intentas concatenar todo al momento de mandarlo a imprimir


printf("%s$%s,%s\r\n",dato_salida,tipodato,direccion_pic);


eso te da el resultado que quieres
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 26 de Abril de 2014, 12:28:11
Hola, porque no intentas concatenar todo al momento de mandarlo a imprimir


printf("%s$%s,%s\r\n",dato_salida,tipodato,direccion_pic);


eso te da el resultado que quieres


 Voy a probarlo... respecto a las interrupciones del puerto serie las ves bien definidas? el programa tampoco entra en ella... en la interrupcion de atencion al puerto serie....
Título: Re: Errores al compilar programa en CCS para PIC16F88
Publicado por: Prototipe88 en 28 de Abril de 2014, 10:43:47
Bueno, ahora ya he conseguido que el programa entre dentro de la interrupcion serie pero... es como si el programa me hiciera cosas raras. Yo cuando le envio un dato del estilo "$ADQ,P01,CH0\r" el programa SOLO me hace una VEZ lo que yo quiero... y aunque le vuelva a enviar otro dato igual ya no responde a mi dato. Lego cuando le envio un dato del estilo "$TST,P01\r" el programa me printa infinitas veces lo que quiero que haga.... es super raro...


Código: [Seleccionar]
#include <16f88.h>
#device ADC=10 //INDICO EL NÚMERO DE BITS DEL ADC

#include <stdio.h>
#include <string.h>


#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_B5, rcv=PIN_B2) //CONFIGURO PUERTO SERIE


//**VARIABLES PARA GESTIONAR LA TRAMA RECIBIDA Y LA TRAMA A ENVIAR POR PUERTO SERIE**//

long valor_adc=0; //Variable para lectura ADC

int P_W=0; //puntero escritura
int P_R=0; //puntero lectura

int i=0; //puntero bucle for
int j=0;

int inicio=0;
int final=0;

char string_valor_adc[]=",0000";//Cadena de caracteres para guardar valor ADC en Carcteres
char trama_entrada[91]={0}; //String para guardar el dato de entrada por UART
char direccion_pic[]="P01";
char tipo_dato[]="$ADQ";
char canal[]="CH0";
//char dato_salida[]="$ADQ,P01,CH0,0000\r\n"; //String para guardar lo que envio por UART
char dato[]="$ADQ,P01,CH0\r";


char midireccion[]="P01";
char micabecera[]="$ADQ";
char miretorno[]="\r";
char misimbolo[]="$";
char micanal0[]="CH0";
char micanal1[]="CH1";
char mitest[]="$TST";


short flag_final=0;
short flag_permiso=0;
short flag_tst=0;
short flag_envio=0;


void lectura(){

 for(P_R=0; P_R<91; P_R++){

  if(trama_entrada[P_R]==misimbolo[0]){

  inicio=P_R;
  
  for(P_R=inicio; P_R<91; P_R++){
 
   if(trama_entrada[P_R]==miretorno[0]){

   P_W=0;
   final=P_R;
   flag_permiso=1;
   break;

    }
 
   }
   break;
  }

 }
return;
}


void escritura(){

for(i=inicio; i<=final; i++){
  
dato[j]=trama_entrada[i];
j++;

  }

for(i=0;i<91;i++){
trama_entrada[i]='\0';
}
i=0;
j=0;

return;
}


void procesamiento(){

for(i=0; i<3; i++){

direccion_pic[i]=dato[i+5];

}

direccion_pic[3]='\0';


if(strcmp(direccion_pic, midireccion)==0){

for(i=0; i<4; i++){

tipo_dato[i]=dato[i];

}

tipo_dato[4]='\0';


if(strcmp(tipo_dato, micabecera)==0){

flag_tst=0;

for(i=0; i<3; i++){

canal[i]=dato[i+9];

}

canal[3]='\0';


if(strcmp(canal,micanal0)==0){
 set_adc_channel(0);  
   }
  
  
   else if(strcmp(canal,micanal1)==0){
      set_adc_channel(1);
   }

  
delay_us(20);//retardo para leer ADC
valor_adc=read_adc();//lectura ADC

 }

else if(strcmp(tipo_dato, mitest)==0){

flag_tst=1;

}
flag_envio=1;
}
return;
}


void enviar(){

switch(flag_tst){

case 0:

    sprintf(string_valor_adc,",%04ld",valor_adc);

    output_high(PIN_B0);

    printf("$ADQ,P01,%s%s\r", canal,string_valor_adc); //Envio un solo String con la direccion, canal CHX y el resutado del PIC por UART.

    output_low(PIN_B0);


    break;


case 1:


    output_high(PIN_B0);

    printf("$TST,P01\r"); //Envio un solo String con la direccion, canal CHX y el resutado del PIC por UART.

    output_low(PIN_B0);
    
    

    break;

}

}


#INT_RDA

void INT_UART() {
if(kbhit()){
trama_entrada[P_W]=getc();

if(trama_entrada[P_W]=='\r'){
P_W=0;
flag_final=1;
}

else{
P_W++;
}

}

}
void main(){

output_low(PIN_B0);

enable_interrupts(GLOBAL); //HABIlLITO TODAS LAS INTERRUPCIONES GLOBALES
enable_interrupts(INT_RDA); //HABILITO LA INTERRUPCIÓN UART
setup_adc_ports(sAN0|sAN1|sAN2|sAN3|sAN4|sAN5); //INDICO EL PIN A0/A1/A2/A3/A4/A5 COMO ENTRADA ANALÓGICA
setup_adc(ADC_CLOCK_INTERNAL); //CLOCK INTERNO PARA CONVERSIÓN ADC

 while(1){
if(flag_final==1){
flag_final=0;
 lectura();

if(flag_permiso==1){
 flag_permiso=0;
 escritura();
 procesamiento();
if(flag_envio==1){
flag_envio=0;
enviar();
}
  }
 }
}

}

Debo quizás limpiar el buffer de entrada del puerto serie o limpiar las interrupciones del puerto serie?? Pero creo que las interrupciones del puerto serie se limpian automaticamente con las funciones ddel ccs no?


En la simulacion cuando se ejecuta el SPRINTF y PRINTF un cursor verde se queda justo cuando se abre un arhivo del pic aquí:

//////// Standard Header file for the PIC16F88 device ////////////////
-->#device PIC16F88
    #nolist

así que no sé, se queda pensand justo en ese pnto