{"id":4221,"date":"2026-02-08T06:51:28","date_gmt":"2026-02-08T06:51:28","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=4221"},"modified":"2026-02-08T06:51:30","modified_gmt":"2026-02-08T06:51:30","slug":"stm32-with-1-28-round-display-part-2lcd-initialization-and-draw-pixels","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=4221","title":{"rendered":"STM32 with 1.28 Round Display Part 2:LCD Initialization and Draw Pixels"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/ChatGPT-Image-Jan-26-2026-at-09_43_21-AM-1024x683.png\" alt=\"\" class=\"wp-image-4222\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/ChatGPT-Image-Jan-26-2026-at-09_43_21-AM-1024x683.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/ChatGPT-Image-Jan-26-2026-at-09_43_21-AM-300x200.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/ChatGPT-Image-Jan-26-2026-at-09_43_21-AM-768x512.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/ChatGPT-Image-Jan-26-2026-at-09_43_21-AM-1150x767.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/ChatGPT-Image-Jan-26-2026-at-09_43_21-AM-750x500.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/ChatGPT-Image-Jan-26-2026-at-09_43_21-AM-400x267.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/ChatGPT-Image-Jan-26-2026-at-09_43_21-AM-250x167.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/ChatGPT-Image-Jan-26-2026-at-09_43_21-AM.png 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>In this second part of the guide, we move from configuration to implementation by developing the GC9A01 driver header and source files for STM32. We will initialize the LCD controller and implement a basic draw-pixel function, using it to render randomly colored pixels as a first functional test of the display.<\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Creating source and header file.<\/li>\n\n\n\n<li>Developing the header file.<\/li>\n\n\n\n<li>Developing the source file.<\/li>\n\n\n\n<li>Main.c code.<\/li>\n\n\n\n<li>Results.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Creating Source and Header File:<\/h2>\n\n\n\n<p>irst, we need to create new source and header files.<\/p>\n\n\n\n<p>To create Source file, right click on Src folder and add new source file as following:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"486\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-07_07-03-43-1024x486.jpg\" alt=\"\" class=\"wp-image-2972\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-07_07-03-43-1024x486.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-07_07-03-43-300x142.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-07_07-03-43-768x364.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-07_07-03-43-1536x729.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-07_07-03-43-2048x972.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-07_07-03-43-1150x546.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-07_07-03-43-750x356.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-07_07-03-43-400x190.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-07_07-03-43-250x119.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Give a name for the source file, we shall name it as GC9A01.c as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"734\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_09-34-37-1024x734.jpg\" alt=\"\" class=\"wp-image-4223\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_09-34-37-1024x734.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_09-34-37-300x215.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_09-34-37-768x550.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_09-34-37-1150x824.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_09-34-37-750x538.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_09-34-37-400x287.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_09-34-37-250x179.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_09-34-37.jpg 1172w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>In similar manner, right click on Inc folder and add new header file with name of GC9A01.h.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"734\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_08-53-03-1024x734.jpg\" alt=\"\" class=\"wp-image-4224\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_08-53-03-1024x734.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_08-53-03-300x215.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_08-53-03-768x550.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_08-53-03-1150x824.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_08-53-03-750x538.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_08-53-03-400x287.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_08-53-03-250x179.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/2026-02-08_08-53-03.jpg 1172w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Developing the Header File:<\/h2>\n\n\n\n<p>Within GC9A01.h file, we start by including the following header files:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;stdint.h&quot;\n#include &quot;main.h&quot;\n#include &quot;spi.h&quot;<\/pre><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li>stdint allows us to access uint8_t etc variable type.<\/li>\n\n\n\n<li>main.h for main STM32 header file to access HAL basic functions like HAL_Delay etc.<\/li>\n\n\n\n<li>spi.h allows to access to SPI peripheral related function.<\/li>\n<\/ul>\n\n\n\n<p>Next, define the size of the display:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define LCD_1IN28_HEIGHT 240\n#define LCD_1IN28_WIDTH 240<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Orientation of the display:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define HORIZONTAL 0\n#define VERTICAL   1<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Functions related to display initialization and draw pixel:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void LCD_Init(uint8_t Scan_dir);\n\nvoid Draw_Pixel(uint8_t X, uint8_t Y, uint16_t Color);<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Hence, the header file as follows:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef INC_GC9A01_H_\n#define INC_GC9A01_H_\n\n#include &quot;stdint.h&quot;\n#include &quot;main.h&quot;\n#include &quot;spi.h&quot;\n\n#define LCD_1IN28_HEIGHT 240\n#define LCD_1IN28_WIDTH 240\n\n#define HORIZONTAL 0\n#define VERTICAL   1\n\nvoid LCD_Init(uint8_t Scan_dir);\n\nvoid Draw_Pixel(uint8_t X, uint8_t Y, uint16_t Color);\n\n\n#endif \/* INC_GC9A01_H_ *\/<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7. Developing the Source File:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>We start by including GC9A01 header file as follows:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;GC9A01.h&quot;<\/pre><\/div>\n\n\n\n<p>Data structure to hold some required data:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">typedef struct{\n    uint16_t WIDTH;\n    uint16_t HEIGHT;\n    int8_t SCAN_DIR;\n}LCD_ATTRIBUTES;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Declare the data structure:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">LCD_ATTRIBUTES lcdAttr;<\/pre><\/div>\n\n\n\n<p>Next, we need some functions to handle the CS, CD and RST pins:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">static void CS_Deselect()\n{\n\tHAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, SET);\n}\n\nstatic void CS_Select()\n{\n\tHAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, RESET);\n}\n\nstatic void RST_HIGH()\n{\n\tHAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, SET);\n}\n\nstatic void RST_LOW()\n{\n\tHAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, RESET);\n}\n\nstatic void DC_HIGH()\n{\n\tHAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, SET);\n}\n\nstatic void DC_LOW()\n{\n\tHAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, RESET);\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>These are standardized for any color LCD.<\/p>\n\n\n\n<p>Next, function that will hardware reset the display:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">static void Reset(void)\n{\n\tRST_HIGH();\n    HAL_Delay(100);\n    RST_LOW();\n    HAL_Delay(100);\n    RST_HIGH();\n    HAL_Delay(100);\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>The reset sequence as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Set RST pin to high and wait for 100ms.<\/li>\n\n\n\n<li>Set it low and wait for 100ms.<\/li>\n\n\n\n<li>Set it high again and wait for 100ms.<\/li>\n<\/ul>\n\n\n\n<p>Next, function that will write data, command and 16-bit data as follows:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">static void WriteData(uint8_t data)\n{\n\tCS_Select();\n\tDC_HIGH();\n\n\tHAL_SPI_Transmit(&amp;hspi1, &amp;data, 1, 10);\n\n\tCS_Deselect();\n\n}\n\nstatic void WriteCommand(uint8_t Command)\n{\n\tCS_Select();\n\tDC_LOW();\n\n\tHAL_SPI_Transmit(&amp;hspi1, &amp;Command, 1, 10);\n\n\tCS_Deselect();\n\n}\n\nstatic void WriteData16Bit(uint16_t data)\n{\n\tCS_Select();\n\tDC_HIGH();\n\n\tuint8_t data16_bit[2]={(data&gt;&gt;8)&amp;0xFF, data&amp;0xFF};\n\n\tHAL_SPI_Transmit(&amp;hspi1, data16_bit, 2, 10);\n\n\tCS_Deselect();\n\n}<\/pre><\/div>\n\n\n\n<p>Next, register initialization of the display:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">static void LCD_InitReg(void)\n{\n\n\tWriteCommand(0xEF);\n\tWriteCommand(0xEB);\n\tWriteData(0x14);\n\n\tWriteCommand(0xFE);\n\tWriteCommand(0xEF);\n\n\tWriteCommand(0xEB);\n\tWriteData(0x14);\n\n\tWriteCommand(0x84);\n\tWriteData(0x40);\n\n\tWriteCommand(0x85);\n\tWriteData(0xFF);\n\n\tWriteCommand(0x86);\n\tWriteData(0xFF);\n\n\tWriteCommand(0x87);\n\tWriteData(0xFF);\n\n\tWriteCommand(0x88);\n\tWriteData(0x0A);\n\n\tWriteCommand(0x89);\n\tWriteData(0x21);\n\n\tWriteCommand(0x8A);\n\tWriteData(0x00);\n\n\tWriteCommand(0x8B);\n\tWriteData(0x80);\n\n\tWriteCommand(0x8C);\n\tWriteData(0x01);\n\n\tWriteCommand(0x8D);\n\tWriteData(0x01);\n\n\tWriteCommand(0x8E);\n\tWriteData(0xFF);\n\n\tWriteCommand(0x8F);\n\tWriteData(0xFF);\n\n\n\tWriteCommand(0xB6);\n\tWriteData(0x00);\n\tWriteData(0x20);\n\n\tWriteCommand(0x36);\n\tWriteData(0x08);\/\/Set as vertical screen\n\n\tWriteCommand(0x3A);\n\tWriteData(0x05);\n\n\n\tWriteCommand(0x90);\n\tWriteData(0x08);\n\tWriteData(0x08);\n\tWriteData(0x08);\n\tWriteData(0x08);\n\n\tWriteCommand(0xBD);\n\tWriteData(0x06);\n\n\tWriteCommand(0xBC);\n\tWriteData(0x00);\n\n\tWriteCommand(0xFF);\n\tWriteData(0x60);\n\tWriteData(0x01);\n\tWriteData(0x04);\n\n\tWriteCommand(0xC3);\n\tWriteData(0x13);\n\tWriteCommand(0xC4);\n\tWriteData(0x13);\n\n\tWriteCommand(0xC9);\n\tWriteData(0x22);\n\n\tWriteCommand(0xBE);\n\tWriteData(0x11);\n\n\tWriteCommand(0xE1);\n\tWriteData(0x10);\n\tWriteData(0x0E);\n\n\tWriteCommand(0xDF);\n\tWriteData(0x21);\n\tWriteData(0x0c);\n\tWriteData(0x02);\n\n\tWriteCommand(0xF0);\n\tWriteData(0x45);\n\tWriteData(0x09);\n\tWriteData(0x08);\n\tWriteData(0x08);\n\tWriteData(0x26);\n\tWriteData(0x2A);\n\n\tWriteCommand(0xF1);\n\tWriteData(0x43);\n\tWriteData(0x70);\n\tWriteData(0x72);\n\tWriteData(0x36);\n\tWriteData(0x37);\n\tWriteData(0x6F);\n\n\n\tWriteCommand(0xF2);\n\tWriteData(0x45);\n\tWriteData(0x09);\n\tWriteData(0x08);\n\tWriteData(0x08);\n\tWriteData(0x26);\n\tWriteData(0x2A);\n\n\tWriteCommand(0xF3);\n\tWriteData(0x43);\n\tWriteData(0x70);\n\tWriteData(0x72);\n\tWriteData(0x36);\n\tWriteData(0x37);\n\tWriteData(0x6F);\n\n\tWriteCommand(0xED);\n\tWriteData(0x1B);\n\tWriteData(0x0B);\n\n\tWriteCommand(0xAE);\n\tWriteData(0x77);\n\n\tWriteCommand(0xCD);\n\tWriteData(0x63);\n\n\n\tWriteCommand(0x70);\n\tWriteData(0x07);\n\tWriteData(0x07);\n\tWriteData(0x04);\n\tWriteData(0x0E);\n\tWriteData(0x0F);\n\tWriteData(0x09);\n\tWriteData(0x07);\n\tWriteData(0x08);\n\tWriteData(0x03);\n\n\tWriteCommand(0xE8);\n\tWriteData(0x34);\n\n\tWriteCommand(0x62);\n\tWriteData(0x18);\n\tWriteData(0x0D);\n\tWriteData(0x71);\n\tWriteData(0xED);\n\tWriteData(0x70);\n\tWriteData(0x70);\n\tWriteData(0x18);\n\tWriteData(0x0F);\n\tWriteData(0x71);\n\tWriteData(0xEF);\n\tWriteData(0x70);\n\tWriteData(0x70);\n\n\tWriteCommand(0x63);\n\tWriteData(0x18);\n\tWriteData(0x11);\n\tWriteData(0x71);\n\tWriteData(0xF1);\n\tWriteData(0x70);\n\tWriteData(0x70);\n\tWriteData(0x18);\n\tWriteData(0x13);\n\tWriteData(0x71);\n\tWriteData(0xF3);\n\tWriteData(0x70);\n\tWriteData(0x70);\n\n\tWriteCommand(0x64);\n\tWriteData(0x28);\n\tWriteData(0x29);\n\tWriteData(0xF1);\n\tWriteData(0x01);\n\tWriteData(0xF1);\n\tWriteData(0x00);\n\tWriteData(0x07);\n\n\tWriteCommand(0x66);\n\tWriteData(0x3C);\n\tWriteData(0x00);\n\tWriteData(0xCD);\n\tWriteData(0x67);\n\tWriteData(0x45);\n\tWriteData(0x45);\n\tWriteData(0x10);\n\tWriteData(0x00);\n\tWriteData(0x00);\n\tWriteData(0x00);\n\n\tWriteCommand(0x67);\n\tWriteData(0x00);\n\tWriteData(0x3C);\n\tWriteData(0x00);\n\tWriteData(0x00);\n\tWriteData(0x00);\n\tWriteData(0x01);\n\tWriteData(0x54);\n\tWriteData(0x10);\n\tWriteData(0x32);\n\tWriteData(0x98);\n\n\tWriteCommand(0x74);\n\tWriteData(0x10);\n\tWriteData(0x85);\n\tWriteData(0x80);\n\tWriteData(0x00);\n\tWriteData(0x00);\n\tWriteData(0x4E);\n\tWriteData(0x00);\n\n\tWriteCommand(0x98);\n\tWriteData(0x3e);\n\tWriteData(0x07);\n\n\tWriteCommand(0x35);\n\tWriteCommand(0x21);\n\n\tWriteCommand(0x11);\n\tHAL_Delay(120);\n\tWriteCommand(0x29);\n\tHAL_Delay(20);\n\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>This function sends the required&nbsp;<strong>initialization sequence<\/strong>&nbsp;to the LCD controller so the panel can operate correctly.<\/p>\n\n\n\n<p>It configures internal power circuits, voltage levels, timing parameters, gamma curves, and panel-driving waveforms using a series of command\/data writes. The&nbsp;<code>0x36<\/code>&nbsp;command sets the screen orientation, while&nbsp;<code>0x3A<\/code>&nbsp;selects the pixel format (RGB565). Other grouped commands adjust refresh behavior and image quality.<\/p>\n\n\n\n<p>At the end,&nbsp;<code>0x11<\/code>&nbsp;brings the display out of sleep mode, the delay allows power stabilization, and&nbsp;<code>0x29<\/code>&nbsp;turns the screen on so it is ready to receive pixel data.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, setting display attributes as follows:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">static void LCD_SetAttributes(uint8_t Scan_dir)\n{\n    \/\/Get the screen scan direction\n\tlcdAttr.SCAN_DIR = Scan_dir;\n    uint8_t MemoryAccessReg = 0x08;\n\n    \/\/Get GRAM and LCD width and height\n    if(Scan_dir == HORIZONTAL) {\n    \tlcdAttr.HEIGHT\t= LCD_1IN28_HEIGHT;\n    \tlcdAttr.WIDTH   = LCD_1IN28_WIDTH;\n        MemoryAccessReg = 0XC8;\n    } else {\n    \tlcdAttr.HEIGHT\t= LCD_1IN28_WIDTH;\n    \tlcdAttr.WIDTH   = LCD_1IN28_HEIGHT;\n        MemoryAccessReg = 0X68;\n    }\n\n    \/\/ Set the read \/ write scan direction of the frame memory\n    WriteCommand(0x36); \/\/MX, MY, RGB mode\n    WriteData(MemoryAccessReg);\t\/\/0x08 set RGB\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>This will allow the firmware to adjust the behaviour according to the orientation.<\/p>\n\n\n\n<p>Next, LCD initialization function:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void LCD_Init(uint8_t Scan_dir)\n{\n\n    \/\/ Hardware reset\n\tReset();\n\n    \/\/ Set the resolution and scanning method of the screen\n\tLCD_SetAttributes(Scan_dir);\n\n    \/\/ Set the initialization register\n\tLCD_InitReg();\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, set address window function:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void LCD_SetWindows(uint8_t Xstart, uint8_t Ystart, uint8_t Xend, uint8_t Yend)\n{\n    \/\/set the X coordinates\n\tWriteCommand(0x2A);\n\tWriteData(0x00);\n\tWriteData(Xstart);\n\tWriteData(0x00);\n\tWriteData(Xend);\n\n\t\/\/set the Y coordinates\n\tWriteCommand(0x2B);\n\tWriteData(0x00);\n\tWriteData(Ystart);\n\tWriteData(0x00);\n\tWriteData(Yend);\n\n\tWriteCommand(0X2C);\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>This function defines the\u00a0<strong>active drawing window<\/strong>\u00a0(addressing region) inside the GC9A01\u2019s internal GRAM before any pixel data is written. It uses the\u00a0<strong>Column Address Set (0x2A)<\/strong>\u00a0and\u00a0<strong>Row Address Set (0x2B)<\/strong>\u00a0commands to specify the start and end coordinates of the region where subsequent pixel data will be applied.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Finally draw pixel function:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void Draw_Pixel(uint8_t X, uint8_t Y, uint16_t Color)\n{\n\tLCD_SetWindows(X, Y, X, Y);\n\tWriteData16Bit(Color);\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Hence, the entire source file as follows:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;GC9A01.h&quot;\n\n\ntypedef struct{\n    uint16_t WIDTH;\n    uint16_t HEIGHT;\n    int8_t SCAN_DIR;\n}LCD_ATTRIBUTES;\n\n\nLCD_ATTRIBUTES lcdAttr;\n\n\nstatic void CS_Deselect()\n{\n\tHAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, SET);\n}\n\nstatic void CS_Select()\n{\n\tHAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, RESET);\n}\n\nstatic void RST_HIGH()\n{\n\tHAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, SET);\n}\n\nstatic void RST_LOW()\n{\n\tHAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, RESET);\n}\n\nstatic void DC_HIGH()\n{\n\tHAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, SET);\n}\n\nstatic void DC_LOW()\n{\n\tHAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, RESET);\n}\n\n\nstatic void Reset(void)\n{\n\tRST_HIGH();\n    HAL_Delay(100);\n    RST_LOW();\n    HAL_Delay(100);\n    RST_HIGH();\n    HAL_Delay(100);\n}\n\nstatic void WriteData(uint8_t data)\n{\n\tCS_Select();\n\tDC_HIGH();\n\n\tHAL_SPI_Transmit(&amp;hspi1, &amp;data, 1, 10);\n\n\tCS_Deselect();\n\n}\n\nstatic void WriteCommand(uint8_t Command)\n{\n\tCS_Select();\n\tDC_LOW();\n\n\tHAL_SPI_Transmit(&amp;hspi1, &amp;Command, 1, 10);\n\n\tCS_Deselect();\n\n}\n\nstatic void WriteData16Bit(uint16_t data)\n{\n\tCS_Select();\n\tDC_HIGH();\n\n\tuint8_t data16_bit[2]={(data&gt;&gt;8)&amp;0xFF, data&amp;0xFF};\n\n\tHAL_SPI_Transmit(&amp;hspi1, data16_bit, 2, 10);\n\n\tCS_Deselect();\n\n}\n\n\nstatic void LCD_InitReg(void)\n{\n\n\tWriteCommand(0xEF);\n\tWriteCommand(0xEB);\n\tWriteData(0x14);\n\n\tWriteCommand(0xFE);\n\tWriteCommand(0xEF);\n\n\tWriteCommand(0xEB);\n\tWriteData(0x14);\n\n\tWriteCommand(0x84);\n\tWriteData(0x40);\n\n\tWriteCommand(0x85);\n\tWriteData(0xFF);\n\n\tWriteCommand(0x86);\n\tWriteData(0xFF);\n\n\tWriteCommand(0x87);\n\tWriteData(0xFF);\n\n\tWriteCommand(0x88);\n\tWriteData(0x0A);\n\n\tWriteCommand(0x89);\n\tWriteData(0x21);\n\n\tWriteCommand(0x8A);\n\tWriteData(0x00);\n\n\tWriteCommand(0x8B);\n\tWriteData(0x80);\n\n\tWriteCommand(0x8C);\n\tWriteData(0x01);\n\n\tWriteCommand(0x8D);\n\tWriteData(0x01);\n\n\tWriteCommand(0x8E);\n\tWriteData(0xFF);\n\n\tWriteCommand(0x8F);\n\tWriteData(0xFF);\n\n\n\tWriteCommand(0xB6);\n\tWriteData(0x00);\n\tWriteData(0x20);\n\n\tWriteCommand(0x36);\n\tWriteData(0x08);\/\/Set as vertical screen\n\n\tWriteCommand(0x3A);\n\tWriteData(0x05);\n\n\n\tWriteCommand(0x90);\n\tWriteData(0x08);\n\tWriteData(0x08);\n\tWriteData(0x08);\n\tWriteData(0x08);\n\n\tWriteCommand(0xBD);\n\tWriteData(0x06);\n\n\tWriteCommand(0xBC);\n\tWriteData(0x00);\n\n\tWriteCommand(0xFF);\n\tWriteData(0x60);\n\tWriteData(0x01);\n\tWriteData(0x04);\n\n\tWriteCommand(0xC3);\n\tWriteData(0x13);\n\tWriteCommand(0xC4);\n\tWriteData(0x13);\n\n\tWriteCommand(0xC9);\n\tWriteData(0x22);\n\n\tWriteCommand(0xBE);\n\tWriteData(0x11);\n\n\tWriteCommand(0xE1);\n\tWriteData(0x10);\n\tWriteData(0x0E);\n\n\tWriteCommand(0xDF);\n\tWriteData(0x21);\n\tWriteData(0x0c);\n\tWriteData(0x02);\n\n\tWriteCommand(0xF0);\n\tWriteData(0x45);\n\tWriteData(0x09);\n\tWriteData(0x08);\n\tWriteData(0x08);\n\tWriteData(0x26);\n\tWriteData(0x2A);\n\n\tWriteCommand(0xF1);\n\tWriteData(0x43);\n\tWriteData(0x70);\n\tWriteData(0x72);\n\tWriteData(0x36);\n\tWriteData(0x37);\n\tWriteData(0x6F);\n\n\n\tWriteCommand(0xF2);\n\tWriteData(0x45);\n\tWriteData(0x09);\n\tWriteData(0x08);\n\tWriteData(0x08);\n\tWriteData(0x26);\n\tWriteData(0x2A);\n\n\tWriteCommand(0xF3);\n\tWriteData(0x43);\n\tWriteData(0x70);\n\tWriteData(0x72);\n\tWriteData(0x36);\n\tWriteData(0x37);\n\tWriteData(0x6F);\n\n\tWriteCommand(0xED);\n\tWriteData(0x1B);\n\tWriteData(0x0B);\n\n\tWriteCommand(0xAE);\n\tWriteData(0x77);\n\n\tWriteCommand(0xCD);\n\tWriteData(0x63);\n\n\n\tWriteCommand(0x70);\n\tWriteData(0x07);\n\tWriteData(0x07);\n\tWriteData(0x04);\n\tWriteData(0x0E);\n\tWriteData(0x0F);\n\tWriteData(0x09);\n\tWriteData(0x07);\n\tWriteData(0x08);\n\tWriteData(0x03);\n\n\tWriteCommand(0xE8);\n\tWriteData(0x34);\n\n\tWriteCommand(0x62);\n\tWriteData(0x18);\n\tWriteData(0x0D);\n\tWriteData(0x71);\n\tWriteData(0xED);\n\tWriteData(0x70);\n\tWriteData(0x70);\n\tWriteData(0x18);\n\tWriteData(0x0F);\n\tWriteData(0x71);\n\tWriteData(0xEF);\n\tWriteData(0x70);\n\tWriteData(0x70);\n\n\tWriteCommand(0x63);\n\tWriteData(0x18);\n\tWriteData(0x11);\n\tWriteData(0x71);\n\tWriteData(0xF1);\n\tWriteData(0x70);\n\tWriteData(0x70);\n\tWriteData(0x18);\n\tWriteData(0x13);\n\tWriteData(0x71);\n\tWriteData(0xF3);\n\tWriteData(0x70);\n\tWriteData(0x70);\n\n\tWriteCommand(0x64);\n\tWriteData(0x28);\n\tWriteData(0x29);\n\tWriteData(0xF1);\n\tWriteData(0x01);\n\tWriteData(0xF1);\n\tWriteData(0x00);\n\tWriteData(0x07);\n\n\tWriteCommand(0x66);\n\tWriteData(0x3C);\n\tWriteData(0x00);\n\tWriteData(0xCD);\n\tWriteData(0x67);\n\tWriteData(0x45);\n\tWriteData(0x45);\n\tWriteData(0x10);\n\tWriteData(0x00);\n\tWriteData(0x00);\n\tWriteData(0x00);\n\n\tWriteCommand(0x67);\n\tWriteData(0x00);\n\tWriteData(0x3C);\n\tWriteData(0x00);\n\tWriteData(0x00);\n\tWriteData(0x00);\n\tWriteData(0x01);\n\tWriteData(0x54);\n\tWriteData(0x10);\n\tWriteData(0x32);\n\tWriteData(0x98);\n\n\tWriteCommand(0x74);\n\tWriteData(0x10);\n\tWriteData(0x85);\n\tWriteData(0x80);\n\tWriteData(0x00);\n\tWriteData(0x00);\n\tWriteData(0x4E);\n\tWriteData(0x00);\n\n\tWriteCommand(0x98);\n\tWriteData(0x3e);\n\tWriteData(0x07);\n\n\tWriteCommand(0x35);\n\tWriteCommand(0x21);\n\n\tWriteCommand(0x11);\n\tHAL_Delay(120);\n\tWriteCommand(0x29);\n\tHAL_Delay(20);\n\n}\n\n\n\nstatic void LCD_SetAttributes(uint8_t Scan_dir)\n{\n    \/\/Get the screen scan direction\n\tlcdAttr.SCAN_DIR = Scan_dir;\n    uint8_t MemoryAccessReg = 0x08;\n\n    \/\/Get GRAM and LCD width and height\n    if(Scan_dir == HORIZONTAL) {\n    \tlcdAttr.HEIGHT\t= LCD_1IN28_HEIGHT;\n    \tlcdAttr.WIDTH   = LCD_1IN28_WIDTH;\n        MemoryAccessReg = 0XC8;\n    } else {\n    \tlcdAttr.HEIGHT\t= LCD_1IN28_WIDTH;\n    \tlcdAttr.WIDTH   = LCD_1IN28_HEIGHT;\n        MemoryAccessReg = 0X68;\n    }\n\n    \/\/ Set the read \/ write scan direction of the frame memory\n    WriteCommand(0x36); \/\/MX, MY, RGB mode\n    WriteData(MemoryAccessReg);\t\/\/0x08 set RGB\n}\n\n\nvoid LCD_Init(uint8_t Scan_dir)\n{\n\n    \/\/ Hardware reset\n\tReset();\n\n    \/\/ Set the resolution and scanning method of the screen\n\tLCD_SetAttributes(Scan_dir);\n\n    \/\/ Set the initialization register\n\tLCD_InitReg();\n}\n\nvoid LCD_SetWindows(uint8_t Xstart, uint8_t Ystart, uint8_t Xend, uint8_t Yend)\n{\n    \/\/set the X coordinates\n\tWriteCommand(0x2A);\n\tWriteData(0x00);\n\tWriteData(Xstart);\n\tWriteData(0x00);\n\tWriteData(Xend);\n\n\t\/\/set the Y coordinates\n\tWriteCommand(0x2B);\n\tWriteData(0x00);\n\tWriteData(Ystart);\n\tWriteData(0x00);\n\tWriteData(Yend);\n\n\tWriteCommand(0X2C);\n}\n\nvoid Draw_Pixel(uint8_t X, uint8_t Y, uint16_t Color)\n{\n\tLCD_SetWindows(X, Y, X, Y);\n\tWriteData16Bit(Color);\n}\n\n\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">8. Main.c Code:<\/h2>\n\n\n\n<p>In user code includes in main.c file, include the following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;GC9A01.h&quot;\n\n#include &quot;stdlib.h&quot;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>In user code begin 2 in main function, initialize the LCD in vertical orientation:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">LCD_Init(VERTICAL);<\/pre><\/div>\n\n\n\n<p>In user code begin 3 in while loop:<\/p>\n\n\n\n<p>File each pixel with random color as follows:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t for(int i=0;i&lt;LCD_1IN28_HEIGHT;i++)\n\t {\n\t\t for (int j=0;j&lt;LCD_1IN28_WIDTH;j++)\n\t\t {\n\t\t\t Draw_Pixel(i,j,random()%0xFFFF);\n\n\t\t }\n\t }\n\n\t HAL_Delay(500);<\/pre><\/div>\n\n\n\n<p>Thats all.<\/p>\n\n\n\n<p>Save the project, build it and run it on your board as following:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"28\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/image-5-1024x28.png\" alt=\"\" class=\"wp-image-3917\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/image-5-1024x28.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/image-5-300x8.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/image-5-768x21.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/image-5-1536x43.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/image-5-1150x32.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/image-5-750x21.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/image-5-400x11.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/image-5-250x7.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/image-5.png 1734w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">9. Results:<\/h2>\n\n\n\n<p>Once the IDE finish flashing, you should get random colors on you display, for example:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/02\/IMG_9514.heic\" alt=\"\" class=\"wp-image-4225\" \/><\/figure>\n\n\n\n<p>In part 3, we shall display an image.<\/p>\n\n\n\n<p>Stay tuned.<\/p>\n\n\n\n<p>Happy coding\u00a0\ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this second part of the guide, we move from configuration to implementation by developing the GC9A01 driver header and source files for STM32. We will initialize the LCD controller and implement a basic draw-pixel function, using it to render randomly colored pixels as a first functional test of the display. In this guide, we [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,19,11,12],"tags":[],"class_list":["post-4221","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-lcd","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/4221"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4221"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/4221\/revisions"}],"predecessor-version":[{"id":4226,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/4221\/revisions\/4226"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4221"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4221"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4221"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}