te marca error al compilar? o en la ejecución del programa?
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
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
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
ya te compila y funciona como lo esperabas?
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.
ya encontré tu errorCódigo: C
for(i=0;i<10;i++){ //Con éste for obtengo la direccion recibida por UART DireccionRecibida[i]=DatoEntrada[i]; }
estas copiando los caracteres desde la posición 0 hasta la posición 9, es decir, estas copiando 10 caracteres, no 9
set_adc_channel(canalreibido[2]-0x30);
#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.
}
}
}
}
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
sprintf(StringValorADC,",%d",ValorADC);strcat(DatoSalida,DireccionPICrespuesta); DatoSalida[15]="HolaMundo"
DireccionPICrespuesta[3]="001"
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'
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"
Cuando realizo la concatenación se hará justo despues del último caracter del DatoSalida? es decir tendré esto?
DatoSalida[15]="HolaMundo001" + el caracter nulo ?
output_high(PIN_B1);
output_high(PIN_B0);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
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
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
}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
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!
intenta con ld, en lugar de l
ld es para imprimir "longs" signados y con lu imprimes no signados
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
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); printf("$ADQ,P00,CH0\r);
#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();
}
}
}
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
#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();
}
}
}
}
}