TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: huichoman en 19 de Septiembre de 2007, 15:45:52

Título: Librería SHT11 de J1M. Problema con declaración de cadenas. "Esquivado ;)"
Publicado por: huichoman en 19 de Septiembre de 2007, 15:45:52
Hola. No encuentro el porqué no me deja utlizar itoa teniendo  esta parte del código en el programa.
si tengo un entero ent=123 y lo convierto a string con itoa, el resultado es erroneo me sale string= 00

Código: [Seleccionar]
#int_rda
void serial_isr() {                    // Interrupción recepción serie USART

   rcvchar=0x00;                       // Inicializo caracter recibido                   
   if(kbhit()){                        // Si hay algo pendiente de recibir ...
      rcvchar=getc();                  // lo descargo y ...
      addcbuff(rcvchar);               // lo añado al buffer y ...
      echos(rcvchar);                  // hago eco (si procede).
   }
}

Si la quito, no tengo problemas en utilizarla ya que el resultado es correcto string= 123


Este es el código completo del ejemplo de redpic con una pequeñamodificacion utilizando itoa.

Código: [Seleccionar]
// _232_buffered.c

#include <18F4525.h>                          // Definiciones del PIC 16F876A
#include <stdlib.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT  // Los Fuses de siempre
#use delay(clock=4000000)                     // Oscilador a 4 Mhz
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)// RS232 Estándar

// CONSTANTES /////////////////////////////////////////////////////////////////

int const lenbuff=32;                  // Longitud de buffer, Ajustar
                                       // a lo que desees (o te sea posible)

// VARIABLES EN RAM ///////////////////////////////////////////////////////////

int  xbuff=0x00;                       // Índice: siguiente char en cbuff
char cbuff[lenbuff];                   // Buffer
char rcvchar=0x00;                     // último caracter recibido
int1 flagcommand=0;                    // Flag para indicar comando disponible

// Declaración de Funciones ///////////////////////////////////////////////////

void inicbuff(void);                   // Borra buffer
int  addcbuff(char c);                 // añade caracter recibido al buffer
void echos(char c);                    // Eco selectivo sobre RS232
void procesa_comando(void);            // Procesa comando

// INTERRUPCIONES /////////////////////////////////////////////////////////////


#int_rda
void serial_isr() {                    // Interrupción recepción serie USART

   rcvchar=0x00;                       // Inicializo caracter recibido                   
   if(kbhit()){                        // Si hay algo pendiente de recibir ...
      rcvchar=getc();                  // lo descargo y ...
      addcbuff(rcvchar);               // lo añado al buffer y ...
      echos(rcvchar);                  // hago eco (si procede).
   }
}

// Desarrollo de Funciones ////////////////////////////////////////////////////

void echos(char c){                    // Echo selectivo ----------------------

      switch(c){
         case 0x0D: printf(" [Ent] "); // Si he pulsado la tecla [Intro]
                    break;
         case 0x08: printf(" [Del] "); // Si he pulsado la tecla [Retroceso]
                    break;
         case 0x1B: printf(" [Esc] "); // Si he pulsado la tecla [Escape]
                    break;
         default:   putc(rcvchar);     // Echo de cualquier otro caracter
      }
}

void inicbuff(void){                   // Inicia a \0 cbuff -------------------
   int i;

   for(i=0;i<lenbuff;i++){             // Bucle que pone a 0 todos los
      cbuff[i]=0x00;                   // caracteres en el buffer
   }
   xbuff=0x00;                         // Inicializo el indice de siguiente
                                       // caracter
}

int addcbuff(char c){                  // Añade a cbuff -----------------------

      switch(c){
         case 0x0D:                    // Enter -> Habilita Flag para procesar
            flagcommand=1;             // Comando en Main
            break;
         case 0x08:                    // Del   -> Borra último caracter del Buffer
            if(xbuff>0) cbuff[--xbuff]=0x00;
            break;
         case 0x01B:                   // Esc   -> Borra el Buffer completamente
            inicbuff();
            break;
         default:
            cbuff[xbuff++]=c;          // Añade caracter recibido al Buffer
      }
}


// Programa Principal /////////////////////////////////////////////////////////

void main() {
   char cad[5];
   int num=123;
   inicbuff();                                   // Borra buffer al inicio
 
   printf("\r\n\** RS232 Buffered **\r\n\r\n");  // Presenta menú
   printf("[Enter] Procesa comando\r\n");
   printf("[Escape] Borra todo el buffer\r\n");
   printf("[Delete] Borra último carácter del buffer\r\n");
   printf("[\\w] Comando Escribe\r\n");
   printf("[\\r] Comando Lee\r\n");
   printf("\r\n");
   
   output_high(PIN_C5);
   itoa(num,10,cad);
   printf("%s",cad);
   

   enable_interrupts(int_rda);                   // Habilita Interrupción RDA
   enable_interrupts(global);                    // Habilita interrupciones

   do {
   
      if(flagcommand) procesa_comando();         // Si hay comando pendiente
                                                 // de procesar ... lo procesa.

   } while (TRUE);

}

// Procesador de Comandos /////////////////////////////////////////////////////

void procesa_comando(void){

   int i;
   char arg[lenbuff];                   // Argumento de comando (si lo tiene)

   flagcommand=0;                       // Desactivo flag de comando pendiente.
   printf("\r\nProcesando ... ");       // Monitorizo procesando ...

   for(i=0;i<lenbuff;i++){             // Bucle que pone a 0 todos los
      arg[i]=0x00;                     // caracteres en el argumento
   }

   if(cbuff[0]=='\\'&&cbuff[1]=='r'){   // Comparo inicio del buffer con comando "\r"
   
      printf("Leyendo ... ");           // Aqui lo que deseemos hacer con comando "\r"
     
   }

   if(cbuff[0]=='\\'&&cbuff[1]=='w'){   // Comparo inicio del buffer con comando "\w"
      i=2;
      do{                               // Extraemos argumento del buffer
         arg[i-2]=cbuff[i];             // a partir del 3er byte y hasta \0.
      }while(cbuff[++i]!=0x00);
     
      printf("Escribiendo %s ... ",arg);// Aqui lo que deseemos hacer con comando "\w"
                                        // Monitorizamos el argunmento.
   }

   inicbuff();                          // Borro buffer.

   printf("Procesado.\r\n\r\n");        // Monitorizo procesado.
}



Ya le busqué pero no hallo a que se deba. Gracia por la ayuda que puedan brindar, saludos.
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: RedPic en 20 de Septiembre de 2007, 03:04:22
 :shock:

Voy a hacer la prueba y te cuento. Dime qué versión de CCS usas para compilar.
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: huichoman en 20 de Septiembre de 2007, 07:47:27
Hola RedPic, te agradezco muchísimo la ayuda. Estaba utilizando la version 4.038, la desinstalé y ahora tengo la 4.049 con el mismo problema. No se si sea por el compilador, pero ya me rompí la cabeza los últimos días tratando de encontrar el fallo. Es para un proyecto de la escuela para el control de un invernadero y  es para entregar este viernes (así estoy de tanto café :z) ). He estado trabajando con este proyecto desde el cuatrimestre pasado, pero tenía todo por partes aun no había juntado todas las piezas. Voy a utilizar un sht71 para sensor humedad y temperatura, esté será controlado por un pic18f2525 que enviará los datos por rs485 al control principal donde utilizo un pic18f4525, además de una computadora con un programa de visual basic como estación de monitoreo. Ya hice la prueba enviando cadenas de texto, todo bien, pero ahora que quiero enviar los datos del sensor, los debo convertir de float a string, pero no me deja utilizar las funciones de stdlib.h como itoa, tampoco la sprintf para pasar directo de float a string. Estoy desesperado pues nunca pensé que este tipo de error me estuviera deteniendo para avanzar y terminar el proyecto. La única forma que funcione es quitando el código que menciono de la interrupcion #int_rda.  Ya leí el manual del compilador, ya busqué y rebusqué en todo todopic, ya chequé en el foro de ccs, y nada que pueda hacerme ver la luz. Te estaré eternamente agradecido por toda la ayuda que puedas brindarme. Saludos y gracias de nuevo por todo.
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: jfh900 en 20 de Septiembre de 2007, 08:13:36
El código del ejemplo de RedPic tampoco funciona?

Un saludo
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: huichoman en 20 de Septiembre de 2007, 08:20:28
Si funciona, pero al utilizar itoa o sprintf no me genera los resultados correctos, a menos que quite la interrupcion #int_rda. Saludos. Tengo la version 4.038 y probé con la 4.049. Voy a desinstalar todo y probar con la 3.249 que creo que es la más estable. Saludos
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: RedPic en 20 de Septiembre de 2007, 09:14:39
Te juro que no lo entiendo ....  :shock: :shock: :shock:

En cuanto llegue a casa lo rehago a ver si soy capaz de que me haga lo mismo.  :? :( :x
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: huichoman en 20 de Septiembre de 2007, 09:59:45
Gracias Redpic por tomarte la molestia de brindarme parte de tu tiempo, como te dije antes estaré eternamente agradecido por toda la ayuda que puedas brindarme. Continuaré todo el día de hoy hasta amanecer mañana que entrego el proyecto, me acaban de  llegar los coponentes para armar la parte física, voy a probar el lcd 40x4 con la modificación que le hice a la libreria de flexlcd204. Gracias de nuevo.
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: pocher en 21 de Septiembre de 2007, 13:38:39
Hola.

El programa de RedPic funciona perfectamente, yo lo simulé hace ya bastantes lunas y ¡OK! Por si alguién no entiende lo que hace os lo explico:

- El programa almacena en un buffer todos los caracteres que le van llegando via RS232.

- El buffer es cbuff [32]    (la longitud del buffer se puede cambiar a más de 32 si se desea)

- Los caracteres recibidos también se pueden borrar "a distancia" de dos formas, por ejemplo: Francisco [Del] [Enter] borraría el último caracter recibido en el buffer ó bien Francisco [Esc] [Enter] borraría todo el buffer.

- También es un procesador de comandos escritos antes de la cadena de caracteres a enviar, por ejemplo:

\w Francisco [Enter] Guarda toda la cadena en el buffer y luego reenvía la cadena (en pantalla sale exactamente: Procesando ... Escribiendo Francisco 0 ... Procesado)

\w Francisco [Del] [Enter] Guarda toda la cadena en el buffer y luego reenvía la cadena sin el último caracter (en pantalla sale exactamente: Procesando ... Escribiendo Francisc 0 ... Procesado)

\r Este comando no tiene adjudicada ninguna accción en el programa, le podemos poner la que queramos, así como añadir otros comandos con otras acciones.

Volviendo al tema creo que sería conveniente Huichoman que mandaras un trozo de código pequeño donde intervenga la interrupción y las funciones que no te "funcionan".

Un saludo

Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: huichoman en 22 de Septiembre de 2007, 02:30:13
Hola Pocher. El programa de RedPic funciona perfectamente. Pero hay un conflicto al utilizar itoa o sprintf.

Citar
Volviendo al tema creo que sería conveniente Huichoman que mandaras un trozo de código pequeño donde intervenga la interrupción y las funciones que no te "funcionan".

arriba puse el código de RedPic, con un pequeño código añadido utilizando itoa y añadiendo la stdlib.h.

Código: [Seleccionar]
   printf("[\\r] Comando Lee\r\n");
   printf("\r\n");
   
   output_high(PIN_C5);
   itoa(num,10,cad);
   printf("%s",cad);


en este caso declaro

   char cad[5];
   int num=123;


si no quito el trozo de codigo de de la interrupcion #INR_RDA el resultado que envia es 0, si lo quito el resultado es 123, el correcto.
Saludos.







Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: pocher en 22 de Septiembre de 2007, 16:12:20
Perdona, se me pasó.

Puñetas pués es verdad, te lo he estado simulando y es como dices ... cosa más rara.

¿será el compilador?

Voy a probar con el programa que yo uso con interrupción RDA y Buffer para ver si la función itoa también dá "pol saco".

Por cierto ¿ probaste ya físicamente la LCD para ver si el error en líneas 2 y 4 era del PROTEUS ?(que va a ser que sí)

Un saludo
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: huichoman en 22 de Septiembre de 2007, 19:27:28
Hola, la verda no se, pero ya probé con la version 4.049 la 4.038 y hasta me regresé a la 3.249 y me sucede lo mismo. Ya tengo el lcd de 40x4, en estos días lo pruebo para ver que tal funciona, en cuanto lo haga publico los resultados y las fotos. Saludos y hay que buscar cual es el fallo, jeje. Porque no entiendo que pueda ser, simplemente no jala. Lo que mas desespera, es que algo que aparentemente debiera funcionar sin ningun problema, pues no quiere, no quiere y no quiere. Supongo que es algun conflicto con el código pero a mas bajo nivel, pero lamentablemente no tengo los conocimientos necesarios para identificar cual sea el detalle que hace que no funcione.´Así que... Help.. Help y mas Help.  :mrgreen:
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: jfh900 en 22 de Septiembre de 2007, 19:35:30
Parece ser que las variables utilizadas por el CCS entran en conflicto entre si. Puedes realizar varias pruebas, por ejemplo declara la variable cad a nivel global haber que es lo que pasa. Por cierto tienes unas simulación en Proteus para poder probar el programa? si lo tienes postealo y así poder realizar las pruebas. Cambia esta línea para verificar que num tiene lo correcto:

printf("%s - %u",cad,num);


Un saludo
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: pocher en 23 de Septiembre de 2007, 03:03:58
He estado realizando algunas pruebas,

Con un 876 el programa junto con la itoa funciona bien, sin embargo al cambiar el PIC por un 18 ya va mal.

También he estado probando con otro programa que tengo para la recepción de datos por interrupción y también va mal con el PIC18.

Algo habrá que añadir o cambiar en la programación para que funcione con los PICs18 ... a eso no llego todavía pero me lo voy a mirar.

Un saludo
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: huichoman en 23 de Septiembre de 2007, 15:23:26
Hola amigos, gracias por la ayuda. Esta semana es de exámenes en mi universidad, voy a tener poco tiempo para hacer pruebas, pero el fin de semana seguiré en lo mismo. Saludos y gracias de nuevo por la ayuda.
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: pocher en 24 de Septiembre de 2007, 13:30:27
Joer con la cantidad de tiempo que no tocaba los PICs y encontrarme con este defecto. Bueno después de multiples pruebas con PROTEUS he conseguido detectar porqué no funcionaba el programa _232_Buffered.c original de RedPic con el 18F4525 (con el 16F876 sí que va bien).

El funcionamiento anómalo está en la línea: int const lenbuff=32;

Si en lugar de 32 lo bajamos y ponemos por ejemplo 25 ya va bien. ¿Porqué sucede eso?  ¡ni pajolera idea!
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: RedPic en 24 de Septiembre de 2007, 15:19:15
 :shock: :shock: :shock: :shock: :shock: :shock: :shock: :shock:

Esas son las cosas que te dejan desconcertado hasta el inifinito.
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: pocher en 24 de Septiembre de 2007, 16:31:30
... y más allá. Ayer revolví a ver la película (Toy Story) por cienésima vez. Cualquiera les dice que no a los señores del mando (lease enanos, locos pequeños, monstruitos, niños).
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: huichoman en 30 de Septiembre de 2007, 18:48:45
Hola amigos, estoy denuevo por acá. Sigo con el mismo error, estoy haciendo pruebas con un programa donde utilizo una librería para un sensor sht71.
Lo raro, es que int const lenbuff debe ser igual o menor que 13, si se le da un valor mayor, el sensor me arroja valores erróneos.
Aunque supongo que la instrucción que está fallando es  char cadena[lenbuff];  la cual si se le pone directamente el valor en vez de lenbuff,  no debe ser mayor a 13 porque sucede lo mismo, el sensor me arroja valores fuera de rango.



Código: [Seleccionar]

#include <lcd_40x4_h.c>
#include <sht71.c>
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7,parity=N)

[color=red]int const lenbuff=13;
int  xbuff=0x00;     
char rcvchar=0x00;
char cadena[lenbuff]; <----------- un valor mayor a 13 hace que el sensor arroje valores erroneos



void main()
{
  float restemp, truehumid;
 
 lcd_init1();
 lcd_init2();
 
    sht_init();
    while(1)
  {
    delay_ms(15);
    sht_rd (restemp, truehumid);
    lcd_gotoxy(1,1);
    printf(lcd_putc1, "Temp : %f %cC   ", restemp,223);
    lcd_gotoxy(1,2);
    printf(lcd_putc1, "HR   : %f %%   ", truehumid);   
 }
}


este es la libreria sht71.c

Código: [Seleccionar]
///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// Driver file for SHT75 Temperature & Humidity Sensor                       //
//                                                                           //
// ***** To initialise SHT75 sensor upon power up *****                      //
//                                                                           //
// Function : sht_init()                                                     //
// Return   : none                                                           //
//                                                                           //
//                                                                           //
// ***** To measure and caluculate SHT75 temp & real RH *****                //
//                                                                           //
// Function : sht_rd (temp, truehumid)                                       //
// Return   : temperature & true humidity in float values                    //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#define sht_data_pin   PIN_A1
#define sht_clk_pin    PIN_A2


//***** Function to alert SHT75 *****

void comstart (void)
{
 output_float(sht_data_pin);  //data high
 output_bit(sht_clk_pin, 0);  //clk low
 delay_us(1);
 output_bit(sht_clk_pin, 1);  //clk high
 delay_us(1);
 output_bit(sht_data_pin, 0); //data low
 delay_us(1);
 output_bit(sht_clk_pin, 0);  //clk low
 delay_us(2);
 output_bit(sht_clk_pin, 1);  //clk high
 delay_us(1);
 output_float(sht_data_pin);  //data high
 delay_us(1);
 output_bit(sht_clk_pin, 0);  //clk low
}


//***** Function to write data to SHT75 *****

int1 comwrite (int8 iobyte)
{
 int8 i, mask = 0x80;
 int1 ack;

 //Shift out command
 delay_us(4);
 for(i=0; i<8; i++)
  {
   output_bit(sht_clk_pin, 0);                          //clk low
   if((iobyte & mask) > 0) output_float(sht_data_pin);  //data high if MSB high
   else output_bit(sht_data_pin, 0);                    //data low if MSB low
   delay_us(1);
   output_bit(sht_clk_pin, 1);                          //clk high
   delay_us(1);
   mask = mask >> 1;                                    //shift to next bit
  }

 //Shift in ack
 output_bit(sht_clk_pin, 0);  //clk low
 delay_us(1);
 ack = input(sht_data_pin);   //get ack bit
 output_bit(sht_clk_pin, 1);  //clk high
 delay_us(1);
 output_bit(sht_clk_pin, 0);  //clk low
 return(ack);
}


//***** Function to read data from SHT75 *****

int16 comread (void)
{
 int8 i;
 int16 iobyte = 0;
 const int16 mask0 = 0x0000;
 const int16 mask1 = 0x0001;

 //shift in MSB data
 for(i=0; i<8; i++)
  {
   iobyte = iobyte << 1;
   output_bit(sht_clk_pin, 1);                //clk high
   delay_us(1);
   if (input(sht_data_pin)) iobyte |= mask1;  //shift in data bit
   else iobyte |= mask0;
   output_bit(sht_clk_pin, 0);                //clk low
   delay_us(1);
  }

 //send ack 0 bit
 output_bit(sht_data_pin, 0); //data low
 delay_us(1);
 output_bit(sht_clk_pin, 1);  //clk high
 delay_us(2);
 output_bit(sht_clk_pin, 0);  //clk low
 delay_us(1);
 output_float(sht_data_pin);  //data high

 //shift in LSB data
 for(i=0; i<8; i++)
  {
   iobyte = iobyte << 1;
   output_bit(sht_clk_pin, 1);                //clk high
   delay_us(1);
   if (input(sht_data_pin)) iobyte |= mask1;  //shift in data bit
   else iobyte |= mask0;
   output_bit(sht_clk_pin, 0);                //clk low
   delay_us(1);
  }

 //send ack 1 bit
 output_float(sht_data_pin);  //data high
 delay_us(1);
 output_bit(sht_clk_pin, 1);  //clk high
 delay_us(2);
 output_bit(sht_clk_pin, 0);  //clk low

 return(iobyte);
}


//***** Function to wait for SHT75 reading *****

void comwait (void)
{
 int16 sht_delay;

 output_float(sht_data_pin);                     //data high
 output_bit(sht_clk_pin, 0);                     //clk low
 delay_us(1);
 for(sht_delay=0; sht_delay<30000; sht_delay++)  // wait for max 300ms
  {
   if (!input(sht_data_pin)) break;              //if sht_data_pin low, SHT75 ready
   delay_us(10);
  }
}


//***** Function to reset SHT75 communication *****

void comreset (void)
{
 int8 i;

 output_float(sht_data_pin);    //data high
 output_bit(sht_clk_pin, 0);    //clk low
 delay_us(2);
 for(i=0; i<9; i++)
  {
   output_bit(sht_clk_pin, 1);  //toggle clk 9 times
   delay_us(2);
   output_bit(sht_clk_pin, 0);
   delay_us(2);
 }
 comstart();
}


//***** Function to soft reset SHT75 *****

void sht_soft_reset (void)
{
 comreset();           //SHT75 communication reset
 comwrite(0x1e);       //send SHT75 reset command
 delay_ms(15);         //pause 15 ms
}


//***** Function to measure SHT75 temperature *****

int16 measuretemp ()
{
 int1 ack;
 int16 iobyte;

 comstart();             //alert SHT75
 ack = comwrite(0x03);   //send measure temp command and read ack status
 if(ack == 1) return;
 comwait();              //wait for SHT75 measurement to complete
 iobyte = comread();     //read SHT75 temp data
 return(iobyte);
}


//***** Function to measure SHT75 RH *****

int16 measurehumid (void)
{
 int1 ack;
 int16 iobyte;

 comstart();            //alert SHT75
 ack = comwrite(0x05);  //send measure RH command and read ack status
 if(ack == 1) return;
 comwait();             //wait for SHT75 measurement to complete
 iobyte = comread();    //read SHT75 temp data
 return(iobyte);
}


//***** Function to calculate SHT75 temp & RH *****

void calculate_data (int16 temp, int16 humid, float & tc, float & rhlin, float & rhtrue)
{
 float truehumid1, rh;

 //calculate temperature reading
 tc = ((float) temp * 0.01) - 40.0;

 //calculate Real RH reading
 rh = (float) humid;

 rhlin = (rh * 0.0405) - (rh * rh * 0.0000028) - 4.0;

 //calculate True RH reading
 rhtrue = ((tc - 25.0) * (0.01 + (0.00008 * rh))) + rhlin;
}


//***** Function to measure & calculate SHT75 temp & RH *****

void sht_rd (float & temp, float & truehumid)
{
 int16 restemp, reshumid;
 float realhumid;
 restemp = 0; truehumid = 0;

 restemp = measuretemp();    //measure temp
 reshumid = measurehumid();  //measure RH
calculate_data (restemp, reshumid, temp, realhumid, truehumid);  //calculate temp & RH
}


//***** Function to initialise SHT75 on power-up *****

void sht_init (void)
{
 comreset();    //reset SHT75
 delay_ms(20);  //delay for power-up
}

Saludos amigos, y gracias por toda la ayuda.
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: RedPic en 01 de Octubre de 2007, 03:43:34
¡Cogno! parece un problema de "solapamiento" de variables en RAM  :shock:

Hace poco he tenido uno parecido porque una rutina que leía una cadena desde la EEPROM colocaba un '\0' un byte mas allá de donde debía y sobrescribía la variable alojada en la RAM a continuación suya ....

He repasado el driver del sht71 y no parece tener nada extraño, pero ¿y el driver del lcd_40x4? ¿tendrás algún conflicto de RAM ahí? ¿Hay RAM suficiente?

Investiga un poco por ese lado y coméntanos ...  :|
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: huichoman en 01 de Octubre de 2007, 09:25:32
Hola RedPic, gracias por la ayuda. El driver del lcd 40x4, está basado en el del flex_lcd  solo hice unos pequeños ajustes. Ahorita voy de salida a la uni, en cuanto regrese hago unas pruebas. El driver del lcd 40x4  está en este post http://www.todopic.com.ar/foros/index.php?topic=18699.0 (http://www.todopic.com.ar/foros/index.php?topic=18699.0).

Saludos y gracias por todo.
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: RedPic en 01 de Octubre de 2007, 09:45:52
He revisado el driver del LCD y tampoco encuentro nada que aparentemente pueda ser causa de ese error.  :shock:
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: RedPic en 01 de Octubre de 2007, 09:50:09
huichoman:

¿Puedes postear el .lst que genera el C? o por lo menos la parte del driver del sht71 que hace esto:

Código: C++
  1. void calculate_data (int16 temp, int16 humid, float & tc, float & rhlin, float & rhtrue)
  2. {
  3.  float truehumid1, rh;
  4.  
  5.  //calculate temperature reading
  6.  tc = ((float) temp * 0.01) - 40.0;
  7.  
  8.  //calculate Real RH reading
  9.  rh = (float) humid;
  10.  
  11.  rhlin = (rh * 0.0405) - (rh * rh * 0.0000028) - 4.0;
  12.  
  13.  //calculate True RH reading
  14.  rhtrue = ((tc - 25.0) * (0.01 + (0.00008 * rh))) + rhlin;
  15. }

Si es el .lst completo mejor que mejor. Es solo para comprobar que memoria RAM consume.
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: huichoman en 01 de Octubre de 2007, 11:25:26
Hola RedPic, pongo el rar con el projecto.

Saludos.

Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: RedPic en 01 de Octubre de 2007, 14:25:54
Repasa el fichero .err e intenta quitar todos los errores. Y mira a ver eso de los return que no retornan lo que tienen que retornar, y lo que no entiendo es en el .sta por qué la función comread necesita 1280 bytes de la ram  :shock:

>>> Warning 208 "D:\HUICHOTRONICO\CAUTRIMESTRE VII\Invernadero\Simulaciones\Invernadero\sht71.c" Line 176(19,30): Function not void and does not return a value  measuretemp
>>> Warning 208 "D:\HUICHOTRONICO\CAUTRIMESTRE VII\Invernadero\Simulaciones\Invernadero\sht71.c" Line 192(20,32): Function not void and does not return a value  measurehumid
>>> Warning 203 "Invernadero2.c" Line 23(1,1): Condition always TRUE
>>> Warning 202 "D:\HUICHOTRONICO\CAUTRIMESTRE VII\Invernadero\Simulaciones\Invernadero\sht71.c" Line 210(8,18): Variable never used:   truehumid1
>>> Warning 202 "Invernadero2.c" Line 8(11,18): Variable never used:   lenbuff
>>> Warning 202 "Invernadero2.c" Line 9(6,11): Variable never used:   xbuff
>>> Warning 202 "Invernadero2.c" Line 10(6,13): Variable never used:   rcvchar
>>> Warning 202 "Invernadero2.c" Line 11(6,11): Variable never used:   cbuff
      Memory usage:   ROM=11%      RAM=2% - 6%
      0 Errors,  8 Warnings.
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: huichoman en 08 de Octubre de 2007, 02:07:58
Hola, he estado checando, y no puedo quitar los warnings. Realmente es desesperante. Creen que sea error del compilador? Me recomiendan utilizar mejor el compilador de hitech? Me he estancado en el proyecto por este problema  . Saludos y gracias por todo.
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: RedPic en 08 de Octubre de 2007, 05:03:03
Me he descargado el proyecto y lo he compilado con el CSS C v. 3.242 y ...

0 Errors 0 Warnings  :shock:

ROM used: 3606 (11%)
          3606 (11%) including unused fragments

          3 Average locations per line
          15 Average locations per statement

RAM used: 30 (2%) at main() level
          97 (6%) worst case

Lines Stmts  %   Files
----- ----- ---  -----
   32    11   4  E:\Proyectos\CCS_C\Redraven\ejemplos\Invernadero\Invernadero2.c
  370     0   0  E:\Proyectos\CCS_C\Devices\18F2520.h
  446   124  48  E:\Proyectos\CCS_C\Redraven\ejemplos\Invernadero\lcd_40x4_h.c
  246   111  29  E:\Proyectos\CCS_C\Redraven\ejemplos\Invernadero\sht71.c
----- -----
 2188   492 Total

Page ROM  %  RAM  Functions:
---- --- --- ---  ----------
0     42   1   1  @delay_ms1
0     20   0   0  @const38
0     64   1   1  lcd_send_nibble1
0     64   1   1  lcd_send_nibble2
0     52   1   1  lcd_read_nibble
0     34   0   3  lcd_read_byte
0     66   1   3  lcd_send_byte1
0     66   1   3  lcd_send_byte2
0     92   1   3  lcd_init1
0     92   1   3  lcd_init2
0     78   1   4  lcd_gotoxy
0     76   1   1  lcd_putc1
0     44   1   0  comstart
0     88   1   5  comwrite
0    132   2   3  comread
0     52   1   2  comwait
0     44   1   1  comreset
0     48   1   4  measuretemp
0     48   1   4  measurehumid
0     56   1   2  @ITOF
0    244   3  11  @MULFF
0    620   9  16  @ADDFF
0     12   0   0  sht_init
0    864  12   9  main
0     34   0   0  @const10377
0     64   1   5  @FTOSD
0    124   2  13  @DIV3232
0    382   5  13  @PRINTF_L32D_392FPFPF

 Segment   Used  Free
---------  ----  ----
00000-00002     4  0
00004-07FFE  3602  29162

Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: pocher en 08 de Octubre de 2007, 06:01:21
Los warnings aparecen cuando le pones más opciones para compilar al compilador, si no no aparecen.

De todas formas errores no aparecen y en cuanto a los warnings mira a ver si te pueden dar algún problema. Los warnings Variable never used:  son lógicos si esas variables se definen y luego no las usas en el programa.

Te importaría repetir donde estás atascado ahora? ... las neuronas las tengo de fiesta.

Un saludo

Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: RedPic en 08 de Octubre de 2007, 06:05:58
Cierto amigo Pocher, pero los warnings que dicen que no va a retornar valores de medida me parecen mas graves ...

Function not void and does not return a value  measuretemp ...

Porque seguramente las medidas tomadas se quedaran en algún limbo electrónico.  :shock:
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: pocher en 08 de Octubre de 2007, 12:10:58
Sí, si Diego x..actamente, a esos 2 me refería cuando dije: en cuanto a los warnings mira a ver si te pueden dar algún problema. De todas formas el problemita tiene mala leche, será dificil detectar el fallo ... yo no le acierto.
Título: Re: Ayuda #INT_RDA de _RS232_buffered.c no permite usar itoa.
Publicado por: huichoman en 08 de Marzo de 2008, 14:50:04
Hola amigos, reviviendo el hilo  :mrgreen:.

En conclusión el conflicto está al declarar los arreglos de caracteres. Con ciertos valores, el sensor se pone raro.

Ejemplo:

char cadena[32];    No jala
char cadena[64];    OK
char cadena[128];  OK

Así que lo dejé  en char cadena[64]  :mrgreen:.  Como ya funciona, no lo toco,  :D.

Ganbatte kudasai.

Saludos
Título: Re: Librería SHT11 de J1M. Problema con declaración de cadenas. "Esquivado ;)"
Publicado por: sherckuith en 10 de Marzo de 2011, 19:57:26
Hola compañeros, una pregunta crusial por una apuesta, el SHT11 es I2C o que tipo de comunicación usa????... gracias...
Título: Re: Librería SHT11 de J1M. Problema con declaración de cadenas. "Esquivado ;)"
Publicado por: bmb en 10 de Marzo de 2011, 20:15:37
Hola, según la hoja de datos (http://www.sensirion.com/en/pdf/product_information/Datasheet-humidity-sensor-SHT1x.pdf), la comunicación es serial por 2 hilos.

Saludos!
Título: Re: Librería SHT11 de J1M. Problema con declaración de cadenas. "Esquivado ;)"
Publicado por: sherckuith en 11 de Marzo de 2011, 03:12:08
Exactamente ese es mi dilema, tengo una libreria que funciona perfectamente pero al conectarla al pic y probar la misma secuencia pero usando la comunicacion I2C teniendo en cuenta que es SCK y SDA los pines a usar no funciona... entonces es algo que cambia en el protocolo de I2C o es otro protocolo similar al I2C pero propio del SHT11???, muchisimas gracias por responder tan pronto....
Título: Re: Librería SHT11 de J1M. Problema con declaración de cadenas. "Esquivado ;)"
Publicado por: bmb en 11 de Marzo de 2011, 09:10:07
Hola sherckuith, según leí,  el integrado no utiliza el protocolo I2C.  De la hoja de datos:

Citar
The sensor cannot be addressed by I2C protocol; however, the sensor can be connected to an I2C bus without interference with other devices connected to the bus. The controller must switch between the protocols.

Según entiendo, esto significa que se puede conectar a un bus I2C sin causar interferencia a este, pero debe manejar su propio protocolo.

Por aquí (http://www.ccsinfo.com/forum/viewtopic.php?t=28564) encuentras una librería en c para ese integrado.

Saludos!
Título: Re: Librería SHT11 de J1M. Problema con declaración de cadenas. "Esquivado ;)"
Publicado por: sherckuith en 11 de Marzo de 2011, 17:14:46
Aaaa.. ya! chevere!!!! muchisimas gracias por sacarnos de esa duda, aposte una pizza a que era I2C y por lo que veo perdi! =( no importa, al menos sali de la ignorancia..., esta es la libreria que yo tengo, es la de J1M, esta sumamente bien explicada, si puedes pruebala y a ver que diferencias encontramos ok...

// set DATA and SCK
#define DATOS  PIN_A4
#define CLOCK  PIN_A5

#define SHT11_noACK 0
#define SHT11_ACK   1

// SHT11 commands                 //adr  command  r/w
#define SHT11_STATUS_REG_W 0x06   //000   0011    0
#define SHT11_STATUS_REG_R 0x07   //000   0011    1
#define SHT11_MEASURE_TEMP 0x03   //000   0001    1
#define SHT11_MEASURE_HUMI 0x05   //000   0010    1
#define SHT11_RESET        0x1E   //000   1111    0

enum {TEMP,HUMI};


byte sht11_escribir_byte(byte value)
// writes a byte on the Sensibus and checks the acknowledge
{
   byte i,error=0;

   for (i=128;i>0;i/=2)                 //shift bit for masking
   {
      if (i & value)   output_high(DATOS);   //masking value with i , write to SENSI-BUS
      else output_low(DATOS);
      output_high(CLOCK);               //clk for SENSI-BUS
      delay_us(5);                      //pulswith approx. 5 us
      output_low(CLOCK);
   }
   output_high(DATOS);                   //release DATA-line
   output_high(CLOCK);                   //clk #9 for ack
   error=input(DATOS);                   //check ack (DATA will be pulled down by SHT11)
   output_low(CLOCK);
   return error;                         //error=1 in case of no acknowledge
}


byte sht11_leer_byte(byte ack)
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
   byte i,val=0;

   output_high(DATOS);             //release DATA-line
   for (i=128;i>0;i/=2)           //shift bit for masking 0x80
   {
      output_high(CLOCK);               //clk for SENSI-BUS
      if (input(DATOS))   val=(val | i);  //read bit
      output_low(CLOCK);
   }
   if (ack) output_low(DATOS);      //in case of "ack==1" pull down DATA-Line
   else output_float(DATOS);
   output_high(CLOCK);             //clk #9 for ack
   delay_us(5);                    //pulswith approx. 5 us
   output_low(CLOCK);
   output_high(DATOS);             //release DATA-line
   return val;
}


void sht11_init(void)
// generates a transmission start
//       _____         ________
// DATA:      |_______|
//           ___     ___
// SCK : ___|   |___|   |______
{
   output_high(DATOS);
   output_low(CLOCK);             //Initial state
   delay_us(2);
   output_high(CLOCK);
   delay_us(2);
   output_low(DATOS);
   delay_us(2);
   output_low(CLOCK);
   delay_us(5);
   output_high(CLOCK);
   delay_us(2);
   output_float(DATOS);
   delay_us(2);
   output_low(CLOCK);
}


void sht11_hard_reset(void)
//para hacer un reset completo del sensor se realiza la secuencia...
//       _____________________________________________________         ________
// DATA:                                                      |_______|
//          _    _    _    _    _    _    _    _    _        ___     ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
{
   byte i;

   output_high(DATOS);
   output_low(CLOCK);           //Initial state
   for(i=0;i<9;i++)             //9 SCK cycles
   {
      output_high(CLOCK);
      delay_us(2);
      output_low(CLOCK);
      delay_us(2);
   }
   sht11_init();            //transmission start
}

byte sht11_soft_reset(void)
// resets the sensor by a softreset
{
   byte error=0;

   sht11_hard_reset();                                    //reset communication
   error+=sht11_escribir_byte(SHT11_RESET);          //send RESET-command to sensor
   return error;                               //error=1 in case of no response form the sensor
}


byte sht11_leer_registro_estado(byte *p_valor, byte *p_checksum)
// reads the status register with checksum (8-bit)
{
   byte error=0;

   sht11_init();                           //transmission start
   error = sht11_escribir_byte(SHT11_STATUS_REG_R);  //send command to sensor
   *p_valor = sht11_leer_byte(SHT11_ACK);            //read status register (8-bit)
   *p_checksum = sht11_leer_byte(SHT11_NOACK);       //read checksum (8-bit)
   return error;                               //error=1 in case of no response form the sensor
}


byte sht11_escribir_registro_estado(byte *p_valor)
// writes the status register with checksum (8-bit)
{
   byte error=0;

   sht11_init();                           //transmission start
   error += sht11_escribir_byte(SHT11_STATUS_REG_W); //send command to sensor
   error += sht11_escribir_byte(*p_valor);           //send value of status register
   return error;                               //error>=1 in case of no response form the sensor
}


byte sht11_medicion(byte *p_valor, byte *p_checksum, byte modo)
// makes a measurement (humidity/temperature) with checksum
{
   byte error=0;
   int16 i;

   sht11_init();
   switch(modo)                             //send command to sensor
   {
      case TEMP   : error+=sht11_escribir_byte(SHT11_MEASURE_TEMP); break;
      case HUMI   : error+=sht11_escribir_byte(SHT11_MEASURE_HUMI); break;
      default     : break;
   }
   for (i=0;i<65535;i++) if(input(DATOS)==0) break;  //wait until sensor has finished the measurement
   if(input(DATOS)) error+=1;               // or timeout (~2 sec.) is reached
   *(p_valor+1)  =sht11_leer_byte(SHT11_ACK);     //read the first byte (MSB)
   *(p_valor)    =sht11_leer_byte(SHT11_ACK);     //read the second byte (LSB)
   *(p_checksum) =sht11_leer_byte(SHT11_NOACK);   //read checksum

   return error;
}


void sht11_calculos(float *p_humedad, float *p_temperatura)
{
// calculates temperature [°C] and humidity [%RH]
// input :  humi [Ticks] (12 bit)
//          temp [Ticks] (14 bit)
// output:  humi [%RH]
//          temp [°C]

   const float C1=-4.0;               // for 12 Bit
   const float C2=+0.0405;            // for 12 Bit
   const float C3=-0.0000028;         // for 12 Bit
   const float T1=+0.01;            // for 14 Bit @ 5V
   const float T2=+0.00008;         // for 14 Bit @ 5V

   float rh;
   float t;
   float rh_lin;                     // rh_lin:  Humidity linear
   float rh_true;                     // rh_true: Temperature compensated humidity
   float t_C;                        // t_C   :  Temperature [°C]
   rh = *p_humedad;                  // rh:      Humidity [Ticks] 12 Bit
   t = *p_temperatura;               // t:       Temperature [Ticks] 14 Bit

   t_C = t*0.01 - 40;               //calc. temperature from ticks to [°C]
   rh_lin=C3*rh*rh + C2*rh + C1;      //calc. humidity from ticks to [%RH]
   rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;   //calc. temperature compensated humidity [%RH]
   if(rh_true>100)rh_true=100;      //cut if the value is outside of
   if(rh_true<0.1)rh_true=0.1;      //the physical possible range

   *p_temperatura=t_C;               //return temperature [°C]
   *p_humedad=rh_true;               //return humidity[%RH]
}



bye... y gracias nuevamente...
Título: Re: Librería SHT11 de J1M. Problema con declaración de cadenas. "Esquivado ;)"
Publicado por: sherckuith en 11 de Marzo de 2011, 17:17:09
Sorry, olvide el archivo C,


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/////               LECTURA SENSOR HUMEDAD/TEMPERATURA SHT11               /////
/////                                                                      /////
///// En este programa se muestra como leer el sensor SHT11 de la casa     /////
///// sensirion (www.sensirion.com), para no forzar el sensor se ha puesto /////
///// un delay de 1sg, segun su datasheet el tiempo de lectura y lectura   /////
///// puede ser inferior. Se adjunta un esquema de conexión en Proteus.    /////
///// Aunque puede ser modificado puesto que el protocolo de lectura del   /////
///// sensor está implementado en la libreria.                             /////
/////                                                                      /////
/////                                                                      /////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#include <18F2520.h>

#fuses NOWDT, WDT128, XT, NOPROTECT, BROWNOUT, BORV45, NOPUT, NOCPD
#fuses NOSTVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOIESO, NOFCMEN, NOPBADEN
#fuses NOWRTC, NOWRTB, NOEBTR, NOEBTRB, NOCPB, NOLPT1OSC, MCLR, NOXINST

#use delay(clock=4000000)

#include <lcd420.h>
#include <sht11.h>

void lectura_sht11(void);
void mostrar_temp_hum(void);

unsigned int8 temp_actual, humedad_actual;

typedef union
{
   int16 i;
   float f;
} valor;
valor humedad, temperatura;
byte errorsht11,checksum;


void main()
{
   lcd_init();
   sht11_hard_reset();

   while(true)
   {
      lectura_sht11();
      mostrar_temp_hum();
      delay_ms(1000);
   }
}


void lectura_sht11(void)
{
   errorsht11=0;
   errorsht11+=sht11_medicion((byte*) &humedad.i, &checksum, HUMI);     //measure humidity
   errorsht11+=sht11_medicion((byte*) &temperatura.i, &checksum, TEMP); //measure temperature
   if(errorsht11!=0)                                                    //in case of an error: connection reset
   {
      printf(lcd_putc,"\n\rerror:%U", errorsht11);
      sht11_hard_reset();
     }
   else
   {
      humedad.f=(float)humedad.i;                              //converts integer to float
      temperatura.f=(float)temperatura.i;                      //converts integer to float
      sht11_calculos(&humedad.f, &temperatura.f);              //calculate humidity, temperature
      temp_actual = temperatura.f;
      humedad_actual = humedad.f;
   }
}


void mostrar_temp_hum(void)
{
   lcd_gotoxy(1,1);
   printf(lcd_putc," %2.2f",temperatura.f);
   lcd_send_byte(1,0b11011111);                 //caracter de grados " º "
   printf(lcd_putc,"C  %2.2f%%HR",humedad.f);
}


usa la libreria del display de 4x20:

////////////////////////////////////////////////////////////////////////////
////                             LCD420.C                               ////
////            Driver for common 4x20 LCD modules                      ////
////                                                                    ////
////  lcd_init()   Must be called before any other function.            ////
////                                                                    ////
////  lcd_putc(c)  Will display c on the next position of the LCD.      ////
////                     The following have special meaning:            ////
////                      \f  Clear display                             ////
////                      \n  Go to start of second line                ////
////                      \b  Move back one position                    ////
////                                                                    ////
////  lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)     ////
////                                                                    ////
////  lcd_getc(x,y)   Returns character at position x,y on LCD          ////
////                                                                    ////
////////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,1997 Custom Computer Services            ////
//// This source code may only be used by licensed users of the CCS C   ////
//// compiler.  This source code may only be distributed to other       ////
//// licensed users of the CCS C compiler.  No other use, reproduction  ////
//// or distribution is permitted without written permission.           ////
//// Derivative programs created using this software in object code     ////
//// form are not restricted in any way.                                ////
////////////////////////////////////////////////////////////////////////////

// As defined in the following structure the pin connection is as follows:
//     C0  enable
//     C1  rs
//     C2  rw
//     C4  D4
//     C5  D5
//     C6  D6
//     C7  D7
//
//   LCD pins D0-D3 are not used and PIC C3 is not used.

struct lcd_pin_map {                 // This structure is overlayed
           BOOLEAN enable;           // on to an I/O port to gain
           BOOLEAN rs;               // access to the LCD pins.
           BOOLEAN rw;               // The bits are allocated from
           BOOLEAN unused;           // low order up.  ENABLE will
           int     data : 4;         // be pin B0.
        } lcd;

#byte lcd = 0xF82                        // This puts the entire structure
                                     // on to port C (at address 0xF82)

#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 lines


BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
                             // These bytes need to be sent to the LCD
                             // to start it up.


                             // The following are used for setting
                             // the I/O port direction register.

struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in

BYTE lcdline;

BYTE lcd_read_byte() {
      BYTE low,high;

      set_tris_c(LCD_READ);
      lcd.rw = 1;
      delay_cycles(1);
      lcd.enable = 1;
      delay_cycles(1);
      high = lcd.data;
      lcd.enable = 0;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(1);
      low = lcd.data;
      lcd.enable = 0;
      set_tris_c(LCD_WRITE);
      return( (high<<4) | low);
}


void lcd_send_nibble( BYTE n ) {
      lcd.data = n;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(2);
      lcd.enable = 0;
}


void lcd_send_byte( BYTE address, BYTE n ) {

      lcd.rs = 0;
      while ( bit_test(lcd_read_byte(),7) ) ;
      lcd.rs = address;
      delay_cycles(1);
      lcd.rw = 0;
      delay_cycles(1);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
}


void lcd_init() {
    BYTE i;

    set_tris_c(LCD_WRITE);
    lcd.rs = 0;
    lcd.rw = 0;
    lcd.enable = 0;
    delay_ms(15);
    for(i=1;i<=3;++i) {
       lcd_send_nibble(3);
       delay_ms(5);
    }
    lcd_send_nibble(2);
    for(i=0;i<=3;++i)
       lcd_send_byte(0, LCD_INIT_STRING);
}


void lcd_gotoxy( BYTE x, BYTE y) {
   BYTE address;

   switch(y) {
     case 1 : address=0x80;break;
     case 2 : address=0xc0;break;
     case 3 : address=0x94;break;
     case 4 : address=0xd4;break;
   }
   address+=x-1;
   lcd_send_byte(0,address);
}

void lcd_putc( char c) {
   switch (c) {
     case '\f'   : lcd_send_byte(0,1);
                   lcdline=1;
                   delay_ms(2);
                                           break;
     case '\n'   : lcd_gotoxy(1,++lcdline);        break;
     case '\b'   : lcd_send_byte(0,0x10);  break;
     default     : lcd_send_byte(1,c);     break;
   }
}

char lcd_getc( BYTE x, BYTE y) {
   char value;

    lcd_gotoxy(x,y);
    lcd.rs=1;
    value = lcd_read_byte();
    lcd.rs=0;
    return(value);
}


ahora si... GXS!!!!