Para el comando limpiar usa 60us después de escribir la instrucción, porque si no lo pones
hará cosas raras.
Acá hice una librería que me funcionó bien, la envío a un registro y los retardos están por decirse ajustados al LCD porque si son menores o mayores empieza a escribir basura o simplemente nada.
Mi código es pésimo y tal vez redundante pero funcionó.
hará cosas raras.
Acá hice una librería que me funcionó bien, la envío a un registro y los retardos están por decirse ajustados al LCD porque si son menores o mayores empieza a escribir basura o simplemente nada.
Código:
///////////////////////////////////////////////////////////////////////////
//// ////
//// Mi_LCD_lib.C ////
//// ////
//// LIBRERIA GENERICA PARA MANEJAR UNA LCD16X2 ////
//// ////
//// DAVID CASTILLO SEVERO ////
//// ////
///////////////////////////////////////////////////////////////////////////
/************* COMANDOS PARA LA LCD LA HOJA DE DATOD LA DICE****************/
///////////////////////////////////////////////////////////////////////////
//// ////
//// PRIMERO QUE NADA HAY QUE DECLARAR LOS COMANDOS QUE ////
//// HACEN QUE TRABAJE LA LCD, SEGUN LOS COMANDOS ////
//// HACEN QUE EL LCD SE COMPORTE COMO QUEREMOS ////
//// ////
///////////////////////////////////////////////////////////////////////////
#define LIMPIAR_LCD 0x01 //Limpia el display y lo pone a la dirección 1
#define CURSOR_INICIO 0x02 //Cursor la primera posicion (Dirección 1)
#define DEC_CURSOR 0x04 //Decrementa el cursor
#define INC_CURSOR 0x06 //Incrementa el cursor
#define DISPLAY_DER 0x07 //Rota el display a la derecha
#define DISPLAY_IZQ 0x05 //Rota el display a la izquierda
#define DSPLY_OFF_CRSR_OFF 0x08 //Apaga el display y el cursor
#define DSPLY_OFF_CRSR_BLNK 0x09 //Apaga el display y el cursor
#define DSPLY_OFF_CRSR_ON 0x0A //Apaga el display y prende el cursor
#define DSPLY_ON_CRSR_OFF 0x0C //Enciende el display y apaga el cursor
#define DSPLY_ON_CRSR_OFF_BLNK 0x0D //Enciende el display y apaga el cursor
#define DSPLY_ON_CRSR_ON 0x0E //Apaga el display y parpadea el cursor
#define DSPLY_ON_CRSR_BLINK 0x0F //Enciende el display y parpadea el cursor
#define POSICION_CRSR_IZQ 0x10 //Retrocede el cursor una posición
#define POSICION_CRSR_DER 0x14 //Aumenta el cursor una posición
#define TODO_DISPLAY_IZQ 0x18 //Rota todo el display a la izquierda
#define TODO_DISPLAY_DER 0x1C //Rota todo el display a la derecha
#define CURSOR_LINEA_1 0x80 //Pone el cursor en la linea 1 posicion 1
#define CURSOR_LINEA_2 0xC0 //Pone el cursor en la linea 2 posicion 1
#define BITS_8 0x38 //Establece la interface de 2 lineas y caracteres de 5x7 puntos con 8 bits de datos
#define BITS_4 0x28 //Establece la interface de 2 lineas y caracteres de 5x7 puntos con 4 bits de datos
/***************************************************************************/
// 1 tick es 4/FOSC
// 4/48Mhz = 0.083us
// 1 tick = 0.083us
// 1 tick = Nop();
void delay_us(int num1)
{
int inc;
for(inc=0; inc!=num1 ;inc++) //GENERA 1us
{
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
}
}
void delay_ms(int num)
{
int inc;
for(inc=0; inc!=num; inc++)
{
Delay1KTCYx(12) ; //1ms = 5 k ticks
}
}
void config_4bit(char CMD)
{
unsigned char bit8;
//MODO ESCRITUDA EN LA LCD
//WE =0
//RS =0
//HABILITO LA LCD
//EN =1
bit8=0b00000100;
//ESCRIBO EL COMANDO
bit8=bit8+CMD;
gato(bit8);
delay_us(45);
//DESHABILITO LA LCD
//EN= 0
bit8=0b00000000;
bit8=bit8+CMD;
gato(bit8);
}
void COMANDO(char CMD)
{
unsigned char bit8;
char nible1=0;
char nible2=0;
nible2=CMD; //EJEMPLO AB EN HEX SOLO TRABAJARE CON EL NIBLE ALTO [1111] [0000] EL NIBLE BAJO SE DESECHA
nible2=nible2>>4; //AB ROTADO IZQ QUEDA 0A ,PARA ENVIARLO DEBE SER A LA DERECHA
nible2=nible2<<4; //ENTONCES QUEDARIA A0
nible1=CMD<<4; //AHORA EL NIBLE BAJO DE AB LO ROTO A LA IZQ QUEDARIA SOLO B0
//ENVIO EL NIBLE ALTO
//MODO ESCRITUDA EN LA LCD
//WE =0
//RS =0
//HABILITO LA LCD
//EN =1
bit8=0b00000100;
//ESCRIBO EL COMANDO
bit8=bit8+nible2;
gato(bit8);
delay_us(60);
//DESHABILITO LA LCD
//EN= 0
bit8=0b00000000;
bit8=bit8+nible2;
gato(bit8);
//ENVIO EL NIBLE BAJO
//MODO ESCRITUDA EN LA LCD
//WE =0
//RS =0
//HABILITO LA LCD
//EN =1
bit8=0b00000100;
//ESCRIBO EL COMANDO
bit8=bit8+nible1;
gato(bit8);
delay_us(45);
//DESHABILITO LA LCD
//EN= 0
bit8=0b00000000;
bit8=bit8+nible1;
gato(bit8);
}
void dav_gotoxy(unsigned char x, unsigned char y)
{
unsigned char direccion;
if(y!=1)
direccion=0x40;
else
direccion=0;
direccion +=x-1;
COMANDO(0x80 | direccion);
}
void dav_lcd(char c)
{
unsigned char bit8;
char nible1=0;
char nible2=0;
switch(c)
{
case '\f':
COMANDO(LIMPIAR_LCD);
delay_ms(2);
break;
case '\n':
dav_gotoxy(1,2);
break;
default:
nible2=c; //EJEMPLO AB EN HEX SOLO TRABAJARE CON EL NIBLE ALTO [1111] [0000] EL NIBLE BAJO SE DESECHA
nible2=nible2>>4; //AB ROTADO IZQ QUEDA 0A ,PARA ENVIARLO DEBE SER A LA DERECHA
nible2=nible2<<4; //ENTONCES QUEDARIA A0
nible1=c<<4; //AHORA EL NIBLE BAJO DE AB LO ROTO A LA IZQ QUEDARIA SOLO B0
//MODO ESCRITURA
//RS= 1
//WE= 0
bit8=0b00000001;
gato(bit8);
//HABILITO LA LCD
//EN= 1
bit8=0b00000101;
//ENVIO EL NIBLE ALTO
bit8=bit8+nible2;
gato(bit8);
delay_ms(1);
//DESHABILITO LA LCD
//EN= 0
bit8=0b00000001;
bit8=bit8+nible2;
gato(bit8);
delay_ms(1);
//HABILITO LA LCD
//EN= 1
bit8=0b00000101;
bit8=bit8+nible2;
gato(bit8);
//ENVIO EL NIBLE BAJO
bit8=0b00000101;
bit8=bit8+nible1;
gato(bit8);
delay_ms(1);
//DESHABILITO LA LCD
//EN= 0
bit8=0b00000001;
bit8=bit8+nible1;
gato(bit8);
break;
}
}
void lcd_cadena(char *cadena)
{
char i=0;
while(cadena[i]!='\0')
{
dav_lcd(cadena[i]);
if(i==15)//cuando llega al maximo da un salto de linea
{
COMANDO(CURSOR_LINEA_2);
}
i++;
}
}
void lcd_init()
{
serial_init();
//INICIO CON TODO APAGADO
gato(0x00);
delay_ms(15);
//inicializo el LCD por los 3 comandos de fabrica
COMANDO(0x30);
delay_ms(5);
COMANDO(0x30);
delay_ms(5);
COMANDO(0x30);
delay_ms(5);
//inicializo que va a trabajar en 4 bits
config_4bit(0x20);
//comando 8 bits 0x38 y para 4 bits es
COMANDO(BITS_4);
COMANDO(DSPLY_ON_CRSR_OFF);
COMANDO(LIMPIAR_LCD);
delay_ms(2);
}
Última edición por un moderador: