Quiza te sirva , `puedes adaptar a CCS o hacerte una idea .
Codigo:
// LCD HD44780U 4 bit mode.
// LCD tipos: 1x8, 2x8, 1x16, 2x16, 2x20, 4x16, 4x20
// Modificado para DsPic 30Fxxxx
/*
// USER"S ROUTINES DESCRIPTION:
LCD_INIT() ---> initilalize the LCD.
LCD_CLEAR() ---> Clears and Home LCD.
LCD_CMD("char") ---> Send a command to the LCD. See LCD datasheet for the complete list of commands.
LCD_GOTO(line,pos) ---> Set the Cursor to a specified Line and position. Lines available are from 1 to 4. Pos available starts from 1 to max available on your LCD.
LCD_PUTCH("char") ---> Write a character on LCD (ASCII representation).
LCD_PUTS("string" ---> Write a string on LCD.
LCD_PUTC("constant" ---> Write a const string on LCD.
LCD_PUTUN(unsigned long) ---> Write an Unsigned Number on LCD. It works both with INT (16bit) and CHAR (8bit). y (32bit) maximo 9 digitos
Set_CGRAM_address(char addr) --->
Ejemplo . escribe 2 caracteres predefinidos en direccion 0 y 1
LCD_INIT();
Set_CGRAM_address(0);
LCD_PUTCH(1);LCD_PUTCH(2);LCD_PUTCH(4);LCD_PUTCH(;LCD_PUTCH(16);LCD_PUTCH(32);LCD_PUTCH(1);LCD_PUTCH(1);
LCD_PUTCH(9);LCD_PUTCH(10);LCD_PUTCH(1);LCD_PUTCH(1);LCD_PUTCH(1);LCD_PUTCH(1);LCD_PUTCH(1);LCD_PUTCH(1);
LCD_CLEAR();
LCD_PUTCH(0); LCD_PUTCH(1);
*/
/************************************************************************/
/* Use the following defines to set the lines as your hardware requires */
/* ...you can use ANY output line of the MCU, even on several ports */
/************************************************************************/
#define LCD_ROWS 2 // valid numbers are: 1,2
#define LCD_COLS 20 // valid numbers are: 8,16,20 // (set to 2 for 2 or more rows)
/* PUERTOS */
#define LCD_RS PORTEbits.RE4 // Register select
#define LCD_EN PORTEbits.RE5 // Enable
#define LCD_D4 PORTEbits.RE0 // LCD data 4
#define LCD_D5 PORTEbits.RE1 // LCD data 5
#define LCD_D6 PORTEbits.RE2 // LCD data 6
#define LCD_D7 PORTEbits.RE3 // LCD data 7
/* TRIS */
#define LCD_RS_TRIS TRISEbits.TRISE4 // Register select
#define LCD_EN_TRIS TRISEbits.TRISE5 // Enable
#define LCD_D4_TRIS TRISEbits.TRISE0 // LCD data 4
#define LCD_D5_TRIS TRISEbits.TRISE1 // LCD data 5
#define LCD_D6_TRIS TRISEbits.TRISE2 // LCD data 6
#define LCD_D7_TRIS TRISEbits.TRISE3 // LCD data 7
/************************************************************************/
#define LCD_CLR 0x01 // Clear Display
#define LCD_HOME 0x02 // Cursor to Home position
// Entry mode set
// ejemplo: LCD_CMD( CURSOR_DIRECCTION_Decrement | NO_Accompanies_display_shift );
#define CURSOR_DIRECCTION_Increment 0x6
#define CURSOR_DIRECCTION_Decrement 0x4
#define Accompanies_display_shift 0x5
#define No_Accompanies_display_shift 0x4
// Display on/off control
// ejemplo: LCD_CMD( DISPLAY_ON | CURSOR_ON | CURSOR_BLINKING_OFF );
#define DISPLAY_ON 0x0C
#define DISPLAY_OFF 0x08
#define CURSOR_ON 0x0A
#define CURSOR_OFF 0x08
#define CURSOR_BLINKING_ON 0x09
#define CURSOR_BLINKING_OFF 0x08
// Cursor or display shift
// ejemplo: LCD_CMD( Cursor_move | Shift_to_the_left );
#define Display_shift 0x18
#define Cursor_move 0x10
#define Shift_to_the_right 0x14
#define Shift_to_the_left 0x10
/************************************************************************/
#if (LCD_COLS==20)
#define LCD_line1 0x80 // Line 1 position 1
#define LCD_line2 0xC0 // Line 2 position 1
#define LCD_line3 0x94 // Line 3 position 1 (20 char LCD)
#define LCD_line4 0xD4 // Line 4 position 1 (20 char LCD)
#else
#define LCD_line1 0x80 // Line 1 position 1
#define LCD_line2 0xC0 // Line 2 position 1
#define LCD_line3 0x90 // Line 3 position 1 (16 char LCD)
#define LCD_line4 0xD0 // Line 4 position 1 (16 char LCD)
#endif
/************************************************************************/
// const Font_3x6_0[8] = { 0,0,0,0,0x38,0x44,0x38,0}; /* 0 0x30 */
/****************************************/
/* Enable LCD to read data */
/****************************************/
void LCD_STROBE (void)
{
LCD_EN = 1;
DelayUs(1);
LCD_EN = 0;
}
/****************************************/
/* Write a nibble to the LCD */
/****************************************/
void LCD_NIBBLE_OUT (unsigned char c ) {
LCD_D4=c ; c >>= 1;
LCD_D5=c; c >>= 1;
LCD_D6=c; c >>= 1;
LCD_D7=c;
LCD_STROBE();
}
/****************************************/
/* Write a byte to the LCD (4 bit mode) */
/****************************************/
void LCD_WRITE (unsigned char c)
{
LCD_NIBBLE_OUT(c >> 4);
LCD_NIBBLE_OUT(c);
DelayUs(50);
}
/****************************************/
/* send a command to the LCD */
/****************************************/
void LCD_CMD (char c) {
LCD_RS = 0; // write command
LCD_WRITE(c);
}
/****************************************/
/* GoTO specified line and position */
/****************************************/
void LCD_GOTO (char line,char pos) // Set DDRAM address
{
switch(line)
{
case 1: LCD_CMD((LCD_line1-1)+pos);
break;
case 2: LCD_CMD((LCD_line2-1)+pos);
break;
case 3: LCD_CMD((LCD_line3-1)+pos);
break;
case 4: LCD_CMD((LCD_line4-1)+pos);
}
}
/****************************************/
/* Clear and Home LCD */
/****************************************/
void LCD_CLEAR (void)
{
LCD_CMD(LCD_CLR);
DelayMs(3);
}
/****************************************/
/* Write one character to the LCD */
/****************************************/
void LCD_PUTCH (unsigned char c)
{
LCD_RS = 1; // write characters
LCD_WRITE(c);
}
/****************************************/
/* Write a string to the LCD */
/****************************************/
void LCD_PUTS ( char * s)
{
LCD_RS = 1; // write characters
while(*s)
LCD_WRITE(*s++);
}
/****************************************/
/* Write a const to the LCD */
/****************************************/
void LCD_PUTC ( const * s)
{
LCD_RS = 1; // write characters
while(*s)
LCD_WRITE(*s++);
}
/****************************************/
/* Set CGRAM address */
/****************************************/
void Set_CGRAM_address(unsigned char addr){
addr = addr & 0x3F;
LCD_CMD(0x40 | addr );
}
/************************************************/
/* Write a const to the LCD */
/* escribe un caracter predefinido en cgram */
/************************************************/
void LCD_SetCaracter (unsigned char posicion , const * s)
{ unsigned char a; a=8;
Set_CGRAM_address(posicion);
LCD_RS = 1; // write characters
while(a != 0){
LCD_WRITE(*s++); a--;}
}
/****************************************/
/* Escribe Valor numerico al LCD */
/* Max 1 a 9 digitos */
/* ceros a la izquierda blancos */
/* puno de miles y millones */
/****************************************/
/* ejemplo : 341.000.780 1.886 23 */
void LCD_PUTUN (unsigned char Digitos , unsigned long valor)
{
unsigned char t1,i,wrote;
unsigned long k;
wrote=0;
for (i=Digitos-1; i>=1; i--)
{
switch(i){
case 8: k=100000000;
break;
case 7: k=10000000;
break;
case 6: k=1000000;
break;
case 5: k=100000; if (Digitos > 6){ if (wrote==1){ LCD_PUTCH(".");} else { LCD_PUTCH(" ");}} // millones
break;
case 4: k=10000;
break;
case 3: k=1000;
break;
case 2: k=100; if (Digitos > 3){ if (wrote==1){ LCD_PUTCH(".");} else { LCD_PUTCH(" ");}} // miles
break;
case 1: k=10;
}
t1=valor/k;
if((wrote)||(t1!=0)){LCD_PUTCH(t1+"0"); wrote=1;}
else LCD_PUTCH(" "); // Ceros izquierda blanco
valor-=(t1*k);
}
LCD_PUTCH( valor +"0");
}
/****************************************/
/* Initialize LCD */
/****************************************/
void LCD_INIT (void)
{
/* Configura los TRIS como salidas */
LCD_RS_TRIS = 0; // Register select
LCD_EN_TRIS = 0; // Enable
LCD_D4_TRIS = 0; // LCD data 4
LCD_D5_TRIS = 0; // LCD data 5
LCD_D6_TRIS = 0; // LCD data 6
LCD_D7_TRIS = 0; // LCD data 7
LCD_RS = 0; // write control bytes
DelayMs(20); // power on delay
LCD_NIBBLE_OUT(0x04); // set 4 bit mode
DelayUs(100);
#if (LCD_ROWS==1)
LCD_CMD(0x20); // 4 bit mode, 1 line, 5x8 font (0b00100000);
#else
LCD_CMD(0x28); // 4 bit mode, 2 or more lines, 5x8 font (0b00101000);
#endif
LCD_CMD(DISPLAY_OFF);
LCD_CMD(DISPLAY_ON | CURSOR_OFF | CURSOR_BLINKING_OFF);
LCD_CMD( CURSOR_DIRECCTION_Increment | No_Accompanies_display_shift );
LCD_CLEAR();
}