Tutoriales
Librería LCD Nokia 5110 para Raspberry Pi y otras plataformas
- Detalles
- Categoría: Tutorial
- Publicado el Domingo, 01 Septiembre 2013 10:02
- Escrito por Santiago Villafuerte
- Visto: 43607
En este artículo encontrarás una librería en modo texto para emplear la pantalla Nokia 5110 (driver PCD8544) en tu Raspberry Pi o en cualquier otro microcontrolador o procesador. La librería está basada en código liberado por Mike Pose y simplemente se limpió para desacoplar el código de envío SPI, ya sea por Bitbang o por hardware.
Software necesario
+ Paquete de descarga librería Nokia 5110 Raspberry Pi
+ Ambiente Linux en PC con cross-compiler ARM previamente instalado
Items necesarios
+ Raspberry Pi
+ Pantalla Nokia 5110. La puedes comprar en Deal Extreme (click en la imagen).
Librería de Mike Pose
La librería que Mike Pose publicó es capaz de escribir texto en la pantalla 5110, proporcionando 14 caracteres por 6 líneas. Está programada para ser usada en una tarjeta SimpleCortex. Cuenta con funciones básicas de posicionamiento de cursor y escritura de texto.
La librería envía datos por SPI a la pantalla, pero lo hace en modo bitbang (SPI por software). Tomaremos esta librería, la limpiaremos un poco y la haremos universal para poder ser usada en cualquier microcontrolador o procesador, dejando abierta la implementación SPI para codificarla como mejor convenga.
Modificación de la librería con SPI abierto
La librería cuenta con varias funciones de escritura en un solo archivo, esto complica su implementación abierta en otros amibientes que no sean SimpleCortex. Lo único que se hará es agregar un archivo de callbacks, en el que se llamarán funciones de hardware para enviar los datos por SPI a la pantalla. Los archivos generados son los siguientes:
+ lcd_pcd8544.h
Este header incluye todas las funciones que deberás llamar desde tu código principal para hacer uso de la librería. Es el único archivo que deberás incluir.
+ lcd_pcd8554_cbk.h
Este archivo define los prototipos de funciones que debes implementar en tu microcontrolador o procesador en específico, de forma tal que implementes SPI como mejor te convenga.
+ lcd_pcd8544.c
Aquí se programó el envío de caracteres y dibujado de la pantalla.
+ lcd_pcd8544_callouts.c
Aquí es donde defines las funciones que el archivo lcd_pcd8554_cbk.h está necesitando. Es el único archivo que deberás modificar.
Archivo lcd_pcd8544.h
Contiene las siguientes funciones:
void Nokia_5110_Clear_All(void);
Limpia toda la pantalla.
void Nokia_5110_Init(void);
Inicializa la función SPI y deja lista la pantalla Nokia 5110 para enviarle datos.
void Nokia_5110_Set_Cursor(uint8_t x, uint8_t y);
Coloca el cursor de la pantalla en (x, y).
void Nokia_5110_Putchar(char c, uint8_t print_mode);
Escribe un caracter ASCII (0x20 ' ' a 0x7A 'z') en la posición en la que se encuentre el cursor.
void Nokia_5110_Putstring(const char *string);
void Nokia_5110_Putstring_Inverse(const char *string);
Escriben texto en la posición donde se encuentre el cursor. Inverse simplemente usa fondo negro y texto en blanco.
Archivo lcd_pcd8544_callouts.c
Contiene las siguientes definiciones de funciones...
Este archivo está diseñado para implementar la comunicación SPI por fuera de la librería. Es el único archivo que ha de modificarse dependiendo de la plataforma en la que se vaya a implementar.
void Nokia_5110_Initialize_SPI(void);
Esta función deberá inicializar el periférico SPI (CLK, MOSI, CS) e inicializar las terminales de MODE y RESET. El reset debe bajarse por un momento a 0V y después regresarlo a 3.3V. Este pin puede ahorrarse agregando una pull-up y un capacitor a tierra. El reset se haría por hardware. Impleméntalo como mejor te convenga.
void Nokia_5110_Write_Byte(uint8_t data, uint8_t lcd_mode);
Aquí se hace el envío de datos por SPI. Es SPI común, CS activo en bajo, MSB sale primero.
void Nokia_5110_Stop_SPI(void);
Se proporciona esta función para cuando el puerto SPI debe dejar de usarse.
Conexión LCD Nokia 5110 - Raspberry Pi
La conexión hacia la Raspberry Pi es muy sencilla. Utilicé terminales que pueden funcionar como GPIOs y también como SPI por hardware. Si necesitas cambiarlas de lugar tendrás que usar SPI por bitbang.
SPI por Bitbang - Raspberry Pi
Para la Raspberry Pi se usó la librería bcm2835.h de Mike McCauley. Básicamente se definen los pines como GPIO de salida.
C library for Broadcom BCM 2835 as used in Raspberry Pi
void Nokia_5110_Initialize_SPI(void)
{
if (!bcm2835_init())
{
return;
}
// set the direction of the pins
bcm2835_gpio_fsel(NOKIA_5110_CS , BCM2835_GPIO_FSEL_OUTP); // CE
bcm2835_gpio_fsel(NOKIA_5110_CLK , BCM2835_GPIO_FSEL_OUTP); // SCLK
bcm2835_gpio_fsel(NOKIA_5110_DATA, BCM2835_GPIO_FSEL_OUTP); // MOSI
bcm2835_gpio_fsel(NOKIA_5110_MODE, BCM2835_GPIO_FSEL_OUTP); // MODE
bcm2835_gpio_fsel(NOKIA_5110_RST , BCM2835_GPIO_FSEL_OUTP); // RST
// set the default state for the pins
bcm2835_gpio_write(NOKIA_5110_CS, HIGH);
bcm2835_gpio_write(NOKIA_5110_CLK, HIGH);
bcm2835_gpio_write(NOKIA_5110_DATA, HIGH);
bcm2835_gpio_write(NOKIA_5110_MODE, HIGH);
// reset the display
bcm2835_gpio_write(NOKIA_5110_RST, LOW);
bcm2835_delay(5);
bcm2835_gpio_write(NOKIA_5110_RST, HIGH);
}
void Nokia_5110_Write_Byte(uint8_t data, uint8_t lcd_mode)
{
uint8_t i;
// enable the lcd
bcm2835_gpio_write(NOKIA_5110_CS, LOW);
if (NOKIA_5110_MODE_CMD == lcd_mode)
bcm2835_gpio_write(NOKIA_5110_MODE, LOW);
else
bcm2835_gpio_write(NOKIA_5110_MODE, HIGH);
for (i = 0; i < 8; i++)
{
bcm2835_gpio_write(NOKIA_5110_DATA, data & 0x80);
data = data << 1;
// toggle the clock pin
bcm2835_gpio_write(NOKIA_5110_CLK, LOW);
bcm2835_gpio_write(NOKIA_5110_CLK, HIGH);
}
// disable the lcd
bcm2835_gpio_write(NOKIA_5110_CS, HIGH);
}
void Nokia_5110_Stop_SPI(void)
{
bcm2835_close();
}
SPI por hardware
Se usa el periférico SPI de la Pi directamente. Esto nos permite velocidades de transferencia más eficientes. Se estableció el reloj SPI en 2MHz (BCM2835_SPI_CLOCK_DIVIDER_128) ya que la pantalla permite velocidades de hasta 4MHz.
void Nokia_5110_Initialize_SPI(void)
{
if (!bcm2835_init())
{
return;
}
// set the direction of the pins
bcm2835_gpio_fsel(NOKIA_5110_MODE, BCM2835_GPIO_FSEL_OUTP); // MODE
bcm2835_gpio_fsel(NOKIA_5110_RST , BCM2835_GPIO_FSEL_OUTP); // RST
// set the default state for the pins
bcm2835_gpio_write(NOKIA_5110_MODE, HIGH);
// reset the display
bcm2835_gpio_write(NOKIA_5110_RST, LOW);
bcm2835_delay(5);
bcm2835_gpio_write(NOKIA_5110_RST, HIGH);
bcm2835_spi_begin();
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_128); // 1.953125MHz
bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);
}
void Nokia_5110_Write_Byte(uint8_t data, uint8_t lcd_mode)
{
if (NOKIA_5110_MODE_CMD == lcd_mode)
bcm2835_gpio_write(NOKIA_5110_MODE, LOW);
else
bcm2835_gpio_write(NOKIA_5110_MODE, HIGH);
bcm2835_spi_transfer(data);
}
void Nokia_5110_Stop_SPI(void)
{
bcm2835_spi_end();
bcm2835_close();
}
Ejemplo de uso - Mostrar hora y día
En el siguiente código se genera un main.c que simplemente escribe algo de texto, incluyendo la hora y día actuales de la Raspberry Pi. Si no sabes cómo compilarlo puedes visitar el siguiente tutorial.
Development Environment for the Raspberry Pi using a Cross Compiling Toolchain and Eclipse
#include "bcm2835.h"
#include "lcd_pcd8544.h"
#include "string.h"
#include "stdlib.h"
#include <stdio.h>
#include "time.h"
#include "typedefs.h"
int main(int argc, char **argv)
{
char string[100];
printf("Nokia 5110 Raspberry Pi\n");
printf("Close with Ctrl+C\n");
// initialize the LCD
Nokia_5110_Init();
Nokia_5110_Set_Cursor(0, 0);
Nokia_5110_Putstring("Nokia 5110 LCD");
Nokia_5110_Set_Cursor(1, 2);
Nokia_5110_Putstring_Inverse("Raspberry Pi");
while(1)
{
time_t t = time((void*)0);
struct tm tm = *localtime(&t);
sprintf(string, " %d-%02d-%02d",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
printf("%s\n", string);
Nokia_5110_Set_Cursor(0, 4);
Nokia_5110_Putstring(string);
sprintf(string, " %02d:%02d:%02d",
tm.tm_hour, tm.tm_min, tm.tm_sec);
printf("%s\n", string);
Nokia_5110_Set_Cursor(0, 5);
Nokia_5110_Putstring(string);
bcm2835_delay(500);
}
Nokia_5110_Stop_SPI();
return 0;
}
Espero que no se me haya pasado ningún detalle de la conexión ni del código. Si falta algo por favor mándame un mail o un twit. Gracias por leerme.