Hola a todos. Soy nuevo en el foro y quiero colaborar con algo. Estuve casi una semana peleando con mi LCD y no podia hacer que escriba ni una sola letra. No encontraba info precisa que me sea útil. Hasta que dando vueltas por ahi encontre un tutorial de el mundo de riki o algo asi y realmente me ayudo. Aca dejo el link de la pagina, y la traduccion que hice por si alguien quiere leer.
Esta pagina ayuda mucho mucho
http://www.8051projects.net/lcd-interfacing/introduction.php
Primero pongo un programita hecho en "CCS" que escribe una sola letra en el LCD y luego otro que escribe una cadena. Estoy trabajando con un Lcd de dos lineas y 16 caracteres y en modo 8 bit. Estoy viendo como hacerlo con 4 bit, asi que pondre algo luego de que lo pueda hacer funcionar en ese modo.
Programa que muestra una letra en la pantalla, uso un pic 16f887
Ahora pongo el otro programita que escribe la cadena de caracteres en el LCD
Tambien tengo parte de una libreria para controlar LCD en .asm por si alguine la quiere.
En los dos programas quizas hay codigo de mas, o tal vez se pueden optimizar los retardos. Como lei que algunas veces los LCD tienen problema con los tiempos de acceso, puse varios retardos, quizas algunos de mas.
Espero sea util.
En el adjunto dejo la traduccion que hice de la pagina si por ahi a alguien le sirve.
Esta pagina ayuda mucho mucho
http://www.8051projects.net/lcd-interfacing/introduction.php
Primero pongo un programita hecho en "CCS" que escribe una sola letra en el LCD y luego otro que escribe una cadena. Estoy trabajando con un Lcd de dos lineas y 16 caracteres y en modo 8 bit. Estoy viendo como hacerlo con 4 bit, asi que pondre algo luego de que lo pueda hacer funcionar en ese modo.
Programa que muestra una letra en la pantalla, uso un pic 16f887
Código:
#include<16F887.h>
#use delay (clock=4000000)
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT,NOPUT
#use delay(clock=4000000)
#byte PORTD=0x08
void LCD_busy(void){
unsigned char i,j;
for(i=0;i<50;i++)
for(j=0;j<255;j++);
}
void seteo(unsigned char var)
{
PORTD=Var;
output_low(PIN_E1); //LCD_rs = 0;
output_high(PIN_E2); //LCD_en = 1; Enable H->L
delay_ms(15);
output_low(PIN_E2); //LCD_en = 0;
delay_ms(15);
LCD_busy(); //Wait for LCD to process the command
}
void LCD_init(void) {
delay_ms(15);
delay_ms(15);
delay_ms(15);
seteo(0x38); //function set: 2 Line, 8-bit, 5x7 dots
delay_ms(15);
seteo(0x38); //function set: 2 Line, 8-bit, 5x7 dots
delay_ms(15);
seteo(0x38); //function set: 2 Line, 8-bit, 5x7 dots
delay_ms(15);
seteo(0x39);
delay_ms(15);
seteo(0x06);
delay_ms(15);
seteo(0x0E); //Entry mode
delay_ms(15);
seteo(0x01);
delay_ms(15);
LCD_busy();
}
void LCD_command(unsigned char var)
{
PORTD=Var; //Function set: 2 Line, 8-bit, 5x7 dots
output_low(PIN_E1); //LCD_rs = 0; //Selected command register
output_high(PIN_E2); //LCD_en = 1; Enable H->L
delay_ms(15);
output_low(PIN_E2); //LCD_en = 0;
delay_ms(15);
LCD_busy();
}
void LCD_letra(unsigned char var)
{
PORTD=Var;
output_high(PIN_E1); //LCD_rs = 1; Selected data register
output_high(PIN_E2); //LCD_en = 1; Enable H->L
delay_ms(15);
output_low(PIN_E2); //LCD_en = 0;
delay_ms(15);
LCD_busy();
}
void main() {
set_tris_d(0x00);
set_tris_e(0x00);
LCD_busy();
LCD_init();
LCD_busy();
LCD_letra('R');
}
Ahora pongo el otro programita que escribe la cadena de caracteres en el LCD
Código:
#include<16F887.h>
#use delay (clock=4000000)
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT,NOPUT
#use delay(clock=4000000)
#byte PORTD=0x08
void LCD_busy(void){ //Esta rutina la hago con un simple conteo porque tengo conectado el pin de R/W
unsigned char i,j; //a masa y por lo tanto no puedo leer del LCD ya que siempre lo tengo en modo escritura
for(i=0;i<50;i++)
for(j=0;j<255;j++);
}
void LCD_seteo(unsigned char var)
{
PORTD=Var;
output_low(PIN_E1); //LCD_rs = 0;
output_high(PIN_E2); //LCD_en = 1; Enable H->L
delay_ms(15);
output_low(PIN_E2); //LCD_en = 0;
delay_ms(15);
LCD_busy(); //Wait for LCD to process the command
}
void LCD_init(void) {
delay_ms(15);
delay_ms(15);
delay_ms(15);
LCD_seteo(0x38); //function set: 2 Line, 8-bit, 5x7 dots
delay_ms(15);
LCD_seteo(0x38); //function set: 2 Line, 8-bit, 5x7 dots
delay_ms(15);
LCD_seteo(0x38); //function set: 2 Line, 8-bit, 5x7 dots
delay_ms(15);
LCD_seteo(0x39);
delay_ms(15);
LCD_seteo(0x06); //Entry mode
delay_ms(15);
LCD_seteo(0x0E); //Enciende el cursor
delay_ms(15);
LCD_seteo(0x01); //Limpia el display y la DDRAM
delay_ms(15);
LCD_busy();
}
void LCD_command(unsigned char var)
{
PORTD=Var; //Function set: 2 Line, 8-bit, 5x7 dots
output_low(PIN_E1); //LCD_rs = 0; //Selected command register
output_high(PIN_E2); //LCD_en = 1; Enable H->L
delay_ms(15);
output_low(PIN_E2); //LCD_en = 0;
delay_ms(15);
LCD_busy();
}
void LCD_write_data(unsigned char var)
{
PORTD=Var;
output_high(PIN_E1); //LCD_rs = 1; Selected data register
output_high(PIN_E2); //LCD_en = 1; Enable H->L
delay_ms(15);
output_low(PIN_E2); //LCD_en = 0;
delay_ms(15);
LCD_busy();
}
void LCD_cadena(unsigned char output)
{
PORTD= output; //Entry mode, auto increment with no shift
output_high(PIN_E1); //LCD_rs = 1; Selected data register
output_high(PIN_E2); //LCD_en = 1; Enable H->L
delay_ms(15);
output_low(PIN_E2); //LCD_en = 0;
delay_ms(15);
LCD_busy();
}
void LCD_cambia_cursor (unsigned int SC,unsigned int RL) {
/*
Moves the cursor and shifts the display without changing the DDRAM contents
SC => [Cursor : Display]
0 => Cursor
1 => Display
RL => [Left : Right]
0 => Left
1 => Right
*/
PORTD = 0x00;
RL = RL << 2;
SC = SC << 3;
PORTD = PORTD + 0x10 + SC + RL;
LCD_seteo(PORTD);
}
void LCD_ddram_address (unsigned int ddadrs) {
/*
ddadrs => DDRAM Address Binary 7 bit
Line 1 Column 1
Binary Address : 0B10000000
HEX Address : 0X80
Line 1 Column 16
Binary Address : 0B10001111
HEX Address : 0X8F
Line 2 Column 1
Binary Address : 0B11000000
HEX Address : 0XC0
Line 2 Column 16
Binary Address : 0B11001111
HEX Address : 0XCF
[][][][][][][][][][][][][][][][]
[][][][][][][][][][][][][][][][]
C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16
L1 [0X80][0X81][0X82][0X83][0X84][0X85][0X86][0X87][0X88][0X89][0X8A][0X8B][0X8C][0X8D][0X8E][0X8F]
L2 [0XC0][0XC1][0XC2][0XC3][0XC4][0XC5][0XC6][0XC7][0XC8][0XC9][0XCA][0XCB][0XCC][0XCD][0XCE][0XCF]
*/
PORTD = 0x00;
PORTD = ddadrs;
LCD_seteo(PORTD);
}
void main() {
set_tris_d(0x00);
set_tris_e(0x00);
LCD_busy();
LCD_init();
LCD_busy();
LCD_cadena("Hola");
LCD_busy();
LCD_ddram_address(0xC0); // funcion que se ubiac en la segunda linea del LCD
LCD_busy(); // para seguir escribiendo
LCD_cadena("Mundo");
}
Tambien tengo parte de una libreria para controlar LCD en .asm por si alguine la quiere.
En los dos programas quizas hay codigo de mas, o tal vez se pueden optimizar los retardos. Como lei que algunas veces los LCD tienen problema con los tiempos de acceso, puse varios retardos, quizas algunos de mas.
Espero sea util.
En el adjunto dejo la traduccion que hice de la pagina si por ahi a alguien le sirve.
Adjuntos
Última edición: