TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Pigwedeon en 19 de Abril de 2011, 15:16:19
-
Hola a todos,
estoy trabajando en un proyecto que recoge una serie de datos, y los envia al puerto serie.
Esta es la declaracion de la funcion USART:
void putrsUSART(const char *data)
{
do
{
while(!(TXSTA & 0x02));
TXREG = *data;
}
while (*data++);
}
He declarado lo siguiente:
char td[4];
y luego voy llenando el string de distintos datos: td[0]=a, etc...
Para acabar: putrsUSART(td); asi envio el string de 4 bytes al puerto serie. En el ordenador tengo un programa en VS que recoge estos 4 bytes y los procesa correctamente.
Hasta ahi todo normal, el problema es que quiero anyadir 2 bytes mas del resultado del ADC (RA0). He probado lo mas logico, declarar char td[6] y en td[4] y td[5] meto ambos bytes, pero entonces deja de funcionar el programa. Porque pasa esto?
No tiene sentido que amplie el tamanyo del vector y se cargue todo el vector... alguno sabe que pasa?
Perdon por las tildes y enyes, pero el teclado es ingles. Quiza tambien no me haya explicado del todo bien, pero despues de toda la tarde con el problema estoy ya algo espeso :oops:
gracias!
-
Tienes que tener en cuenta que si tu estring es de 4 bytes, lo tienes que declarar de 5 así el último lugar puede ser ocupado por el caracter nulo '\0' que es el que indica el final del string.
Ejemplo válido
char variable[5];
variable[0] = 'H';
variable[1] = 'o';
variable[2] = 'l';
variable[3] = 'a';
variable[4] = '\0';
Ejemplo no válido
char variable[4];
variable[0] = 'H';
variable[1] = 'o';
variable[2] = 'l';
variable[3] = 'a';
este último no es válido por que no queda lugar para el caracter nulo
-
Gracias por tu respuesta AngelGris ;-)
Pero, si es eso que dices, ¿porqué declaro el string de 4 bytes, le meto las 4 variables y funciona?
-
Gracias por tu respuesta AngelGris ;-)
Pero, si es eso que dices, ¿porqué declaro el string de 4 bytes, le meto las 4 variables y funciona?
No sabría decirte el porque te funciona, pero sí que toda string necesita ser terminada por el caracter nulo.
Fijate que incluso en tu función lo estás evaluando en la línea
eso se fija si el caracter apuntado es distinto de 0, por lo tanto cuando encuentra el 0 (que indica que termino el string) sale de la función.
-
Pues es extraño que funcione, ya que como te digo no lo tuve en cuenta, este es el código completo:
#include <pic.h> //Standard Hi-Tec C header file this includes the definition for the generic functions and variables i.e TRISC, PORTC, TXREG
#include "i2c.h" //Defines the I2C functions, this came with the HI-Tec C
/*Setting the config register.
Watchdog Timer Disable
Using Hi Speed Xtal
Low voltage program mode disable
*/
__CONFIG (WDTDIS & HS & LVPDIS);
void putrsUSART(const char *data); //Function prototype, this defines the functions other than the main() function
void main()
{
[b]//[/b]INTCON= 0; //Disable Interrupts
SPBRG = 129; //Set the baudrate for 9600 @ 20 MHz (0x81)
TXSTA = 0x24; //Set the serial port parameters
RCSTA = 0x90; //Set the serial port parameters
PORTC = 0; //Clear PORTC pins
TRISC = 0x80; //
[b] TRISA=0x01;
[/b]
int a, b, c, d; //Variables holds I2C Data
char td[4]; //Char Array to store I2C Data, this will be sent to the Serial port
[b]int ADC_VALUE; /* The value from the analog - digital convertor */
[/b]
/*
Continuosly monitor the I2C bus and read the humidity and temperature data
And send the data to the Serial Port
*/
while(1)
{
<funciones que obtienen a,b,c y d de un bus i2c>
td[0]=a; //Filling the I2C Data into a Char Array
td[1]=b;
td[2]=c;
td[3]=d;
[b]ADCON0=0b1000011;
ADCON1= 0x10;
ADIE = 0; /* Masking the interrupt */
ADIF = 0; /* Resetting the ADC interupt bit */
ADRESL = 0; /* Resetting the ADRES value register */
ADRESH = 0;
GODONE=1; /* Staring the ADC process */
while(GODONE); /* Wait for conversion complete */
{ADC_VALUE = ((ADRESH*5)/255); /* Getting HSB of CCP1, in 8 bit mode only ADRESH in 10 bit mode need the ADRESL to perform the first 8 bits, THE ADRESH perform the 8 last bits*/
} [/b]
putrsUSART(td); //Send the 4 Bytes Char Array to the serial port
for(int t=0;t<4;t++) //Cleaning the data array, so that we can avoid repeating the same data
{
__delay_us(20000);
td[t]=0;
}
}
}
void putrsUSART(const char *data) //Function we use to send the data to the Serial port, const char *data is the Char array
{
do //Check the Char Array until it finishes data
{
while(!(TXSTA & 0x02)); //Check the TXREG is empty
TXREG = *data; //Send the Byte to the TXREG
}
while( *data++ );//Check the Char Array until it finishes data
}
La parte en negrita ha sido lo incluido para el ADC. Hasta ahí todo OK y funciona perfectamente, pero no consigo meter el resultado de la conversión junto con las 4 primeras variables. Además, para más inri, al programa de ordenador me llegan 6 bytes, y descarto los 2 ultimos... que me vendrían de lujo si contuvieran el resultado de la ADC...
-
No tiene sentido que envíe 6 bytes si sólo tienes definido un array de 4 bytes. Posiblemente esa falla se deba a que no existe el lugar para el caracter nulo.
Cambiá la dimensión del array a 5 y probá como funciona, para saber si cambia la cantidad de bytes enviados. Luego se puede seguir probando los cambios necesarios para enviar también los datos del ADC.
También podés buscar en el foro, ya que no hace mucho, edu1989 hizo algo similar para un PIC18. Leía unos valores por ADC y otro creo que por I2C y los enviaba por RS232
-
No tiene sentido que envíe 6 bytes si sólo tienes definido un array de 4 bytes. Posiblemente esa falla se deba a que no existe el lugar para el caracter nulo.
Cambiá la dimensión del array a 5 y probá como funciona, para saber si cambia la cantidad de bytes enviados. Luego se puede seguir probando los cambios necesarios para enviar también los datos del ADC.
Sin duda ese es el problema, cuando se trabaja con string se debe tener en cuenta el carácter nulo ('\0') que indica final de trama ;-)
Saludos!