Tutoriales

Librería LCD Nokia 5110 para Raspberry Pi y otras plataformas

nokia 5110 raspberry piEn 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

Bitbang SPI (Raspberry Pi)

Hardware SPI (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).

nokia 5110 raspberry pi

 

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.

Link a librería original

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:

 

 

nokia 5110 files

 

 

+ 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:

nokia 5110 functions

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...

nokia 5110 callouts

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.

nokia 5110 pinout

 

 



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.

 


nokia 5110 raspberry pi