Anda di halaman 1dari 10

Manejo de la LCD

Este tutorial fue escrito considerando el microcontrolador ATMEGA48 y el compilador


Codevision.

La Pantalla es de 16x2, esto significa que es de 16 caracteres por dos líneas. El chip que
tiene es compatible con el HD44780 de Hitachi que es el que tienen todas las LCDs
alfanuméricas, además la disposición de terminales es la misma que todas las LCDs con
controlador Hitachi HD44780.

La disposición y descripción de terminales es la siguiente:

Nombre de terminales:
Pin Nombre Descripción
1 Vss Conecte a tierra
2 Vcc Conecte a 5V
3 Vee Es la terminal de ajuste de contraste, conéctelo a tierra
4 RS Conéctelo al bit del puerto que le indica el codevision
5 R/W (RD) Conéctelo al bit del puerto que le indica el codevision
6 E (EN) Conéctelo al bit del puerto que le indica el codevision
7 DB0 No conectar
8 DB1 No conectar
9 DB2 No conectar
10 DB3 No conectar
11 DB4 Conéctelo al bit del puerto que le indica el codevision
12 DB5 Conéctelo al bit del puerto que le indica el codevision
13 DB6 Conéctelo al bit del puerto que le indica el codevision
14 DB7 Conéctelo al bit del puerto que le indica el codevision

Si trabaja con el compilador del codevision no haga caso al punto de importante.


Si trabaja en ensamblador u otro compilador tenga en cuenta que:

Importante. La única diferencia con respecto a las pantallas de otras marcas es que la
posición de la DDRAM de la fila superior es 0x84 en lugar de 0x80 y de la fila de abajo
es 0xc4 en lugar de 0xc0
En el codevision dé clic como se muestra en la siguiente figura, si desea colocar la LCD
en otro puerto sólo indíquele donde quiere conectarlo y el compilador le dirá donde
conectar los pines y él se encargará de inicializar la LCD.

Es importante señalar que las siguientes funciones que se explicarán sólo se pueden usar
si se indicó en el codevision que va a utilizar una LCD como fue en el paso anterior.

lcd_gotoxy(x,y);
x y y pueden ser variables tipo unsigned char, o constantes.
Esta función permite indicarle donde colocar el cursor, que es donde empezará a escribir
el mensaje. x es la columna, y es la fila.
Casi todas las pantallas inician con x=0 y y=0, pero ésta en particular tiene las
siguientes coordenadas:
(4,0) (5,0) (6,0) (7,0) (8,0) (9,0) (10,0) (11,0) (12,0) (13,0) (14,0) (15,0) (16,1) (17,1) (18,1) (19,1)
(4,1) (5,1) (6,1) (7,1) (8,1) (9,1) (10,1) (11,1) (12,1) (13,1) (14,1) (15,1) (16,2) (17,2) (18,2) (19,2

Note que hay 4 bloques de coordenadas consecutivas, y que en la extrema derecha inicia
en (16,1) y en (16,2).

lcd_putsf(“mensaje”);
Con la función anterior le indicamos el mensaje a escribir en la LCD y empezará donde
ubicamos el cursor con la función lcd_gotoxy(x,y);

Ejemplo1.
Escriba el siguiente mensaje:

C O M I N I D A D A T M E L
P R O Y E C T O S

Note que la parte de TMEL está en otras coordenadas, y que S está en otras
coordenadas, así que para desplegar el mensaje debemos hacer lo siguiente:

lcd_gotoxy(5,0);
putsf(“COMUNIDAD A”);
lcd_gotoxy(16,1);
putsf(“TMEL”);
lcd_gotoxy(8,1);
putsf(“PROYECTO”);
lcd_gotoxy(16,2);
putsf(“S”);

Y con ello desplegamos el mensaje completo, esto lo tuvimos que hacer porque las
coordenadas en x no son consecutivas y por lo tanto hay que cambiar de región para
desplegar el mensaje.

Otras funciones útiles:

Borrar Pantalla
lcd_clear(); // Esta función borra el mensaje en el display.
Escribir un carácter o una variable
lcd_putchar(‘A’); // Esta función escribe en pantalla una sóla letra o un carácter

Importante al hacer ‘B’ el compilador convierte el carácter a su equivalente ASCII,


pero también podemos ver el código ASCII en la siguiente tabla y hacer
lcd_putchar(0x40); el código 0x40 corresponde a la A.

Note en la tabla de abajo que el código ASCII del 0 al 9 es 0x30+número, el 0x30 es del
0 y el del 9 es 0x39, así que si desea imprimir una variable, digamos que valga 27,
entonces debemos obtener sus dos digitos (decenas y unidades) y sumarle 0x30 para
convertir ese número a ASCII.

Si deseará sacar el símbolo de grados (o un símbolo raro) tendría que ver su código y
poner lcd_putchar(0xdf); //El código=0xdf corresponde al de grados
Control de la LCD: Cursor On-Off, Parpadeo On-Off, Stand by de LCD on-Off

Aquí se deben usar dos funciones siempre:


_lcd_ready();
_lcd_data(dato);

Los bits para controlar el cursor y la pantalla son:


Dato=00001DCB
D=1 Enciende pantalla, D=0 coloca en stand by la pantalla (bajo consumo)
C=1 Cursor on, C=0 Cursor Off
B=1 Cursor parpadea, B=0 Cursor fijo

El bit B sólo tiene sentido si el cursor está on. Cuando el bit D=0 apaga la pantalla
pareciendo que borra la información, pero no la borra, cuando D=1 la enciende de
nuevo apareciendo los caracteres escritos.

Ejemplo. Suponga que quiere pantalla on, cursor on y parpadeo de cursor on, entonces
deberá escribir:

_lcd_ready();
_lcd_data(0x0f); //Dato=00001DCB con D=1, C=1 y B=1 entonces dato=0x0f;

Programa Ejemplo: Configure la LCD para usarla en el puerto B, recuerde que debe
seleccionar 16 en el wizard. En este programa usé delays para poder ver los efectos del
cursor on, apagar cursosr, etc.

#include <mega48.h>
#include <delay.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x05 ;PORTB
#endasm
#include <lcd.h>

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 8


#pragma optsize-
CLKPR=0x80;
CLKPR=0x03;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization


// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2A output: Disconnected
// OC2B output: Disconnected
ASSR=0x00;
TCCR2A=0x00;
TCCR2B=0x00;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;

// External Interrupt(s) initialization


// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=0x00;
EIMSK=0x00;
PCICR=0x00;

// Timer/Counter 0 Interrupt(s) initialization


TIMSK0=0x00;
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=0x00;
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=0x00;

// Analog Comparator initialization


// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;
// LCD module initialization

lcd_init(16);

while (1)
{
lcd_gotoxy(4,0);
lcd_putsf("IVONNE");
delay_ms(4000); //Delay de 1 segundo para poder ver el efecto
lcd_clear();
delay_ms(4000); //Delay de 1 segundo
lcd_gotoxy(4,0);
lcd_putsf("DAVID");
delay_ms(4000); //Delay de 1 segundo
_lcd_ready();
_lcd_write_data(0x0f); //Display On Cursor On parpadeo On
delay_ms(4000); //Delay de 1 segundo
_lcd_ready();
_lcd_write_data(0x0e); //Display On Cursor On parpadeo Off
delay_ms(4000); //Delay de 1 segundo
_lcd_ready();
_lcd_write_data(0x0b); //Display Off Cursor On parpadeo Off
delay_ms(4000); //Delay de 1 segundo
_lcd_ready();
_lcd_write_data(0x0c); //Display On Cursor Off parpadeo Off

// Place your code here


for(;;);
};
}

Desplazamiento de texto

Antes de iniciar con esta parte es importante indicar que las pantallas basadas en el chip
HD44780 como es el caso de esta tiene la posibilidad de manejar hasta 80 caracteres.
Esto significa que si la pantalla es de 16*2 muestra 32 caracteres a la vez, pero hay 48
caracteres que no se ven, imagine que tiene un papel de dos lineas con 40 caracteres y
existe una ventana de 16*2 para poder ver esos caracteres es necesario mover la
“ventana” en este caso la ventana es el display. Existe la posibilidad de mover a la izq.
O derecha el puro cursor pero en ese caso no se moverá la “ventana” para ver los
caracteres que no alcanza a visualizar la pantalla, entonces lo que se ocupa hacer es
mover la “ventana” a la izq. O derecha. Esta función la hacemos con los siguientes bits:

Aquí se deben usar dos funciones siempre:


_lcd_ready();
_lcd_data(dato);

Los bits para controlar el desplazamiento del cursor y la pantalla son:


Dato=0001 S/C R/L 00

Y los bits S/C y R/L tienen la siguiente descripción

S/C R/L Descripción


0 0 Desplaza el cursor a la izquierda
0 1 Desplaza el cursor a la derecha
1 0 Desplaza la pantalla y cursor a la izquierda
1 1 Desplaza la pantalla y cursor a la derecha
Si queremos mover el mensaje a la derecha entonces S/C=1 y R/L=1 por lo que
Dato=00011100

Vea el siguiente programa:


Inicialice el display en 16 con el codevision y dígale que se va a conectar al puerto B.
Lo que está en azul es el código que deberá agregar, programe el microcontrolador,
conéctelo y vea el desplazamiento del mensaje.

#include <mega48.h>
#include <delay.h>
unsigned char i;
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x05 ;PORTB
#endasm
#include <lcd.h>

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 8


#pragma optsize-
CLKPR=0x80;
CLKPR=0x03;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization


// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2A output: Disconnected
// OC2B output: Disconnected
ASSR=0x00;
TCCR2A=0x00;
TCCR2B=0x00;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;

// External Interrupt(s) initialization


// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=0x00;
EIMSK=0x00;
PCICR=0x00;

// Timer/Counter 0 Interrupt(s) initialization


TIMSK0=0x00;
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=0x00;
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=0x00;

// Analog Comparator initialization


// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;

// LCD module initialization


lcd_init(16);

while (1)
{
// Place your code here
_lcd_ready();
_lcd_write_data(0x0e); //Display On Cursor On parpadeo Off
delay_ms(1000);

lcd_gotoxy(6,0); //En la segunda columna comienza el mensaje


lcd_putsf("IVONNE");

for(i=0;i<20;i++)
{
_lcd_ready();
_lcd_write_data(0x1c); //Desplaza cursor y mensaje a derecha
delay_ms(1000);
};
// Place your code here
};
}

Importante. Sólo se muestran algunas funciones para el manejo de la LCD pero es


posible otras funciones como generar caracteres, si desea abundar más en ello puede
bajar la hoja de datos del microcontrolador hd4470 en pdf y ahí verá información de
ello.

Importante. Este tutorial está enfocado con la pantalla de www.comunidadatmel.com si


maneja otra puede que existan ligeros cambios. El fin de este tutorial es para iniciar a
los programadores de los microcontroladores de ATMEL en el manejo de la LCD, si
tienen dudas exprésenlas en el foro de la página esperando que les ayuden aquellas
personas que trabajan con ATMEL. Dudas, preguntas por correo no respondo ninguna
(He llegado a recibir más de 100 en un solo día de distintas partes del mundo), mi
objetivo es dar las herramientas necesarias para que partan de ahí.

Atentamente
David Infante Sánchez
Fundador de www.comunidadatmel.com