Autor Tema: Configuración LCD  (Leído 2203 veces)

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

Desconectado freshdesing

  • Colaborador
  • PIC12
  • *****
  • Mensajes: 88
Configuración LCD
« en: 04 de Noviembre de 2009, 15:32:30 »
Hola he estado probando varias librerias de LCD pero no me funcionan, el LCD no se enciende. Está todo bien conectado, ya que con otro micro programado en CSS fuciona el hardware correctamente. También he probado algunos ejemplos de C18, pero quizás sea que tenga algún fuse mal configrado. Mi programa es el siguiente:

Código: C
  1. //*** ESCRIBIR LCD      ***
  2.  
  3. #include <p18f2550.h>
  4. #include <delays.h>
  5. #include <stdio.h>
  6. #include "xlcd.h"
  7.  
  8.  
  9. #pragma config FOSC = XT_XT,FCMEN = OFF,IESO = OFF, PLLDIV = 2, CPUDIV = OSC1_PLL2//CONFIG1H
  10. #pragma config PWRT = ON,BOR = OFF,BORV = 0 //CONFIG2L
  11. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  12. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = ON//CONFIG3H
  13. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  14. #pragma config CP0 = ON,CP1 = ON,CP2 = ON, CP3 = ON//CONFIG5L
  15. #pragma config CPB = ON,CPD = ON//CONFIG5H
  16. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON,WRT3 = ON//CONFIG6L
  17. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  18. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON,EBTR3 = ON//CONFIG7L
  19. #pragma config EBTRB = ON//CONFIG7H
  20.  
  21.  
  22.  
  23. void DelayFor18TCY(void) /*provides a 18 Tcy delay */
  24.         {
  25.         Delay10TCYx(2);         //20 cycles
  26.         return;
  27.         }
  28. void DelayPORXLCD(void) /*provides at least 15ms delay */
  29.         {
  30.         Delay1KTCYx(30);        //Cycles=(TimeDelay * Fosc)/4
  31.                                                 //Cycles=(15ms * 8Mhz)/4
  32.                                                 //Cycles=30.000
  33.         return;
  34.         }
  35. void DelayXLCD(void)    /*provides at least 5ms delay */
  36.         {
  37.         Delay1KTCYx(10);                //Cycles=(TimeDelay * Fosc)/4
  38.                                                 //Cycles=(5ms * 8Mhz)/4
  39.                                                 //Cycles=10.000
  40.         return;
  41.         }
  42.  
  43.  
  44. // Envia comando al LCD
  45.  void comandXLCD(unsigned char a){
  46. BusyXLCD();
  47. WriteCmdXLCD(a);
  48.  }
  49.  // Ubica cursor en (x = Posicion en linea, y = nº de linea)
  50. void gotoxyXLCD(unsigned char x, unsigned char y){
  51. unsigned char direccion;
  52.  if(y != 1)
  53.  direccion = 0x40;
  54.  else direccion=0;
  55.  direccion += x-1;
  56.  comandXLCD(0x80 | direccion);
  57.  }
  58.  
  59.  
  60. void main(void){
  61. OpenXLCD(FOUR_BIT & LINES_5X7); // Iniciamos LCD.-
  62. comandXLCD(0x0C); // Encendemos LCD.-
  63. putrsXLCD("Probando LCD");
  64. gotoxyXLCD(1,2); //Pasamos al oriden del Linea 2.-
  65. putrsXLCD("Por Suky");
  66. while(1){ // Bucle infinito.
  67. }
  68. }

Adjunto una imagen con los ficheros del proyecto.

Estoy utilizando un Xtal de 8Mhz.

Agradecería que alguien me ayudara, ya que le he dado muchas vueltas y creo que no es cuestión de algo que no estoy mirando.

Gracias de antemano.

Desconectado freshdesing

  • Colaborador
  • PIC12
  • *****
  • Mensajes: 88
Re: Configuración LCD
« Respuesta #1 en: 10 de Noviembre de 2009, 12:38:08 »
Solucionado....
Siento no saber el porqué pero ya está solucionado. Aquí el programa que me ha funcionado por si alguien lo necesita.
Está sacado de "MPLAB C18 desde 0", por Suky  www.ucontrol.com.ar  y de "encaminando C", por navaismo http://encaminandoc.blogspot.com/. Gracias a ambos.

LCD18F2550PORTB.c
Código: C
  1. #include <p18f2550.h>
  2. #include <delays.h>
  3. #include <lcd.h>
  4. #include <stdlib.h>
  5.  
  6. #pragma config FOSC = XT_XT,FCMEN = OFF,IESO = OFF, CPUDIV = OSC1_PLL2
  7. #pragma config PWRT = ON,BOR = OFF,BORV = 0
  8. #pragma config WDT = OFF,WDTPS = 32768
  9. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = OFF
  10. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF
  11. #pragma config CP0 = ON,CP1 = ON,CP2 = ON
  12. #pragma config CPB = ON,CPD = ON
  13. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON
  14. #pragma config WRTB = ON,WRTC = ON,WRTD = ON
  15. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON
  16. #pragma config EBTRB = ON
  17.  
  18. char aaa[]="Hello";
  19. char bbb[]="Microchip";
  20.  
  21.  
  22. void DelayFor18TCY(void){
  23.         Delay10TCYx(2);
  24. }
  25. void DelayPORXLCD(void){
  26.         Delay1KTCYx(15);
  27. }
  28. void DelayXLCD(void){
  29.         Delay1KTCYx(2);
  30. }
  31.  
  32. // Envia comando al LCD
  33. void comandXLCD(unsigned char a){
  34.         BusyXLCD();            
  35.         WriteCmdXLCD(a);
  36. }
  37.  
  38.  
  39. // Escribir Strings en el LCD
  40. void WriteLCD( char txt[16], char num[5])
  41. {
  42. putrsXLCD(txt);                 //Mostramos mensaje en LCD
  43. putsXLCD(num);                  //Enviamos cadena de enteros
  44. }
  45.  
  46.  
  47. // Ubica cursor en (x = Posicion en linea, y = nº de linea)
  48. void gotoxyXLCD(unsigned char x, unsigned char y){
  49.         unsigned char direccion;
  50.  
  51.         if(y != 1)
  52.                 direccion = 0x40;
  53.         else
  54.                 direccion=0;
  55.        
  56.         direccion += x-1;
  57.         comandXLCD(0x80 | direccion);
  58. }
  59.  
  60. void main(void){
  61.         int num=101;
  62.         char nums;              //numeo en cadena
  63.         itoa(num,nums);
  64.  
  65.         OpenXLCD(FOUR_BIT & LINES_5X7); // Iniciamos LCD.-
  66.     comandXLCD(0x0C);
  67.         comandXLCD(0x06); // Nos aseguramos incremento de direccion, display fijo
  68.                                 // Encendemos LCD.-
  69.        
  70.         putsXLCD(aaa);
  71.         putsXLCD(bbb);
  72.         gotoxyXLCD(1,2);                        //Pasamos al oriden del Linea 2.-
  73.         putrsXLCD("hello");
  74.         comandXLCD(DON);
  75.         Delay1KTCYx(200);
  76.         comandXLCD(CLEAR);
  77.         WriteLCD("el número es:",nums);
  78.         while(1){                               // Bucle infinito.
  79.         }
  80. }

lcd.h

Código: C
  1. #ifndef __XLCD_H
  2. #define __XLCD_H
  3.  
  4. /* PIC18 XLCD peripheral routines.
  5.  *
  6.  *   Notes:
  7.  *      - These libraries routines are written to support the
  8.  *        Hitachi HD44780 LCD controller.
  9.  *      - The user must define the following items:
  10.  *          - The LCD interface type (4- or 8-bits)
  11.  *          - If 4-bit mode
  12.  *              - whether using the upper or lower nibble
  13.  *          - The data port
  14.  *              - The tris register for data port
  15.  *              - The control signal ports and pins
  16.  *              - The control signal port tris and pins
  17.  *          - The user must provide three delay routines:
  18.  *              - DelayFor18TCY() provides a 18 Tcy delay
  19.  *              - DelayPORXLCD() provides at least 15ms delay
  20.  *              - DelayXLCD() provides at least 5ms delay
  21.  */
  22.  
  23. /* Interface type 8-bit or 4-bit
  24.  * For 8-bit operation uncomment the #define BIT8
  25.  */
  26. /* #define BIT8 */
  27.  
  28. /* When in 4-bit interface define if the data is in the upper
  29.  * or lower nibble.  For lower nibble, comment the #define UPPER
  30.  */
  31. //#define UPPER
  32.  
  33. /* DATA_PORT defines the port to which the LCD data lines are connected */
  34. #define DATA_PORT      PORTB
  35. #define TRIS_DATA_PORT TRISB
  36.  
  37. /* CTRL_PORT defines the port where the control lines are connected.
  38.  * These are just samples, change to match your application.
  39.  */
  40. #define RW_PIN   PORTBbits.RB6   /* PORT for RW */
  41. #define TRIS_RW  DDRBbits.RB6    /* TRIS for RW */
  42. #define RS_PIN   PORTBbits.RB5   /* PORT for RS */
  43. #define TRIS_RS  DDRBbits.RB5    /* TRIS for RS */
  44. #define E_PIN    PORTBbits.RB4   /* PORT for E  */
  45. #define TRIS_E   DDRBbits.RB4    /* TRIS for E  */
  46.  
  47. /* Display ON/OFF Control defines */
  48. #define DON         0b00001111  /* Display on      */
  49. #define DOFF        0b00001011  /* Display off     */
  50. #define CURSOR_ON   0b00001111  /* Cursor on       */
  51. #define CURSOR_OFF  0b00001101  /* Cursor off      */
  52. #define BLINK_ON    0b00001111  /* Cursor Blink    */
  53. #define BLINK_OFF   0b00001110  /* Cursor No Blink */
  54.  
  55. /* Cursor or Display Shift defines */
  56. #define SHIFT_CUR_LEFT    0b00010011  /* Cursor shifts to the left   */
  57. #define SHIFT_CUR_RIGHT   0b00010111  /* Cursor shifts to the right  */
  58. #define SHIFT_DISP_LEFT   0b00011011  /* Display shifts to the left  */
  59. #define SHIFT_DISP_RIGHT  0b00011111  /* Display shifts to the right */
  60.  
  61.  
  62. /*Funciones*/
  63. #define CLEAR   0x01  /*Borra el display*/
  64.  
  65. /* Function Set defines */
  66. #define FOUR_BIT   0b00101111  /* 4-bit Interface               */
  67. #define EIGHT_BIT  0b00111111  /* 8-bit Interface               */
  68. #define LINE_5X7   0b00110011  /* 5x7 characters, single line   */
  69. #define LINE_5X10  0b00110111  /* 5x10 characters               */
  70. #define LINES_5X7  0b00111011  /* 5x7 characters, multiple line */
  71.  
  72. #define PARAM_SCLASS auto
  73. #define MEM_MODEL far  /* Change this to near for small memory model */
  74.  
  75. /* OpenXLCD
  76.  * Configures I/O pins for external LCD
  77.  */
  78. void OpenXLCD(unsigned char lcdtype);
  79.  
  80. /* SetCGRamAddr
  81.  * Sets the character generator address
  82.  */
  83. void SetCGRamAddr(unsigned char CGaddr);
  84.  
  85. /* SetDDRamAddr
  86.  * Sets the display data address
  87.  */
  88. void SetDDRamAddr(unsigned char DDaddr);
  89.  
  90. /* BusyXLCD
  91.  * Returns the busy status of the LCD
  92.  */
  93. unsigned char BusyXLCD(void);
  94.  
  95. /* ReadAddrXLCD
  96.  * Reads the current address
  97.  */
  98. unsigned char ReadAddrXLCD(void);
  99.  
  100. /* ReadDataXLCD
  101.  * Reads a byte of data
  102.  */
  103. char ReadDataXLCD(void);
  104.  
  105. /* WriteCmdXLCD
  106.  * Writes a command to the LCD
  107.  */
  108. void WriteCmdXLCD(unsigned char cmd);
  109.  
  110. /* WriteDataXLCD
  111.  * Writes a data byte to the LCD
  112.  */
  113. void WriteDataXLCD(char data);
  114.  
  115. /* putcXLCD
  116.  * A putc is a write
  117.  */
  118. #define putcXLCD WriteDataXLCD
  119.  
  120. /* putsXLCD
  121.  * Writes a string of characters to the LCD
  122.  */
  123. void putsXLCD(char *buffer);
  124.  
  125. /* putrsXLCD
  126.  * Writes a string of characters in ROM to the LCD
  127.  */
  128. void putrsXLCD(const rom char *buffer);
  129.  
  130. /* User defines these routines according to the oscillator frequency */
  131. extern void DelayFor18TCY(void);
  132. extern void DelayPORXLCD(void);
  133. extern void DelayXLCD(void);
  134.  
  135. /********************************************************************
  136. *       Function Name:  OpenXLCD                                    *
  137. *       Return Value:   void                                        *
  138. *       Parameters:     lcdtype: sets the type of LCD (lines)       *
  139. *       Description:    This routine configures the LCD. Based on   *
  140. *                       the Hitachi HD44780 LCD controller. The     *
  141. *                       routine will configure the I/O pins of the  *
  142. *                       microcontroller, setup the LCD for 4- or    *
  143. *                       8-bit mode and clear the display. The user  *
  144. *                       must provide three delay routines:          *
  145. *                       DelayFor18TCY() provides a 18 Tcy delay     *
  146. *                       DelayPORXLCD() provides at least 15ms delay *
  147. *                       DelayXLCD() provides at least 5ms delay     *
  148. ********************************************************************/
  149.  
  150. void OpenXLCD(unsigned char lcdtype)
  151. {
  152.         // The data bits must be either a 8-bit port or the upper or
  153.         // lower 4-bits of a port. These pins are made into inputs
  154. #ifdef BIT8                             // 8-bit mode, use whole port
  155.         DATA_PORT = 0;
  156.         TRIS_DATA_PORT = 0xff;
  157. #else                                   // 4-bit mode
  158. #ifdef UPPER                            // Upper 4-bits of the port
  159.         DATA_PORT &= 0x0f;
  160.         TRIS_DATA_PORT |= 0xf0;
  161. #else                                   // Lower 4-bits of the port
  162.         DATA_PORT &= 0xf0;
  163.         TRIS_DATA_PORT |= 0x0f;
  164. #endif
  165. #endif
  166.         TRIS_RW = 0;                    // All control signals made outputs
  167.         TRIS_RS = 0;
  168.         TRIS_E = 0;
  169.         RW_PIN = 0;                     // R/W pin made low
  170.         RS_PIN = 0;                     // Register select pin made low
  171.         E_PIN = 0;                      // Clock pin made low
  172.  
  173.         // Delay for 15ms to allow for LCD Power on reset
  174.         DelayPORXLCD();
  175.        
  176.         // Setup interface to LCD
  177. #ifdef BIT8                             // 8-bit mode interface
  178.         TRIS_DATA_PORT = 0;             // Data port output
  179.         DATA_PORT = 0b00110000;         // Function set cmd(8-bit interface)
  180. #else                                   // 4-bit mode interface
  181. #ifdef UPPER                            // Upper nibble interface
  182.         TRIS_DATA_PORT &= 0x0f;
  183.         DATA_PORT &= 0x0f;
  184.         DATA_PORT |= 0b00100000;        // Function set cmd(4-bit interface)
  185. #else                                   // Lower nibble interface
  186.         TRIS_DATA_PORT &= 0xf0;
  187.         DATA_PORT &= 0xf0;
  188.         DATA_PORT |= 0b00000010;        // Function set cmd(4-bit interface)
  189. #endif
  190. #endif
  191.         E_PIN = 1;                      // Clock the cmd in
  192.         DelayFor18TCY();
  193.         E_PIN = 0;
  194.        
  195.         // Delay for at least 4.1ms
  196.         DelayXLCD();
  197.  
  198.         // Setup interface to LCD
  199. #ifdef BIT8                             // 8-bit interface
  200.         DATA_PORT = 0b00110000;         // Function set cmd(8-bit interface)
  201. #else                                   // 4-bit interface
  202. #ifdef UPPER                            // Upper nibble interface
  203.         DATA_PORT &= 0x0f;              // Function set cmd(4-bit interface)
  204.         DATA_PORT |= 0b00100000;
  205. #else                                   // Lower nibble interface
  206.         DATA_PORT &= 0xf0;              // Function set cmd(4-bit interface)
  207.         DATA_PORT |= 0b00000010;
  208. #endif
  209. #endif
  210.         E_PIN = 1;                      // Clock the cmd in
  211.         DelayFor18TCY();
  212.         E_PIN = 0;
  213.  
  214.         // Delay for at least 100us
  215.         DelayXLCD();
  216.  
  217.         // Setup interface to LCD
  218. #ifdef BIT8                             // 8-bit interface
  219.         DATA_PORT = 0b00110000;         // Function set cmd(8-bit interface)
  220. #else                                   // 4-bit interface
  221. #ifdef UPPER                            // Upper nibble interface
  222.         DATA_PORT &= 0x0f;              // Function set cmd(4-bit interface)
  223.         DATA_PORT |= 0b00100000;
  224. #else                                   // Lower nibble interface
  225.         DATA_PORT &= 0xf0;              // Function set cmd(4-bit interface)
  226.         DATA_PORT |= 0b00000010;
  227. #endif
  228. #endif
  229.         E_PIN = 1;                      // Clock cmd in
  230.         DelayFor18TCY();
  231.         E_PIN = 0;
  232.  
  233. #ifdef BIT8                             // 8-bit interface
  234.         TRIS_DATA_PORT = 0xff;          // Make data port input
  235. #else                                   // 4-bit interface
  236. #ifdef UPPER                            // Upper nibble interface
  237.         TRIS_DATA_PORT |= 0xf0;         // Make data nibble input
  238. #else                                   // Lower nibble interface
  239.         TRIS_DATA_PORT |= 0x0f;         // Make data nibble input
  240. #endif
  241. #endif
  242.  
  243.         // Set data interface width, # lines, font
  244.         while(BusyXLCD());              // Wait if LCD busy
  245.         WriteCmdXLCD(lcdtype);          // Function set cmd
  246.  
  247.         // Turn the display on then off
  248.         while(BusyXLCD());              // Wait if LCD busy
  249.         WriteCmdXLCD(DOFF&CURSOR_OFF&BLINK_OFF);        // Display OFF/Blink OFF
  250.         while(BusyXLCD());              // Wait if LCD busy
  251.         WriteCmdXLCD(DON&CURSOR_ON&BLINK_ON);           // Display ON/Blink ON
  252.  
  253.         // Clear display
  254.         while(BusyXLCD());              // Wait if LCD busy
  255.         WriteCmdXLCD(0x01);             // Clear display
  256.  
  257.         // Set entry mode inc, no shift
  258.         while(BusyXLCD());              // Wait if LCD busy
  259.         WriteCmdXLCD(SHIFT_CUR_LEFT);   // Entry Mode
  260.  
  261.         // Set DD Ram address to 0
  262.         while(BusyXLCD());              // Wait if LCD busy
  263.         SetDDRamAddr(0);                // Set Display data ram address to 0
  264.  
  265.         return;
  266. }
  267.  
  268. /********************************************************************
  269. *       Function Name:  BusyXLCD                                    *
  270. *       Return Value:   char: busy status of LCD controller         *
  271. *       Parameters:     void                                        *
  272. *       Description:    This routine reads the busy status of the   *
  273. *                       Hitachi HD44780 LCD controller.             *
  274. ********************************************************************/
  275. unsigned char BusyXLCD(void)
  276. {
  277.         RW_PIN = 1;                     // Set the control bits for read
  278.         RS_PIN = 0;
  279.         DelayFor18TCY();
  280.         E_PIN = 1;                      // Clock in the command
  281.         DelayFor18TCY();
  282. #ifdef BIT8                             // 8-bit interface
  283.         if(DATA_PORT&0x80)                      // Read bit 7 (busy bit)
  284.         {                               // If high
  285.                 E_PIN = 0;              // Reset clock line
  286.                 RW_PIN = 0;             // Reset control line
  287.                 return 1;               // Return TRUE
  288.         }
  289.         else                            // Bit 7 low
  290.         {
  291.                 E_PIN = 0;              // Reset clock line
  292.                 RW_PIN = 0;             // Reset control line
  293.                 return 0;               // Return FALSE
  294.         }
  295. #else                                   // 4-bit interface
  296. #ifdef UPPER                            // Upper nibble interface
  297.         if(DATA_PORT&0x80)
  298. #else                                   // Lower nibble interface
  299.         if(DATA_PORT&0x08)
  300. #endif
  301.         {
  302.                 E_PIN = 0;              // Reset clock line
  303.                 DelayFor18TCY();
  304.                 E_PIN = 1;              // Clock out other nibble
  305.                 DelayFor18TCY();
  306.                 E_PIN = 0;
  307.                 RW_PIN = 0;             // Reset control line
  308.                 return 1;               // Return TRUE
  309.         }
  310.         else                            // Busy bit is low
  311.         {
  312.                 E_PIN = 0;              // Reset clock line
  313.                 DelayFor18TCY();
  314.                 E_PIN = 1;              // Clock out other nibble
  315.                 DelayFor18TCY();
  316.                 E_PIN = 0;
  317.                 RW_PIN = 0;             // Reset control line
  318.                 return 0;               // Return FALSE
  319.         }
  320. #endif
  321. }
  322.  
  323. /********************************************************************
  324. *       Function Name:  putrsXLCD
  325. *       Return Value:   void
  326. *       Parameters:     buffer: pointer to string
  327. *       Description:    This routine writes a string of bytes to the
  328. *                       Hitachi HD44780 LCD controller. The user
  329. *                       must check to see if the LCD controller is
  330. *                       busy before calling this routine. The data
  331. *                       is written to the character generator RAM or
  332. *                       the display data RAM depending on what the
  333. *                       previous SetxxRamAddr routine was called.
  334. ********************************************************************/
  335. void putrsXLCD(const rom char *buffer)
  336. {
  337.         while(*buffer)                  // Write data to LCD up to null
  338.         {
  339.                 while(BusyXLCD());      // Wait while LCD is busy
  340.                 WriteDataXLCD(*buffer); // Write character to LCD
  341.                 buffer++;               // Increment buffer
  342.         }
  343.         return;
  344. }
  345.  
  346. /********************************************************************
  347. *       Function Name:  putsXLCD
  348. *       Return Value:   void
  349. *       Parameters:     buffer: pointer to string
  350. *       Description:    This routine writes a string of bytes to the
  351. *                       Hitachi HD44780 LCD controller. The user
  352. *                       must check to see if the LCD controller is
  353. *                       busy before calling this routine. The data
  354. *                       is written to the character generator RAM or
  355. *                       the display data RAM depending on what the
  356. *                       previous SetxxRamAddr routine was called.
  357. ********************************************************************/
  358. void putsXLCD(char *buffer)
  359. {
  360.         while(*buffer)                  // Write data to LCD up to null
  361.         {
  362.                 while(BusyXLCD());      // Wait while LCD is busy
  363.                 WriteDataXLCD(*buffer); // Write character to LCD
  364.                 buffer++;               // Increment buffer
  365.         }
  366.         return;
  367. }
  368.  
  369. /*********************************************************************
  370. *       Function Name:  ReadAddrXLCD                                 *
  371. *       Return Value:   char: address from LCD controller            *
  372. *       Parameters:     void                                         *
  373. *       Description:    This routine reads an address byte from the  *
  374. *                       Hitachi HD44780 LCD controller. The user     *
  375. *                       must check to see if the LCD controller is   *
  376. *                       busy before calling this routine. The address*
  377. *                       is read from the character generator RAM or  *
  378. *                       the display data RAM depending on what the   *
  379. *                       previous SetxxRamAddr routine was called.    *
  380. *********************************************************************/
  381. unsigned char ReadAddrXLCD(void)
  382. {
  383.         char data;                      // Holds the data retrieved from the LCD
  384.  
  385. #ifdef BIT8                             // 8-bit interface
  386.         RW_PIN = 1;                     // Set control bits for the read
  387.         RS_PIN = 0;
  388.         DelayFor18TCY();
  389.         E_PIN = 1;                      // Clock data out of the LCD controller
  390.         DelayFor18TCY();
  391.         data = DATA_PORT;               // Save the data in the register
  392.         E_PIN = 0;
  393.         RW_PIN = 0;                     // Reset the control bits
  394. #else                                   // 4-bit interface
  395.         RW_PIN = 1;                     // Set control bits for the read
  396.         RS_PIN = 0;
  397.         DelayFor18TCY();
  398.         E_PIN = 1;                      // Clock data out of the LCD controller
  399.         DelayFor18TCY();
  400. #ifdef UPPER                            // Upper nibble interface
  401.         data = DATA_PORT&0xf0;          // Read the nibble into the upper nibble of data
  402. #else                                   // Lower nibble interface
  403.         data = (DATA_PORT<<4)&0xf0;     // Read the nibble into the upper nibble of data
  404. #endif
  405.         E_PIN = 0;                      // Reset the clock
  406.         DelayFor18TCY();
  407.         E_PIN = 1;                      // Clock out the lower nibble
  408.         DelayFor18TCY();
  409. #ifdef UPPER                            // Upper nibble interface
  410.         data |= (DATA_PORT>>4)&0x0f;    // Read the nibble into the lower nibble of data
  411. #else                                   // Lower nibble interface
  412.         data |= DATA_PORT&0x0f;         // Read the nibble into the lower nibble of data
  413. #endif
  414.         E_PIN = 0;
  415.         RW_PIN = 0;                     // Reset the control lines
  416. #endif
  417.         return (data&0x7f);             // Return the address, Mask off the busy bit
  418. }
  419.  
  420. /********************************************************************
  421. *       Function Name:  ReadDataXLCD                                *
  422. *       Return Value:   char: data byte from LCD controller         *
  423. *       Parameters:     void                                        *
  424. *       Description:    This routine reads a data byte from the     *
  425. *                       Hitachi HD44780 LCD controller. The user    *
  426. *                       must check to see if the LCD controller is  *
  427. *                       busy before calling this routine. The data  *
  428. *                       is read from the character generator RAM or *
  429. *                       the display data RAM depending on what the  *
  430. *                       previous SetxxRamAddr routine was called.   *
  431. ********************************************************************/
  432. char ReadDataXLCD(void)
  433. {
  434.         char data;
  435.  
  436. #ifdef BIT8                             // 8-bit interface
  437.         RS_PIN = 1;                     // Set the control bits
  438.         RW_PIN = 1;
  439.         DelayFor18TCY();
  440.         E_PIN = 1;                      // Clock the data out of the LCD
  441.         DelayFor18TCY();
  442.         data = DATA_PORT;               // Read the data
  443.         E_PIN = 0;
  444.         RS_PIN = 0;                     // Reset the control bits
  445.         RW_PIN = 0;
  446. #else                                   // 4-bit interface
  447.         RW_PIN = 1;
  448.         RS_PIN = 1;
  449.         DelayFor18TCY();
  450.         E_PIN = 1;                      // Clock the data out of the LCD
  451.         DelayFor18TCY();
  452. #ifdef UPPER                            // Upper nibble interface
  453.         data = DATA_PORT&0xf0;          // Read the upper nibble of data
  454. #else                                   // Lower nibble interface
  455.         data = (DATA_PORT<<4)&0xf0;     // read the upper nibble of data
  456. #endif
  457.         E_PIN = 0;                      // Reset the clock line
  458.         DelayFor18TCY();
  459.         E_PIN = 1;                      // Clock the next nibble out of the LCD
  460.         DelayFor18TCY();
  461. #ifdef UPPER                            // Upper nibble interface
  462.         data |= (DATA_PORT>>4)&0x0f;    // Read the lower nibble of data
  463. #else                                   // Lower nibble interface
  464.         data |= DATA_PORT&0x0f;         // Read the lower nibble of data
  465. #endif
  466.         E_PIN = 0;                                      
  467.         RS_PIN = 0;                     // Reset the control bits
  468.         RW_PIN = 0;
  469. #endif
  470.         return(data);                   // Return the data byte
  471. }
  472.  
  473. /********************************************************************
  474. *       Function Name:  SetCGRamAddr                                *
  475. *       Return Value:   void                                        *
  476. *       Parameters:     CGaddr: character generator ram address     *
  477. *       Description:    This routine sets the character generator   *
  478. *                       address of the Hitachi HD44780 LCD          *
  479. *                       controller. The user must check to see if   *
  480. *                       the LCD controller is busy before calling   *
  481. *                       this routine.                               *
  482. ********************************************************************/
  483. void SetCGRamAddr(unsigned char CGaddr)
  484. {
  485. #ifdef BIT8                                     // 8-bit interface
  486.         TRIS_DATA_PORT = 0;                     // Make data port ouput
  487.         DATA_PORT = CGaddr | 0b01000000;        // Write cmd and address to port
  488.         RW_PIN = 0;                             // Set control signals
  489.         RS_PIN = 0;
  490.         DelayFor18TCY();
  491.         E_PIN = 1;                              // Clock cmd and address in
  492.         DelayFor18TCY();
  493.         E_PIN = 0;
  494.         DelayFor18TCY();
  495.         TRIS_DATA_PORT = 0xff;                  // Make data port inputs
  496. #else                                           // 4-bit interface
  497. #ifdef UPPER                                    // Upper nibble interface
  498.         TRIS_DATA_PORT &= 0x0f;                 // Make nibble input
  499.         DATA_PORT &= 0x0f;                      // and write upper nibble
  500.         DATA_PORT |= ((CGaddr | 0b01000000) & 0xf0);
  501. #else                                           // Lower nibble interface
  502.         TRIS_DATA_PORT &= 0xf0;                 // Make nibble input
  503.         DATA_PORT &= 0xf0;                      // and write upper nibble
  504.         DATA_PORT |= (((CGaddr |0b01000000)>>4) & 0x0f);
  505. #endif
  506.         RW_PIN = 0;                             // Set control signals
  507.         RS_PIN = 0;
  508.         DelayFor18TCY();
  509.         E_PIN = 1;                              // Clock cmd and address in
  510.         DelayFor18TCY();
  511.         E_PIN = 0;
  512. #ifdef UPPER                                    // Upper nibble interface
  513.         DATA_PORT &= 0x0f;                      // Write lower nibble
  514.         DATA_PORT |= ((CGaddr<<4)&0xf0);
  515. #else                                           // Lower nibble interface
  516.         DATA_PORT &= 0xf0;                      // Write lower nibble
  517.         DATA_PORT |= (CGaddr&0x0f);
  518. #endif
  519.         DelayFor18TCY();
  520.         E_PIN = 1;                              // Clock cmd and address in
  521.         DelayFor18TCY();
  522.         E_PIN = 0;
  523. #ifdef UPPER                                    // Upper nibble interface
  524.         TRIS_DATA_PORT |= 0xf0;                 // Make inputs
  525. #else                                           // Lower nibble interface
  526.         TRIS_DATA_PORT |= 0x0f;                 // Make inputs
  527. #endif
  528. #endif
  529.         return;
  530. }
  531.  
  532. /********************************************************************
  533. *       Function Name:  SetDDRamAddr                                *
  534. *       Return Value:   void                                        *
  535. *       Parameters:     CGaddr: display data address                *
  536. *       Description:    This routine sets the display data address  *
  537. *                       of the Hitachi HD44780 LCD controller. The  *
  538. *                       user must check to see if the LCD controller*
  539. *                       is busy before calling this routine.        *
  540. ********************************************************************/
  541. void SetDDRamAddr(unsigned char DDaddr)
  542. {
  543. #ifdef BIT8                                     // 8-bit interface
  544.         TRIS_DATA_PORT = 0;                     // Make port output
  545.         DATA_PORT = DDaddr | 0b10000000;        // Write cmd and address to port
  546.         RW_PIN = 0;                             // Set the control bits
  547.         RS_PIN = 0;
  548.         DelayFor18TCY();
  549.         E_PIN = 1;                              // Clock the cmd and address in
  550.         DelayFor18TCY();
  551.         E_PIN = 0;
  552.         DelayFor18TCY();
  553.         TRIS_DATA_PORT = 0xff;                  // Make port input
  554. #else                                           // 4-bit interface
  555. #ifdef UPPER                                    // Upper nibble  interface
  556.         TRIS_DATA_PORT &= 0x0f;                 // Make port output
  557.         DATA_PORT &= 0x0f;                      // and write upper nibble
  558.         DATA_PORT |= ((DDaddr | 0b10000000) & 0xf0);
  559. #else                                           // Lower nibble interface
  560.         TRIS_DATA_PORT &= 0xf0;                 // Make port output
  561.         DATA_PORT &= 0xf0;                      // and write upper nibble
  562.         DATA_PORT |= (((DDaddr | 0b10000000)>>4) & 0x0f);
  563. #endif
  564.         RW_PIN = 0;                             // Set control bits
  565.         RS_PIN = 0;
  566.         DelayFor18TCY();
  567.         E_PIN = 1;                              // Clock the cmd and address in
  568.         DelayFor18TCY();
  569.         E_PIN = 0;
  570. #ifdef UPPER                                    // Upper nibble interface
  571.         DATA_PORT &= 0x0f;                      // Write lower nibble
  572.         DATA_PORT |= ((DDaddr<<4)&0xf0);
  573. #else                                           // Lower nibble interface
  574.         DATA_PORT &= 0xf0;                      // Write lower nibble
  575.         DATA_PORT |= (DDaddr&0x0f);
  576. #endif
  577.         DelayFor18TCY();
  578.         E_PIN = 1;                              // Clock the cmd and address in
  579.         DelayFor18TCY();
  580.         E_PIN = 0;
  581. #ifdef UPPER                                    // Upper nibble interface
  582.         TRIS_DATA_PORT |= 0xf0;                 // Make port input
  583. #else                                           // Lower nibble interface
  584.         TRIS_DATA_PORT |= 0x0f;                 // Make port input
  585. #endif
  586. #endif
  587.         return;
  588. }
  589.  
  590. /********************************************************************
  591. *       Function Name:  WriteCmdXLCD                                *
  592. *       Return Value:   void                                        *
  593. *       Parameters:     cmd: command to send to LCD                 *
  594. *       Description:    This routine writes a command to the Hitachi*
  595. *                       HD44780 LCD controller. The user must check *
  596. *                       to see if the LCD controller is busy before *
  597. *                       calling this routine.                       *
  598. ********************************************************************/
  599. void WriteCmdXLCD(unsigned char cmd)
  600. {
  601. #ifdef BIT8                             // 8-bit interface
  602.         TRIS_DATA_PORT = 0;             // Data port output
  603.         DATA_PORT = cmd;                // Write command to data port
  604.         RW_PIN = 0;                     // Set the control signals
  605.         RS_PIN = 0;                     // for sending a command
  606.         DelayFor18TCY();
  607.         E_PIN = 1;                      // Clock the command in
  608.         DelayFor18TCY();
  609.         E_PIN = 0;
  610.         DelayFor18TCY();
  611.         TRIS_DATA_PORT = 0xff;          // Data port input
  612. #else                                   // 4-bit interface
  613. #ifdef UPPER                            // Upper nibble interface
  614.         TRIS_DATA_PORT &= 0x0f;
  615.         DATA_PORT &= 0x0f;
  616.         DATA_PORT |= cmd&0xf0;
  617. #else                                   // Lower nibble interface
  618.         TRIS_DATA_PORT &= 0xf0;
  619.         DATA_PORT &= 0xf0;
  620.         DATA_PORT |= (cmd>>4)&0x0f;
  621. #endif
  622.         RW_PIN = 0;                     // Set control signals for command
  623.         RS_PIN = 0;
  624.         DelayFor18TCY();
  625.         E_PIN = 1;                      // Clock command in
  626.         DelayFor18TCY();
  627.         E_PIN = 0;
  628. #ifdef UPPER                            // Upper nibble interface
  629.         DATA_PORT &= 0x0f;
  630.         DATA_PORT |= (cmd<<4)&0xf0;
  631. #else                                   // Lower nibble interface
  632.         DATA_PORT &= 0xf0;
  633.         DATA_PORT |= cmd&0x0f;
  634. #endif
  635.         DelayFor18TCY();
  636.         E_PIN = 1;                      // Clock command in
  637.         DelayFor18TCY();
  638.         E_PIN = 0;
  639. #ifdef UPPER                            // Make data nibble input
  640.         TRIS_DATA_PORT |= 0xf0;
  641. #else
  642.         TRIS_DATA_PORT |= 0x0f;
  643. #endif
  644. #endif
  645.         return;
  646. }
  647.  
  648. /********************************************************************
  649. *       Function Name:  WriteDataXLCD                               *
  650. *       Return Value:   void                                        *
  651. *       Parameters:     data: data byte to be written to LCD        *
  652. *       Description:    This routine writes a data byte to the      *
  653. *                       Hitachi HD44780 LCD controller. The user    *
  654. *                       must check to see if the LCD controller is  *
  655. *                       busy before calling this routine. The data  *
  656. *                       is written to the character generator RAM or*
  657. *                       the display data RAM depending on what the  *
  658. *                       previous SetxxRamAddr routine was called.   *
  659. ********************************************************************/
  660. void WriteDataXLCD(char data)
  661. {
  662. #ifdef BIT8                             // 8-bit interface
  663.         TRIS_DATA_PORT = 0;             // Make port output
  664.         DATA_PORT = data;               // Write data to port
  665.         RS_PIN = 1;                     // Set control bits
  666.         RW_PIN = 0;
  667.         DelayFor18TCY();
  668.         E_PIN = 1;                      // Clock data into LCD
  669.         DelayFor18TCY();
  670.         E_PIN = 0;
  671.         RS_PIN = 0;                     // Reset control bits
  672.         TRIS_DATA_PORT = 0xff;          // Make port input
  673. #else                                   // 4-bit interface
  674. #ifdef UPPER                            // Upper nibble interface
  675.         TRIS_DATA_PORT &= 0x0f;
  676.         DATA_PORT &= 0x0f;
  677.         DATA_PORT |= data&0xf0;
  678. #else                                   // Lower nibble interface
  679.         TRIS_DATA_PORT &= 0xf0;
  680.         DATA_PORT &= 0xf0;
  681.         DATA_PORT |= ((data>>4)&0x0f);
  682. #endif
  683.         RS_PIN = 1;                     // Set control bits
  684.         RW_PIN = 0;
  685.         DelayFor18TCY();
  686.         E_PIN = 1;                      // Clock nibble into LCD
  687.         DelayFor18TCY();
  688.         E_PIN = 0;
  689. #ifdef UPPER                            // Upper nibble interface
  690.         DATA_PORT &= 0x0f;
  691.         DATA_PORT |= ((data<<4)&0xf0);
  692. #else                                   // Lower nibble interface
  693.         DATA_PORT &= 0xf0;
  694.         DATA_PORT |= (data&0x0f);
  695. #endif
  696.         DelayFor18TCY();
  697.         E_PIN = 1;                      // Clock nibble into LCD
  698.         DelayFor18TCY();
  699.         E_PIN = 0;
  700. #ifdef UPPER                            // Upper nibble interface
  701.         TRIS_DATA_PORT |= 0xf0;
  702. #else                                   // Lower nibble interface
  703.         TRIS_DATA_PORT |= 0x0f;
  704. #endif
  705. #endif
  706.         return;
  707. }

Un saludo.