Home > electronics, projects > PIC and 5110 Interface with SPI hardware – PR3

PIC and 5110 Interface with SPI hardware – PR3

September 26th, 2011 Leave a comment Go to comments

This is the first “official” project I am doing with my PIC prototyping board. This project is about interfacing and using a simple Graphic LCD. So to follow this project you need a PIC to have SPI hardware, in order to communicate with the device. The GLCD (Nokia 5110) I am using is well known in the community and it is a cheap device. I bought it off ebay for about 5 Euros.

This screen has 8 pins:

  • 2 pins for the SPI communication
  • 2 pins for power and ground
  • 1 pin to power the backlight LEDs
  • 1 pin for Chip Enable (active low)
  • 1 pin for Reset (active low)
  • 1 pin to select command or data operation


5V PIC but 3.3V device!

In general, the GLCD works in the 3.3Volt environment. If you are operating your PIC on the 3.3V level you then connect the pins straight away. However, if you are like me with a 5V PIC, then you will need some extra components. First of all you need to make sure that you are supplying 3.3V of power. For this project I used a 3.3V regulator I had already on my bread board. Another trick I often use, are 2-3 diodes connected in series. Since diodes have forward voltage drop, you can use that to drop the 5V supply down and match 3.3V as close as possible without violating the limits of the target device (or you will burn it!). I don’t recommend you use this method for your final board, but for a quick prototyping testing it should be ok.

Another problem is the logic levels of the communication. You have 5 pins in total which are connected from the PIC to the GLCD. I followed the advice I read here and just connected a 10kOhms resistor between each communication line. And it worked just fine!

Operating the 5110 GLCD

As we already said, we will use the SPI portocol to send data and commands to the device. So the first thing you need to do is to setup the SPI settings in your program. Since I am using the Microchip’s C18 free compiler, I used the following command:


On page 15, the datasheet specifies the procedure we need to follow in order to turn on the GLCD. Before we see how to do that, let me just first write the function I use to send the data, LCD5110_send function:

void LCD5110_send(unsigned char data, unsigned char dc)
    DC_5110 = dc; // Set the appropriate status for command=0 or data=1

Using this command, you can send a byte (unsigned char) to the device but you need define whether this byte is a data byte or command. The DC_5110 you see there is the pin I defined earlier on which represents the command/data line. I also defined the rest of the pins and you can see this in the full source code of the program. So now that we are able to send stuff to the screen, lets initialize it!

Initializing 5110 GLCD

This is the code I am using. I got this from here, and convert it to my own needs:

LCD5110_send(0x20 + 0x01, 0); // Extended instructions enabled
LCD5110_send(0x80 + 0x40, 0); // Set contrast 0 - 127
LCD5110_send(0x04 + 0x02, 0); // Temperature control
LCD5110_send(0x10 + 0x03, 0); // Set bias system
LCD5110_send(0x20 + 0x00, 0); // Return to basic instruction set, power on, set horizontal addressing
LCD5110_send(0x08 + 0x04, 0); // Display control set to normal mode

These commands set your screen ready to send some text on! There are some other stuff you need to do before sending the above, so make sure you take a look at the full source code (at the end of this post).

Sending characters to the screen

Remember this is a GLCD not a text LCD, so we define the state of each individual pixel.  Each character is made out of 40 pixels (5 columns x 8 rows).  In order to display some text we need to use a font array which contains the correct sequence of pixels to display symbols, letters and numbers. I found a great font collection on the net which works great. This array is usually stored in the ROM area. The function I am using for sending a character to the screen is the following:

void LCD5110_sendchar(unsigned char character)
    unsigned char column = 0;
    character = character - 0x20; // 0x20 is the first element of the array
    for (column = 0; column < 5; column++)  // Pass through each column
        LCD5110_send(font[(int) character * 5 + column], 1);
    LCD5110_send(0x00, 1); // Send a small space

Notice that we are sending data since the second parameter of the LCD5110_send function is 1.

Selecting where to display your character

So now you know how to display something on the screen, but where will it appear? In order to define the position of the next character you have to send the following commands to the GLCD

LCD5110_send(0x40 + 0, 0); // set Y address
LCD5110_send(0x80 + 0, 0); // set X address

Address for the X ranges from 0 to 84 while for Y ranges from 0 to 6. So its like you have six horizontal lines where you can start writing at any point in that line. Since we are using horizontal addressing, sequential characters are displayed next to each other horizontally. Maybe you can understand this better if you read the datasheet on page 9. So to determine the Y address you have to send the 0x40 (notice the 0 parameter on the LCD5110_send function) command, plus the vertical location you want. For X, you send 0x80 command plus the horizontal location you want. For example to write Hello World! on the second line of the display starting from the beginning of the line we should write the following before sending the characters

LCD5110_send(0x40 + 1, 0); // set Y address
LCD5110_send(0x80 + 0, 0); // set X address


The Hello World I was telling you about!

Sending strings to the display

I am using the following function to send a string to the display

void LCD5110_sendstring(rom unsigned char *str)
    while (*str)

This function iterates through each character of the string and then sends it using the LCD5110_sendchar function. Its simple.


The main.c file I used with C18 compiler. This is the full source code

References: Interfacing Nokia 3510i and 5110 LCD with PIC Microcontroller

Related Posts:

Incoming search terms:

  • nokia 5110 lcd pic (32)
  • interface pic18f con lcd (13)
Categories: electronics, projects Tags: , , , ,
  1. Sarah S
    March 28th, 2012 at 01:34 | #1

    Great site! I was wondering how I could modify the code to print variables that I have initialized ? Please let me know as soon as you can 🙂 Thanks !

  2. psychoul
    March 28th, 2012 at 12:08 | #2

    Hi Sarah,
    did you try using the LCD5110_sendstring function? You can pass your string there and it will print it. Try it and let me know.

  3. Sarah S
    March 28th, 2012 at 22:45 | #3

    So are you saying for …

    LCD5110_sendstring(“Hello World”);

    I would write:

    float P=5;

    and then the LCD should show 5 ?

    I don’t have my LCD with me right now but I will in a bit. Let me know if this is the right approach.

    Seeing as how P is a float instead of an int, would I need to modify this part of your code:

    void LCD5110_sendchar(unsigned char character)
    unsigned char column = 0;
    character = character – 0x20; // 0x20 is the first element of the array

    for (column = 0; column < 5; column++) // Pass through each column
    LCD5110_send(font[(int) character * 5 + column], 1);

    LCD5110_send(0x00, 1); // Send a small space

    Thanks for your help!

  4. psychoul
    March 30th, 2012 at 20:47 | #4

    Hello Sarah,
    I see what you are saying. The function wont work like that because its meant to output strings not numbers. You will have to format your data as a string before using that function, something like printf.
    Hope that helps!

  5. Sarah S
    April 4th, 2012 at 22:36 | #5

    So I wrote

    int P;
    P = 5;

    LCD5110_send(0x40 + 0, 0);
    LCD5110_send(0x80, 0);

    The build succeeded but LCD outputs nothing. Any tips ? Thanks!

  6. Robert Kendrick
    April 8th, 2012 at 01:20 | #6


    printf sends its output to standard output — console etc in the unix world.

    You need a version of printf that does the same formatting but places the result into a string variable rather than sending the result to standard output.
    I believe the standard library function sprintf does what you need.

  7. Marko
    April 14th, 2013 at 20:00 | #7

    void LCD5110_sendnum(unsigned int inum)
    unsigned char *str;
    while (*str) // pass through each character

    LCD5110_sendchar(*str); // and send it


    work fine (-9999,9999) :]

  8. Alessio
    August 6th, 2013 at 23:37 | #8

    Dear psychoul, I am trying to talk with a 5110 lcd screen with a pic18f4620, but it seems it doesn’t work at all: nothing happens at all (but through thw logic analyzer it seems the data being sent are correct).
    Am I missing something? So you remind something that caused you trouble? 🙂
    Thank you! 😛

  9. psychoul
    August 19th, 2013 at 12:22 | #9

    Hey Alessio,
    Well, unfortunately I don’t have much information on what is causing you trouble so there is not much I can say. Since your logic analyzer indicates that the signals are OK you should look into the hardware. First of all, is your 5110 screen operational? Does it show any signals that it is alive? Check the voltage levels both for power and for the signals.

  10. Ramiro
    September 25th, 2013 at 20:29 | #10

    Hi , please anyone can help me ? I wrote mi code in c18 , in pic 18f2550, I have used , the code main.c , but nothing in screen , sorry my english , I only have black screen , I have used serie 10 k resistors in line CE , CLK , DC, DIN, and RST , but nothing happened , when the power up chip , the screen is black , only change the port C with B, please if anyone can tell me something very thanks in advance

  11. jabcek
    June 21st, 2014 at 13:23 | #11

    I have pic24f08ka101. I am trying to connect it with Nokia 5110 through SPI. Which SPI pins should I use? SCK and SDI or SDO ? And how should I configure the SPI module?

  1. No trackbacks yet.