les dejo una driver para controlar casi todo tipo de lcd alfanumerico la e probado con varias e funciono en todas elhas perfectamente he tenido algunas que con una configuracion funciona perfectamente pero quando conectaba otra de marca diferente esta ya no funcionaba de manera que e ido retocando el driver e con solo aumentar o diminuir los delays consegui acer que todas elhas funcionen
si alguien le interesa lo puede simular en el proteus e ir aciendo canbios con varias lcds e canbiando la configuracion del driver para que assi se aga una idea de las diferencias que ay entre elhas
este es el driver se puede canbiar facilmente el puerto que queramos usar
//GUARDAR CON ESTE NOME LCDTESTE.C
#use delay(clock=20000000)
//PARA USAR A PORTA D CONVENIENTE PARA 16F877A
#define LCD_D0 PIN_D2
#define LCD_D1 PIN_D3
#define LCD_D2 PIN_D4
#define LCD_D3 PIN_D5
#define LCD_EN PIN_D1
#define LCD_RS PIN_D0
//O PIN R/W LIGADO A GND SENAO NAO FUNCIONA
// EXPECIAL PARA LCD 4x20 //
//#define LINHA_1 0x00
//#define LINHA_2 0x40
//#define LINHA_3 0x14
//#define LINHA_4 0x54
// EXPECIAL PARA LCD 4X16 //
//#define LINHA_1 0x00
//#define LINHA_2 0x40
//#define LINHA_3 0x10
//#define LINHA_4 0x50
// EXPECIAL PARA LCD 2x20 //
#define LINHA_1 0x00
#define LINHA_2 0x40
// EXPECIAL PARA LCD 1X16 //
//#define LINHA_1 0x00
// EXPECIAL PARA LCD 2X16 //
//#define LINHA_1 0x00
//#define LINHA_2 0x40
#define CLEAR 0x01
void LCD_Init ( void );
void LCD_SetPosition ( unsigned int cX );
void LCD_PutChar ( unsigned int cX );
void LCD_PutCmd ( unsigned int cX );
void LCD_PulseEnable ( void );
void LCD_SetData ( unsigned int cX );
void LCD_Init ( void )
{
LCD_SetData ( 0x00 );
delay_ms ( 50 ); /* COLOCAR O TEMPO PARA DIFERENTES LCD REALIZAR EXPERIENCIAS*/
output_low ( LCD_RS );
LCD_SetData ( 0x03 );
LCD_PulseEnable();
LCD_PulseEnable();
LCD_PulseEnable();
LCD_SetData ( 0x02 );
LCD_PulseEnable();
LCD_PutCmd ( 0x2C );
LCD_PutCmd ( 0x0C );
LCD_PutCmd ( 0x01 );
LCD_PutCmd ( 0x06 );
}
void LCD_SetPosition ( unsigned int cX )
{
LCD_SetData ( swap ( cX ) | 0x08 );
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) );
LCD_PulseEnable();
}
void LCD_PutChar ( unsigned int cX )
{
output_high ( LCD_RS );
LCD_SetData ( swap ( cX ) );
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) );
LCD_PulseEnable();
output_low ( LCD_RS );
}
void LCD_PutCmd ( unsigned int cX )
{
LCD_SetData ( swap ( cX ) );
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) );
LCD_PulseEnable();
}
void LCD_PulseEnable ( void )
{
output_high ( LCD_EN );
delay_us ( 20 ); //IR MODIFICANDO O VALOR ATE CONSEGUIR O MAIS ADEQUADO
output_low ( LCD_EN );
delay_ms ( 20 ); //IR MODIFICANDO O VALOR ATE CONSEGUIR O MAIS ADEQUADO
}
void LCD_SetData ( unsigned int cX )
{
output_bit ( LCD_D0, cX & 0x01 );
output_bit ( LCD_D1, cX & 0x02 );
output_bit ( LCD_D2, cX & 0x04 );
output_bit ( LCD_D3, cX & 0x08 );
}
esto es un teste para usar este driver con el 16f877a
#include <16F877A.h>
#include <LCDTESTE.C>
#use delay(clock=20000000)
#fuses NOWDT,RC, NOPUT, NOPROTECT, NODEBUG, BROWNOUT, LVP, NOCPD, NOWRT
void main ( void )
{
LCD_Init();
LCD_PutCmd ( CLEAR );
LCD_SetPosition ( LINHA_1 );
printf ( LCD_PutChar, " LINHA1 " );
delay_ms (500);
LCD_SetPosition ( LINHA_2 );
printf ( LCD_PutChar, " LINHA2 " );
delay_ms ( 1000);
LCD_PutCmd ( CLEAR );
LCD_SetPosition ( LINHA_1 );
printf ( LCD_PutChar, "TESTE LCD 2 LINHAS POR 40 CARACTERES"
;
delay_ms (500);
LCD_SetPosition ( LINHA_2 );
printf ( LCD_PutChar, " PREPARADO POR XASTRE NORDESTECNICA "
;
delay_ms ( 1000);
}