GLCD 128×64 ST7920 interfacing with STM32

Today in this tutorial, we will interface ST7920 GLCD (128×64) display with STM32 using the Serial mode. This way we only have to use 4 pins from the microcontroller to control the entire display.

We will start with displaying simple texts, than we will look into some bitmaps and finally we will draw some shapes on the LCD. I am using STM32F103C8 microcontroller.

Setup

I will start this tutorial by setting up the CubeMx. In Cube Mx, for the connection purpose, we only need to select 4 pin as output as shown below


Also some of the delays will be required in the microseconds, and so, I will use the TIMER 1 to create delays in microseconds. The setup is shown below. I already did a tutorial on this. You can check it HERE

This is all the setup, that is needed for the ST7920. Let’s see some functions that we are going to use to interface this display.



Some Insight into the CODE

void SendByteSPI(uint8_t byte)

Sends a byte to the MOSI / SID Pin. This is Just like How the SPI transfers the data.


Sending Command

void ST7920_SendCmd (uint8_t cmd)
{

	HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET);  // PUll the CS high

	SendByteSPI(0xf8+(0<<1));  // send the SYNC + RS(0)
	SendByteSPI(cmd&0xf0);  // send the higher nibble first
	SendByteSPI((cmd<<4)&0xf0);  // send the lower nibble
	delay_us(50);

	HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET);  // PUll the CS LOW

}

According to the datasheet of ST7920, In order to send a command to the display, We need to perform the following operations:-
1. Pull the CS Pin HIGH
2. Send the Synchronizing byte (0xF8) along with R/W and RS
3. Send the Higher command Byte
4. Send the Lower command Byte
5. Pull the CS Pin LOW to end the transfer


Sending Data

void ST7920_SendData (uint8_t data)
{

	HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET);  // PUll the CS high

	SendByteSPI(0xf8+(1<<1));  // send the SYNC + RS(1)
	SendByteSPI(data&0xf0);  // send the higher nibble first
	SendByteSPI((data<<4)&0xf0);  // send the lower nibble
	delay_us(50);
	HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET);  // PUll the CS LOW
}

Data is also sent in the same manner as the command, except the RS will be a ‘1’. Following are the operations:-
1. Pull the CS Pin HIGH
2. Send the Synchronizing byte (0xF8) along with R/W and RS
3. Send the Higher data Byte
4. Send the Lower data Byte
5. Pull the CS Pin LOW to end the transfer


Initializing Display

void ST7920_Init (void)
{
	HAL_GPIO_WritePin(RST_PORT, RST_PIN, GPIO_PIN_RESET);  // RESET=0
	HAL_Delay(10);   // wait for 10ms
	HAL_GPIO_WritePin(RST_PORT, RST_PIN, GPIO_PIN_SET);  // RESET=1

	HAL_Delay(50);   //wait for >40 ms


	ST7920_SendCmd(0x30);  // 8bit mode
	delay_us(110);  //  >100us delay

	ST7920_SendCmd(0x30);  // 8bit mode
	delay_us(40);  // >37us delay

	ST7920_SendCmd(0x08);  // D=0, C=0, B=0
	delay_us(110);  // >100us delay

	ST7920_SendCmd(0x01);  // clear screen
	HAL_Delay(12);  // >10 ms delay


	ST7920_SendCmd(0x06);  // cursor increment right no shift
	HAL_Delay(1);  // 1ms delay

	ST7920_SendCmd(0x0C);  // D=1, C=0, B=0
    HAL_Delay(1);  // 1ms delay

	ST7920_SendCmd(0x02);  // return to home
	HAL_Delay(1);  // 1ms delay

}

To initialize the display, we have to follow some sequence of command. And they are mentioned below:
1. Reset the display and wait for more than 40 ms
2. Send the Function Set command and wait for more than 100 us
3. Send the Function Set command and wait for more than 37 us
4. Send the Display ON/OFF Control command and wait for more than 100 us
5. Send the Display Clear command and wait for more than 10 ms
6. Send the Entry Mode set command and this will end the initialization of the display.


Graphic Mode

void ST7920_GraphicMode ()   
{
  ST7920_SendCmd(0x30);  // 8 bit mode
  HAL_Delay (1);
  ST7920_SendCmd(0x34);  // switch to Extended instructions
  HAL_Delay (1);
  ST7920_SendCmd(0x36);  // enable graphics
  HAL_Delay (1);
}

To enable the Graphic mode, we have to
-> Switch to Extended Instruction Set
-> Enable the Graphics
Note that we have to perform both of these operations in separate commands as according to it is mentioned in the datasheet.


Drawing Bitmaps

void ST7920_DrawBitmap(const unsigned char* graphic)
{
	uint8_t x, y;
	for(y = 0; y < 64; y++)
	{
		if(y < 32)
		{
			for(x = 0; x < 8; x++)	/ Draws top half of the screen.
			{			
                 		// In extended instruction mode, vertical and horizontal coordinates must be specified before sending data in.
				ST7920_SendCmd(0x80 | y);	// Vertical coordinate of the screen is specified first. (0-31)
				ST7920_SendCmd(0x80 | x);	// Then horizontal coordinate of the screen is specified. (0-8)
				ST7920_SendData(graphic[2*x + 16*y]);	// Data to the upper byte is sent to the coordinate.
				ST7920_SendData(graphic[2*x+1 + 16*y]);	// Data to the lower byte is sent to the coordinate.
			}
		}
		else
		{
			for(x = 0; x < 8; x++)	// Draws bottom half of the screen.
			{
                           // Actions performed as same as the upper half screen.
			   ST7920_SendCmd(0x80 | (y-32));// Vertical coordinate must be scaled back to 0-31 as it is dealing with another half of the screen.
			  ST7920_SendCmd(0x88 | x);
			  ST7920_SendData(graphic[2*x + 16*y]);
			  ST7920_SendData(graphic[2*x+1 + 16*y]);
			}
		}

	}
}

In order to draw a bitmap, we need to draw on the two half of the screen. First upper half and than the lower half.
To draw, first set the coordinate of the Y axis and than the coordinate of the X axis.
After the coordinates are set, send the upper byte of the data and than the lower byte.



RESULT

Check out the Video Below




Info

You can help with the development by DONATING Below.
To download the project, click the DOWNLOAD button.

Subscribe
Notify of

42 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
keyboard_arrow_up