Experimenting with ST7920 128×64 graphical LCD on a PIC

0.00 avg. rating (0% score) - 0 votes

This is a monochrome 128×64 graphical LCD using the ST7920 controller that I purchased from eBay:

The module is using a 20-pin standard 2.54mm connector, making it easy for prototype development on a breadboard:

Communication modes

According to the datasheet, the following communication modes are supported:

  • 8-bit mode. Data or instruction bytes are transferred via pin DB7-DB0.
  • 4-bit mode. Data or instruction bytes are separated into two parts. Higher 4 bits will be transferred through DB7-DB4, followed by the lower 4 bits. The DB3-DB0 pins will not be used and should be connected to ground. 
  • Serial mode. This is done by pulling down the PSB pin. When enabled, communication will only require 4 pins in total. Only writing data is supported in serial mode

Unfortunately, the board that I purchased has the PSB pin permanently connected to VCC. Hence, only parallel communication is possible. To cut down on the number of output pins required, I have selected 4-bit mode, instead of 8-bit.

The LCD supports both graphics and text modes:

  • Maximum 16 characters x 4 lines in text mode
  • 128×64 resolution in graphics mode.

Initialization codes

The following code performs LCD initialization and configures 4-bit communication in text mode:

void LCD_Init(void) 
{
LCD_REST=1;
LCD_REST=0;
delay_ms(5);
LCD_REST=1;

delay_ms(50);

LCD_WriteCommand(0b00100000);
delay_ms(5);

LCD_WriteCommand(0b00100000);
delay_ms(5);

LCD_WriteCommand(0b00001100);
delay_ms(5);

LCD_WriteCommand(0x01);
delay_ms(5);

LCD_WriteCommand(0x06);
delay_ms(5);

LCD_WriteCommand(0b00000010);
delay_ms(5);
}

After the LCD has been initialized, the following function will display a string on the LCD:

void LCD_TextDisplayString(unsigned char line, char* string)
{
unsigned char addr,i;
if(line==1)
addr=0x80; //The first line address
else if(line==2)
addr=0x90; //The second line address
else if(line==3)
addr=0x88; //The third line address
else if(line==4)
addr=0x98; //The fourth line address

LCD_WriteCommand(addr);

for(i=0;i<16;i++)
LCD_WriteData(*string++);

This is how it will look when displaying 4 lines of text:


Displaying graphics

Despite the large screen resolution, the default text mode only allows me to display up to 64 characters on the screen due to the thick font. My next attempt is to use graphics mode, so that I can use my custom font and display more characters. The following code shows how to enable and disable the graphics mode on this LCD:

void LCD_EnableGraphics(void)
{
LCD_WriteCommand(0x20);
delay_ms(1);
LCD_WriteCommand(0x24);
delay_ms(1);
LCD_WriteCommand(0x26);
delay_ms(1);
}

void LCD_DisableGraphics(void)
{
LCD_WriteCommand(0x20);
delay_ms(1);
}

Similar to the Nokia 5110 LCD, every 8 pixels on this LCD will consume a single byte in the display memory space. With that knowledge I was quickly able to use my custom 5×7 bitmap font and display more characters. The following picture is the display showing information from various sensors that I have interfaced with the PIC24FJ64GA002. It can show up to 16×8=128 characters:

Various graphics that I manage to display on this LCD:

The full C30 source code for this LCD can be downloaded here. If you are interested, the syntax highlighting of the source code in this article is done using this tool.

0.00 avg. rating (0% score) - 0 votes
ToughDev

ToughDev

A tough developer who likes to work on just about anything, from software development to electronics, and share his knowledge with the rest of the world.

23 thoughts on “Experimenting with ST7920 128×64 graphical LCD on a PIC

  • December 14, 2013 at 8:42 pm
    Permalink

    with what software did u use to code this?

    Reply
  • December 14, 2013 at 8:44 pm
    Permalink

    You can use any PIC C compiler. I am using Microchip MPLAB with its C30 compiler.

    Reply
  • April 9, 2014 at 4:40 pm
    Permalink

    Hi Friend, what applicattion do you use to make the fonts? Thank you!

    Reply
  • April 11, 2014 at 1:42 pm
    Permalink

    hi
    can i create this circuit diagram using pic microcontroller? our university dont give chance to use Arduino and pic 32 boards so i am in big trouble with this disply

    Reply
  • April 11, 2014 at 3:52 pm
    Permalink

    Of course, if you read the article at all it says I am using a PIC24FJ64GA002. The code of course can be ported to any other micro controller with no issues.

    Reply
  • April 17, 2014 at 9:18 pm
    Permalink

    i am confused with
    #define LCD_RS LATAbits.LATA3
    #define LCD_EN LATBbits.LATB11
    #define LCD_REST LATAbits.LATA4
    #define LCD_DB4 LATBbits.LATB12
    #define LCD_DB5 LATBbits.LATB13
    #define LCD_DB6 LATBbits.LATB14
    #define LCD_DB7 LATBbits.LATB10
    i am using 16F877A pic so how should i initialised pins in there..please give me example code for that..

    Reply
  • April 17, 2014 at 9:22 pm
    Permalink

    The PIC16F877A does not have the latch registers (e.g. LATB, LATA, etc) which is for newer PICs such as the PIC24. Just replace the LAT registers with the PORT registers. If you're using Hi-Tech C compiler, replace LATAbits.LATA3 and other similar declarations with, for example, RA3 and it should compile.

    Reply
  • July 7, 2014 at 10:29 pm
    Permalink

    do we need to enable graphics mode to display character string on this or any GLCD..?
    please help..!
    urgent..!!

    Reply
  • January 7, 2015 at 1:35 pm
    Permalink

    Please tell me how to display a variable on your cord.,.

    Reply
  • March 19, 2015 at 8:33 am
    Permalink

    Hello MD,

    Thanks for the code. Some years back I've written this for a PIC32 microcontroller in a website (you have seen this already – Cytron tutorial) – glad that you added new features to it! :)

    Reply
  • March 19, 2015 at 12:48 pm
    Permalink

    Hi NYH,

    Glad you find the code for this LCD useful :) I also have codes for other LCD/OLED modules which I purchased from eBay and plan to make it available on my blog shortly for the benefits of the electronics hobbyist community :)

    Reply
  • April 10, 2015 at 4:45 pm
    Permalink

    how can i use 5×7 font, ai only show 4 like with big font ="=

    Reply
  • April 11, 2015 at 11:22 am
    Permalink

    Hi,

    You can download the custom 5×7 font (font.zip) and the LCD sample code (12864_lcd.zip) from my article. After that you can use the LCD_GraphicsDisplayString(unsigned char line, char* str) function to display the text on string as graphics using the 5×7 font.

    This way you can show up to 128 characters on the screen, and not just 64 big characters.

    Let me know if this works.

    Reply
  • April 21, 2015 at 11:52 am
    Permalink

    Hello MD,
    I am trying to use the custom 5×7 font you provided. When I use the LCD_GraphicsDisplayString(unsigned char line, char* str) function it displays the 5×7 font but uses a larger space to do it, resulting in the same number of characters (16) as the larger font in each row. What is wrong?
    Thank you

    Reply
  • April 21, 2015 at 12:02 pm
    Permalink

    Hi,

    The LCD_GraphicsDisplayString in the code I provided will display 16 characters per row and 8 rows on the screen, so it can display a total of 16×8=128 characters.

    Although the number of characters per row is the same (16), the height of each row is shorter compared with the default font so it can display twice as many characters. The default text mode can only display 4 rows of 16 characters each, totaling to 64 characters.

    This is because each character is displayed in a 8×8 box. I have tried to use a smaller box in order to display more characters, but the results don't look nice due to the lack of spacing between characters. So for now, 16 characters on 8 rows should be sufficient for most use cases.

    As you can see on the screenshot, the LCD can display much more text using the custom 5×7 font.

    Let me know if you have any questions.

    Reply
  • May 5, 2015 at 8:17 am
    Permalink

    Thanks. I mod it to use with CCS and it work fine.

    Reply
  • July 9, 2015 at 9:33 am
    Permalink

    Good night you have examples with this code em ccs

    Reply
  • July 31, 2015 at 7:15 am
    Permalink

    Could you send me your code in CCS? Please, I need it urgent for my thesis project. In my country I one can find displays with this driver.
    My email is glori.mag3@hotmail.com.

    Reply
  • December 19, 2016 at 6:56 pm
    Permalink

    thankyou for this code its helped me alot. however the .h file has the function LCD_GraphicsDisplayChar() but itisnt in the .c file

    Reply
    • ToughDev
      December 19, 2016 at 9:49 pm
      Permalink

      Hi,

      Thanks for spotting that. You are right that function LCD_GraphicsDisplayChar is present in the header but not in the .c file. I probably forgot about it when I write the code. However you can still adapt from function LCD_GraphicsDisplayString (present in the .c file) to output a character at a specific position. Just some minor modifications. Let me know if you have any issues.

      Reply
  • March 8, 2017 at 7:33 pm
    Permalink

    Hi
    I’m trying to display characters on the 12864zw (st7920) using a pic 16f877a and xc8 in 8 bit mode.
    could you please post the code for the LCD_WriteCommand and LCD_WriteData please.

    Reply
    • ToughDev
      March 8, 2017 at 11:46 pm
      Permalink

      The C code for these 2 functions (and other functions) are already provided in the download link at the end of this article.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>