TEngo dos librerias para LCD, una funciona bien, la segunda parece ser que trabaja con el 16F877 a 20 Mhz, pero a mi no me funciona. No logro ver diferencias entre ellas apreciables pero esta claro que existen.
LAs pego a ver si alguien sabe que ocurre porque el display con la de 20 ni se entera.
ESTA FUNCIONA
///////////////////////////////////////////////////////////////////////////
//// LCD1.C ////
//// Driver para modulo LCD ////
//// ////
//// lcd_init() Debe ser llamada antes que cualquier funcion. ////
//// ////
//// lcd_putc(c) Mostrara c en la siguiente posicion del LCD. ////
//// Los siguientes envios tienen funciones especiales: ////
//// f Borra el LCD ////
////
Va al principio de la segunda linea ////
//// Mueve una posicion atras ////
//// ////
//// lcd_gotoxy(x,y) Fija la posicion de escritura (Arr. Izda es 1,1) ////
//// ////
//// lcd_getc(x,y) Devuelve el caracter de la posicion x,y del LCD ////
//// ////
///////////////////////////////////////////////////////////////////////////
// el conexionado de de los pines es el siguiente:
// D0 rs
// D1 rw
// D2 en
// D4 D4
// D5 D5
// D6 D6
// D7 D7
//
// Los pines D0-D3 del LCd no se usan
// Elimina el // del comentario siguiente para usar el puerto B, en caso contrario se usa el D
//#define use_portb_lcd TRUE
struct lcd_pin_map { // Mediante el orden de esta estructura
BOOLEAN rs; // se organizan los pines asignados al LCD
BOOLEAN rw; // De menor a mayor, asi como estan el 0 sera RS
BOOLEAN enable; // el 1 RW y el 2 Enable
BOOLEAN unused; //
int data : 4;
} lcd;
#if defined(__PCH__)
#if defined use_portb_lcd
#byte lcd = 0xF81 // Esto fija la estructura entera
#else
#byte lcd = 0xF83 // Esto fija la estructura entera
#endif
#else
#if defined use_portb_lcd
#byte lcd = 6 // en el puerto B (la direccion 6)
#else
#byte lcd = 8 // en el puerto D (la direccion

#endif
#endif
#if defined use_portb_lcd
#define set_tris_lcd(x) set_tris_b(x)
#else
#define set_tris_lcd(x) set_tris_d(x)
#endif
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lineas
#define numero_caracteres 20 // cambiar aqui si es 2*16 2*20 o el numero de caracteres de la linea
#define lcd_line_two 0x40 // direccion de la LCD RAM para la segunda linea
BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// Estos bytes necesitan enviarse al LCD
// para arrancarlo.
// Lo siguiente se usa para fijar
// la direccion del registro del puerto de I/O.
struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // Para escribir todos los pines como salida
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // Para leer todos los pines como entrada
BYTE lcd_read_byte() {
BYTE low,high;
set_tris_lcd(LCD_READ);
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd.enable = 0;
delay_cycles(1);
lcd.enable = 1;
delay_us(1);
low = lcd.data;
lcd.enable = 0;
set_tris_lcd(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( BYTE n ) {
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}
void lcd_send_byte( BYTE address, BYTE n ) {
lcd.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd.rs = address;
delay_cycles(1);
lcd.rw = 0;
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
BYTE i;
set_tris_lcd(LCD_WRITE);
lcd.rs = 0;
lcd.rw = 0;
lcd.enable = 0;
delay_ms(15);
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_send_byte(0,LCD_INIT_STRING
);
}
void lcd_gotoxy( BYTE x, BYTE y) {
BYTE address;
if(y!=1)
address=lcd_line_two;
else
address=0;
address+=x-1;
lcd_send_byte(0,0x80|address);
}
void lcd_putc( char c) {
switch (c) {
case "f" : lcd_send_byte(0,1);
delay_ms(2);
break;
case "
" : lcd_gotoxy(1,2); break;
case "" : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
}
char lcd_getc( BYTE x, BYTE y) {
char value;
lcd_gotoxy(x,y);
while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
}
void lcd_clr_line(char fila)
{
int j;
lcd_gotoxy(1,fila);
for (j=0;j<numero_caracteres;j++) lcd_putc(" ");
lcd_gotoxy(1,fila);
}
void lcd_back_off(void)
{
output_low(PIN_D3);
}
void lcd_back_on(void)
{
output_high(PIN_D3);
}
ESTA NO FUNCIONA
// coach_lcd.c
//
// Funciones para la gestion del display 2x16 [ByCoach]:
//
// lcd_init() Debe ser llamada antes que las otras funciones.
//
// lcd_putc(c) Visualiza c en la siguiente posición del display.
// Caracteres especiales de control:
// f Borrar display
//
Saltar a la segunda linea
// Retroceder una posición.
//
// lcd_gotoxy(x,y) Selecciona la nueva posicion de escritura en el display.
// (la esquina superior izquierda es 1,1)
//
// lcd_getc(x,y) Devuelve el caracter de la posicion x,y del display.
//Definicion de pines:
#define lcd_rs PIN_D0 //
#define lcd_rw PIN_D1 //
#define lcd_en PIN_D2 //
#define lcd_DB4 PIN_D4 //
#define lcd_DB5 PIN_D5 //
#define lcd_DB6 PIN_D6 //
#define lcd_DB7 PIN_D7
void lcd_enviar_nibble( int nibble )
{
output_bit( lcd_DB4, bit_test( nibble, 0 ) ); //Pone en el puerto B[4..7] el valor en nibble[0..3]
output_bit( lcd_DB5, bit_test( nibble, 1 ) );
output_bit( lcd_DB6, bit_test( nibble, 2 ) );
output_bit( lcd_DB7, bit_test( nibble, 3 ) );
delay_us( 1 );
output_high( lcd_en ); //Activa y desactiva enable para que el lcd capture el nibble
delay_us( 2 );
output_low( lcd_en );
}
int lcd_leer_byte( void )
{
int valor = 0;
output_high( lcd_rw ); //Se activa rw indicando que se va a realizar una lectura
delay_us( 1 );
output_high( lcd_en ); //Se activa enable para que el lcd saque la parte alta del byte deseado
delay_us( 1 ); //por los pines de datos
if( input( lcd_DB7 ) ) //Se captura la parte alta del byte deseado
bit_set( valor, 7 );
if( input( lcd_DB6 ) )
bit_set( valor, 6 );
if( input( lcd_DB5 ) )
bit_set( valor, 5 );
if( input( lcd_DB4 ) )
bit_set( valor, 4 );
output_low( lcd_en ); //Se desactiva y se vuelve a activar enable para que el lcd saque la parte
delay_us( 1 ); //baja del byte deseado por los pines de datos
output_high( lcd_en );
delay_us( 1 );
if( input( lcd_DB7 ) ) //Se captura la parte baja del byte deseado
bit_set( valor, 3 );
if( input( lcd_DB6 ) )
bit_set( valor, 2 );
if( input( lcd_DB5 ) )
bit_set( valor, 1 );
if( input( lcd_DB4 ) )
bit_set( valor, 0 );
output_low( lcd_en ); //Se desactiva enable, indicando al lcd el fin de la lectura del byte
return( valor ); //Devuelve el byte capturado
}
void lcd_enviar_byte( int dir, int valor ) //Si recibe en dir un 1 se trata de un dato y si es un 0 es un comando
{
output_low( lcd_rs );
while( bit_test( lcd_leer_byte(), 7 ) ); //Lectura del Flag de Busy (ocupado), si 1 se espera, si 0 se continúa
output_bit( lcd_rs, dir ); //Se asigna a rs el valor de dir para indicar si es dato o comando
delay_us( 1 );
output_low( lcd_rw ); //Se pone a cero rw para indicar que se va a realizar una escritura
delay_us( 1 );
output_low( lcd_en ); //Se pone a cero enable para preparar el valor a enviar
lcd_enviar_nibble( valor >> 4 ); //Se envía primero la parte alta del byte
lcd_enviar_nibble( valor & 0x0F ); //a continuación se envía la parte baja
}
void lcd_gotoxy( int x, int y ) //Se reciben las coordenadas x e y a las que se desea desplazarse
{
int dir;
if ( y != 1 ) //La posición "y" determinará la línea elegida, si es 1 -> Línea 1, si no -> Línea 2
dir = 0x40; //Dirección de la RAM del LCD para la 2ª línea
else
dir = 0x00; //Dirección de la RAM del LCD para la 1ª línea
dir += x - 1; //Resta uno, ya que la posición 1 sería la 0 para el lcd
lcd_enviar_byte( 0, dir | 0x80 ); //Se envía el byte, indicando que es un comando y poniendo el bit
} //más significativo a 1, para diferenciar este comando de los demás
void lcd_init( void )
{
int i;
// BYTE bytes_inicio[4] = { 0x20, 0x0C, 1, 6 };
int bytes_inicio[4] = { 0x28, 0x0C, 0x01, 0x06 };
set_tris_D(0xff);
output_low( lcd_rs ); //Pone a cero todos los pines de control
output_low( lcd_rw );
output_low( lcd_en );
delay_ms( 30 );
for ( i = 1 ; i <= 3 ; i++ )
{
lcd_enviar_nibble( 3 );
delay_ms( 5 );
}
lcd_enviar_nibble( 2 );
for( i = 0 ; i <= 3 ; i++ ) //Se configura el lcd con las características indicadas anteriormente
lcd_enviar_byte( 0 , bytes_inicio );
}
void lcd_putc( char c ) //Se recibe el caracter a enviar
{
switch( c )
{
case "f" : lcd_enviar_byte( 0, 1 ); //Si c = "f", se envía un 1, e indica que es un comando
delay_ms( 2 ); //Enviando un 1, se borra la pantalla del lcd
break;
case "
" : lcd_gotoxy( 1, 2 ); //Si c = "
", se posiciona en la segunda línea
break;
case "" : lcd_enviar_byte( 0, 0x10 ); //Si c = "", se sitúa una posición a la izquierda
break;
default : lcd_enviar_byte( 1, c ); //Si no es ninguna de las anteriores, envía un caracter
break;
}
}
char lcd_getc( int x,int y ) //Se reciben las coordenadas x e y de las que se desea el dato
{
char valor;
lcd_gotoxy( x, y ); //Se posiciona en el punto deseado
output_high( lcd_rs ); //Pone a 1 el pin rs, indicando que se trata de un dato
valor = lcd_leer_byte(); //Lee el byte de la posición deseada
output_low( lcd_rs );
return( valor ); //Devuelve el caracter leído
}