Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / bytes

Experimenting with ST7920 128×64 Graphical LCD on a PIC

4.00/5 (1 vote)
7 May 2023CPOL2 min read 3.7K  
Experiment with ST7920 128×64 graphical LCD on PIC
In this post, you will experiment with a ST7920 controller 128×64 Graphical LCD on a PIC.

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:

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

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

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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)