UNIVERASIDAD NACIONAL DEL CALLAO-FIEE- MICROCONTROLADORES-2015 MICROCONTROLADORES-2015
CONTROL DE MODULO LCD CON ATMEGA8 Introducción
Este capítulo capítulo está está dedicado dedicado a los LCDs LCDs alfanuméricos alfanuméricos con controlador Hitachi HD44780 o compatible, es decir, decir, la mayoría. Hay diversas diversas firmas, como Optrex Optrex,, Sharp Sharp,, Crystalfontz America, America, Tianma Tianma,, etc., que producen muchísimos LCDs de este tipo. Los hay desde 1 a 4 líneas, desde 8 a 40 letras por línea, algunos con iluminación de fondo, con diferente tecnología de fabricación, etc. Dada la compatibilidad en el control de todos ellos, la elección de un modelo en particular queda a tu cargo. El LCD utilizado en este curso es de 2 líneas, de 16 letras cada una.
FIG.1 Un display LCD de 2 líneas, de 16 caracteres cada una. Pines Pines del LCD LCD PINES DEL DISPLAY LCD. Tabla Número de Pin
Número de Pin
Símbolo
1
Vss o GND
2
Vcc o Vdd
3
Vee o Vo
4
RS
5
R/W
6
E
7...14
DB0...DB7
15 y 16
Los pines 15 y 16 corresponden a la iluminación de fondo del LCD, pero aquí el orden varía mucho. Sea como fuere, los 14 primeros pines siempre deberían coincidir. Nombre de señal Función DB0-DB7 o D0-D7
8 líneas de bus de datos. Para transferencia bidireccional de datos entre el MCU y el LCD. DB7 también se puede usar como bit busy flag. En operación de 4 bits solo se usa el nibble alto.
E
Enable – Señal de inicio de operación de lectura/escritura.
R/W
Señal para seleccionar operación de lectura o escritura. 0 : Escribir en LCD 1 : Leer de LCD
RS
Register Select 0 : Registro de comandos (escritura). : Busy flag + puntero de RAM (lectura). 1 : Registro de datos (escritura, lectura). Acceso a DDRAM o CGRAM.
Vee Vee o Vo
Ajuste de cont ontraste del LCD. Vee Vee = GND es máximo imo contr ntraste.
Vdd o Vcc
Alimentación = +5 V típicamente.
Vss
Alimentación = 0 V (GND).
AyK
Son los pin pines de Anodo odo y Katodo odo de la iluminación de fondo ondo que tienen nen alguno unos LCD.
MSc. Ing. JACOB ASTOCONDOR VILLAR
1
UNIVERASIDAD NACIONAL DEL CALLAO-FIEE- MICROCONTROLADORES-2015
Un modo de operación del LCD (con ventajas y desventajas) le permite trabajar sin conectar el pin RW al microcontrolador. En ese modo pin RW siempre debe plantarse a GND.
LCDs con iluminación de fondo Algunos LCDs tienen iluminación de fondo. Esta característica se basa en diferentes tecnologías, siendo la más habitual el empleo de una matriz de diodos LED colocados detrás de la pantalla. La iluminación basada en LEDs suele activarse con los pines 15 y 16, identificados como A (de ánodo) y K (de cátodo) pero no necesariamente en ese orden. Estos pines son independientes del controlador interno del LCD así que de poco sirve que nuestro LCD diga ser compatible con HD44780. La polaridad varía tanto que en los diagramas he puesto 15/16 para no especificar. En todo caso, la independencia de los pines A y K permitirá que todas las prácticas de este curso funcionen con iluminación o sin ella.
Si los pines de iluminación en tu LCD no están marcados como A y K puedes consultar su datasheet para ver cuáles son o averiguarlo manualmente del mismo modo que compruebas la polaridad de un LED: aplica 5 V entre los pines 15 y 16 y si prende,. Como en todo LED, no debes olvidar ponerle una resistencia en serie, como se ve arriba. ¿Resistencia de cuánto? en términos generales, los LEDs de la iluminación requieren cerca de 4.3V y consumen algo de 300 mA. De aquí calculamos que el valor de la resistencia debe andar por los 5 a 20 ohms. Queda a tu criterio hacer los ajustes para que alumbren tanto como quieras.
Memorias del LCD CGROM - Character Generator ROM Es la zona de memoria donde se encuentran grabados los patrones de todos los caracteres que puede visualizar el LCD de fábrica. Tiene grabados cerca de 200 (varía mucho) tipos de caracteres de 5×7 puntos (lo más común) o 32 caracteres de 5×10 puntos. Este último modo es raramente usado porque no todos los modelos lo soportan.
DDRAM - Display Data RAM La DDRAM almacena los códigos de las letras que se visualizan en la pantalla del LCD. Tiene capacidad de 80 bytes, un byte por carácter si la fuente es de 5×7 puntos. Observa que no siempre se podrán visualizar los 80 caracteres. Por ejemplo, si quisiéramos mostrar el mensaje Hello en la pantalla, deberíamos enviar a la DDRAM los códigos ascii de cada letra de esa palabra. El controlador interno del LCD tomará esos códigos para buscar en la CGROM sus correspondientes patrones de visualización y luego los mostrará en la pantalla. La siguiente figura muestra la correspondencia entre las locaciones de la DDRAM y las posiciones de las letras que vemos en la pantalla de un LCD de 2 líneas, particularmente de uno de 2×16. Fíjate en que los 80 bytes de la DDRAM se dividen en dos sectores de 40 bytes, un sector por línea, así: Línea 1, con sector de DDRAM desde 0x00 hasta 0x27. Línea 2, con sector de DDRAM desde 0x40 hasta 0x67. • •
MSc. Ing. JACOB ASTOCONDOR VILLAR
2
UNIVERASIDAD NACIONAL DEL CALLAO-FIEE- MICROCONTROLADORES-2015
Por lo tanto, podemos entender que siempre tenemos un LCD virtual de 2×40; aunque solo podamos ver 8, 16 ó 20 letras por cada línea. Los otros datos escritos en la DDRAM permanecen allí aunque no se visualicen.
Posiciones en DDRAM de las letras de la pantalla (números en hexadecimal).
CGRAM - Character Generator RAM La CGRAM es una RAM de 64 bytes donde el usuario puede programar los patrones de nuevos caracteres gráficos, ya sean de 5×7 puntos (hasta 8 caracteres) o de 5×10 puntos (hasta 4 caracteres). Este tema lo detallaré en la práctica final.
El Puntero de RAM Llamado también Address Counter, es un registro que sirve para acceder a las memorias RAM del LCD. Por ejemplo, si el Puntero de RAM vale 0x00, accedemos a la locación de DDRAM (o CGRAM) de esa dirección. Ahora bien, solo hay un puntero de RAM que trabaja con las dos RAMs del LCD, y para saber a cuál de ellas accede actualmente debemos ver la instrucción enviada más recientemente. Las instrucciones Clear Display, Return Home y Set DDRAM Address designan el Puntero de RAM a la DDRAM, mientras que Set CGRAM Address lo designa a la CGRAM. Afortunadamente, en la gran mayoría de los casos, el Puntero de RAM estará apuntando a la DDRAM. Además, en este caso viene a representar la posición del cursor (visible o no) del LCD en la pantalla
SET DE INSTRUCCIONES DEL DISPLAY LCD Es el controlador interno HD44780 (u otro) del LCD quien ejecutará las operaciones de mostrar las letras en la pantalla, mover el cursor, desplazar el contenido de la pantalla, etc. Lo que nos toca a nosotros es enviarle los códigos de esas operaciones. A continuación, un resumen. Instrucciones del Display LCD
Código RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
Instrucciones
Instrucciones de comando
Instrucciones de datos
Clear Display
0
0
0
0
0
0
0
0
0
1
Return Home
0
0
0
0
0
0
0
0
1
×
Entry Mode Set
0
0
0
0
0
0
0
1
I/D
S
Display ON/OFF Control 0
0
0
0
0
0
1
D
C
B
Cursor or Display Shift
0
0
0
0
0
1
S/C R/L ×
×
Function Set
0
0
0
0
1
DL
N
×
Set CGRAM Address
0
0
0
1
Puntero de RAM (CGRAM)
Set DDRAM Address
0
0
1
Puntero de RAM (DDRAM)
Read Busy & RAM Pointer
0
1
BF
Puntero de RAM (DDRAM o CGRAM)
1
0
Escribir dato
1
1
Leer dato
Flag
Write to or DDRAM
CGRAM
Read from or DDRAM
CGRAM
MSc. Ing. JACOB ASTOCONDOR VILLAR
3
F
×
UNIVERASIDAD NACIONAL DEL CALLAO-FIEE- MICROCONTROLADORES-2015
Conviene saber que las instrucciones Clear Display y Return Home tienen un tiempo de ejecución de cerca de 1.52 ms. Las demás toman algo de 40 µs. El LCD cuenta con dos registros internos principales, que dividen, grosso modo, las instrucciones en de datos y de comando. Poniendo el pin RS = 1 accedemos al registro de datos y mediante él a cualquier locación de la DDRAM o CGRAM, para operaciones de lectura y escritura de datos. Con RS = 0 accedemos al registro de comandos para escribir instrucciones de control del LCD (Clear Display, Function Set, etc.). En el caso de una lectura, obtenemos un dato particular que contiene el valor del puntero de RAM junto con el bit Busy flag.
Clear display: 0 0 0 0 0 0 0 1 Limpia toda la pantalla del LCD. También retorna el cursor a su posición inicial (cima izquierda), esto es, designa el puntero de RAM a la dirección 0x00 de la DDRAM.
Return home: 0 0 0 0 0 0 1 x Regresa el cursor a su posición inicial pero sin alterar el texto del display, es decir, solo designa el puntero de RAM a la dirección 0x00 de la DDRAM.
Entry mode set: 0 0 0 0 0 1 I/D S Establece el modo de incremento o decremento y modo de desplazamiento del LCD. I/D = 1: El puntero de RAM se incrementa en 1 después de leer o escribir un dato. Así accedemos automáticamente a la siguiente locación de DDRAM o CGRAM. Si es DDRAM, este puntero representa la posición del cursor en la pantalla y el incremento significa su avance a la derecha. I/D = 0: El puntero de RAM se decrementa en 1 después de leer o escribir un dato. S = 1: Si se escribe un nuevo dato de carácter en el LCD, entonces el display entero se desplaza a la derecha cuando I/D = 0 o a la izquierda cuando I/D = 1. S = 0: El display no se desplaza luego de escribir en la DDRAM. Esto es lo usual. •
• •
•
Display on/off control: 0 0 0 0 1 D C B Prende o apaga el Display, el Cursor y la función Blink del cursor. D = 1: El display se prende. D = 0: Apaga el display. (No significa que los datos de las RAMs se vayan a borrar.) C = 1: Despliega el cursor. C = 0: No despliega el cursor B = 1: La letra indicada por el cursor parpadea. B = 0: La letra no parpadea. • • • • • •
Cursor or display shift: 0 0 0 1 S/C R/L x x Desplaza el cursor o el display a la derecha o la izquierda sin escribir o leer datos . Tabla S/C
S/C R/L
Operación
0
0
Mueve el cursor a la izquierda (puntero de RAM se decrementa en 1)
0
1
Mueve el cursor a la derecha (puntero de RAM se incrementa en 1)
1
0
El Cursor y el display entero se desplazan a la izquierda
1
1
El Cursor y el display entero se desplazan a la derecha
Function set: 0 0 1 DL N F x x Configura la longitud del bus de datos, el número de líneas y el tipo de fuente. DL = 1 : La interface con el LCD es mediante un bus de datos de 8 bits. DL = 0 : La interface con el LCD es mediante un bus de datos de 4 bits. • •
MSc. Ing. JACOB ASTOCONDOR VILLAR
4
UNIVERASIDAD NACIONAL DEL CALLAO-FIEE- MICROCONTROLADORES-2015
• • • •
N = 1: Configura un display de 2 líneas. N = 0: Configura un display de 1 línea. F = 0: Fuente de carácter de 5×7 puntos. F = 1: Fuente de carácter de 5×10 puntos.
Set DDRAM address: 1AAAAAAA Designa el puntero de RAM a la nueva dirección AAAAAAA de la DDRAM. Digamos que sirve para controlar la posición del cursor del LCD. Ejemplo, para escribir un texto en la segunda línea del display (que tiene dirección inicial 0x40), primero habría que enviar el comando Set DDRAM Address con el número 0x40 en el parámetro AAAAAAA.
Set CGRAM address: 01AAAAAA Designa el puntero de RAM a la nueva dirección AAAAAAA de la CGRAM.
Read Busy Flag & RAM Pointer: BF AAAAAAA Leer bit Busy Flag (BF) y el valor del puntero de RAM. BF = 1 indica que una operación interna está en progreso. El LCD no aceptará una nueva instrucción hasta que BF sea 0.
El valor de AAAAAAA leído representa el valor del puntero de RAM . Es posible prescindir del bit BF. Para ello debemos esperar el tiempo adecuado antes de enviar la siguiente instrucción.
Write data to CGRAM / DDRAM: DDDDDDDD Escribe el dato de 8 bits DDDDDDDD en la DDRAM o CGRAM, dependiendo de cuál de las dos esté siendo direccionada actualmente. Después de la escritura el puntero de RAM se incrementa o decrementa, según se haya configurado el display. Ver instrucción Entry Mode Set.
Read data from CGRAM / DDRAM: DDDDDDDD Lee un dato de 8 bits de la DDRAM o CGRAM, dependiendo de cuál de ellas esté siendo direccionada actualmente. Después de la lectura el puntero de RAM se incrementa o decrementa en uno, según la configuración del display. Ver instrucción Entry Mode Set .
Inicialización del LCD Los LCDs tienen un circuito interno de reset que los inicializan automáticamente tras la alimentación. Lo cierto es que la auto-inicialización no siempre es fiable. Por eso existe la inicialización por software, que permite una completa configuración de los parámetros del LCD. Se constituye de una serie de pasos aparentemente bastante exóticos, sobre todo los primeros, pero que se justifican si tratamos de entender que este procedimiento debe ser capaz de configurar el LCD para que funcione con bus de datos de 4 u 8 bits, sin importar cómo estuvo operando antes, es decir, podemos cambiar "al vuelo" entre un modo y otro. Además de ello cada nueva instrucción debe ser enviada al LCD asegurándonos de que no se encuentre ocupado. El LCD indica su disponibilidad mediante el llamado bit BF (Busy Flag). BF = 1 indica LCD ocupado y BF = 0 es LCD listo. BF es el MSbit del byte que se lee del LCD cuando el pin RS = 0. Obviamente la lectura implica que debemos poder controlar el pin RW. De no usar este pin en nuestra conexión, debemos hacer pausas entre una instrucción y otra. Pero incluso si usamos el bit BF, al inicio debemos poner pausas porque se supone que el LCD aún no sabe si va trabajar con bus de datos de 4 u 8 bits y no sabe cómo responder a las instrucciones de lectura (no sabe si entregar bytes enteros o en nibbles). Que enredo!, ¿verdad? Por eso los siguientes flowcharts se ven tan complicados pese a tratarse de los LCD más simples del mundo. La inicialización de los LCD gráficos por ejemplo es más pequeña.
MSc. Ing. JACOB ASTOCONDOR VILLAR
5
UNIVERASIDAD NACIONAL DEL CALLAO-FIEE- MICROCONTROLADORES-2015
Inicialización del LCD con bus de datos de 4 bits.
MSc. Ing. JACOB ASTOCONDOR VILLAR
6
UNIVERASIDAD NACIONAL DEL CALLAO-FIEE- MICROCONTROLADORES-2015
Inicialización del LCD con bus de datos de 8 bits
Interface entre un Microcontrolador y un display LCD Esta presentación es poco usual. Los libros o los manuales de los compiladores suelen resaltar solo la interface de la librería que proveen. Esta exposición va pensando en los noveles
usuarios del Arduino, que encuentran algo confusa la inicialización de su librería de LCD por contemplar todos los modos de operación viables. Aunque los LCDs parezcan simples de usar, para bien o para mal sus características abren puertas a diversos modos de interface. Considerando que el bus de datos puede ser de 8 o 4 bits y que se puede usar o prescindir de la línea de control RW , podemos obtener los siguientes 4
MSc. Ing. JACOB ASTOCONDOR VILLAR
7
UNIVERASIDAD NACIONAL DEL CALLAO-FIEE- MICROCONTROLADORES-2015
tipos de conexión. (Nota, la conexión de los pines de alimentación, de contraste y de la iluminación de fondo se estudia en la sección pines del LCD) Interface de display LCD
8 líneas de Datos
4 líneas de Datos
3 líneas de Control (con RW) Interface de 11 líneas Interface de 7 líneas 2 líneas de Control (sin RW) Interface de 10 líneas Interface de 6 líneas
La interface de 11 líneas se trabaja con los 8 bits del bus de datos y las 3 líneas de Control. El uso del pin RW controla las operaciones de escritura (RW = 0) y lectura ( RW = 1) del LCD. Las lecturas nos permiten por un lado conocer si el LCD está ocupado o no para saber si podemos enviar la siguiente instrucción de escritura, así como leer la posición actual del cursor. La otra finalidad de las lecturas es obtener los datos de las memorias DDRAM y CGRAM del LCD. Los datasheets dicen que el acceso bidireccional a las rams del LCD permite utilizarlas como memoria extendida del sistema. Ahora parece hasta ridículo pero tiene cierto sentido considerando que estos LCDs nacieron en la prehistoria de los microcontroladores , donde los microcontroladores tenían muy poca RAM o en su lugar se usaban microprocesadores (que simplemente no tienen RAM).
Interface de 11 líneas entre un microcontrolador y un LCD
En la interface de 10 lineas El pin RW del LCD va siempre plantado a GND (RW = 0). Ello significa que el LCD solo aceptará operaciones de escritura del microcontrolador. Renunciar a la lectura de las memorias RAM es un hecho que pasa casi desapercibido. El punto clave de no controlar el pin RW es no enviar al LCD una nueva instrucción sin que haya terminado de procesar la anterior. Ya que no podemos leer del LCD para saber su estado, debemos calcular su disponibilidad a partir de los tiempos que demoran en ejecutarse las instrucciones. Por ejemplo, una vez inviada la instrucción Clear Display debemos esperar al menos 1.6 ms (que es su tiempo de ejecución) antes de enviar la siguiente instrucción.
MSc. Ing. JACOB ASTOCONDOR VILLAR
8
UNIVERASIDAD NACIONAL DEL CALLAO-FIEE- MICROCONTROLADORES-2015
Interface de 10 líneas entre un microcontrolador y un LCD
En la interface de 7 líneas El bus de datos del LCD se conecta con el microcontrolador por sus 4 pines más altos: D4, D5, D6 y D7. Como todas las instrucciones (de datos y de comando) son de un byte, los bytes deben ser transferidos en dos mitades. Primero se envía o recibe el nibble alto y luego el nibble bajo, siendo cada nibble validado por un pulso del pin Enable. Esas rutinas extras harán crecer un poco el firmware (programa del microcontrolador). En la contraparte, con el microcontrolador aun disponiendo de las tres líneas de control, podemos realizar cualquier operación de lectura y escritura, lo mismo que en la interface completa de 11 líneas pero ahorrándonos 4 pines. Este beneficio suele prevalecer sobre el handicap derivado del firmware. Los LCDs están fabricados con tecnología CMOS, por lo que algunos modelos sugieren conectar los pines de entrada no usados a alguna señal estable para evitar que por ellos se filtre algún ruido que pueda perturbar la operación del LCD.
Interface de 7 líneas entre un microcontrolador y un LCD
Por último tenemos la interface de 6 líneas. Aquí se nos juntan todas las desventajas software de tener que trabajar a base de nibbles y de renunciar a las lecturas del LCD para obtener datos de sus memorias RAM o para saber si el LCD está ocupado o no antes de poder enviarle una nueva instrucción. A pesar de todo eso, pueden darse ocasiones, como disponer de un microcontrolador de muy pocos pines, donde tengamos que recurrir a esta conexión.
Interface de 6 líneas entre un microcontrolador y un LCD MSc. Ing. JACOB ASTOCONDOR VILLAR
9
UNIVERASIDAD NACIONAL DEL CALLAO-FIEE- MICROCONTROLADORES-2015
LIBRERÍA PARA DISPLAY LCD Tenemos a continuación una librería para controlar un LCD con una interface de 4 bits y usando el bit BF (Busy Flag). Si tuviste la paciencia de leer las páginas anteriores, verás que es un claro reflejo de todo lo expuesto. Y si no, de todos modos en seguida citaré ligeramente cómo utilizarla. La librería trabaja para los compiladores IAR C y AVR GCC y consta de dos archivos
lcd.h y lcd.c.
Ambos deberán ser indexados al proyecto en el entorno de AVR IAR C o Atmel Studio 6 para WinAVR (ante alguna duda puedes ir a la sección Adición de Archivos o Librerías al Proyecto). En el código fuente, sin embargo, solo se debe indicar el archivo de cabecera i2c.h mediante la directiva #include. #include "lcd.h"
La librería utiliza por defecto el puerto B del AVR tanto para el bus de datos del LCD como para las líneas de control E, RS y R/W. Esta interface se puede modificar en los #defines del archivo i2c.h. Nota que por cada puerto se deben cambiar los tres registros, PORT, DDR y PIN. Esa podría ser una configuración de cierta recurrencia, en cambio, no deberíamos tocar lcd.c, salvo que por alguna razón deseemos editar su código.
Funciones Básicas Disponibles •
•
•
• •
•
lcd_init(). Obviamente es la primera función a llamar. Tras ejecutarse el LCD debe quedar inicializado, con la pantalla limpia y con el cursor en el primer casillero. lcd_gotorc(r,c). El LCD tiene un cursor que, si bien puede mostrarse en pantalla, suele configurarse para que permanezca oculto. Bien, visible o no, el cursor avanza automáticamente tras cada letra que se escribe. Con lcd_gotorc(r,c) podemos mover el cursor manualmente a la fila r y columna c. El parámetro r puede valer entre 1 y 2, y el valor de c va de 1 en adelante. lcd_puts(s). Visualiza la cadena s en el LCD empezando en la posición actual del cursor. La cadena s es almacenada en RAM. No se suelen mostrar grandes datos en un LCD, así que no implemente una función análoga que opere sobre la memoria FLASH.
lcd_clear(). Limpia la pantalla del LCD y coloca el cursor al inicio, en la fila 1, columna 1.
lcd_data(c). Escribe una sola letra en el LCD, en la posición actual del cursor. lcd_data() también permite crear caracteres gráficos, como se muestra en una práctica más adelante. lcd_cmd(com). Ocasionalmente también usaremos esta función para enviar comandos al LCD, por ejemplo: • • • • •
lcd_cmd(LCD_LINE2); //Mover cursor al inicio de línea 2 lcd_cmd(LCD_CLEAR); // Limpiar pantalla lcd_cmd(LCD_CURBLK); // Mostrar Cursor + Blink lcd_cmd(LCD_CURSOR); // Mostrar solo Cursor lcd_cmd(LCD_CGRAM+7); //Mover Puntero de RAM a dirección 7 de la CGRAM
Las constantes LCD_CLEAR y algunas más se hallan definidas en el archivo lcd.h. Por supuesto que también se pueden formar cualesquiera códigos de instrucciones de los estudiados antes.
MSc. Ing. JACOB ASTOCONDOR VILLAR
10
UNIVERASIDAD NACIONAL DEL CALLAO-FIEE- MICROCONTROLADORES-2015
/****************************************************************** lcd.h * FileName: * Purpose: Librería de funciones para controlar un display LCD con chip * Hitachi HD44780 o compatible. La interface es de 4 bits. * Processor: ATmel AVR * Compiler: AVR IAR C y AVR GCC (WinAVR) * Author: *******************************************************************/ #include "avr_compiler.h" //****************************************************************** // CONFIGURACIÓN DE LOS PINES DE INTERFACE //****************************************************************** /* Define el puerto a donde se conectará el bus de datos del LCD * Se utilizará el nible alto del puerto escogido (ejem. PB4-DB4,...,PB7-DB7) */ #define lcd_DATAout PORTB // Registro PORT del puerto #define lcd_DATAin PINB // Registro PIN del puerto #define lcd_DATAddr DDRB // Registro DDR del puerto /* Define * E, RW #define #define #define
el puerto a donde se conectarán las líneas de control del LCD
y RS. Puede ser el mismo lcd_CTRLout PORTB lcd_CTRLin PINB lcd_CTRLddr DDRB
puerto del bus de datos.*/ // Registro PORT del puerto // Registro PIN del puerto // Registro DDR del puerto
/* Define los números de los pines del puerto anterior que corresponderán a * las líneas E, RW y RS del LCD. */ #define lcd_E 3 // Pin Enable #define lcd_RW 2 // Pin Read/Write #define lcd_RS 1 // Pin Register Select //***************************************************************** // CÓDIGOS DE COMANDO USUALES //***************************************************************** #define LCD_CLEAR 0x01 // Limpiar Display #define LCD_RETHOM 0x02 // Cursor a inicio de línea 1 #define LCD_LINE1 0x80 // Línea 1 posición 0 #define LCD_LINE2 0xC0 // Línea 2 posición 0 #define LCD_DDRAM 0x80 // Dirección 0x00 de DDRAM #define LCD_CGRAM 0x40 // Dirección 0x00 de CGRAM #define LCD_CURSOR 0x0E // Mostrar solo Cursor #define LCD_BLINK 0x0D // Mostrar solo Blink #define LCD_CURBLK 0x0F // Mostrar Cursor + Blink #define LCD_NOCURBLK 0x0C // No mostrar ni Cursor ni Blink //**************************************************************** // PROTOTIPOS DE FUNCIONES //*************************************************************** void lcd_init(void); // Inicializa el LCD void lcd_puts(char * s); // Envía una cadena ram al LCD void lcd_gotorc(char r, char c); // Cursor a fila r, columna c void lcd_clear(void); // Limpia el LCD y regresa el cursor al inicio void lcd_data(char dat); // Envía una instrucción de dato al LCD void lcd_cmd(char com); // Envía una instrucción de comando al LCD char lcd_read(char RS); // Lee un dato del LCD void lcd_write(char inst, char RS); // Escribe una instrucción en el LCD void lcd_nibble(char nibble); void ldelay_ms(unsigned char );
MSc. Ing. JACOB ASTOCONDOR VILLAR
11
UNIVERASIDAD NACIONAL DEL CALLAO-FIEE- MICROCONTROLADORES-2015
/*********************************************************** ******* * FileName:
lcd.c
* Purpose: Librería de funciones para controlar un display LCD con chip * Hitachi HD44780 o compatible. La interface es de 4 bits. * Processor: ATmel AVR * Compiler: AVR IAR C y AVR GCC (WinAVR) * Author: *******************************************************************/ #include "lcd.h" //******************************************************************* // Ejecuta la inicialización software completa del LCD. La configuración es // de: interface de 4 bits, despliegue de 2 líneas y caracteres de 5x7 puntos. //******************************************************************** void lcd_init(void)
{ /* Configurar las direcciones de los pines de interface del LCD */ lcd_DATAddr |= 0xF0; lcd_CTRLddr |= (1< 40 ms lcd_nibble(0x30); // Function Set: 8-bit ldelay_ms(5); // > 4.1 ms lcd_nibble(0x30); // Function Set: 8-bit ldelay_ms(1); // > 100 µs lcd_nibble(0x30); // Function Set: 8-bit ldelay_ms(1); // > 40 µs lcd_nibble(0x20); // Function Set: 4-bit ldelay_ms(1); // > 40 µs lcd_nibble(0x20); // Function Set: 4-bit, 2lines, 4×7font lcd_nibble(0x80); // lcd_write(0x0C, 0);//Display ON/OFF Control: Display on, Cursor off, Blink off lcd_write(0x01, 0); lcd_write(0x06, 0);
// Clear Display // Entry Mode Set
} //****************************************************************** // Escribe una instrucción en el LCD: // Si RS = 0 la instrucción es de comando (Function Set, Entry Mode set, etc). // Si RS = 1 la instrucción es de dato y va a la DDRAM o CGRAM. //******************************************************************** void lcd_write(char inst, char RS) { while(lcd_read(0)&0x80); // Esperar mientras LCD esté ocupado if(RS) lcd_CTRLout |= (1< 140 ns lcd_CTRLout |= (1< 450 ns lcd_CTRLout &= ~(1<
12
UNIVERASIDAD NACIONAL DEL CALLAO-FIEE- MICROCONTROLADORES-2015
// Si RS = 0 se lee el 'bit de Busy Flag' + el 'Puntero de RAM'. //**************************************************************** char lcd_read(char RS) { char high, low; if(RS) lcd_CTRLout |= (1< 140 ns lcd_CTRLout |= (1< 1320 ns high = lcd_DATAin; // Leer nibble alto lcd_CTRLout &= ~(1< 1200 ns lcd_CTRLout |= (1< 1320 ns low = lcd_DATAin; // Leer nibble bajo lcd_CTRLout &= ~(1<>4); // Juntar nibbles leídos } //******************************************************************* // Envían cadenas RAM terminadas en nulo al LCD. //****************************************************************** void lcd_puts(char * s) { unsigned char c, i=0; while(c = s[i++]) lcd_write(c, 1); // Instrucción 'Write Data to DDRAM/CGRAM' } //****************************************************************** // Ubica el cursor del LCD en la columna c de la línea r. //*********************************************************** void lcd_gotorc(char r, char c) { if(r==1) r = LCD_LINE1; else r = LCD_LINE2; lcd_write(r+c-1, 0); // Instrucción 'Set DDRAM Address' } //************************************************************* // Limpia la pantalla del LCD y regresa el cursor a la primera posición // de la línea 1. //*************************************************************** void lcd_clear(void) { lcd_write(LCD_CLEAR, 0); // Instrucción 'Clear Display' } //************************************************************ // Envían instrucciones de comando y de datos al LCD. //************************************************************ void lcd_cmd(char com) { lcd_write(com, 0); // Cualquier instrucción de comando } void lcd_data(char dat) { lcd_write(dat, 1); // Instrucción 'Write Data to DDRAM/CGRAM' } //*********************************************************** // Genera un delay de n milisegundos //********************************************************* void ldelay_ms(unsigned char n) { while(n--) delay_us(1000); }
MSc. Ing. JACOB ASTOCONDOR VILLAR
13
UNIVERASIDAD NACIONAL DEL CALLAO-FIEE- MICROCONTROLADORES-2015
LABORATORIO CONTROL DEL MODULO LCD FUNDAMENTO Mostrar un mensaje de “UNAC -FIEE Y MICRO – ATMEGA8 ” en el LCD es un programa de visualización de mensaje en el LCD. Según la configuración por defecto de la librería para el LCD, debemos usar la conexión mostrada en el esquema de abajo. La configuración de puertos y de pines a usar se puede cambiar en archivo lcd.h . El pin VEE (o Vo) del LCD establece el contraste de la pantalla. Muchas veces se prefiere quitar el potenciómetro y conectar VEE a tierra para fijar el máximo contraste. En los siguientes circuitos haremos algo parecido. Instrucciones
/************************************************************************ * FileName: main.c * Purpose: LCD - Visualización de texto * Processor: AVR ATmegaXX4 * Compiler: AVR IAR C & AVR GCC (WinAVR) * Author: ************************************************************************/
#include "avr_compiler.h" #include "lcd.h" void delay_ms(unsigned int t) { while(t--) delay_us(1000); } int main(void) { lcd_init(); // Inicializar LCD while(1) { lcd_gotorc(1,7); // Cursor a fila 1 posición 7 lcd_puts("Hello"); // Escribir Hello lcd_gotorc(2,7); // Cursor a fila 2 posición 7 lcd_puts("World"); // ... delay_ms(600); // Pausa de 600 ms lcd_clear(); // Limpiar pantalla delay_ms(400); // ... } }
CIRCUITO A IMPLEMENTAR
MSc. Ing. JACOB ASTOCONDOR VILLAR
14