TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Miquel_S en 02 de Febrero de 2016, 19:00:41

Título: Visualizar voltaje en Lcd
Publicado por: Miquel_S en 02 de Febrero de 2016, 19:00:41
Buenas noches, estoy intentando crear un menú en el lcd, algo como esto: https://www.youtube.com/watch?v=S88RLnohySQ&index=14&list=PLA4AF5BC61DE424D6  (https://www.youtube.com/watch?v=S88RLnohySQ&index=14&list=PLA4AF5BC61DE424D6) minuto 2:00, pero me encuentro que itoa solo acepta valores int no float y no se como resolver el problema. ¿Alguien podría ayudarme con la solución y decirme si el programa tiene errores?
Otra cosa, ¿Porque 10 como ultimo parámetro de itoa?
Código: C
  1. void main(void)
  2. {
  3.     char cadena_de_texto [5];
  4.     unsigned int valor_adc, voltios;
  5.    
  6.     OpenXLCD(FOUR_BIT & LINES_5X7);     // Iniciamos Lcd
  7.     comandXLCD(0x06);       // Nos aseguramos incremento de direccion, display fijo
  8.     OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_16_TAD,
  9.             ADC_CH0 & ADC_INT_OFF & ADC_REF_VDD_VSS, ADC_0ANA);
  10.     comandXLCD(0x0C);       // Encendemos Lcd
  11.     gotoxyXLCD(1,1);
  12.     putrsXLCD("Bateria: ");
  13.     gotoxyXLCD(1,2);
  14.     putrsXLCD("Estado: ");
  15.    
  16.    
  17.     while(1)
  18.     {
  19.        ConvertADC();    //Iniciamos conversion
  20.        while(BusyADC());    //Esperamos que termine la conversion
  21.        valor_adc = ReadADC();
  22.        voltios = (valor_adc/1024.0)*5.0;
  23.        gotoxyXLCD(10,1);
  24.        itoa(cadena_de_texto, voltios, 10);
  25.        putsXLCD(cadena_de_texto);
  26.     }
  27. }

Gracias.
Título: Re:Visualizar voltaje en Lcd
Publicado por: KILLERJC en 02 de Febrero de 2016, 19:13:26
Que tal con

Código: C
  1. sprintf(cadena_de_texto,"%.2f",voltios);
Título: Re:Visualizar voltaje en Lcd
Publicado por: RALF2 en 02 de Febrero de 2016, 19:31:45
El 10 representa la base en la que quieres el resultado, decimal = 10, hexadecimal = 16...

Saludos
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 02 de Febrero de 2016, 19:37:04
Gracias KILLERJC por la solución, he sustituido
Código: C
  1. itoa(cadena_de_texto, voltios, 10);
por
Código: C
  1. sprintf(cadena_de_texto,"%.2f",voltios);
y ahora funciona.
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 03 de Febrero de 2016, 18:21:47
Hola de nuevo, he cambiado el código anterior por este y no funciona como debería, el Lcd no para de fluctuar. No se donde puede haber el error, a mi parecer el procedimiento es el correcto.
Código: C
  1. void main(void)
  2. {
  3.     char cadena_de_texto [5];
  4.     unsigned int valor_adc;
  5.     float voltios;
  6.    
  7.     OpenXLCD(FOUR_BIT & LINES_5X7);     // Iniciamos Lcd
  8.     comandXLCD(0x06);       // Nos aseguramos incremento de direccion, display fijo
  9.     OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_16_TAD,
  10.             ADC_CH0 & ADC_INT_OFF & ADC_REF_VDD_VSS, ADC_0ANA);
  11.     comandXLCD(0x0C);       // Encendemos Lcd
  12.    
  13.     while(1)
  14.     {
  15.         comandXLCD(0x01);   //Borramos pantalla
  16.         SetChanADC(0);  //Seleccionamos canal
  17.         ConvertADC();    //Iniciamos conversion
  18.        
  19.         while(BusyADC()){}    //Esperamos que termine la conversion
  20.         valor_adc = ReadADC();  //Leemos conversion y la guardamos en valor_adc
  21.         voltios = (valor_adc/1024.0)*5.0;   //Convertimos valor ADC
  22.         gotoxyXLCD(1,1);    //Nos posicionamos en el Lcd
  23.         putrsXLCD("Bateria: ");
  24.         sprintf(cadena_de_texto,"%.2f",voltios);    //Visualizamos voltaje en formato float
  25.         putrsXLCD(cadena_de_texto);
  26.     }
  27. }

Gracias.
Título: Re:Visualizar voltaje en Lcd
Publicado por: AngelGris en 03 de Febrero de 2016, 18:37:52
Hola Miguel, y a todos en gral, vuelvo a escribir luego de mucho tiempo de no hacerlo.... espero no estar tan oxidado  :D :D :D

  Si siempre lees el mismo canal del ADC, creo que no debería ser necesario seleccionarlo siempre, por lo tanto podrías sacarlo del ciclo while. ¿Al borrar el LCD no queda posicionado directamente en el inicio del mismo? (Habría que ver en el datasheet que indica respecto de ese comando)
  En ocasiones suele variar el bit de menor peso entre lecturas sucesivas del ADC es por ello que se estila hacer un promedio de varias lecturas. A su vez podrías mantener en una variable el valor anterior y compararlo con el nuevo valor y de haber diferencia sí hacer todo el procedimiento de escritura en el LCD....
  Algo así

valor0 = ADC
valor1 = ADC
valor3 = ADC
valorLeido = (valor0 + valor1 + valor2)/3 // para hacer el promedio de las lecturas

si valorLeido != valorAnterior
{
  valorAnterior = valorLeido
  borrar display
  convertir a ascii
  imprimir display
}

  Controla el consumo de sprintf, ya que suele llevarse muchos ciclos de instrucción

Espero haberme explicado
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 03 de Febrero de 2016, 18:38:54
Resuelto, no me había dado cuenta de que estaba borrando la pantalla constantemente.

Saludos!
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 03 de Febrero de 2016, 18:42:46
Hola AngelGris te has dado mas prisa que yo ¿Que otra opción hay a parte de sprintf, porque itoa solo trabaja con int?
Título: Re:Visualizar voltaje en Lcd
Publicado por: AngelGris en 03 de Febrero de 2016, 18:53:12
  Una vez lo había resuelto multiplicando el número digamos por 100 para poder obtener 3 decimales y hacía uso de módulo y otras funciones que no recuerdo si eran del compilador o las había hecho yo. Voy a fijarme entre los programas que tengo guardados a ver que encuentro.
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 03 de Febrero de 2016, 18:54:49
Gracias AngelGris.
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 04 de Febrero de 2016, 11:35:31
Bueno veamos si se explicarme, tengo este código;
Código: C
  1. void main(void)
  2. {
  3.     char cadena_de_texto [5];
  4.     unsigned int valor_adc;
  5.     float voltios;
  6.    
  7.     OpenXLCD(FOUR_BIT & LINES_5X7);     // Iniciamos Lcd
  8.     comandXLCD(0x06);       // Nos aseguramos incremento de direccion, display fijo
  9.     OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_16_TAD,
  10.             ADC_CH0 & ADC_INT_OFF & ADC_REF_VDD_VSS, ADC_0ANA);
  11.     comandXLCD(0x0C);       // Encendemos Lcd
  12.     comandXLCD(0x01);   //Borramos pantalla
  13.    
  14.     while(1)
  15.     {
  16.         SetChanADC(0);  //Seleccionamos canal
  17.         ConvertADC();    //Iniciamos conversion
  18.        
  19.         while(BusyADC()){}    //Esperamos que termine la conversion
  20.         valor_adc = ReadADC();  //Leemos conversion y la guardamos en valor_adc
  21.         voltios = (valor_adc/1024.0)*5.0;   //Convertimos valor ADC
  22.         gotoxyXLCD(1,1);    //Nos posicionamos en el Lcd
  23.         putrsXLCD("Bateria: ");
  24.         sprintf(cadena_de_texto,"%.2f",voltios);    //Visualizamos voltaje en formato float
  25.         putsXLCD(cadena_de_texto);
  26.         gotoxyXLCD(1,2);
  27.         putrsXLCD("Estado: ");
  28.         Delay1KTCYx(180);
  29.     }
  30. }
y me pasa que después de iniciar el programa al cabo de unos segundos me empiezan a aparecer caracteres extraños en el Lcd (funcionaria bien de no ser por esto). Pero si quito la instrucción sprintf y coloco en su lugar itoa declarando voltios como int ya que no puedo hacerlo como float funciona como es debido sin que aparezcan caracteres raros en el Lcd, y mi duda es si sera problema de hardware o por el contrario sera la instrucción sprintf la que ocasiona el fallo.

Gracias.
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 04 de Febrero de 2016, 12:44:42
He encontrado esta instruccion:
Código: C
  1. ftoa(float f, int * status);
en stdlib.h pero no se muy bien como usarlo, ya que a mi parecer lo que hace es convertir un float a int.

Miquel_S
Título: Re:Visualizar voltaje en Lcd
Publicado por: KILLERJC en 04 de Febrero de 2016, 12:57:04
Yo mire y no posee nada asi la stdlib.h de C.
Es una implementacion de Microchip y si miras la funcion:


Código: C
  1. char *
  2. ftoa(float f, int * status)
  3. {
  4.         static char             buf[17];
  5.         char *                  cp = buf;
  6.         unsigned long   l, rem;
  7.  
  8.         if(f < 0) {
  9.                 *cp++ = '-';
  10.                 f = -f;
  11.         }
  12.         l = (unsigned long)f;
  13.         f -= (float)l;
  14.         rem = (unsigned long)(f * 1e6);
  15.         sprintf(cp, "%lu.%6.6lu", l, rem);
  16.         return buf;
  17. }

tenes tu sprintf :P
Si queres un ftoa hecho a "mano" el programa se puede volver bastaaaante larguito. Si es que buscas rapidez.
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 04 de Febrero de 2016, 13:11:06
Gracias KILLERJC habia visto la funcion pero lo que no termino de entender es el porque de los fallos en el Lcd al usar sprintf.

Título: Re:Visualizar voltaje en Lcd
Publicado por: KILLERJC en 04 de Febrero de 2016, 13:26:31
No se por que tendrias fallos en el LCD por usar sprintf algo esta mal entonces, pero no el programa, tal ves el driver? o tal ves el LCD.

La otra que queda es si podes ver el string que salio del sprintf de algun otra forma ( UART ) y ver que exactamente esta saliendo como debe.
Título: Re:Visualizar voltaje en Lcd
Publicado por: elgarbe en 04 de Febrero de 2016, 13:32:35
probá con:

Código: C
  1. char cadena_de_texto [6];

saludos
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 04 de Febrero de 2016, 13:33:03
El problema es que no se que es porque al usar itoa no falla.
¿Pudes decirme si el codigo esta bien y asi descartaria alguna cosa?

Gracias.
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 04 de Febrero de 2016, 13:42:21
Estoy con el mobil y os dais mas prisa vosotros en contestar que yo en escribir, :D
Seguire probando cosas.
Título: Re:Visualizar voltaje en Lcd
Publicado por: AngelGris en 04 de Febrero de 2016, 14:32:24
  Creo que el problema podría venir por la longitud del bufer, como bien lo indica elgarbe
Título: Re:Visualizar voltaje en Lcd
Publicado por: AngelGris en 04 de Febrero de 2016, 14:47:51
  Otro detalle es que si utilizas el ADC en 10 bits el mayor número será 1023 y no 1024. Son 1024 posibilidades ya que va des 0 a 1023
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 04 de Febrero de 2016, 16:02:46
He dado con el problema aunque no se que delay modificar, cambiando el Lcd por uno que tengo bastante viejo he conseguido que me funcione, por eso entiendo que es problema de la inicialización del Lcd aunque tampoco lo tengo claro, porque si intento visualizar algún mensaje sin usar el ADC no tengo problemas de inicialización.  :5]
El Lcd que estoy usando y con el que tengo problemas es el QC1602A v2.0 y los delays que he modificado son:
Código: C
  1. void DelayFor18TCY(void)    //Delay 0,00002sec => 20us => 0,02ms
  2. {
  3.     Delay10TCYx(24);
  4. }
  5. void DelayPORXLCD(void)     //Delay 0,015sec => 15000us => 15ms
  6. {
  7.     Delay1KTCYx(180);
  8. }
  9. void DelayXLCD(void)        //Delay 0,002sec => 2000us => 2ms
  10. {
  11.     Delay1KTCYx(24);
  12. }
Estoy trabajando a 48MHz
Título: Re:Visualizar voltaje en Lcd
Publicado por: elgarbe en 04 de Febrero de 2016, 16:18:53
probaste con ftoa?

saludos
Título: Re:Visualizar voltaje en Lcd
Publicado por: KILLERJC en 04 de Febrero de 2016, 16:47:22
probaste con ftoa?
saludos

Nuevametne, el source provisto por MCHP de la funcion ftoa() utiliza un sprintf() como el lo uso.

Citar
He dado con el problema aunque no se que delay modificar, cambiando el Lcd por uno que tengo bastante viejo he conseguido que me funcione, por eso entiendo que es problema de la inicialización del Lcd aunque tampoco lo tengo claro, porque si intento visualizar algún mensaje sin usar el ADC no tengo problemas de inicialización

Pero por lo que comentas no ocurre al comienzo sino mientras esta funcionando, y ahi puede ser problema de las funciones que manejen el LCD.
De todas formas los tiempos incluso son gigantes. Creo que el maximo tiempo en la inicializacion es de 2ms de delay, y lo demas cambiando el pin E que es el unico que se cambia rapido son nanosegundos creo.
Título: Re:Visualizar voltaje en Lcd
Publicado por: AngelGris en 04 de Febrero de 2016, 17:23:11
  Es  como si alguna función quisiera escribir en el LCD mientras éste está ocupado. Habría que ver las implementaciones de las rutinas. Creo que putrsXLCD chequea primero el flag de busy por lo tanto no creo que sea. No sé gotoxyXLCD como estará implementado.
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 04 de Febrero de 2016, 18:20:26
No se por que motivo, pero si elimino las dos ultimas lineas de código funciona sin problemas con el Lcd que antes no funcinaba:
Código: C
  1. while(1)
  2.     {
  3.         SetChanADC(0);  //Seleccionamos canal
  4.         ConvertADC();    //Iniciamos conversion
  5.        
  6.         while(BusyADC()){}    //Esperamos que termine la conversion
  7.         valor_adc = ReadADC();  //Leemos conversion y la guardamos en valor_adc
  8.         voltios = (valor_adc/1024.0)*5.0;   //Convertimos valor ADC
  9.         gotoxyXLCD(1,1);    //Nos posicionamos en el Lcd
  10.         putrsXLCD("Bateria: ");
  11.         sprintf(cadena_de_texto,"%.2f",voltios);    //Visualizamos voltaje en formato float
  12.         putrsXLCD(cadena_de_texto);
  13.         //gotoxyXLCD(1,2);
  14.         //putrsXLCD("Estado: ");
  15.     }
  16. }
Título: Re:Visualizar voltaje en Lcd
Publicado por: KILLERJC en 04 de Febrero de 2016, 18:33:27
Podrias poner el archivo donde tenes todas las funciones del LCD definidas ?
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 04 de Febrero de 2016, 18:54:48
Código: C
  1. #include <p18cxxx.h>
  2. #include <xlcd.h>
  3.  
  4. /********************************************************************
  5. *       Function Name:  BusyXLCD                                    *
  6. *       Return Value:   char: busy status of LCD controller         *
  7. *       Parameters:     void                                        *
  8. *       Description:    This routine reads the busy status of the   *
  9. *                       Hitachi HD44780 LCD controller.             *
  10. ********************************************************************/
  11. unsigned char BusyXLCD(void)
  12. {
  13.         RW_PIN = 1;                     // Set the control bits for read
  14.         RS_PIN = 0;
  15.         DelayFor18TCY();
  16.         E_PIN = 1;                      // Clock in the command
  17.         DelayFor18TCY();
  18. #ifdef BIT8                             // 8-bit interface
  19.         if(DATA_PORT&0x80)                      // Read bit 7 (busy bit)
  20.         {                               // If high
  21.                 E_PIN = 0;              // Reset clock line
  22.                 RW_PIN = 0;             // Reset control line
  23.                 return 1;               // Return TRUE
  24.         }
  25.         else                            // Bit 7 low
  26.         {
  27.                 E_PIN = 0;              // Reset clock line
  28.                 RW_PIN = 0;             // Reset control line
  29.                 return 0;               // Return FALSE
  30.         }
  31. #else                                   // 4-bit interface
  32. #ifdef UPPER                            // Upper nibble interface
  33.         if(DATA_PORT&0x80)
  34. #else                                   // Lower nibble interface
  35.         if(DATA_PORT&0x08)
  36. #endif
  37.         {
  38.                 E_PIN = 0;              // Reset clock line
  39.                 DelayFor18TCY();
  40.                 E_PIN = 1;              // Clock out other nibble
  41.                 DelayFor18TCY();
  42.                 E_PIN = 0;
  43.                 RW_PIN = 0;             // Reset control line
  44.                 return 1;               // Return TRUE
  45.         }
  46.         else                            // Busy bit is low
  47.         {
  48.                 E_PIN = 0;              // Reset clock line
  49.                 DelayFor18TCY();
  50.                 E_PIN = 1;              // Clock out other nibble
  51.                 DelayFor18TCY();
  52.                 E_PIN = 0;
  53.                 RW_PIN = 0;             // Reset control line
  54.                 return 0;               // Return FALSE
  55.         }
  56. #endif
  57. }
Código: C
  1. #include <p18cxxx.h>
  2. #include "delays.h"
  3. #include <xlcd.h>
  4.  
  5. /********************************************************************
  6. *       Function Name:  OpenXLCD                                    *
  7. *       Return Value:   void                                        *
  8. *       Parameters:     lcdtype: sets the type of LCD (lines)       *
  9. *       Description:    This routine configures the LCD. Based on   *
  10. *                       the Hitachi HD44780 LCD controller. The     *
  11. *                       routine will configure the I/O pins of the  *
  12. *                       microcontroller, setup the LCD for 4- or    *
  13. *                       8-bit mode and clear the display. The user  *
  14. *                       must provide three delay routines:          *
  15. *                       DelayFor18TCY() provides a 18 Tcy delay     *
  16. *                       DelayPORXLCD() provides at least 15ms delay *
  17. *                       DelayXLCD() provides at least 5ms delay     *
  18. ********************************************************************/
  19. void OpenXLCD(unsigned char lcdtype)
  20. {
  21.         // The data bits must be either a 8-bit port or the upper or
  22.         // lower 4-bits of a port. These pins are made into inputs
  23. #ifdef BIT8                             // 8-bit mode, use whole port
  24.         DATA_PORT = 0;
  25.         TRIS_DATA_PORT = 0x00;
  26. #else                                   // 4-bit mode
  27. #ifdef UPPER                            // Upper 4-bits of the port
  28.         DATA_PORT &= 0x0f;
  29.         TRIS_DATA_PORT &= 0x0F;
  30. #else                                   // Lower 4-bits of the port
  31.         DATA_PORT &= 0xf0;
  32.         TRIS_DATA_PORT &= 0xF0;
  33. #endif
  34. #endif
  35.         TRIS_RW = 0;                    // All control signals made outputs
  36.         TRIS_RS = 0;
  37.         TRIS_E = 0;
  38.         RW_PIN = 0;                     // R/W pin made low
  39.         RS_PIN = 0;                     // Register select pin made low
  40.         E_PIN = 0;                      // Clock pin made low
  41.  
  42.         // Delay for 15ms to allow for LCD Power on reset
  43.         DelayPORXLCD();
  44.  //-------------------reset procedure through software----------------------      
  45.                  WriteCmdXLCD(0x30);
  46.                         Delay10KTCYx(0x05);
  47.  
  48.                  WriteCmdXLCD(0x30);
  49.                         Delay10KTCYx(0x01);
  50.  
  51.  
  52.                  WriteCmdXLCD(0x32);
  53.                 while( BusyXLCD() );
  54. //------------------------------------------------------------------------------------------
  55.  
  56.  
  57.         // Set data interface width, # lines, font
  58.         while(BusyXLCD());              // Wait if LCD busy
  59.         WriteCmdXLCD(lcdtype);          // Function set cmd
  60.  
  61.         // Turn the display on then off
  62.         while(BusyXLCD());              // Wait if LCD busy
  63.         WriteCmdXLCD(DOFF&CURSOR_OFF&BLINK_OFF);        // Display OFF/Blink OFF
  64.         while(BusyXLCD());              // Wait if LCD busy
  65.         WriteCmdXLCD(DON&CURSOR_ON&BLINK_ON);           // Display ON/Blink ON
  66.  
  67.         // Clear display
  68.         while(BusyXLCD());              // Wait if LCD busy
  69.         WriteCmdXLCD(0x01);             // Clear display
  70.  
  71.         // Set entry mode inc, no shift
  72.         while(BusyXLCD());              // Wait if LCD busy
  73.         WriteCmdXLCD(SHIFT_CUR_LEFT);   // Entry Mode
  74.  
  75.         // Set DD Ram address to 0
  76.         while(BusyXLCD());              // Wait if LCD busy
  77.         SetDDRamAddr(0x80);                // Set Display data ram address to 0
  78.  
  79.         return;
  80. }
Código: C
  1. #include <p18cxxx.h>
  2. #include <xlcd.h>
  3.  
  4. /********************************************************************
  5. *       Function Name:  putrsXLCD
  6. *       Return Value:   void
  7. *       Parameters:     buffer: pointer to string
  8. *       Description:    This routine writes a string of bytes to the
  9. *                       Hitachi HD44780 LCD controller. The user
  10. *                       must check to see if the LCD controller is
  11. *                       busy before calling this routine. The data
  12. *                       is written to the character generator RAM or
  13. *                       the display data RAM depending on what the
  14. *                       previous SetxxRamAddr routine was called.
  15. ********************************************************************/
  16. void putrsXLCD(const char *buffer)
  17. {
  18.         while(*buffer)                  // Write data to LCD up to null
  19.         {
  20.                 while(BusyXLCD());      // Wait while LCD is busy
  21.                 WriteDataXLCD(*buffer); // Write character to LCD
  22.                 buffer++;               // Increment buffer
  23.         }
  24.         return;
  25. }
Código: C
  1. #include <p18cxxx.h>
  2. #include <xlcd.h>
  3.  
  4. /********************************************************************
  5. *       Function Name:  putsXLCD
  6. *       Return Value:   void
  7. *       Parameters:     buffer: pointer to string
  8. *       Description:    This routine writes a string of bytes to the
  9. *                       Hitachi HD44780 LCD controller. The user
  10. *                       must check to see if the LCD controller is
  11. *                       busy before calling this routine. The data
  12. *                       is written to the character generator RAM or
  13. *                       the display data RAM depending on what the
  14. *                       previous SetxxRamAddr routine was called.
  15. ********************************************************************/
  16. void putsXLCD(char *buffer)
  17. {
  18.         while(*buffer)                  // Write data to LCD up to null
  19.         {
  20.                 while(BusyXLCD());      // Wait while LCD is busy
  21.                 WriteDataXLCD(*buffer); // Write character to LCD
  22.                 buffer++;               // Increment buffer
  23.         }
  24.         return;
  25. }
Código: C
  1. include <p18cxxx.h>
  2. #include <xlcd.h>
  3.  
  4. /*********************************************************************
  5. *       Function Name:  ReadAddrXLCD                                 *
  6. *       Return Value:   char: address from LCD controller            *
  7. *       Parameters:     void                                         *
  8. *       Description:    This routine reads an address byte from the  *
  9. *                       Hitachi HD44780 LCD controller. The user     *
  10. *                       must check to see if the LCD controller is   *
  11. *                       busy before calling this routine. The address*
  12. *                       is read from the character generator RAM or  *
  13. *                       the display data RAM depending on what the   *
  14. *                       previous SetxxRamAddr routine was called.    *
  15. *********************************************************************/
  16. unsigned char ReadAddrXLCD(void)
  17. {
  18.         char data;                      // Holds the data retrieved from the LCD
  19.  
  20. #ifdef BIT8                             // 8-bit interface
  21.         RW_PIN = 1;                     // Set control bits for the read
  22.         RS_PIN = 0;
  23.         DelayFor18TCY();
  24.         E_PIN = 1;                      // Clock data out of the LCD controller
  25.         DelayFor18TCY();
  26.         data = DATA_PORT;               // Save the data in the register
  27.         E_PIN = 0;
  28.         RW_PIN = 0;                     // Reset the control bits
  29. #else                                   // 4-bit interface
  30.         RW_PIN = 1;                     // Set control bits for the read
  31.         RS_PIN = 0;
  32.         DelayFor18TCY();
  33.         E_PIN = 1;                      // Clock data out of the LCD controller
  34.         DelayFor18TCY();
  35. #ifdef UPPER                            // Upper nibble interface
  36.         data = DATA_PORT&0xf0;          // Read the nibble into the upper nibble of data
  37. #else                                   // Lower nibble interface
  38.         data = (DATA_PORT<<4)&0xf0;     // Read the nibble into the upper nibble of data
  39. #endif
  40.         E_PIN = 0;                      // Reset the clock
  41.         DelayFor18TCY();
  42.         E_PIN = 1;                      // Clock out the lower nibble
  43.         DelayFor18TCY();
  44. #ifdef UPPER                            // Upper nibble interface
  45.         data |= (DATA_PORT>>4)&0x0f;    // Read the nibble into the lower nibble of data
  46. #else                                   // Lower nibble interface
  47.         data |= DATA_PORT&0x0f;         // Read the nibble into the lower nibble of data
  48. #endif
  49.         E_PIN = 0;
  50.         RW_PIN = 0;                     // Reset the control lines
  51. #endif
  52.         return (data&0x7f);             // Return the address, Mask off the busy bit
  53. }
Código: C
  1. #include <p18cxxx.h>
  2. #include <xlcd.h>
  3.  
  4. /********************************************************************
  5. *       Function Name:  ReadDataXLCD                                *
  6. *       Return Value:   char: data byte from LCD controller         *
  7. *       Parameters:     void                                        *
  8. *       Description:    This routine reads a data byte from the     *
  9. *                       Hitachi HD44780 LCD controller. The user    *
  10. *                       must check to see if the LCD controller is  *
  11. *                       busy before calling this routine. The data  *
  12. *                       is read from the character generator RAM or *
  13. *                       the display data RAM depending on what the  *
  14. *                       previous SetxxRamAddr routine was called.   *
  15. ********************************************************************/
  16. char ReadDataXLCD(void)
  17. {
  18.         char data;
  19.  
  20. #ifdef BIT8                             // 8-bit interface
  21.         RS_PIN = 1;                     // Set the control bits
  22.         RW_PIN = 1;
  23.         DelayFor18TCY();
  24.         E_PIN = 1;                      // Clock the data out of the LCD
  25.         DelayFor18TCY();
  26.         data = DATA_PORT;               // Read the data
  27.         E_PIN = 0;
  28.         RS_PIN = 0;                     // Reset the control bits
  29.         RW_PIN = 0;
  30. #else                                   // 4-bit interface
  31.         RW_PIN = 1;
  32.         RS_PIN = 1;
  33.         DelayFor18TCY();
  34.         E_PIN = 1;                      // Clock the data out of the LCD
  35.         DelayFor18TCY();
  36. #ifdef UPPER                            // Upper nibble interface
  37.         data = DATA_PORT&0xf0;          // Read the upper nibble of data
  38. #else                                   // Lower nibble interface
  39.         data = (DATA_PORT<<4)&0xf0;     // read the upper nibble of data
  40. #endif
  41.         E_PIN = 0;                      // Reset the clock line
  42.         DelayFor18TCY();
  43.         E_PIN = 1;                      // Clock the next nibble out of the LCD
  44.         DelayFor18TCY();
  45. #ifdef UPPER                            // Upper nibble interface
  46.         data |= (DATA_PORT>>4)&0x0f;    // Read the lower nibble of data
  47. #else                                   // Lower nibble interface
  48.         data |= DATA_PORT&0x0f;         // Read the lower nibble of data
  49. #endif
  50.         E_PIN = 0;                                      
  51.         RS_PIN = 0;                     // Reset the control bits
  52.         RW_PIN = 0;
  53. #endif
  54.         return(data);                   // Return the data byte
  55. }
Código: C
  1. #include <p18cxxx.h>
  2. #include <xlcd.h>
  3.  
  4. /********************************************************************
  5. *       Function Name:  SetCGRamAddr                                *
  6. *       Return Value:   void                                        *
  7. *       Parameters:     CGaddr: character generator ram address     *
  8. *       Description:    This routine sets the character generator   *
  9. *                       address of the Hitachi HD44780 LCD          *
  10. *                       controller. The user must check to see if   *
  11. *                       the LCD controller is busy before calling   *
  12. *                       this routine.                               *
  13. ********************************************************************/
  14. void SetCGRamAddr(unsigned char CGaddr)
  15. {
  16. #ifdef BIT8                                     // 8-bit interface
  17.         TRIS_DATA_PORT = 0;                     // Make data port ouput
  18.         DATA_PORT = CGaddr | 0b01000000;        // Write cmd and address to port
  19.         RW_PIN = 0;                             // Set control signals
  20.         RS_PIN = 0;
  21.         DelayFor18TCY();
  22.         E_PIN = 1;                              // Clock cmd and address in
  23.         DelayFor18TCY();
  24.         E_PIN = 0;
  25.         DelayFor18TCY();
  26.         TRIS_DATA_PORT = 0xff;                  // Make data port inputs
  27. #else                                           // 4-bit interface
  28. #ifdef UPPER                                    // Upper nibble interface
  29.         TRIS_DATA_PORT &= 0x0f;                 // Make nibble input
  30.         DATA_PORT &= 0x0f;                      // and write upper nibble
  31.         DATA_PORT |= ((CGaddr | 0b01000000) & 0xf0);
  32. #else                                           // Lower nibble interface
  33.         TRIS_DATA_PORT &= 0xf0;                 // Make nibble input
  34.         DATA_PORT &= 0xf0;                      // and write upper nibble
  35.         DATA_PORT |= (((CGaddr |0b01000000)>>4) & 0x0f);
  36. #endif
  37.         RW_PIN = 0;                             // Set control signals
  38.         RS_PIN = 0;
  39.         DelayFor18TCY();
  40.         E_PIN = 1;                              // Clock cmd and address in
  41.         DelayFor18TCY();
  42.         E_PIN = 0;
  43. #ifdef UPPER                                    // Upper nibble interface
  44.         DATA_PORT &= 0x0f;                      // Write lower nibble
  45.         DATA_PORT |= ((CGaddr<<4)&0xf0);
  46. #else                                           // Lower nibble interface
  47.         DATA_PORT &= 0xf0;                      // Write lower nibble
  48.         DATA_PORT |= (CGaddr&0x0f);
  49. #endif
  50.         DelayFor18TCY();
  51.         E_PIN = 1;                              // Clock cmd and address in
  52.         DelayFor18TCY();
  53.         E_PIN = 0;
  54. #ifdef UPPER                                    // Upper nibble interface
  55.         TRIS_DATA_PORT |= 0xf0;                 // Make inputs
  56. #else                                           // Lower nibble interface
  57.         TRIS_DATA_PORT |= 0x0f;                 // Make inputs
  58. #endif
  59. #endif
  60.         return;
  61. }
Código: C
  1. #include <p18cxxx.h>
  2. #include <xlcd.h>
  3.  
  4. /********************************************************************
  5. *       Function Name:  SetDDRamAddr                                *
  6. *       Return Value:   void                                        *
  7. *       Parameters:     CGaddr: display data address                *
  8. *       Description:    This routine sets the display data address  *
  9. *                       of the Hitachi HD44780 LCD controller. The  *
  10. *                       user must check to see if the LCD controller*
  11. *                       is busy before calling this routine.        *
  12. ********************************************************************/
  13. void SetDDRamAddr(unsigned char DDaddr)
  14. {
  15. #ifdef BIT8                                     // 8-bit interface
  16.         TRIS_DATA_PORT = 0;                     // Make port output
  17.         DATA_PORT = DDaddr | 0b10000000;        // Write cmd and address to port
  18.         RW_PIN = 0;                             // Set the control bits
  19.         RS_PIN = 0;
  20.         DelayFor18TCY();
  21.         E_PIN = 1;                              // Clock the cmd and address in
  22.         DelayFor18TCY();
  23.         E_PIN = 0;
  24.         DelayFor18TCY();
  25.         TRIS_DATA_PORT = 0xff;                  // Make port input
  26. #else                                           // 4-bit interface
  27. #ifdef UPPER                                    // Upper nibble  interface
  28.         TRIS_DATA_PORT &= 0x0f;                 // Make port output
  29.         DATA_PORT &= 0x0f;                      // and write upper nibble
  30.         DATA_PORT |= ((DDaddr | 0b10000000) & 0xf0);
  31. #else                                           // Lower nibble interface
  32.         TRIS_DATA_PORT &= 0xf0;                 // Make port output
  33.         DATA_PORT &= 0xf0;                      // and write upper nibble
  34.         DATA_PORT |= (((DDaddr | 0b10000000)>>4) & 0x0f);
  35. #endif
  36.         RW_PIN = 0;                             // Set control bits
  37.         RS_PIN = 0;
  38.         DelayFor18TCY();
  39.         E_PIN = 1;                              // Clock the cmd and address in
  40.         DelayFor18TCY();
  41.         E_PIN = 0;
  42. #ifdef UPPER                                    // Upper nibble interface
  43.         DATA_PORT &= 0x0f;                      // Write lower nibble
  44.         DATA_PORT |= ((DDaddr<<4)&0xf0);
  45. #else                                           // Lower nibble interface
  46.         DATA_PORT &= 0xf0;                      // Write lower nibble
  47.         DATA_PORT |= (DDaddr&0x0f);
  48. #endif
  49.         DelayFor18TCY();
  50.         E_PIN = 1;                              // Clock the cmd and address in
  51.         DelayFor18TCY();
  52.         E_PIN = 0;
  53. #ifdef UPPER                                    // Upper nibble interface
  54.         TRIS_DATA_PORT |= 0xf0;                 // Make port input
  55. #else                                           // Lower nibble interface
  56.         TRIS_DATA_PORT |= 0x0f;                 // Make port input
  57. #endif
  58. #endif
  59.         return;
  60. }
Código: C
  1. #include <p18cxxx.h>
  2. #include <xlcd.h>
  3.  
  4. /********************************************************************
  5. *       Function Name:  WriteCmdXLCD                                *
  6. *       Return Value:   void                                        *
  7. *       Parameters:     cmd: command to send to LCD                 *
  8. *       Description:    This routine writes a command to the Hitachi*
  9. *                       HD44780 LCD controller. The user must check *
  10. *                       to see if the LCD controller is busy before *
  11. *                       calling this routine.                       *
  12. ********************************************************************/
  13. void WriteCmdXLCD(unsigned char cmd)
  14. {
  15. #ifdef BIT8                             // 8-bit interface
  16.         TRIS_DATA_PORT = 0;             // Data port output
  17.         DATA_PORT = cmd;                // Write command to data port
  18.         RW_PIN = 0;                     // Set the control signals
  19.         RS_PIN = 0;                     // for sending a command
  20.         DelayFor18TCY();
  21.         E_PIN = 1;                      // Clock the command in
  22.         DelayFor18TCY();
  23.         E_PIN = 0;
  24.         DelayFor18TCY();
  25.         TRIS_DATA_PORT = 0xff;          // Data port input
  26. #else                                   // 4-bit interface
  27. #ifdef UPPER                            // Upper nibble interface
  28.         TRIS_DATA_PORT &= 0x0f;
  29.         DATA_PORT &= 0x0f;
  30.         DATA_PORT |= cmd&0xf0;
  31. #else                                   // Lower nibble interface
  32.         TRIS_DATA_PORT &= 0xf0;
  33.         DATA_PORT &= 0xf0;
  34.         DATA_PORT |= (cmd>>4)&0x0f;
  35. #endif
  36.         RW_PIN = 0;                     // Set control signals for command
  37.         RS_PIN = 0;
  38.         DelayFor18TCY();
  39.         E_PIN = 1;                      // Clock command in
  40.         DelayFor18TCY();
  41.         E_PIN = 0;
  42. #ifdef UPPER                            // Upper nibble interface
  43.         DATA_PORT &= 0x0f;
  44.         DATA_PORT |= (cmd<<4)&0xf0;
  45. #else                                   // Lower nibble interface
  46.         DATA_PORT &= 0xf0;
  47.         DATA_PORT |= cmd&0x0f;
  48. #endif
  49.         DelayFor18TCY();
  50.         E_PIN = 1;                      // Clock command in
  51.         DelayFor18TCY();
  52.         E_PIN = 0;
  53. #ifdef UPPER                            // Make data nibble input
  54.         TRIS_DATA_PORT |= 0xf0;
  55. #else
  56.         TRIS_DATA_PORT |= 0x0f;
  57. #endif
  58. #endif
  59.         return;
  60. }
Código: C
  1. #include <p18cxxx.h>
  2. #include <xlcd.h>
  3.  
  4. /********************************************************************
  5. *       Function Name:  WriteDataXLCD                               *
  6. *       Return Value:   void                                        *
  7. *       Parameters:     data: data byte to be written to LCD        *
  8. *       Description:    This routine writes a data byte to the      *
  9. *                       Hitachi HD44780 LCD controller. The user    *
  10. *                       must check to see if the LCD controller is  *
  11. *                       busy before calling this routine. The data  *
  12. *                       is written to the character generator RAM or*
  13. *                       the display data RAM depending on what the  *
  14. *                       previous SetxxRamAddr routine was called.   *
  15. ********************************************************************/
  16. void WriteDataXLCD(char data)
  17. {
  18. #ifdef BIT8                             // 8-bit interface
  19.         TRIS_DATA_PORT = 0;             // Make port output
  20.         DATA_PORT = data;               // Write data to port
  21.         RS_PIN = 1;                     // Set control bits
  22.         RW_PIN = 0;
  23.         DelayFor18TCY();
  24.         E_PIN = 1;                      // Clock data into LCD
  25.         DelayFor18TCY();
  26.         E_PIN = 0;
  27.         RS_PIN = 0;                     // Reset control bits
  28.         TRIS_DATA_PORT = 0xff;          // Make port input
  29. #else                                   // 4-bit interface
  30. #ifdef UPPER                            // Upper nibble interface
  31.         TRIS_DATA_PORT &= 0x0f;
  32.         DATA_PORT &= 0x0f;
  33.         DATA_PORT |= data&0xf0;
  34. #else                                   // Lower nibble interface
  35.         TRIS_DATA_PORT &= 0xf0;
  36.         DATA_PORT &= 0xf0;
  37.         DATA_PORT |= ((data>>4)&0x0f);
  38. #endif
  39.         RS_PIN = 1;                     // Set control bits
  40.         RW_PIN = 0;
  41.         DelayFor18TCY();
  42.         E_PIN = 1;                      // Clock nibble into LCD
  43.         DelayFor18TCY();
  44.         E_PIN = 0;
  45. #ifdef UPPER                            // Upper nibble interface
  46.         DATA_PORT &= 0x0f;
  47.         DATA_PORT |= ((data<<4)&0xf0);
  48. #else                                   // Lower nibble interface
  49.         DATA_PORT &= 0xf0;
  50.         DATA_PORT |= (data&0x0f);
  51. #endif
  52.         DelayFor18TCY();
  53.         E_PIN = 1;                      // Clock nibble into LCD
  54.         DelayFor18TCY();
  55.         E_PIN = 0;
  56. #ifdef UPPER                            // Upper nibble interface
  57.         TRIS_DATA_PORT |= 0xf0;
  58. #else                                   // Lower nibble interface
  59.         TRIS_DATA_PORT |= 0x0f;
  60. #endif
  61. #endif
  62.         return;
  63. }
Título: Re:Visualizar voltaje en Lcd
Publicado por: elgarbe en 04 de Febrero de 2016, 20:11:29
Mi primerera duda era que si en 5 caracteres entran lodos los datos más el '\0' y si la funcion sprinf pone ese caracter 'null', porque la funcion lo necesita:

Código: C
  1. void putrsXLCD(const char *buffer)
  2. {
  3.         while(*buffer)                  // Write data to LCD up to null
  4.         {
  5.                 while(BusyXLCD());      // Wait while LCD is busy
  6.                 WriteDataXLCD(*buffer); // Write character to LCD
  7.                 buffer++;               // Increment buffer
  8.         }
  9.         return;
  10. }

Quizá si la tension es 9.10 entra el \0, pero si la tension es 10.23 no entra en el buffer. Por eso sugería aumentarlo a 6.

Saludos!
Título: Re:Visualizar voltaje en Lcd
Publicado por: KILLERJC en 04 de Febrero de 2016, 20:24:53
Citar
sprintf
int sprintf ( char * str, const char * format, ... );
Write formatted data to string
Composes a string with the same text that would be printed if format was used on printf, but instead of being printed, the content is stored as a C string in the buffer pointed by str.

The size of the buffer should be large enough to contain the entire resulting string (see snprintf for a safer version).

A terminating null character is automatically appended after the content.

Mirando el codigo parece todo correcto. Si

DelayFor18TCY();

es exactamente 18 TCY, a 48Mhz son 1.5us, suficiente como el enable que solo pide un ciclo completo 1us a 3.3V o 500ns a 5V

Lo unico que me llama la atencion es esto:

Citar
*       Description:    This routine writes a string of bytes to the
*                       Hitachi HD44780 LCD controller. The user
*                       must check to see if the LCD controller is
*                       busy before calling this routine. The data

Y las rutinas de demora:

Código: C
  1. void DelayFor18TCY(void)    // Delay MAL lo anterior
  2. {
  3.     Delay10TCYx(2); // 20 TCY = 1.66us , 1TCY = 83.3ns
  4. }
  5. void DelayPORXLCD(void)     //Delay 0,015sec => 15000us => 15ms
  6. {
  7.     Delay1KTCYx(180); //Bien
  8. }
  9. void DelayXLCD(void)        //Delay MAL lo anterior pide 5ms no 2ms
  10. {
  11.     Delay1KTCYx(60);         // 5ms = 60000 TCY
  12. }
Título: Re:Visualizar voltaje en Lcd
Publicado por: AngelGris en 04 de Febrero de 2016, 20:49:56
  Por lo visto hay rutinas que sí chequean si está ocupado el LCD mientras que otras no chequean. Seguramente por allí vendrá el problema
Título: Re:Visualizar voltaje en Lcd
Publicado por: elgarbe en 04 de Febrero de 2016, 20:52:18
Citar
sprintf
int sprintf ( char * str, const char * format, ... );
Write formatted data to string
Composes a string with the same text that would be printed if format was used on printf, but instead of being printed, the content is stored as a C string in the buffer pointed by str.

The size of the buffer should be large enough to contain the entire resulting string (see snprintf for a safer version).

A terminating null character is automatically appended after the content.

Mirando el codigo parece todo correcto. Si

Insisto en que si quiere escribir 10.23 en el LCD, el '\0' cae en cualquier lugar de la RAM...

Título: Re:Visualizar voltaje en Lcd
Publicado por: KILLERJC en 04 de Febrero de 2016, 21:09:33
ahh pero pense que ya habia probado con eso de ponerle unos lugares mas al array
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 05 de Febrero de 2016, 03:04:36
Perdón si que he probado de modificar el array como comenta elgarbe pero no esta aquí el fallo, de todos modos en las pruebas no tengo mas de 5 voltios, aun así si el fallo estuviera en el array no tendría porque funcionar bien con un Lcd y mal con otro,
otra cosa, he probado de modificar los valores de los delays como comenta KILLERJC y con estos valores no escribe en el Lcd.

Gracias.
Título: Re:Visualizar voltaje en Lcd
Publicado por: KILLERJC en 05 de Febrero de 2016, 14:28:50
Bueno me quede sin ideas... La unica que me queda es:

Código: C
  1. while( BusyXLCD() );
  2.         gotoxyXLCD(1,1);
  3.         while( BusyXLCD() );
  4.         putrsXLCD("Bateria: ");
  5.         sprintf(cadena_de_texto,"%.2f",voltios);    //Visualizamos voltaje en formato float
  6.         while( BusyXLCD() );
  7.         putrsXLCD(cadena_de_texto);
  8.         while( BusyXLCD() );
  9.         gotoxyXLCD(1,2);
  10.         while( BusyXLCD() );
  11.         putrsXLCD("Estado: ");

Los delays como lo puse deberian ser correctos. De todas formas si tiene mas tiempo no deberia haber problemas.
Y tambien pone el buffer cadena_de_texto para que tenga unos 10 lugares masomenos y no salvamos de eso como dijo elgarbe

char cadena_de_texto[10];

Si ya con eso no se arregla entonces es el LCD :3 creo yo.
Título: Re:Visualizar voltaje en Lcd
Publicado por: elgarbe en 05 de Febrero de 2016, 14:56:40
+1!!!
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 05 de Febrero de 2016, 17:25:29
Nada he probado con el código de KILLERJC, he cambiado el Lcd por otro nuevo del mismo modelo y sigue sin funcionar, ya no se que probar eso me desespera. :cry:
Título: Re:Visualizar voltaje en Lcd
Publicado por: elgarbe en 05 de Febrero de 2016, 20:06:59
foto del circuito montado?
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 06 de Febrero de 2016, 11:42:51
Tengo el Lcd conectado en modo 4bits en el Puerto B y el potenciometro en RA0.

Saludos.
Título: Re:Visualizar voltaje en Lcd
Publicado por: KILLERJC en 06 de Febrero de 2016, 12:48:57
El tema es que lo imprime como 3/4 veces bien. Y luego se pone re loco, y por lo que parece es el LCD, es como si el puntero a memoria ( el que debe barrer para refrescar el LCD ) se volviera re loco y saltara a cualquier lado.
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 06 de Febrero de 2016, 16:01:39
Con este código cumpliría su cometido, el problema creo que sera al leer los sensores que pasara lo mismo que antes.
Código: C
  1. /*
  2.  * File:   main.c
  3.  * Author: miquel
  4.  *
  5.  * Created on 23 de enero de 2016, 21:43
  6.  */
  7.  
  8. #include <xc.h>
  9. #include <delays.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include "MyXLCD.h"
  13. #include "word_config.h"
  14.  
  15. #define _XTAL_FREQ 48000000
  16.  
  17. /*
  18.  *
  19.  */
  20.  
  21. void DelayFor18TCY(void)    //Delay 0,00002sec => 20us => 0,02ms
  22. {
  23.     //Delay10TCYx(2);
  24.     Delay10TCYx(24);
  25. }
  26. void DelayPORXLCD(void)     //Delay 0,015sec => 15000us => 15ms
  27. {
  28.     //Delay1KTCYx(15);
  29.     Delay1KTCYx(180);
  30. }
  31. void DelayXLCD(void)        //Delay 0,002sec => 2000us => 2ms
  32. {
  33.     //Delay1KTCYx(2);
  34.     Delay1KTCYx(24);
  35. }
  36. /* Envia comando al LCD */
  37. void comandXLCD(unsigned char a)
  38. {
  39.     BusyXLCD();
  40.     WriteCmdXLCD(a);
  41. }
  42.  
  43. /* Ubica cursor en ( x = Posicion en linea , y = N de linea ) */
  44. void gotoxyXLCD(unsigned char x, unsigned char y)
  45. {
  46.     unsigned char direccion;
  47.  
  48.     if(y != 1)
  49.         direccion = 0x40;
  50.     else
  51.         direccion = 0;
  52.  
  53.     direccion += x-1;
  54.     comandXLCD(0x80 | direccion);
  55. }
  56.  
  57. void main(void)
  58. {
  59.     unsigned char i,j;
  60.     char cadena_de_texto[6];
  61.     unsigned int valor_adc;
  62.     float voltios;
  63.    
  64.     OpenADC(ADC_FOSC_RC & ADC_RIGHT_JUST & ADC_2_TAD,
  65.             ADC_CH0 & ADC_INT_OFF & ADC_REF_VDD_VSS, ADC_0ANA);
  66.     OpenXLCD(FOUR_BIT & LINES_5X7);     // Iniciamos Lcd
  67.     comandXLCD(0x06);       // Nos aseguramos incremento de direccion, display fijo
  68.     comandXLCD(0x0C);       // Encendemos Lcd
  69.     gotoxyXLCD(1,1);
  70.     putrsXLCD("Test DIONE by");
  71.     gotoxyXLCD(1,2);
  72.     putrsXLCD("Miquel Servera");
  73.  
  74.     for(i=0; i<=15; i++)
  75.     {
  76.         for(j=0; j<=i; j++)
  77.         {
  78.             Delay10KTCYx(20);
  79.         }
  80.     }
  81.    
  82.     comandXLCD(0x01);       //Clear display
  83.     SetChanADC(0);  //Seleccionamos canal
  84.     ConvertADC();    //Iniciamos conversion
  85.     while(BusyADC()){}    //Esperamos que termine la conversion
  86.     valor_adc = ReadADC();  //Leemos conversion y la guardamos en valor_adc
  87.     voltios = (valor_adc/1024.0)*5.0;   //Convertimos valor ADC
  88.     gotoxyXLCD(1,1);
  89.     putrsXLCD("Battery: ");
  90.     sprintf(cadena_de_texto,"%.2f",voltios);    //Visualizamos voltaje en formato float
  91.     putrsXLCD(cadena_de_texto);
  92.     gotoxyXLCD(1,2);
  93.     putrsXLCD("State: ");
  94.    
  95.     if(voltios >= 3)
  96.     {
  97.         gotoxyXLCD(9,2);
  98.         putrsXLCD("OK");
  99.     }else{
  100.         gotoxyXLCD(9,2);
  101.         putrsXLCD("LOW");
  102.     }
  103.  
  104.     for(i=0; i<=15; i++)
  105.     {
  106.         for(j=0; j<=i; j++)
  107.         {
  108.             Delay10KTCYx(20);
  109.         }
  110.     }
  111.    
  112.     comandXLCD(0x01);       //Clear display
  113.     gotoxyXLCD(1,1);
  114.     putrsXLCD("ENT for Start");
  115.     gotoxyXLCD(1,2);
  116.     putrsXLCD("MOV for Menu.");
  117.    
  118.     while(1)
  119.     {
  120.        
  121.     }
  122. }


Miquel_S
Título: Re:Visualizar voltaje en Lcd
Publicado por: elgarbe en 06 de Febrero de 2016, 20:39:21
Bueno, pero ese LCD no parece estar roto!!!
Es el mismo que no funcionaba?

sds.
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 06 de Febrero de 2016, 21:02:28
Si es el mismo LCD lo que pasa es que ahora todo el codigo esta fuera del while

Saludos!
Título: Re:Visualizar voltaje en Lcd
Publicado por: KILLERJC en 06 de Febrero de 2016, 21:09:40
Hace el ejemplo mas corto y pasa el ASM / hex... es rarisimo, Igual el problema sucede cuando se actualiza una y otra ves. Me digno a navegar por el ASM para intentar ver que pasa en el main... ( Mejor si es un dissasembly :3 ). Y hablo del codigo cuando falla
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 06 de Febrero de 2016, 21:42:55
Código: C
  1. /*
  2.  * File:   main.c
  3.  * Author: miquel
  4.  *
  5.  * Created on 31 de enero de 2016, 19:03
  6.  */
  7.  
  8. #include <xc.h>
  9. #include <delays.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include "MyXLCD.h"
  13. #include "word_config.h"
  14. #include <adc.h>
  15.  
  16. #define _XTAL_FREQ 48000000
  17.  
  18. /*
  19.  *
  20.  */
  21.  
  22. void DelayFor18TCY(void)    //Delay 0,00002sec => 20us => 0,02ms
  23. {
  24.     //Delay10TCYx(2);
  25.     Delay10TCYx(24);
  26. }
  27. void DelayPORXLCD(void)     //Delay 0,015sec => 15000us => 15ms
  28. {
  29.     //Delay1KTCYx(15);
  30.     Delay1KTCYx(180);
  31. }
  32. void DelayXLCD(void)        //Delay 0,002sec => 2000us => 2ms
  33. {
  34.     //Delay1KTCYx(60);
  35.     Delay1KTCYx(24);
  36. }
  37.  
  38. void Temp_menu(unsigned char i, unsigned char j)
  39. {
  40.     for(i=0; i<=15; i++)
  41.     {
  42.         for(j=0; j<=i; j++)
  43.         {
  44.             Delay10KTCYx(20);
  45.         }
  46.     }
  47. }
  48. /* Envia comando al LCD */
  49. void comandXLCD(unsigned char a)
  50. {
  51.     BusyXLCD();
  52.     WriteCmdXLCD(a);
  53. }
  54.  
  55. /* Ubica cursor en ( x = Posicion en linea , y = N de linea ) */
  56. void gotoxyXLCD(unsigned char x, unsigned char y)
  57. {
  58.     unsigned char direccion;
  59.  
  60.     if(y != 1)
  61.         direccion = 0x40;
  62.     else
  63.         direccion = 0;
  64.  
  65.     direccion += x-1;
  66.     comandXLCD(0x80 | direccion);
  67. }
  68.  
  69. void main(void)
  70. {
  71.     char cadena_de_texto [10];
  72.     unsigned int valor_adc;
  73.     float voltios;
  74.    
  75.     OpenXLCD(FOUR_BIT & LINES_5X7);     // Iniciamos Lcd
  76.     comandXLCD(0x06);       // Nos aseguramos incremento de direccion, display fijo
  77.     OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_16_TAD,
  78.             ADC_CH0 & ADC_INT_OFF & ADC_REF_VDD_VSS, ADC_0ANA);
  79.     comandXLCD(0x0C);       // Encendemos Lcd
  80.     comandXLCD(0x01);   //Borramos pantalla
  81.    
  82.          while(1)
  83.         {
  84.             SetChanADC(0);  //Seleccionamos canal
  85.             ConvertADC();    //Iniciamos conversion
  86.            
  87.             while(BusyADC()){}    //Esperamos que termine la conversion
  88.             valor_adc = ReadADC();  //Leemos conversion y la guardamos en valor_adc
  89.             voltios = (valor_adc/1024.0)*5.0;   //Convertimos valor ADC
  90.             gotoxyXLCD(1,1);    //Nos posicionamos en el Lcd
  91.             putrsXLCD("Bateria: ");
  92.             sprintf(cadena_de_texto,"%.2f",voltios);    //Visualizamos voltaje en formato float
  93.             putrsXLCD(cadena_de_texto);
  94.             gotoxyXLCD(1,2);
  95.             putrsXLCD("Estado: ");
  96.         }
  97.     }

Código: ASM
  1. !void main(void)
  2. !{
  3. !    char cadena_de_texto [10];
  4. !    unsigned int valor_adc;
  5. !    float voltios;
  6. !    
  7. !    OpenXLCD(FOUR_BIT & LINES_5X7);     // Iniciamos Lcd
  8. 0x1496: MOVLW 0x28
  9. 0x1498: CALL 0x1888, 0
  10. 0x149A: NOP
  11. !    comandXLCD(0x06);       // Nos aseguramos incremento de direccion, display fijo
  12. 0x149C: MOVLW 0x6
  13. 0x149E: CALL 0x1F2C, 0
  14. 0x14A0: NOP
  15. !    OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_16_TAD,
  16. !            ADC_CH0 & ADC_INT_OFF & ADC_REF_VDD_VSS, ADC_0ANA);
  17. 0x14A2: MOVLW 0x4
  18. 0x14A4: MOVWF __pcstackCOMRAM, ACCESS
  19. 0x14A6: SETF dividend, ACCESS
  20. 0x14A8: MOVLW 0xED
  21. 0x14AA: CALL 0x1BD4, 0
  22. 0x14AC: NOP
  23. !    comandXLCD(0x0C);       // Encendemos Lcd
  24. 0x14AE: MOVLW 0xC
  25. 0x14B0: CALL 0x1F2C, 0
  26. 0x14B2: NOP
  27. !    comandXLCD(0x01);   //Borramos pantalla
  28. 0x14B4: MOVLW 0x1
  29. 0x14B6: CALL 0x1F2C, 0
  30. 0x14B8: NOP
  31. !    
  32. !         while(1)
  33. !        {
  34. !            SetChanADC(0);  //Seleccionamos canal
  35. 0x14BA: MOVLW 0x0
  36. 0x14BC: CALL 0x1EE0, 0
  37. 0x14BE: NOP
  38. !            ConvertADC();    //Iniciamos conversion
  39. 0x14C0: CALL 0x1F60, 0
  40. 0x14C2: NOP
  41. !            
  42. !            while(BusyADC()){}    //Esperamos que termine la conversion
  43. 0x14C4: CALL 0x1F4C, 0
  44. 0x14C6: NOP
  45. 0x14C8: IORLW 0x0
  46. 0x14CA: BNZ 0x14C4
  47. !            valor_adc = ReadADC();  //Leemos conversion y la guardamos en valor_adc
  48. 0x14CC: CALL 0x1F42, 0
  49. 0x14CE: NOP
  50. 0x14D0: MOVFF __pcstackCOMRAM, valor_adc
  51. 0x14D2: NOP
  52. 0x14D4: MOVFF dividend, 0x91
  53. 0x14D6: NOP
  54. !            voltios = (valor_adc/1024.0)*5.0;   //Convertimos valor ADC
  55. 0x14D8: CLRF exp1, ACCESS
  56. 0x14DA: MOVLW 0x80
  57. 0x14DC: MOVWF exp1, ACCESS
  58. 0x14DE: MOVLW 0x44
  59. 0x14E0: MOVWF exp, ACCESS
  60. 0x14E2: MOVFF valor_adc, quotient
  61. 0x14E4: NOP
  62. 0x14E6: MOVFF 0x91, quot
  63. 0x14E8: NOP
  64. 0x14EA: CALL 0x1E6A, 0
  65. 0x14EC: NOP
  66. 0x14EE: MOVFF quotient, f1
  67. 0x14F0: NOP
  68. 0x14F2: MOVFF quot, counter
  69. 0x14F4: NOP
  70. 0x14F6: MOVFF quot, cntr
  71. 0x14F8: NOP
  72. 0x14FA: CALL 0x17D4, 0
  73. 0x14FC: NOP
  74. 0x14FE: MOVFF f1, f1
  75. 0x1500: NOP
  76. 0x1502: MOVFF counter, 0x1C
  77. 0x1504: NOP
  78. 0x1506: MOVFF cntr, 0x1D
  79. 0x1508: NOP
  80. 0x150A: CLRF f2, ACCESS
  81. 0x150C: MOVLW 0xA0
  82. 0x150E: MOVWF 0x1F, ACCESS
  83. 0x1510: MOVLW 0x40
  84. 0x1512: MOVWF 0x20, ACCESS
  85. 0x1514: CALL 0x164A, 0
  86. 0x1516: NOP
  87. 0x1518: MOVFF f1, voltios
  88. 0x151A: NOP
  89. 0x151C: MOVFF 0x1C, 0x8E
  90. 0x151E: NOP
  91. 0x1520: MOVFF 0x1D, 0x8F
  92. 0x1522: NOP
  93. !            gotoxyXLCD(1,1);    //Nos posicionamos en el Lcd
  94. 0x1524: MOVLW 0x1
  95. 0x1526: MOVWF f2, ACCESS
  96. 0x1528: CALL 0x1EC6, 0
  97. 0x152A: NOP
  98. !            putrsXLCD("Bateria: ");
  99. 0x152C: MOVLW 0x8
  100. 0x152E: MOVWF f2, ACCESS
  101. 0x1530: MOVLW 0x77
  102. 0x1532: MOVWF multiplicand, ACCESS
  103. 0x1534: CALL 0x1B7A, 0
  104. 0x1536: NOP
  105. !            sprintf(cadena_de_texto,"%.2f",voltios);    //Visualizamos voltaje en formato float
  106. 0x1538: MOVLW 0x8A
  107. 0x153A: MOVWF f, ACCESS
  108. 0x153C: MOVFF voltios, 0x4B
  109. 0x153E: NOP
  110. 0x1540: MOVFF 0x8E, 0x4C
  111. 0x1542: NOP
  112. 0x1544: MOVFF 0x8F, 0x4D
  113. 0x1546: NOP
  114. 0x1548: MOVLB 0x0
  115. 0x154A: MOVLW 0x83
  116. 0x154C: CALL 0x890, 0
  117. 0x154E: NOP
  118. !            putrsXLCD(cadena_de_texto);
  119. 0x1550: CLRF f2, ACCESS
  120. 0x1552: MOVLW 0x83
  121. 0x1554: MOVWF multiplicand, ACCESS
  122. 0x1556: CALL 0x1B7A, 0
  123. 0x1558: NOP
  124. !            gotoxyXLCD(1,2);
  125. 0x155A: MOVLW 0x2
  126. 0x155C: MOVWF f2, ACCESS
  127. 0x155E: MOVLW 0x1
  128. 0x1560: CALL 0x1EC6, 0
  129. 0x1562: NOP
  130. !            putrsXLCD("Estado: ");
  131. 0x1564: MOVLW 0x8

Gracias KILLERJC.
Título: Re:Visualizar voltaje en Lcd
Publicado por: elgarbe en 06 de Febrero de 2016, 21:49:52
En ese codigo que no funciona. Si comentas la escritura en la segunda linea, el programa funciona?
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 06 de Febrero de 2016, 21:54:48
Hola elgarbe comentando las dos ultimas lineas que seria la escritura en la segunda linea del LCD si funciona.

Miquel Servera
Título: Re:Visualizar voltaje en Lcd
Publicado por: elgarbe en 06 de Febrero de 2016, 22:08:10
prueba de escrivir las dos líneas en la primera linea del LCD, con un delay en medio. me explico?

sds.
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 07 de Febrero de 2016, 16:08:08
prueba de escrivir las dos líneas en la primera linea del LCD, con un delay en medio. me explico?

sds.
Hola elgarbe de esta manera si parece funcionar:
Código: C
  1. while(1)
  2.         {
  3.             SetChanADC(0);  //Seleccionamos canal
  4.             ConvertADC();    //Iniciamos conversion
  5.            
  6.             while(BusyADC()){}    //Esperamos que termine la conversion
  7.             valor_adc = ReadADC();  //Leemos conversion y la guardamos en valor_adc
  8.             voltios = (valor_adc/1024.0)*5.0;   //Convertimos valor ADC
  9.             gotoxyXLCD(1,1);    //Nos posicionamos en el Lcd
  10.             putrsXLCD("Bateria: ");
  11.             sprintf(cadena_de_texto,"%.2f",voltios);    //Visualizamos voltaje en formato float
  12.             putrsXLCD(cadena_de_texto);
  13.            
  14.             for(i=0; i<=15; i++)
  15.             {
  16.                 for(j=0; j<=i; j++)
  17.                 {
  18.                     Delay10KTCYx(20);
  19.                 }
  20.             }
  21.             comandXLCD(0x01);
  22.             gotoxyXLCD(1,1);
  23.             putrsXLCD("Estado: ");
  24.            
  25.             for(i=0; i<=15; i++)
  26.             {
  27.                 for(j=0; j<=i; j++)
  28.                 {
  29.                     Delay10KTCYx(20);
  30.                 }
  31.             }
  32.         }
  33.     }

Saludos!
Título: Re:Visualizar voltaje en Lcd
Publicado por: elgarbe en 07 de Febrero de 2016, 16:53:29
Código: C
  1. }
  2.             }
  3.             comandXLCD(0x01);
  4.             gotoxyXLCD(1,1);
  5.             putrsXLCD("Estado: ");

eliminá ese comandXLCD(0x01) y proba.
Si sigue funcionando, prová lo mismo pero escriviendo solo en la línea 2 y nos cuentas.
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 07 de Febrero de 2016, 17:34:15
Código: C
  1. while(1)
  2.         {
  3.             SetChanADC(0);  //Seleccionamos canal
  4.             ConvertADC();    //Iniciamos conversion
  5.            
  6.             while(BusyADC()){}    //Esperamos que termine la conversion
  7.             valor_adc = ReadADC();  //Leemos conversion y la guardamos en valor_adc
  8.             voltios = (valor_adc/1024.0)*5.0;   //Convertimos valor ADC
  9.             gotoxyXLCD(1,2);    //Nos posicionamos en el Lcd
  10.             putrsXLCD("Bateria: ");
  11.             sprintf(cadena_de_texto,"%.2f",voltios);    //Visualizamos voltaje en formato float
  12.             putrsXLCD(cadena_de_texto);
  13.            
  14.             for(i=0; i<=15; i++)
  15.             {
  16.                 for(j=0; j<=i; j++)
  17.                 {
  18.                     Delay10KTCYx(20);
  19.                 }
  20.             }
  21.             //comandXLCD(0x01);
  22.             gotoxyXLCD(1,2);
  23.             putrsXLCD("Estado: ");
  24.            
  25.             for(i=0; i<=15; i++)
  26.             {
  27.                 for(j=0; j<=i; j++)
  28.                 {
  29.                     Delay10KTCYx(20);
  30.                 }
  31.             }
  32.         }
  33.     }
Lo que pasa es que aunque ponga el comandXLCD(0X01) al principio antes de posicionarme en el LCD no se me borra la primera linea.
Título: Re:Visualizar voltaje en Lcd
Publicado por: elgarbe en 07 de Febrero de 2016, 17:47:00
Por que la primer batería lo escrive en la linea 1??
No debería escribir siempre en la linea 2?
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 08 de Febrero de 2016, 03:31:55
Por que la primer batería lo escrive en la linea 1??
No debería escribir siempre en la linea 2?
Eso mismo creo yo, no se porque motivo no se borra la primera linea.

Saludos.
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 09 de Febrero de 2016, 05:31:53
Después de muchas pruebas estoy casi seguro que el problema radica en no poder dejar de escribir en la primera linea del LCD, con eso quiero decir que aunque le digas que escriba en la segunda linea el aparte de escribir en la segunda linea escribe lo mismo en la primera, mi primera opción sera probar de posicionarme en el Lcd sin usar la función
Código: C
  1. gotoxyXLCD()
creada en su día por Suky.
Código: C
  1. /* Ubica cursor en ( x = Posicion en linea , y = N de linea ) */
  2. void gotoxyXLCD(unsigned char x, unsigned char y)
  3. {
  4.     unsigned char direccion;
  5.  
  6.     if(y != 1)
  7.         direccion = 0x40;
  8.     else
  9.         direccion = 0;
  10.  
  11.     direccion += x-1;
  12.     comandXLCD(0x80 | direccion);
  13. }

Miquel_S
Título: Re:Visualizar voltaje en Lcd
Publicado por: elgarbe en 09 de Febrero de 2016, 11:28:20
y si cambias de LCD, esas mismas instrucciones hacen que otro LCD no escriba en la línea 1?
que micro estás usando?
podrías poner el código completo, con los fuses y todo lo necesario del programa que funciona bien unos segundos y luego se muere?

cuales son los LCD que tenes?

saludos
Título: Re:Visualizar voltaje en Lcd
Publicado por: Miquel_S en 15 de Febrero de 2016, 19:07:05
Perdón elgarbe por no haber contestado antes pero estaba probando cosas, tengo dos LCD's iguales los cuales pongo la foto y funcionan correctamente siempre y cuando sea mensaje fijo y fuera del while, el PIC que estoy usando es el 18F2550, luego tengo otro ya muy viejo y para colmo lo desmonte para limpiarlo y ahora apenas se ve los mensajes y este con el mismo código que no funciona el los anteriores LCD's en este funciona correctamente, esto me da a entender que lo que debe de estar pasando esta relacionado con los delay's de las librerías pero no consigo ver donde esta fallando.
Nota: El otro LCD que estoy usando que es el que funciona es el modelo WM-C1602M

(http://www.todopic.com.ar/foros/imgtiny/hwjn6b.png)

Gracias.