{"id":4118,"date":"2025-12-27T14:00:55","date_gmt":"2025-12-27T14:00:55","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=4118"},"modified":"2025-12-27T14:00:57","modified_gmt":"2025-12-27T14:00:57","slug":"stm32-with-color-lcd-st7789v2-part-2-lcd-initialization-and-draw-pixels","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=4118","title":{"rendered":"STM32 with Color LCD ST7789V2 Part 2:\u00a0LCD Initialization and Draw Pixels"},"content":{"rendered":"\n<p><\/p>\n\n\n\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\/2025\/12\/ChatGPT-Image-Nov-26-2025-at-04_08_42-PM-1024x683.png\" alt=\"\" class=\"wp-image-4119\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Nov-26-2025-at-04_08_42-PM-1024x683.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Nov-26-2025-at-04_08_42-PM-300x200.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Nov-26-2025-at-04_08_42-PM-768x512.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Nov-26-2025-at-04_08_42-PM-1150x767.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Nov-26-2025-at-04_08_42-PM-750x500.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Nov-26-2025-at-04_08_42-PM-400x267.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Nov-26-2025-at-04_08_42-PM-250x167.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Nov-26-2025-at-04_08_42-PM.png 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In this second part of the guide, we move from configuration to implementation by developing the ST7789V2 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>First, 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 st7789v2.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\/2025\/12\/2025-12-27_07-57-51-1024x734.jpg\" alt=\"\" class=\"wp-image-4120\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_07-57-51-1024x734.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_07-57-51-300x215.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_07-57-51-768x550.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_07-57-51-1150x824.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_07-57-51-750x538.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_07-57-51-400x287.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_07-57-51-250x179.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_07-57-51.jpg 1172w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>n similar manner, right click on Inc folder and add new header file with name of st7789v2.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\/2025\/12\/2025-12-27_16-31-57-1024x734.jpg\" alt=\"\" class=\"wp-image-4121\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_16-31-57-1024x734.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_16-31-57-300x215.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_16-31-57-768x550.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_16-31-57-1150x824.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_16-31-57-750x538.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_16-31-57-400x287.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_16-31-57-250x179.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-27_16-31-57.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><\/p>\n\n\n\n<p>Within st7789v2.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 &lt;stdint.h&gt;\n\n#include &quot;main.h&quot;\n\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 ST7789V2_HEIGHT 280\n#define ST7789V2_WIDTH 240<\/pre><\/div>\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>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(uint16_t X, uint16_t Y, uint16_t Color);<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Hence, the entire 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_ST7789V2_H_\n#define INC_ST7789V2_H_\n\n\n#include &lt;stdint.h&gt;\n\n#include &quot;main.h&quot;\n\n#include &quot;spi.h&quot;\n\n#define ST7789V2_HEIGHT 280\n#define ST7789V2_WIDTH 240\n\n\n#define HORIZONTAL 0\n#define VERTICAL   1\n\nvoid LCD_Init(uint8_t Scan_dir);\n\nvoid Draw_Pixel(uint16_t X, uint16_t Y, uint16_t Color);\n\n\n#endif \/* INC_ST7789V2_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 st7789v2 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 &lt;st7789v2.h&gt;<\/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>Declare the data structure 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;}\">LCD_ATTRIBUTES lcdAttr;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, we need some functions to handle the CS, CD and RST pins:<\/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 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>These are standardized for any color LCD.<\/p>\n\n\n\n<p><\/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>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<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}\n<\/pre><\/div>\n\n\n\n<p>These are also standard for any color LCD.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, software reset 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 soft_Reset(void)\n{\n\tWriteCommand(0x01);\n\tHAL_Delay(15);\n}<\/pre><\/div>\n\n\n\n<p><\/p>\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    WriteCommand(0x36);\n    WriteData(0x00);\n\n    WriteCommand(0x3A);\n    WriteData(0x05);\n\n    WriteCommand(0xB2);\n    WriteData(0x0B);\n    WriteData(0x0B);\n    WriteData(0x00);\n    WriteData(0x33);\n    WriteData(0x35);\n\n    WriteCommand(0xB7);\n    WriteData(0x11);\n\n    WriteCommand(0xBB);\n    WriteData(0x35);\n\n    WriteCommand(0xC0);\n    WriteData(0x2C);\n\n    WriteCommand(0xC2);\n    WriteData(0x01);\n\n    WriteCommand(0xC3);\n    WriteData(0x0D);\n\n    WriteCommand(0xC4);\n    WriteData(0x20);\n\n    WriteCommand(0xC6);\n    WriteData(0x13);\n\n    WriteCommand(0xD0);\n    WriteData(0xA4);\n    WriteData(0xA1);\n\n    WriteCommand(0xD6);\n    WriteData(0xA1);\n\n    WriteCommand(0xE0);\n    WriteData(0xF0);\n    WriteData(0x06);\n    WriteData(0x0B);\n    WriteData(0x0A);\n    WriteData(0x09);\n    WriteData(0x26);\n    WriteData(0x29);\n    WriteData(0x33);\n    WriteData(0x41);\n    WriteData(0x18);\n    WriteData(0x16);\n    WriteData(0x15);\n    WriteData(0x29);\n    WriteData(0x2D);\n\n    WriteCommand(0xE1);\n    WriteData(0xF0);\n    WriteData(0x04);\n    WriteData(0x08);\n    WriteData(0x08);\n    WriteData(0x07);\n    WriteData(0x03);\n    WriteData(0x28);\n    WriteData(0x32);\n    WriteData(0x40);\n    WriteData(0x3B);\n    WriteData(0x19);\n    WriteData(0x18);\n    WriteData(0x2A);\n    WriteData(0x2E);\n\n    WriteCommand(0xE4);\n    WriteData(0x25);\n    WriteData(0x00);\n    WriteData(0x00);\n\n    WriteCommand(0x21);\n\n    WriteCommand(0x11);\n    HAL_Delay(120);\n    WriteCommand(0x29);\n}<\/pre><\/div>\n\n\n\n<p>This initialization routine configures the&nbsp;<strong>ST7789V2 display controller<\/strong>&nbsp;by programming its core operating parameters, including memory access behavior, pixel format, power settings, frame rate, and gamma correction. The sequence starts by setting the&nbsp;<strong>memory data access control (0x36)<\/strong>&nbsp;and&nbsp;<strong>pixel format (0x3A)<\/strong>&nbsp;to define orientation and RGB565 color mode, followed by porch control, gate control, and voltage-related commands (0xB2\u20130xD6) that stabilize the panel\u2019s timing and power characteristics.<\/p>\n\n\n\n<p>The&nbsp;<strong>gamma correction commands (0xE0 and 0xE1)<\/strong>&nbsp;configure the positive and negative voltage curves, which directly affect color accuracy and contrast on the LCD. Additional commands such as&nbsp;<strong>display inversion (0x21)<\/strong>&nbsp;and extended control (0xE4) fine-tune visual behavior. Finally, the display is brought out of sleep mode using&nbsp;<strong>Sleep Out (0x11)<\/strong>, followed by a mandatory delay to allow internal circuits to stabilize, and then&nbsp;<strong>Display ON (0x29)<\/strong>&nbsp;is issued to activate the panel and begin normal operation.<\/p>\n\n\n\n<p>This sequence ensures the display is electrically stable, correctly timed, and visually calibrated before any pixel data is transmitted.<\/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 = 0x00;\n\n    \/\/ Get GRAM and LCD width and height\n    if (Scan_dir == HORIZONTAL) {\n    \tlcdAttr.HEIGHT = ST7789V2_WIDTH;\n    \tlcdAttr.WIDTH = ST7789V2_HEIGHT;\n        MemoryAccessReg = 0X70;\n    }\n    else {\n    \tlcdAttr.HEIGHT = ST7789V2_HEIGHT;\n    \tlcdAttr.WIDTH = ST7789V2_WIDTH;\n        MemoryAccessReg = 0X00;\n    }\n\n    \/\/ Set the read \/ write scan direction of the frame memory\n    WriteCommand(0x36); \/\/ MX, MY, RGB mode\n    WriteData(MemoryAccessReg); \/\/ 0x08 set RGB\n}<\/pre><\/div>\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<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\t\/\/software reset\n\tsoft_Reset();\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>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;}\">static void LCD_SetWindows(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend)\n{\n    if (lcdAttr.SCAN_DIR == VERTICAL) {\n\t\t\t\t\/\/ set the X coordinates\n    \tWriteCommand(0x2A);\n    \tWriteData(Xstart &gt;&gt; 8);\n    \tWriteData(Xstart);\n    \tWriteData((Xend-1) &gt;&gt; 8);\n    \tWriteData(Xend-1);\n\n        \/\/ set the Y coordinates\n        WriteCommand(0x2B);\n        WriteData((Ystart+10) &gt;&gt; 8);\n        WriteData(Ystart+10);\n        WriteData((Yend+10-1) &gt;&gt; 8);\n        WriteData(Yend+10-1);\n\n    }\n    else {\n        \/\/ set the X coordinates\n    \tWriteCommand(0x2A);\n    \tWriteData((Xstart+10) &gt;&gt; 8);\n    \tWriteData(Xstart+10);\n    \tWriteData((Xend+10-1) &gt;&gt; 8);\n    \tWriteData(Xend+10-1);\n\n        \/\/ set the Y coordinates\n        WriteCommand(0x2B);\n        WriteData(Ystart &gt;&gt; 8);\n        WriteData(Ystart);\n        WriteData((Yend-1) &gt;&gt; 8);\n        WriteData(Yend-1);\n    }\n\n    WriteCommand(0X2C);\n}<\/pre><\/div>\n\n\n\n<p>This function defines the&nbsp;<strong>active drawing window<\/strong>&nbsp;(addressing region) inside the ST7789V2\u2019s internal GRAM before any pixel data is written. It uses the&nbsp;<strong>Column Address Set (0x2A)<\/strong>&nbsp;and&nbsp;<strong>Row Address Set (0x2B)<\/strong>&nbsp;commands to specify the start and end coordinates of the region where subsequent pixel data will be applied.<\/p>\n\n\n\n<p>The behavior changes based on the selected&nbsp;<strong>scan direction<\/strong>: when vertical scanning is enabled, the X and Y axes are mapped differently to match the display orientation. The added offset (<code>+10<\/code>) compensates for the panel\u2019s internal pixel mapping, which is common on ST7789-based displays where the visible area does not start at GRAM coordinate (0,0). Finally, the&nbsp;<strong>Memory Write command (0x2C)<\/strong>&nbsp;is issued, indicating that the next transmitted data bytes represent pixel color values for the defined window.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Finally draw pixel 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 Draw_Pixel(uint16_t X, uint16_t Y, uint16_t Color)\n{\n\tLCD_SetWindows(X, Y, X, Y);\n\tWriteData16Bit(Color);\n}<\/pre><\/div>\n\n\n\n<p>Hence, the source 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 &lt;st7789v2.h&gt;\n\n\n\ntypedef struct{\n    uint16_t WIDTH;\n    uint16_t HEIGHT;\n    int8_t SCAN_DIR;\n}LCD_ATTRIBUTES;\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\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\n\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 soft_Reset(void)\n{\n\tWriteCommand(0x01);\n\tHAL_Delay(15);\n}\n\n\nstatic void LCD_InitReg(void)\n{\n    WriteCommand(0x36);\n    WriteData(0x00);\n\n    WriteCommand(0x3A);\n    WriteData(0x05);\n\n    WriteCommand(0xB2);\n    WriteData(0x0B);\n    WriteData(0x0B);\n    WriteData(0x00);\n    WriteData(0x33);\n    WriteData(0x35);\n\n    WriteCommand(0xB7);\n    WriteData(0x11);\n\n    WriteCommand(0xBB);\n    WriteData(0x35);\n\n    WriteCommand(0xC0);\n    WriteData(0x2C);\n\n    WriteCommand(0xC2);\n    WriteData(0x01);\n\n    WriteCommand(0xC3);\n    WriteData(0x0D);\n\n    WriteCommand(0xC4);\n    WriteData(0x20);\n\n    WriteCommand(0xC6);\n    WriteData(0x13);\n\n    WriteCommand(0xD0);\n    WriteData(0xA4);\n    WriteData(0xA1);\n\n    WriteCommand(0xD6);\n    WriteData(0xA1);\n\n    WriteCommand(0xE0);\n    WriteData(0xF0);\n    WriteData(0x06);\n    WriteData(0x0B);\n    WriteData(0x0A);\n    WriteData(0x09);\n    WriteData(0x26);\n    WriteData(0x29);\n    WriteData(0x33);\n    WriteData(0x41);\n    WriteData(0x18);\n    WriteData(0x16);\n    WriteData(0x15);\n    WriteData(0x29);\n    WriteData(0x2D);\n\n    WriteCommand(0xE1);\n    WriteData(0xF0);\n    WriteData(0x04);\n    WriteData(0x08);\n    WriteData(0x08);\n    WriteData(0x07);\n    WriteData(0x03);\n    WriteData(0x28);\n    WriteData(0x32);\n    WriteData(0x40);\n    WriteData(0x3B);\n    WriteData(0x19);\n    WriteData(0x18);\n    WriteData(0x2A);\n    WriteData(0x2E);\n\n    WriteCommand(0xE4);\n    WriteData(0x25);\n    WriteData(0x00);\n    WriteData(0x00);\n\n    WriteCommand(0x21);\n\n    WriteCommand(0x11);\n    HAL_Delay(120);\n    WriteCommand(0x29);\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 = 0x00;\n\n    \/\/ Get GRAM and LCD width and height\n    if (Scan_dir == HORIZONTAL) {\n    \tlcdAttr.HEIGHT = ST7789V2_WIDTH;\n    \tlcdAttr.WIDTH = ST7789V2_HEIGHT;\n        MemoryAccessReg = 0X70;\n    }\n    else {\n    \tlcdAttr.HEIGHT = ST7789V2_HEIGHT;\n    \tlcdAttr.WIDTH = ST7789V2_WIDTH;\n        MemoryAccessReg = 0X00;\n    }\n\n    \/\/ Set the read \/ write scan direction of the frame memory\n    WriteCommand(0x36); \/\/ MX, MY, RGB mode\n    WriteData(MemoryAccessReg); \/\/ 0x08 set RGB\n}\n\nvoid LCD_Init(uint8_t Scan_dir)\n{\n\n    \/\/ Hardware reset\n\tReset();\n\n\t\/\/software reset\n\tsoft_Reset();\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\nstatic void LCD_SetWindows(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend)\n{\n    if (lcdAttr.SCAN_DIR == VERTICAL) {\n\t\t\t\t\/\/ set the X coordinates\n    \tWriteCommand(0x2A);\n    \tWriteData(Xstart &gt;&gt; 8);\n    \tWriteData(Xstart);\n    \tWriteData((Xend-1) &gt;&gt; 8);\n    \tWriteData(Xend-1);\n\n        \/\/ set the Y coordinates\n        WriteCommand(0x2B);\n        WriteData((Ystart+10) &gt;&gt; 8);\n        WriteData(Ystart+10);\n        WriteData((Yend+10-1) &gt;&gt; 8);\n        WriteData(Yend+10-1);\n\n    }\n    else {\n        \/\/ set the X coordinates\n    \tWriteCommand(0x2A);\n    \tWriteData((Xstart+10) &gt;&gt; 8);\n    \tWriteData(Xstart+10);\n    \tWriteData((Xend+10-1) &gt;&gt; 8);\n    \tWriteData(Xend+10-1);\n\n        \/\/ set the Y coordinates\n        WriteCommand(0x2B);\n        WriteData(Ystart &gt;&gt; 8);\n        WriteData(Ystart);\n        WriteData((Yend-1) &gt;&gt; 8);\n        WriteData(Yend-1);\n    }\n\n    WriteCommand(0X2C);\n}\n\nvoid Draw_Pixel(uint16_t X, uint16_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<h2 class=\"wp-block-heading\">8. Main.c code:<\/h2>\n\n\n\n<p><\/p>\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;st7789v2.h&quot;\n\n#include &quot;stdlib.h&quot; \/\/for random<\/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<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;}\">for (int i=0;i&lt;ST7789V2_WIDTH ;i++)\n\t  {\n\t\t  for (int j=0;j&lt;ST7789V2_HEIGHT;j++)\n\t\t  {\n\t\t\t  Draw_Pixel(i,j,random()%0xFFFF);\n\t\t  }\n\t  }<\/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<h2 class=\"wp-block-heading\">9. Results:<\/h2>\n\n\n\n<p><\/p>\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\/2025\/12\/IMG_9020.heic\" alt=\"\" class=\"wp-image-4122\" \/><\/figure>\n\n\n\n<p>In part 3, we shall display an image.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Stay tuned.<\/p>\n\n\n\n<p>Happy coding \ud83d\ude09<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this second part of the guide, we move from configuration to implementation by developing the ST7789V2 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-4118","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\/4118"}],"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=4118"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/4118\/revisions"}],"predecessor-version":[{"id":4123,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/4118\/revisions\/4123"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4118"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4118"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4118"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}