Ejemplo 3 - Manejo del LCD
Antes de empezar
Referencias principales:
- Microcontroladores PIC - Programación en BASIC: componentes-adicionales (link)
- Character LCDs - Adafruit (link)
- Basic Character LCD Hookup Guide - Sparkfun (link)
- Random Nerd Tutorials (link)
- SparkFun Inventor's Kit Experiment Guide - v4.0 --> Project 4: Display (link)
Sobre los displays LCD
Pines y conexión
La siguiente figura muestra un LCD 16x2 con sus respectivos pines de interfaz:
La descripción de cada uno de los pines se muestra en la siguiente tabla:
Función | Pin | Nombre | Estado Lógico | Descripción |
---|---|---|---|---|
Tierra (GND) | 1 | VSS | - | 0V |
Alimentación | 2 | VDD | - | +5V |
Contraste | 3 | VEE o V0 | - | 0 - VDD |
Control de funcionamiento | 4 | RS | 0/1 | |
Control de funcionamiento | 5 | R/W | 0/1 | |
Control de funcionamiento | 6 | E | Transición de 0 a 1 | |
Datos / Comandos | 7 | D0 | 0 / 1 | Bit 0 LSB |
Datos / Comandos | 8 | D1 | 0 / 1 | Bit 1 |
Datos / Comandos | 9 | D2 | 0 / 1 | Bit 2 |
Datos / Comandos | 10 | D3 | 0 / 1 | Bit 3 |
Datos / Comandos | 11 | D4 | 0 / 1 | Bit 4 |
Datos / Comandos | 12 | D5 | 0 / 1 | Bit 5 |
Datos / Comandos | 13 | D6 | 0 / 1 | Bit 6 |
Datos / Comandos | 14 | D7 | 0 / 1 | Bit 7 MSB |
Alimentación positiva del backlight | 15 | K | - | 0V |
Alimentación negativa del backlight | 16 | A | - | +5V |
La siguiente figura muestra la forma conexión tipica entre un LCD y un microcontrolador:
Tal y como se resalta en la figura, es posible usar o no todas las lineas de datos del LCD y de esto depende el tipo de conexión la cual puede ser:
- Conexión a 4 lineas: Los bits de datos menos significativos (D0-D3) no se conectan.
- Conexión a 8 lineas: Se conectan todos los pines asociados a los bits de datos.
Los display LCD que normalmente se suelen usar, emplean el controlador Hitachi HD44780. El datasheet del controlador Hitachi HD44780 (link) contiene toda la información sobre la estructura, comunicación y control del LCD y por lo tanto, es una guia obligada cuando se desea diseñar un driver desde cero. El estudio de esta información se sale de los objetivos de esta guia (y hasta nos da tres vueltas) de modo que no se tratara en detalle. Sin embargo es util hablar de algunos aspectos basicos del controlador Hitachi.
Memoria del controlador Hitachi HD44780
El controlador Hitachi HD44780 tiene tres localizaciones de memoria principales:
-
DDRAM (Data Display Random Access Memory): La memoria DDRAM se utiliza para almacenar los caracteres a visualizar. Tiene una capacidad de almacenar 80 caracteres.
-
CGROM (Character Generation Read Only Memory): Esta memoria contiene un mapa estándar de todos los caracteres que se pueden visualizar en la pantalla. A cada carácter se le asigna lugar de memoria, las direcciones de cada uno de los caracteres son los numeros de cada uno de los caracteres ASCCI (tabla ASCII):
-
CGRAM (Character Generation Random Access Memory): En esta región de 64 bytes se almacenan los caracteres definidos por el usuario (personalizados). El usario puede definir hasta 8 caracteres de 5x8 pixeles. Para esto, se utiliza los 5 bits mas bajos de cada registro (de 8 bits) para definir los puntos oscuros (1) de cada fila que conforma el caracter el cual, agrupa un total de ocho filas (registros).
Comandos básicos
Todos los datos transmitidos a un display LCD por las salidas D0-D7 serán interpretados como un comando o un dato dependiendo del estado logico de pin RS:
- RS = 1: Los bits D0 - D7 son direcciones de los caracteres a visualizar. En este caso, el controlado del LCD direcciona un carácter seleccionado y lo visualiza en la dirección especificada en la DDRAM la cual se define antes de transmitir el carácter, o en caso contrario se toma con base en la dirección del carácter anteriormente transmitido la cual se aumenta automaticamente.
- RS = 0: Los bits D0 - D7 son empleados como comandos para ajustar el modo del visualización.
La siguiente tabla muestra una linea de comandos para el LCD:
Comando | RS | RW | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | |
---|---|---|---|---|---|---|---|---|---|---|---|
Borrar el visualizador | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | |
Poner el cursor al inicio | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | x | |
Modo de entrada | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | I/D | S | |
Activar/desactivar el visualizador | 0 | 0 | 0 | 0 | 0 | 0 | 1 | D | U | B | |
Desplazar el cursor/visualizador | 0 | 0 | 0 | 0 | 0 | 1 | D/C | R/L | x | x | |
Modo de funcionamiento | 0 | 0 | 0 | 0 | 1 | DL | N | F | x | x | |
Establecer la dirección CGRAM | 0 | 0 | 0 | 1 | Dirección CGRAM | ||||||
Establecer la dirección DDRAM | 0 | 0 | 1 | Dirección DDRAM | |||||||
Leer la bandera "BUSY"(ocupado) (BF) | 0 | 1 | BF | Dirección DDRAM | |||||||
Escribir en la CGRAM o en la DDRAM | 1 | 0 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | |
Leer la CGRAM o la DDRAM | 1 | 1 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
Donde:
- I/D
- 1 = Incremento (por 1)
- 0 = Decremento (por 1)
- R/L
- 1 = Desplazamiento a la derecha
- 0 = Desplazamiento a la izquierda
- S
- 1 = Desplazamiento del visualizador activado
- 0 = Desplazamiento del visualizador desactivado
- DL
- 1 = Bus de datos de 8 bits
- 0 = Bus de datos de 4 bits
- D
- 1 = Visualizador encendido
- 0 = Visualizador apagado
- N
- 1 = Visualizar en dos lineas
- 0 = Visualizar en una linea
- U
- 1 = Cursor activado
- 0 = Cursor desactivado
- F
- 1 = Carácter de 5x8 puntos
- 0 = Carácter de 5x7 puntos
- B
- 1 = Parpadeo del cursor encendido
- 0 = Parpadeo del cursor apagado
- D/C
- 1 = Desplazamiento del visualizador
- 0 = Desplazamiento del cursor
Bandera de ocupado (BF - BUSY FLAG)
Es una señal que indica que el display esta listo para recibir el siguiente dato, despues de ejecutado un comando. Esta señal se puede leer de la línea D7 y cuando su valor es de 0V (BF=0) indica que el display esta listo para recibir un nuevo comando.
Manejo del LCD usando Arduino
Afortunadamente no es necesario implementar toda la logica anterior ya que esto implicaria diseñar el driver.
Las funciones para el control del LCD de caracteres se encuentran en la libreria LiquidCrystal de Arduino (link). Afortunadamente, estas tambien funcionan para el ESP32.
Función | Descripción |
---|---|
LiquidCrystal() | Crea un objeto tipo LiquidCrystal para controlar el display. El display puede ser controlado usando usando una conexión a 4 (para lo cual se dejan sin conectar D0-D3) u 8 lineas. Adicionalmente, el pin RW lo cual permite que sea omitido como parametro de la funciónSintaxis: LiquidCrystal(rs, enable, d4, d5, d6, d7) LiquidCrystal(rs, rw, enable, d4, d5, d6, d7) LiquidCrystal(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7) LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7) Parámetros: rs : Numero del pin del arduino conectado al pin RS del LCD rw : Numero del pin del arduino conectado al pin RW del LCD enable : Numero del pin del arduino conectado al pin E del LCD d0, d1, d2, d3, d4, d5, d6, d7 : Numero de los pines del arduino conectado a los correspondientes pines del bus de datos del LCD. Los parametros d0, d1, d2, d3 son opcionales y son omitidos cuando el LDC se conecta al arduino usando cuatro lineas |
begin() | Especifica tipo de display que sera empleado indicando sus dimensiones (filas y columnas) Sintaxis: lcd.begin(cols, rows) Parámetros: lcd : Variable tipo LiquidCrystal .cols : Numero de columnas que tiene el display.rows : Numero de filas que tiene el display. |
clear() | Borra la pantalla del LDC y coloca el cursor en la esquina superior izquierda. Sintaxis: lcd.clear() Parámetros: lcd : Variable tipo LiquidCrystal |
home() | Posiciona el cursor en la parte superior izquierda de la pantalla LCD. Sintaxis: lcd.home() Parámetros: lcd : Variable tipo LiquidCrystal |
setCursor() | Especifica la posición en la que se ubicara el cursor Sintaxis: lcd.setCursor(col, row) Parámetros: lcd : Variable tipo LiquidCrystal .col : Columna en la que se ubicara el cursor (siendo 0 la primera columna).row : Fila en la que se colocará el cursor (Donde 0 es la primera fila). |
write() | Escribe un caracter en el LCD Sintaxis: lcd.write(data) Parámetros: lcd : Variable tipo LiquidCrystal .data : Caracter a escribir en el Display. |
print() | Imprime texto en el LCD Sintaxis: lcd.print(data) lcd.print(data,BASE) Parámetros: lcd : Variable tipo LiquidCrystal .data : Dato a imprimir (char , byte , int , long , or string ).BASE : Parametro opcional para definir la BASE en la que se muestran los numeros (BIN , DEC , OCT , HEX , or string ). |
cursor() | Muestra el cursor en el LCD Sintaxis: lcd.cursor() Parámetros: lcd : Variable tipo LiquidCrystal |
noCursor() | Oculta el cursor Sintaxis: lcd.noCursor() Parámetros: lcd : Variable tipo LiquidCrystal |
blink() | Muestra el cursor parpadeando Sintaxis: lcd.blink() Parámetros: lcd : Variable tipo LiquidCrystal |
noBlink() | Apaga el parpadeo del cursor Sintaxis: lcd.noBlink() Parámetros: lcd : Variable tipo LiquidCrystal |
display() | Enciende la pantalla del LCD, después de apagarla con noDisplay() .Sintaxis: lcd.display() Parámetros: lcd : Variable tipo LiquidCrystal |
noDisplay() | Apaga la pantalla del display. El texto que se encuentra en esta no se pierde. Sintaxis: lcd.noDisplay() Parámetros: lcd : Variable tipo LiquidCrystal |
scrollDisplayLeft() | Desplaza el contenido del display (texto y cursor) un espacio a la izquierda. Sintaxis: lcd.scrollDisplayLeft() Parámetros: lcd : Variable tipo LiquidCrystal |
scrollDisplayRight() | Desplaza el contenido del display (texto y cursor) un espacio a la derecha. Sintaxis: lcd.scrollDisplayRight() Parámetros: lcd : Variable tipo LiquidCrystal |
autoScroll() | Activa el desplazamiento automatico del contenido del display. Sintaxis: lcd.autoScroll() Parámetros: lcd : Variable tipo LiquidCrystal |
noAutoScroll() | Desactiva el desplazamiento automatico del contenido del display. Sintaxis: lcd.noAutoScroll() Parámetros: lcd : Variable tipo LiquidCrystal |
leftToRight() | Establece la dirección en que se escribe el texto en el display de izquierda a derecha (default). Sintaxis: lcd.leftToRight() Parámetros: lcd : Variable tipo LiquidCrystal |
rightToLeft() | Establece la dirección en que se escribe el texto en el display de derecha a izquierda. Sintaxis: lcd.rightToLeft() Parámetros: lcd : Variable tipo LiquidCrystal |
createChar() | Crea un carácter personalizado (glyph) para ser usado en el LCD. Se admiten hasta ocho caracteres de 5x8 píxeles (numeradas del 0 al 7). La apariencia de cada caracter se define en un arreglo de 8 bytes, uno por cada fila. Los cinco bits menos significativos de cada byte determinan los pixeles en esa fila. Para mostrar un caracter personalizado en el display se usa la función write con el numero del caracter personalizado (0-7) que se quiere mostrarSintaxis: lcd.createChar(num, data) Parámetros: lcd : Variable tipo LiquidCrystal num : Numero del caracter a crear (0-7) data : Matrix de pixeles del dato a crear |
Como herramientas de apoyo para facilitar la generación de caracteres personalizados se recomienda el uso de las siguientes: