Displays LCD alfanuméricos

En muchos casos, la señalización de estados de nuestros proyectos mediante diodos LED resulta insuficiente. Una alternativa muy profesional y económica (y de fácil implementación) es la utilización de displays LCD alfanuméricos. Continuando con la serie de notas dedicadas a aprender a programar microcontroladores, veremos las instrucciones que dispone el lenguaje de programación PIC BASIC orientadas al manejo de displays LCD.

Existen en el mercado una enorme variedad de pantallas de cristal líquido, de un precio accesible, con características comunes en cuanto a la interfaz y programación, gracias a que la mayoría utiliza para comunicarse con el "exterior" el mismo chip de la empresa Hitachi, el HD44780. Esto hace posible que con un puñado de instrucciones podamos manejar desde un sencillo display de una línea de 8 caracteres hasta uno de 4 líneas con 80 caracteres.

El aspecto físico de estas pantallas se puede ver en las fotos que ilustran la nota: básicamente son una pequeña placa de circuito impreso con un par de integrados (tipo "gota") pegados en una de sus caras, y la pantalla propiamente dicha en la otra, rodeada de una estructura metálica que la protege. Esta placa casi siempre dispone de agujeros para poder fijar el conjunto a un chasis o gabinete sin grandes complicaciones. Desde el punto de vista eléctrico, hay un conector (a veces solo agujeros metalizados donde soldar los cables) que tiene 14 pines cuando no poseen iluminación propia (backlite) o 16 cuando sí la tienen.

TUTORIAL: Programación de Microcontroladores – Parte 7
Vista trasera de un LCD 2x16 típico.
TUTORIAL: Programación de Microcontroladores – Parte 7
Hermoso: un LCD de 4 lineas de 40 caracteres, color azul.

Mediante las señales apropiadas enviadas y recibidas a través de este conector, el display es capaz de representar caracteres, mostrar o esconder un cursor, borrar la pantalla, etc.

TUTORIAL: Programación de Microcontroladores – Parte 7
TUTORIAL: Programación de Microcontroladores – Parte 7

Descripción de los pines

Como mencionamos, la gran mayoría de los displays existentes en el mercado respetan la misma distribución de pines. Igualmente, antes de conectar nada, debemos asegurarnos de que así sea, para no dañar de forma permanente el LCD. Siempre es necesario tener a mano la "datasheet" (hoja de datos) del componente electrónico que queremos usar.

Veamos qué función cumple cada uno de los pines de un display LCD genérico:

Pines 1, 2 y 3: Estos pines están dedicados a la alimentación y contraste del LCD. Efectivamente, el pin 1 (VSS) es el que se debe conectar al negativo (masa) de la alimentación, y el pin 2 (Vdd/Vcc) es el que va unido al positivo (5 voltios). El pin 3 permite el ajuste del contraste del panel. Se puede unir al pin 1 mediante una resistencia de 220 ohms para obtener un contraste adecuado (pero fijo) o bien utilizar un potenciómetro o preset de 10 KOhm para variar el contraste a gusto.

Pines 4, 5 y 6: Estos pines son de alguna manera los que controlan el funcionamiento del display. El pin 4, también llamado RS (Registration Select), es el que le indica al controlador interno del LCD que el valor presente en el bus de datos es un comando (cuando RS=0) o bien un carácter para representar (cuando RS=1).

El pin 5 ("R/W" por "Read/Write" o "Leer/Escribir") permite decidir si queremos enviar datos al display (R/W=0) o bien nos interesa leer lo que el display tiene en su memoria o conocer su estado (R/W=1).

Por último, el pin 6 (E por "Enable" o "habilitado") es el que selecciona el display a utilizar. Es decir, podemos tener varios LCD conectados a un mismo bus de datos (pines 7-14) de control, y mediante E seleccionar cuál es el que debe usarse en cada momento.

Pines 7, 8, 9, 10, 11, 12, 13, 14: Estos ocho pines son el "bus de datos" del controlador de la pantalla. Llamados DB0-DB7 son los encargados de recibir (o enviar) los comandos o datos desde o hacia el display. DB0 es el bit de menor peso y DB7 es el más significativo.

Por último, los pines 15 y 16: son los que se utilizan para alimentar el (o los) LEDs de fondo de la pantalla, que brindan la iluminación (backlight). El pin 15 debe ser conectado a 5 voltios y el 16 al negativo o masa de la fuente. En estas condiciones, la luz de fondo está encendida al 100% de su brillo. Nuevamente, se puede utilizar un potenciómetro o preset para ajustar el brillo. Como una nota curiosa, muy frecuentemente estos dos pines están ubicados ANTES del pin 1 (ver esquema). Debemos asegurarnos de cuál es su posición consultando la hoja de datos del fabricante o la serigrafía que existe sobre la placa del LCD.

Estos displays soportan dos modos de trabajo: en uno de ellos reciben en DB0-DB7 los 8 bits del dato, y en el otro, llamado "modo de 4 bits", reciben los datos en dos mitades (nibbles) por los pines DB4-DB7, en dos pasos sucesivos. Si bien esto puede complicar ligeramente la programación en assembler, en PIC BASIC es completamente transparente, a la vez que supone un ahorro de 4 pines en el bus de datos, y esto en microcontroladores con pocos pines de I/O es muy útil.

TUTORIAL: Programación de Microcontroladores – Parte 7
Los pines de un display LCD genérico.
TUTORIAL: Programación de Microcontroladores – Parte 7
De esa forma podemos controlar el contraste del LCD.
TUTORIAL: Programación de Microcontroladores – Parte 7
TUTORIAL: Programación de Microcontroladores – Parte 7

El manejo de los LCD con PIC BASIC

A grandes rasgos, y a pesar de la simplicidad que brinda el disponer de un mismo integrado especializado en casi todos los modelos de displays, la escritura en estos es relativamente compleja, dado que se deben respetar protocolos de inicialización, tiempos entre envío de datos, etc., lo que hace bastante tediosa su programación en assembler. Pero PIC BASIC dispone de un juego de instrucciones especiales para manejar displays en modo "8 bits" y en modo "4 bits" que nos evitan toda esa complejidad. Veremos cuáles son y algunos ejemplos de uso. La próxima semana realizaremos un módulo para el PIC TRAINER y escribiremos varios programas de ejemplo.

El manejo de los LCD se hace mediante el uso de sentencias "DEFINE", que le dicen al compilador a qué pines del microcontrolador hemos conectado cada uno de los pines del LCD. La forma de la instrucción DEFINE es la siguiente:

DEFINE parametro = valor

Donde "parametro" es el nombre del parámetro al que le queremos asignar el "valor". Los parámetros disponibles para el manejo de LCD alfanuméricos son los siguientes:

Parámetros DEFINE para LCD

  • LCD_BITS: Define el número de bits de la interfaz de datos. Se pueden asignar valores de 4 u 8, siendo 4 el valor por defecto.
  • LCD_DREG: Define a qué puerto del PIC tenemos conectado el puerto de datos del LCD. Los valores permitidos son PORTA, PORTB, PORTC, etc. Por defecto se asume PORTB.
  • LCD_DBIT: Define cuál es el primer pin del puerto que usamos para enviar los datos al LCD cuando seleccionamos un bus de 4 bits. Solo puede ser el 0 (para los pines 0, 1, 2 y 3) o 4 (para usar los pines 4, 5, 6 y 7). Por defecto se asume "4", y esta instrucción se ignora para LCD_BITS = 8.
  • LCD_RSREG: Define a qué puerto del PIC tenemos conectado el pin RS del LCD. Los valores permitidos son PORTA, PORTB, PORTC, etc. Por defecto se asume PORTB.
  • LCD_RSBIT: Define a qué pin del puerto tenemos conectado el pin RS del LCD. Por defecto se asume "3".
  • LCD_EREG: Define a qué puerto del PIC tenemos conectado el pin E del LCD. Los valores permitidos son PORTA, PORTB, PORTC, etc. Por defecto se asume PORTB.
  • LCD_EBIT: Define a qué pin del puerto tenemos conectado el pin E del LCD. Por defecto se asume "2".
  • LCD_RWREG: Define a qué puerto del PIC tenemos conectado el pin RW del LCD. Los valores permitidos son 0, PORTA, PORTB, PORTC, etc. Por defecto se asume "0", que significa "no usamos el pin RW".
  • LCD_RWBIT: Define a qué pin del puerto tenemos conectado el pin RW del LCD. Por defecto se asume "0", que significa "no usamos el pin RW".
  • LCD_COMMANDUS: Define cuántos microsegundos demora la escritura de un comando en el display. Por defecto, este valor es de 5000. La mayoría de los LCD funcionan bien con un valor de 2000, lo que hace más rápidos nuestros programas.
  • LCD_DATAUS: Define cuántos microsegundos demora la escritura de un dato en el LCD. Por defecto, este valor es de 100.
  • LCD_INITMS: Define cuántos microsegundos demora la inicialización de la electrónica del LCD. Por defecto, este valor es de 100.

Luego tenemos una serie de instrucciones que manejan el envío de comandos e instrucciones al display:

Instrucciones para el envío de comandos

LCDINIT debe utilizarse antes de enviar cualquier comando o dato al LCD. La forma de esta instrucción es la siguiente:

LCDINIT n

Donde "n" es el tipo de cursor que queremos que muestre el display. "0" significa que el cursor estará oculto, "1" significa que el cursor parpadeará, "2" nos mostrará un cursor subrayado, y "3" un cursor subrayado y parpadeando.

LCDCMDOUT es la instrucción que envía comandos al LCD. Se emplea de la siguiente manera:

LCDCMDOUT comando

Donde "comando" es alguno de los siguientes:

  • LcdClear: Borra el contenido del LCD.
  • LcdHome: Lleva el cursor a la primera posición del primer renglón del LCD.
  • LcdLine2Home: Lleva el cursor a la primera posición del segundo renglón del LCD.
  • LcdLeft: Mueve el cursor una posición a la izquierda.
  • LcdRight: Mueve el cursor una posición a la derecha.
  • LcdShiftLeft: Desplaza el contenido del LCD una posición a la izquierda.
  • LcdShiftRight: Desplaza el contenido del LCD una posición a la derecha.
  • LcdLine1Clear: Borra la primera línea del LCD.
  • LcdLine2Clear: Borra la segunda línea del LCD.
  • LcdLine1Pos(x): Coloca el cursor en la posición "x" del primer renglón del LCD. "X" puede tener cualquier valor entre 1 y 40.
  • LcdLine2Pos(x): Coloca el cursor en la posición "x" del segundo renglón del LCD. "X" puede tener cualquier valor entre 1 y 40.

LCDOUT envía datos al display. Si son caracteres, simplemente los ponemos entre comillas a continuación del comando. Si se trata de mostrar el contenido de una variable, se escribe la variable (precedida por "#") a continuación del comando. Si se necesitan imprimir varias variables, se pueden separar por "comas".

TUTORIAL: Programación de Microcontroladores – Parte 7
Un LCD en acción.
TUTORIAL: Programación de Microcontroladores – Parte 7
TUTORIAL: Programación de Microcontroladores – Parte 7

A continuación, un par de ejemplos de cómo se utilizan todas estas instrucciones. El primero se encarga de mostrar un texto parpadeando en la primera línea del display. Intenten deducir cómo está conectado el LCD al PIC mirando las instrucciones "DEFINE" del principio del programa.

DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTB
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTD
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTD
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTD
DEFINE LCD_RWBIT = 2
LCDINIT 0 'inicializo el LCD sin cursor.

loop:
 LCDOUT "www.NeoTeo.com" 'Muestra el texto…
 WAITMS 1000 'Espero un segundo
 LCDCMDOUT LcdClear 'Borro el display
 WAITMS 1000 'Espero un segundo
GOTO loop 'Vuelvo a loop: para repetir indefinidamente.

El segundo ejemplo muestra cómo imprimir el contenido de una variable ("A") en el LCD. Concretamente, se muestra un texto en el primer renglón, mientras que en el segundo se cuentan los números del 65535 al 0.

DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTB
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTD
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTD
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTD
DEFINE LCD_RWBIT = 2
DIM A AS WORD
A = 65535

LCDINIT 3 'Cursor parpadeando
WAITMS 1000

loop:
 LCDOUT "¡Estoy contando!" 'Texto del primer renglón
 LCDCMDOUT LcdLine2Home 'Paso al Segundo renglón
 LCDOUT #A 'Muestro el valor de A
 A = A - 1
 WAITMS 250
 LCDCMDOUT LcdClear 'Limpio del display
GOTO loop

Esto es todo por hoy. La semana próxima veremos cómo implementar estos ejemplos en una placa de expansión para nuestro PIC TRAINER, y también cómo definir nuestros propios caracteres especiales. ¡Hasta la próxima!

TUTORIAL: Programación de Microcontroladores – Parte 7
Veremos como definir nuestros propios caracteres.
TUTORIAL: Programación de Microcontroladores – Parte 7
Estos LCD son ideales para modding.
TUTORIAL: Programación de Microcontroladores – Parte 7
TUTORIAL: Programación de Microcontroladores – Parte 7