{"id":4328,"date":"2026-04-02T11:45:55","date_gmt":"2026-04-02T11:45:55","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=4328"},"modified":"2026-04-02T11:45:57","modified_gmt":"2026-04-02T11:45:57","slug":"stm32f429-discovery-display-guide-part-3-display-images","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=4328","title":{"rendered":"STM32F429 Discovery Display Guide \u2013 Part 3: Display Images"},"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\/04\/ChatGPT-Image-Mar-19-2026-at-10_15_45-AM-1024x683.png\" alt=\"\" class=\"wp-image-4329\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Mar-19-2026-at-10_15_45-AM-1024x683.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Mar-19-2026-at-10_15_45-AM-300x200.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Mar-19-2026-at-10_15_45-AM-768x512.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Mar-19-2026-at-10_15_45-AM-1150x767.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Mar-19-2026-at-10_15_45-AM-750x500.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Mar-19-2026-at-10_15_45-AM-400x267.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Mar-19-2026-at-10_15_45-AM-250x167.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Mar-19-2026-at-10_15_45-AM.png 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Part 3 focuses on displaying images on the ILI9341 by transferring pre-formatted pixel data from the STM32 to the display\u2019s GRAM. It explains how image data is structured, converted to the appropriate color format, and efficiently written to the screen using the address window mechanism.<\/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>Header file modification.<\/li>\n\n\n\n<li>Source file modification.<\/li>\n\n\n\n<li>Image code.<\/li>\n\n\n\n<li>Main 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\">1. Header File Modification:<\/h2>\n\n\n\n<p>Open ILI9341.h and declare the following 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_Bitmap(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, const uint8_t *Image);<\/pre><\/div>\n\n\n\n<p>The function prototype<\/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 ILI9341_Draw_Bitmap(uint16_t Xstart, uint16_t Ystart,\n                         uint16_t Xend, uint16_t Yend,\n                         const uint8_t *Image);\n<\/pre><\/div>\n\n\n\n<p>defines a routine that draws a bitmap image on a display controlled by the ILI9341. The prototype specifies the&nbsp;<strong>function name, return type, and parameters<\/strong>, which together describe how the function is called and what data must be provided to render the image.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Return Type<\/h3>\n\n\n\n<p><code>void<\/code><\/p>\n\n\n\n<p>This indicates that the function&nbsp;<strong>does not return any value<\/strong>. Its purpose is purely procedural\u2014it sends pixel data to the display to render an image, but it does not produce a result that the caller needs to store.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Function Name<\/h3>\n\n\n\n<p><code>ILI9341_Draw_Bitmap<\/code><\/p>\n\n\n\n<p>The name indicates that the function belongs to a driver or library for the ILI9341 display controller and that its purpose is to&nbsp;<strong>draw a bitmap image<\/strong>&nbsp;on the screen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Parameters<\/h3>\n\n\n\n<p><strong>1.&nbsp;<code>uint16_t Xstart<\/code><\/strong><br>Represents the&nbsp;<strong>starting X coordinate<\/strong>&nbsp;(horizontal position) on the display where the bitmap will begin.<br>Since the display resolution is relatively small (e.g., 240\u00d7320), a 16-bit integer is more than sufficient to store the coordinate value.<\/p>\n\n\n\n<p><strong>2.&nbsp;<code>uint16_t Ystart<\/code><\/strong><br>Represents the&nbsp;<strong>starting Y coordinate<\/strong>&nbsp;(vertical position) where the bitmap will begin.<\/p>\n\n\n\n<p>Together,&nbsp;<code>Xstart<\/code>&nbsp;and&nbsp;<code>Ystart<\/code>&nbsp;define the&nbsp;<strong>top-left corner of the image<\/strong>&nbsp;on the display.<\/p>\n\n\n\n<p><strong>3.&nbsp;<code>uint16_t Xend<\/code><\/strong><br>Specifies the&nbsp;<strong>ending X coordinate<\/strong>&nbsp;of the image area. This determines how far the image extends horizontally.<\/p>\n\n\n\n<p><strong>4.&nbsp;<code>uint16_t Yend<\/code><\/strong><br>Specifies the&nbsp;<strong>ending Y coordinate<\/strong>&nbsp;of the image area, determining the vertical extent of the image.<\/p>\n\n\n\n<p>The four parameters&nbsp;<code>(Xstart, Ystart, Xend, Yend)<\/code>&nbsp;collectively define a&nbsp;<strong>rectangular region on the display<\/strong>&nbsp;where the bitmap will be rendered.<\/p>\n\n\n\n<p><strong>5.&nbsp;<code>const uint8_t *Image<\/code><\/strong><br>This is a&nbsp;<strong>pointer to the bitmap image data stored in memory<\/strong>.<\/p>\n\n\n\n<p>Key aspects of this parameter:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>uint8_t*<\/code>\u00a0indicates that the image data is stored as a\u00a0<strong>byte array<\/strong>.<\/li>\n\n\n\n<li>The pointer allows the function to\u00a0<strong>sequentially read pixel data from memory<\/strong>.<\/li>\n\n\n\n<li>The\u00a0<code>const<\/code>\u00a0qualifier ensures the image data\u00a0<strong>cannot be modified inside the function<\/strong>, which is important when the image is stored in flash memory or in a constant array.<\/li>\n<\/ul>\n\n\n\n<p>Typically, the image data is arranged as a&nbsp;<strong>stream of pixel values<\/strong>&nbsp;(for example RGB565 format), which the function later sends to the display through SPI.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Hence, the updated 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_ILI9341_H_\n#define INC_ILI9341_H_\n\n#include &quot;main.h&quot;\n\n#include &quot;spi.h&quot;\n\ntypedef enum {\n\tROTATE_0,\n\tROTATE_90,\n\tROTATE_180,\n\tROTATE_270\n} LCD_Horizontal_t;\n\nvoid ILI9341_Init(LCD_Horizontal_t rot);\n\nvoid ILI9341_WritePixel(uint16_t x, uint16_t y, uint16_t color);\n\nvoid ILI9341_Draw_Bitmap(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, const uint8_t *Image);\n\n#endif <\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Source File Modification:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Open ILI9341.c file. <br>Add the following 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 ILI9341_Draw_Bitmap(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, const uint8_t *Image)<\/pre><\/div>\n\n\n\n<p>Within the function, calculate the width and height of the image 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;}\">uint16_t width  = Xend - Xstart;\nuint16_t height = Yend - Ystart;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, declare an index variable to keep track of the data in the array 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;}\">uint32_t idx = 0;<\/pre><\/div>\n\n\n\n<p>An array with two elements to represent the pixel 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;}\">uint8_t  pixel[2];<\/pre><\/div>\n\n\n\n<p>Next, set the address window 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;}\">ILI9341_SetWindow(Xstart,Ystart,Xend-1,Yend-1);<\/pre><\/div>\n\n\n\n<p>Send the command to draw directly to the GRAM 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;}\">WriteCommand(0x2c);<\/pre><\/div>\n\n\n\n<p>This will let you stream the pixel data in one go rather than draw it pixel by pixel.<\/p>\n\n\n\n<p>Next, set the display in data mode and enable it  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;}\">CS_Select();\n\nDC_HIGH();<\/pre><\/div>\n\n\n\n<p>Transfer image 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;}\">for (uint16_t y = 0; y &lt; height; y++)\n\t\t{\n\t\t\tfor (uint16_t x = 0; x &lt; width; x++)\n\t\t\t{\n\t\t\t\tpixel[0] = Image[idx++];  \/\/ High byte\n\t\t\t\tpixel[1] = Image[idx++];  \/\/ Low byte\n\n\t\t\t\tHAL_SPI_Transmit(&amp;hspi5, pixel, 2, HAL_MAX_DELAY);\n\t\t\t}\n\t\t}<\/pre><\/div>\n\n\n\n<p>Deselect the display 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;}\">CS_Deselect();<\/pre><\/div>\n\n\n\n<p>Here is the detailed explanation:<\/p>\n\n\n\n<p>The function&nbsp;<strong><code>ILI9341_Draw_Bitmap()<\/code><\/strong>&nbsp;displays an image on the screen controlled by the ILI9341 by sending pixel data through SPI.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. Calculate Image Size<\/h3>\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;}\">uint16_t width  = Xend - Xstart;\nuint16_t height = Yend - Ystart;\n<\/pre><\/div>\n\n\n\n<p>The function first calculates the&nbsp;<strong>width and height of the image<\/strong>&nbsp;using the start and end coordinates.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. Prepare Variables<\/h3>\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;}\">uint32_t idx = 0;\nuint8_t pixel[2];\n<\/pre><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>idx<\/code>\u00a0keeps track of the\u00a0<strong>current position in the image array<\/strong>.<\/li>\n\n\n\n<li><code>pixel[2]<\/code>\u00a0stores\u00a0<strong>two bytes for each pixel<\/strong>\u00a0(commonly RGB565 format).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">3. Define Display Drawing Area<\/h3>\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;}\">ILI9341_SetWindow(Xstart,Ystart,Xend-1,Yend-1);\n<\/pre><\/div>\n\n\n\n<p>This sets the&nbsp;<strong>drawing window<\/strong>&nbsp;on the display. All incoming pixel data will be written inside this rectangular area.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4. Send Memory Write Command<\/h3>\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;}\">WriteCommand(0x2c);\n<\/pre><\/div>\n\n\n\n<p>Command&nbsp;<code>0x2C<\/code>&nbsp;tells the display controller to&nbsp;<strong>start receiving pixel data<\/strong>&nbsp;for writing into its internal GRAM.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5. Enable SPI Data Transfer<\/h3>\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;}\">CS_Select();\nDC_HIGH();\n<\/pre><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>CS_Select()<\/code>\u00a0activates the display SPI chip select.<\/li>\n\n\n\n<li><code>DC_HIGH()<\/code>\u00a0indicates that the following bytes are\u00a0<strong>data (pixels)<\/strong>\u00a0rather than commands.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">6. Send Pixel Data<\/h3>\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 (uint16_t y = 0; y &lt; height; y++)\n{\n    for (uint16_t x = 0; x &lt; width; x++)\n<\/pre><\/div>\n\n\n\n<p>Two nested loops scan the image&nbsp;<strong>row by row<\/strong>.<\/p>\n\n\n\n<p>Inside the loop:<\/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;}\">pixel[0] = Image[idx++];  \/\/ High byte\npixel[1] = Image[idx++];  \/\/ Low byte\n<\/pre><\/div>\n\n\n\n<p>Each pixel is read from the image array&nbsp;<strong>two bytes at a time<\/strong>.<\/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;}\">HAL_SPI_Transmit(&amp;hspi5, pixel, 2, HAL_MAX_DELAY);\n<\/pre><\/div>\n\n\n\n<p>The pixel is then&nbsp;<strong>sent to the display through SPI<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">7. Finish Communication<\/h3>\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;}\">CS_Deselect();\n<\/pre><\/div>\n\n\n\n<p>Finally, the SPI communication with the display is closed.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><\/h3>\n\n\n\n<h2 class=\"wp-block-heading\">3. Image code:<\/h2>\n\n\n\n<p>Create new header and source file with name of image_240x320_rgb565.h and image_240x320_rgb565.c respectively.<\/p>\n\n\n\n<p>In image_240x320_rgb565 header file:<\/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_IMAGE_240X320_RGB565_H_\n#define INC_IMAGE_240X320_RGB565_H_\n\n#include &quot;stdint.h&quot;\n\nextern const uint8_t image_240x320[240*320*2];\n\n#endif <\/pre><\/div>\n\n\n\n<p>For the source file, you can download from the end of the guide.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Main Code:<\/h2>\n\n\n\n<p>In main.c, include the image header file:<\/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;image_240x320_rgb565.h&quot;<\/pre><\/div>\n\n\n\n<p>After the display initialization, draw the image 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;}\">ILI9341_Draw_Bitmap(0, 0, 240, 320, image_240x320);<\/pre><\/div>\n\n\n\n<p>Make sure that while 1 loop is empty.<\/p>\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\">5. Results:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>You should get the following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/04\/IMG_9772.heic\" alt=\"\" class=\"wp-image-4330\" \/><\/figure>\n\n\n\n<p>You may download the entire project from here.<\/p>\n\n\n\n<div class=\"wp-block-file\"><a id=\"wp-block-file--media-5bdbd731-8578-4144-aa64-7ae4f669bbaf\" href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/04\/ILI9341_STM32.zip\">ILI9341_STM32<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/04\/ILI9341_STM32.zip\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-5bdbd731-8578-4144-aa64-7ae4f669bbaf\">Download<\/a><\/div>\n\n\n\n<p>Happy coding \ud83d\ude09<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Part 3 focuses on displaying images on the ILI9341 by transferring pre-formatted pixel data from the STM32 to the display\u2019s GRAM. It explains how image data is structured, converted to the appropriate color format, and efficiently written to the screen using the address window mechanism. In this guide, we shall cover the following: 1. Header [&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-4328","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\/4328"}],"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=4328"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/4328\/revisions"}],"predecessor-version":[{"id":4332,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/4328\/revisions\/4332"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4328"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4328"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4328"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}