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