Cuando los simples indicadores luminosos con led ya no son suficientes, habitualmente el siguiente paso para todo programador es ir por una pantalla lcd 16×2. Llegados a este punto, encontramos que existen módulos LCD que facilitan la interfaz con este periférico. El estándar en la industria para estos módulos con “controlador a bordo” es el chipset HD44780 (y otros más compatibles desarrollados a partir de este), para los cuales encontramos soporte en prácticamente cualquier plataforma: Arduino, PIC, AVR, MSP430, etc.

En esta entrada introducimos la librería de control altamente portable a cualquier microcontrolador, la cual puede ser utilizada tanto para PIC, como AVR y prácticamente cualquier otro microcontrolador o computadora embebida que se nos ocurra.

Nuestra foto de portada para el artículo muestra módulos LCD con iluminación azul y letras color blanco.

Conexiones básicas de una pantalla lcd 16×2

El HD44780 permite conectarse a través de un bus de 4 u 8 bits. El modo de 4 bits permite usar solo 4 pines para el bus de datos, dándonos un total de 6 o 7 pines requeridos para la interfaz con el LCD, mientras que el modo de 8 bits requiere 10 u 11 pines. El pin RW es el único que puede omitirse si se usa la pantalla en modo de solo escritura y deberá conectarse a tierra si no se usa. En este caso el microcontrolador no puede leer desde el chip controlador de pantalla, pero en la mayoría de las situaciones esto no es necesario y nuestra librería no implementa aun esta funcionalidad.

Notese que todas estas configuraciones son ilustrarivas, la pantalla se puede conectar a cualquier combinación de pines posible, ya que nuestra librería soporta usar cualquier pin como parte del bus de datos y señales de control.

Diagrama para modo de 4 bits

Las conexiones para el módo de 4 bits en un PIC16F88 se muestran a continuación. Se utilizan los primeros 4 bits del puerto A (RA0-RA3) como bus de datos. RB0 como señal de habilitación (E) y RB1 como señal de selección de registro (RS).

Diagrama de conexion pantalla LCD 16x2 con PIC modo 4 bits

Diagrama para modo de 8 bits

Las conexiones para el módo de 8 bits son algo más complicadas, ya que requerimos las 8 lineas de datos activas. En este caso utilizaremos los 8 bits del puerto B, aunque se puede usar cualquier combinación de pines con nuestra librería. RA0 ahora funciona como señal de selección de registro (RS) y RA1 como señal de habilitación (E).

Diagrama de conexion pantalla LCD 16x2 con PIC modo 4 bits

Comandos del controlador HD44780

Para conocer un poco mejor los comandos soportados por la librería para la pantalla lcd 16×2, es necesario estudiar el juego de instrucciones soportadas por el chip controlador de pantalla, el cual se resume en la siguiente tabla que hemos traducido de la hoja de datos. La mayoría de los comandos listados pueden ser ejecutados llamando a una función en C de nuestra librería.

InstrucciónCódigo de OperaciónDescripciónTiempo de Ejecución
RSR/WB7B6B5B4B3B2B1B0
Clear display0000000001Borra el contenido de la pantalla y retorna el cursor a la posición “home” (dirección 0).1.52 ms
Cursor home000000001*Retorna el cursor a la posición “Home”. Retorna también el área de visión a la posición inicial. El contenido de la DDRAM permanece intacto.1.52 ms
Entry mode set00000001I/DSIncrementar/Decrementar dirección (I/D); Habilitar corrimiento de pantalla (S). Estas operaciones se realizan al leer o escribir datos37 μs
Display on/off control0000001DCBEnciende o apaga el display (D), Cursor encendido / apagado (C), destello del cursor (blink) (B).37 μs
Cursor/display shift000001S/CR/L**Selecciona entre desplazamiento de pantalla o de cursor (S/C), selecciona la dirección de desplazamiento (R/L). El contenido de la DDRAM permanece intacto.37 μs
Function set00001DLNF**Configurar en ancho de bus (4 u 8 bits) (DL),Numero de lineas de display (N), y tipo de fuente (F).37 μs
Set CGRAM address0001CGRAM addressEscribe la dirección de CGRAM. Los datos a almacenar en CGRAM pueden ser enviados después de esta instrucción37 μs
Set DDRAM address001DDRAM addressEscribe la dirección de DDRAM. Los datos a almacenar en DDRAM pueden ser enviados después de esta instrucción37 μs
Read busy flag &address counter01BFCGRAM/DDRAM addressLeer bandera “Ocupado” (Bussy Flag) indicando si el controlador está realizando alguna operación interna o esta listo para aceptar datos/comandos. Lee la dirección CGRAM o DDRAM (dependiendo de la instrucción previa).0 μs
Write CGRAM orDDRAM10Write DataEscribe datos a las memorias CGRAM o DDRAM.37 μs
Read from CG/DDRAM11Read DataLee datos desde las memorias CGRAM o DDRAM.37 μs
Nombres y significado de de bits en instrucciones

I/D – 0 = disminuir el contador de dirección, 1 = incrementar el contador de dirección;

S – 0 = Sin corrimiento de display, 1 = Con corrimiento de display;

D – 0 = Display Apagado, 1 = Display Encendido;

C – 0 = Cursor Apagado, 1 = Cursor Encendido;

B – 0 = Parpadeo cursor Apagado, 1 = Parpadeo Cursor Encendido;

S/C – 0 = Mover Cursor, 1 = Corrimiento de pantalla;

R/L – 0 = Mover/Correr a la izquierda, 1 = Mover/Correr a la derecha;

DL – 0 = Interfaz de 4 bits, 1 = Interfaz de 8 bits;

N – 0 = 1 linea, 1 = 2 lineas;

F – 0 = 5×8 puntos, 1 = 5×10 puntos;

BF – 0 = puede aceptar instrucción, 1 = operación interna en progreso.

Librería para pantalla de 16×2 con PIC

Nuestra librería para pantalla lcd 16×2 se encuentra alojada en Github. La librería es capaz de controlar una pantalla conectada en cualquier combinación de pines del microcontrolador. Además es bastante fácil llevar esta librería a otros microcontroladores PIC de mejor desempleño  y también a microcontroladores de otras marcas (Atmel, TI MSP430, etc). De igual forma,  el código esta pensado para admitir distintas capas de abstracción de hardware para el acceso a pines de entrada/salida en situaciones en las que esto no sea tan sencillo como lo es en un microcontrolador (abordaremos esto en otra entrada futura sobre la conexión de una pantalla a un Raspberry Pi).

La librería para pantalla lcd 16×2 puede encontrarse en el siguiente repositorio que puedes clocar o bien descargar los archivos de la librería en formato ZIP.

github_logo

https://github.com/geekfactory/LCD

Para obtener la ultima versión de la librería podemos usar git con el siguiente comando:

git clone --recursive https://github.com/geekfactory/LCD.git

La librería básica para el PIC consiste en 4 archivos de código fuente:

  • LCD.h – Contiene la declaración y documentación de las funciones (prototipos).
  • LCD.c – Definición del funcionamiento de las funciones de usuario (API) de la pantalla LCD.
  • LCD-PIC16.h Configuración específica para la LCD en la arquitectura del microcontrolador PIC.
  • LCD-PIC16.c – Definición de las funciones específicas para acceso a los pines de I/O en el PIC16.

Como ya dijimos, a veces utilizamos esta librería en otros microcontroladores, por esta razón puedes encontrar otros archivos en github, pero estos 4 son los que se requieren para trabajar en cualquier proyecto con PIC.

Configuración de los pines en la librería

Para adecuar la librería para pantalla lcd 16×2 a nuestro circuito hay que editar el archivo LCD-PIC16.h. Dentro de este, encontramos las definiciones de los pines utilizados en la interfaz con el controlador de pantalla. En este caso definimos un bus de 4 bits en la parte baja del puerto A (RA0 – RA3) y lineas de control RS y E en los pines RB1 y RB0 respectivamente. Esto corresponde a la ilustración del modo de 4 bits que se encuentra arriba en esta página.

/**
 * Definitions for common control lines
 */

#define LCD_PIN_RS	PORTBbits.RB1
#define LCD_TRIS_RS	TRISBbits.TRISB1
#define LCD_PIN_E	PORTBbits.RB0
#define LCD_TRIS_E	TRISBbits.TRISB0

/**
 * Configuration example for 4 bit mode
 */
#define LCD_TRIS_D4	TRISAbits.TRISA0
#define LCD_TRIS_D5	TRISAbits.TRISA1
#define LCD_TRIS_D6	TRISAbits.TRISA2
#define LCD_TRIS_D7	TRISAbits.TRISA3
#define LCD_PIN_D4	PORTAbits.RA0
#define LCD_PIN_D5	PORTAbits.RA1
#define LCD_PIN_D6	PORTAbits.RA2
#define LCD_PIN_D7	PORTAbits.RA3

Para utilizar la librería con un bus de 8 bits, es necesario definir los pines restantes del bus de datos: LCD_PIN_D0 a LCD_PIN_D3.

Escribir caracteres a la pantalla

Cada uno de los caracteres que escribimos a la pantalla son almacenados en una ubicación en la memoria RAM apuntada por la dirección del cursor. Cuando escribimos un carácter, el código ASCII correspondiente a este, se almacena en la memoria interna conocida como Display Data RAM o DDRAM. Para escribir caracteres a la DDRAM utilizamos las funciones lcd_write() y lcd_puts(), que escriben un caracter y una cadena, respectivamente.

// Podemos mover el cursor a donde deseamos comenzar a escribir
lcd_goto( 0, 0 );
// Enviamos texto a la pantalla (DDRAM)
lcd_puts( "Hola Mundo" );
// Enviar un solo caracter (signo de admiracion)
lcd_write("!");

Definir nuestros propios caracteres personalizados en una pantalla lcd 16×2

El controlador HD44780 en la pantalla lcd 16×2 nos permite también definir caracteres especiales definidos por el usuario (hasta 8 caracteres). Cuando deseamos escribir un carácter personalizado, el mapa de bits que lo compone se almacenan en otro segmento de memoria independiente conocida como Character Generator RAM o simplemente CGRAM. Cada carácter se define como un grupo de 8 bytes que se envían a la memoria CGRAM. Por ejemplo, podemos crear un ícono con una carita feliz de la siguiente forma:

lcd_16x2_caracteres_CGRAM

Mapa de bits para caracteres personalizados (CGRAM) en pantalla HD44780

En lenguaje C podemos declarar un array con el caracter personalizado que mostramos en la figura anterior de la siguiente manera:

// Caracter personalizado carita feliz :)
const char smile[8] = {
	0b00000000,
	0b00001010,
	0b00001010,
	0b00001010,
	0b00000000,
	0b00010001,
	0b00001110,
	0b00000000,
};

Para usar el caracter, es necesario transferirlo al controlador de pantalla mediante la función lcd_create_char() y luego mostrarlo en pantalla enviando el código correspondiente al caracter con la función lcd_write(). El código para mostrar el carácter que acabamos de crear quedaría de la siguiente manera:

// Cargar el caracter a CGRAM
// El primer parámetro es el código del caracter (0 - 7)
// El segundo es el apuntador a donde se guarda el bitmap (el array declarado anteriormente)
lcd_create_char(0, smile);
// Borrar la pantalla despues de terminar de escribir a CGRAM
lcd_clear();
// Escribir el código de carita feliz (número 0 de 7)
lcd_write(0);

Ejemplo completo MPLAB pantalla LCD 16×2

En el programa de ejemplo aplicamos lo aprendido para iniciar la pantalla, mostrar letras, mover el cursor y escribir caracteres personalizados. Dentro del repositorio de Github podemos encontrar el proyecto demo para MPLAB X listo para compilarse para un PIC16F88 pero que podemos utilizar fácilmente con cualquier microcontrolador de la familia PIC16F.

El programa requiere un PIC16F88 con cristal de 4 Mhz conectado en los pines correspondientes y la pantalla conectada como se muestra en la ilustración de “Modo de 4 bits” mostrada más arriba.

#define CONFIG_TIMING_MAIN_CLOCK 1000000
#include <xc.h>			// Encabezado para el compilador XC8
#include "../LCD.h"

/* Device specific configuration */
#pragma config FOSC = XT        // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON	// RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = OFF      // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off)
#pragma config CCPMX = RB0      // CCP1 Pin Selection bit (CCP1 function on RB0)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode disabled)

// Declaration of custom characters
const char arrowr[8] = {
	0b00001000,
	0b00000100,
	0b00000010,
	0b00011111,
	0b00000010,
	0b00000100,
	0b00001000,
	0b00000000,
};

const char arrowu[8] = {
	0b00000100,
	0b00001110,
	0b00010101,
	0b00000100,
	0b00000100,
	0b00000100,
	0b00000100,
	0b00000000,
};

const char arrowd[8] = {
	0b00000100,
	0b00000100,
	0b00000100,
	0b00000100,
	0b00010101,
	0b00001110,
	0b00000100,
	0b00000000,
};

const char arrowl[8] = {
	0b00000010,
	0b00000100,
	0b00001000,
	0b00011111,
	0b00001000,
	0b00000100,
	0b00000010,
	0b00000000,
};

void main()
{
	int i;

	ANSEL = 0x00;
	TRISA = 0xFF;
	TRISB = 0x7F;

	// Initialize lcd driver
	lcd_init(0, 16, 2);

	// Load characters to CGRAM
	lcd_create_char(0, arrowr);
	lcd_create_char(1, arrowu);
	lcd_create_char(2, arrowl);
	lcd_create_char(3, arrowd);

	// Clear screen to end write to character generator
	lcd_clear();
	// Turn on display
	lcd_on();
	// Display message on the first row
	lcd_puts(" geekfactory.mx ");
	// Move cursor to the fourth column on second line
	lcd_goto(3, 1);
	// Print a message there
	lcd_puts("Hello World");
	// Mover cursor to the sixteenth column on second row
	lcd_goto(15, 1);

	// Main loop
	for (;;) {
		for (i = 0; i < 4; i++) {
			// 1 Hz led blink
			delay_ms(500);
			// Toggle pin RB7
			PORTB ^= 0x80;
			// Write custom defined character code (can be 0-7)
			lcd_write(i);
			// Goto the last visible position on the screen
			lcd_goto(50, 50);
		}
	}
}

Resultado del programa de prueba

Al cargar y ejecutar de manera exitosa el programa de prueba en el microcontrolador, deberíamos ver en nuestra pantalla algo como lo siguiente:

lcd_resultado_ejemplo

Si no aparece nada en la pantalla o solamente aparecen caracteres que no se reconocen, procederemos a revisar cada uno de los siguientes aspectos del montaje:

  • Revisar el potenciometro de contraste: cambiar de posición hasta que logremos ver algo
  • Revisar que las señales E y RS estén conectadas en los pines adecuados
  • Revisar las conexiones en el bus de datos, revisar que los pines coincidan con los definidos en el programa
  • Revisar la velocidad de reloj, si el controlador no puede recibir correctamente algunos comandos podría causar que la información no se muestre correctamente.

Tips y trucos para el uso de esta librería

Revisa la ayuda incluida

Te recomendamos aprovechar al máximo el apoyo de la documentación incluida. Si estamos acostumbrados a trabajar con MPLAB X siempre podemos oprimir las teclas “CTRL + Espacio” para acceder a la función de autocompletado. Esta función nos muestra una ventana sobre nuestro editor de texto donde podemos observar la documentación de la librería. Esto incluye las funciones disponibles e información sobre los parámetros que reciben. La ventana de autocompletado tiene la siguiente apariencia:

pantalla_lcd_16x2_con_PIC_ayuda_docu

Use caracteres personalizados

La librería viene con funciones que permiten definir caracteres especiales. En el ejemplo de la librería hemos definido 4 caracteres personalizados (flechas) que aparecen durante el programa de demostración. Sin embargo, la creatividad de cada persona permitirá crear caracteres que pueden utilizarse como iconos para los más diversos usos.

lcd_16x2_caracteres_personalizados

 Aporta tus ideas y correcciones

Nuestra librería de LCD esta alojada en github. Cualquier persona puede realizar correcciones o mejoras al código fuente y aportarlas al repositorio. Alguien en nuestro equipo revisará los cambios propuestos y los integrará al código principal en caso de ser necesario.

Descargas y enlaces relacionados

Conclusión

En este artículo, sentamos las bases para que puedas incluir de manera sencilla pantallas LCD de 16×2 caracteres en tus diseños con microcontroladores PIC. Nosotros lo hacemos habitualmente y encontrarás muchos ejemplos que funcionan con esta librería dentro de nuestro sitio web.

Como ya dijimos, te invitamos a crear una cuenta en Github y a mejorar la librería y aportar cualquier mejora que creas conveniente. Será un placer también recibir tus comentarios a través de este medio o mediante correo electrónico.

Por ultimo, te invitamos a comprar tus pantallas LCD en nuestra tienda virtual para ayudarnos a seguir desarrollando ejemplos, software y tecnología.

 

¡Compra en nuestra tienda virtual y apoyanos!