Autor Tema: Enviando datos con el puerto serie y PIC16F877A  (Leído 2805 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Pigwedeon

  • PIC10
  • *
  • Mensajes: 5
Enviando datos con el puerto serie y PIC16F877A
« 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:

Código: [Seleccionar]
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!

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Enviando datos con el puerto serie y PIC16F877A
« Respuesta #1 en: 19 de Abril de 2011, 15:58:18 »
  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

Código: C
  1. char variable[5];
  2. variable[0] = 'H';
  3. variable[1] = 'o';
  4. variable[2] = 'l';
  5. variable[3] = 'a';
  6. variable[4] = '\0';

Ejemplo no válido

Código: C
  1. char variable[4];
  2. variable[0] = 'H';
  3. variable[1] = 'o';
  4. variable[2] = 'l';
  5. variable[3] = 'a';

  este último no es válido por que no queda lugar para el caracter nulo
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Pigwedeon

  • PIC10
  • *
  • Mensajes: 5
Re: Enviando datos con el puerto serie y PIC16F877A
« Respuesta #2 en: 19 de Abril de 2011, 16:22:16 »
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?

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Enviando datos con el puerto serie y PIC16F877A
« Respuesta #3 en: 19 de Abril de 2011, 16:35:29 »
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

Código: C
  1. while (*data++);

  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.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Pigwedeon

  • PIC10
  • *
  • Mensajes: 5
Re: Enviando datos con el puerto serie y PIC16F877A
« Respuesta #4 en: 19 de Abril de 2011, 16:51:05 »
Pues es extraño que funcione, ya que como te digo no lo tuve en cuenta, este es el código completo:

Código: [Seleccionar]
#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...

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Enviando datos con el puerto serie y PIC16F877A
« Respuesta #5 en: 19 de Abril de 2011, 18:08:45 »
  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
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Enviando datos con el puerto serie y PIC16F877A
« Respuesta #6 en: 19 de Abril de 2011, 18:10:59 »
  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!
No contesto mensajes privados, las consultas en el foro