{"id":3793,"date":"2025-09-24T12:28:28","date_gmt":"2025-09-24T12:28:28","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=3793"},"modified":"2025-09-24T12:30:50","modified_gmt":"2025-09-24T12:30:50","slug":"ssd1331-color-oled-with-stm32-part-2-initialization-and-draw-single-pixel","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=3793","title":{"rendered":"SSD1331 Color OLED with STM32 Part 2: Initialization and Draw Single Pixel"},"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\/2025\/09\/image-2-1024x683.png\" alt=\"\" class=\"wp-image-3794\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/image-2-1024x683.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/image-2-300x200.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/image-2-768x512.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/image-2-1150x767.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/image-2-750x500.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/image-2-400x267.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/image-2-250x167.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/image-2.png 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In this guide, we will focus on the firmware side by initializing the SSD1331 controller and preparing it for operation. Once initialized, we\u2019ll implement a simple routine to draw a single pixel on the OLED display as the foundation for more complex graphics.<\/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>Initialization of the display.<\/li>\n\n\n\n<li>Main Firmware.<\/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.  Initialization of the Display:<\/h2>\n\n\n\n<p>We start by creating new source and header file with name of ssd1331.c and ssd1331.h respectively.<\/p>\n\n\n\n<p>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 ssd1331.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\/09\/2025-09-24_14-38-13-1024x734.jpg\" alt=\"\" class=\"wp-image-3795\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/2025-09-24_14-38-13-1024x734.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/2025-09-24_14-38-13-300x215.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/2025-09-24_14-38-13-768x550.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/2025-09-24_14-38-13-1150x824.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/2025-09-24_14-38-13-750x538.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/2025-09-24_14-38-13-400x287.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/2025-09-24_14-38-13-250x179.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/09\/2025-09-24_14-38-13.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 ssd1331.h.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, open ssd1331.h header file and include 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;main.h&quot;\n#include &quot;spi.h&quot;<\/pre><\/div>\n\n\n\n<p>These headers files will enable us access to SPI functions and the symbolics names of the GPIO.<\/p>\n\n\n\n<p>Next, declare the size of 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;}\">#define SSD1331_WIDTH   96\n#define SSD1331_HEIGHT  64<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, declare the following two functions:<\/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 ssd1331_init(void);\nvoid ssd1331_drawPixel(uint8_t x, uint8_t y, uint16_t color);<\/pre><\/div>\n\n\n\n<p>First function to initialize the OLED display.<\/p>\n\n\n\n<p>The second one to draw a single pixel.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Thats all for the header file.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, open ssd1331.c file.<\/p>\n\n\n\n<p>Within the source file, include ssd1331 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;ssd1331.h&quot;<\/pre><\/div>\n\n\n\n<p>Next, static functions for setting the state of the reset pin 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 RST_LOW(void)\n{\n\tHAL_GPIO_WritePin(RES_GPIO_Port, RES_Pin, GPIO_PIN_RESET);\n}\n\nstatic void RST_HIGH(void)\n{\n\tHAL_GPIO_WritePin(RES_GPIO_Port, RES_Pin, GPIO_PIN_SET);\n}<\/pre><\/div>\n\n\n\n<p>Once the reset pin is set to low, the ssd1331 shall reset itself and remain in the reset state until the reset pin is set back to high.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, function to select and deselect the ssd1331 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;}\">static void SSD_Deselect(void)\n{\n\tHAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);\n}\n\nstatic void SSD_Select(void)\n{\n\tHAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);\n}<\/pre><\/div>\n\n\n\n<p>The ssd1331 follows the conventional chip select for any SPI peripheral, when CS pin is low, the ssd1331 will accept data from the SPI bus and won&#8217;t accept data from SPI bus when CS pin is high.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, a function to write a command to 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;}\">static void ssd1331_command(uint8_t cmd)\n{\n    HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, GPIO_PIN_RESET); \/\/ DC = 0\n    SSD_Select();\n    HAL_SPI_Transmit(&amp;hspi1, &amp;cmd, 1, HAL_MAX_DELAY);\n    SSD_Deselect();\n}<\/pre><\/div>\n\n\n\n<p>When the DC pin is set to low, the ssd1331 shall treat the data as command and configure its internal registers. <\/p>\n\n\n\n<p>Next, we need to transmit data buffer 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 ssd1331_data_buffer(uint8_t *data, size_t len)\n{\n    HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, GPIO_PIN_SET); \/\/ DC = 1\n    SSD_Select();\n    HAL_SPI_Transmit(&amp;hspi1, data, len, HAL_MAX_DELAY);\n    SSD_Deselect();\n}<\/pre><\/div>\n\n\n\n<p>When DC pin is set to high, the ssd1331 will treat the data as pixel data. This will be necessary when draw a pixel later.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, ssd1331 initialization.<\/p>\n\n\n\n<p>Start by declaring the initialization sequence 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 ssd1331_init(void)<\/pre><\/div>\n\n\n\n<p>Within the function:<\/p>\n\n\n\n<p>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;}\">RST_LOW();\nHAL_Delay(10);\nRST_HIGH();\nHAL_Delay(50);<\/pre><\/div>\n\n\n\n<p>Next Initialize 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;}\">\/\/ Initialization sequence\nssd1331_command(0xAE);              \/\/ Display off\nssd1331_command(0xA0); ssd1331_command(0x72); \/\/ Set Remap &amp; Color Depth\nssd1331_command(0xA1); ssd1331_command(0x00); \/\/ Set Display Start Line\nssd1331_command(0xA2); ssd1331_command(0x00); \/\/ Set Display Offset\nssd1331_command(0xA4);              \/\/ Normal Display (not all-on)\nssd1331_command(0xA8); ssd1331_command(0x3F); \/\/ Set Multiplex Ratio\nssd1331_command(0xAD); ssd1331_command(0x8E); \/\/ Master Config\nssd1331_command(0xB0); ssd1331_command(0x0B); \/\/ Power Save Mode\nssd1331_command(0xB1); ssd1331_command(0x31); \/\/ Phase Period Adjust\nssd1331_command(0xB3); ssd1331_command(0xF0); \/\/ Clock Divider \/ Oscillator\nssd1331_command(0x8A); ssd1331_command(0x64); \/\/ Precharge A\nssd1331_command(0x8B); ssd1331_command(0x78); \/\/ Precharge B\nssd1331_command(0x8C); ssd1331_command(0x64); \/\/ Precharge C\nssd1331_command(0xBB); ssd1331_command(0x3A); \/\/ Precharge Level\nssd1331_command(0xBE); ssd1331_command(0x3E); \/\/ VCOMH\nssd1331_command(0x87); ssd1331_command(0x06); \/\/ Master Current\nssd1331_command(0x81); ssd1331_command(0x91); \/\/ Contrast A\nssd1331_command(0x82); ssd1331_command(0x50); \/\/ Contrast B\nssd1331_command(0x83); ssd1331_command(0x7D); \/\/ Contrast C\nssd1331_command(0xAF);              \/\/ Display ON<\/pre><\/div>\n\n\n\n<p>These has been taken from adafruit library.<\/p>\n\n\n\n<p>Next, 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 ssd1331_drawPixel(uint8_t x, uint8_t y, uint16_t color)\n{\n    if (x &gt;= SSD1331_WIDTH || y &gt;= SSD1331_HEIGHT) return; \/\/ Out of bounds\n\n    \/\/ Set column\n    ssd1331_command(0x15);\n    ssd1331_command(x);\n    ssd1331_command(x);\n\n    \/\/ Set row\n    ssd1331_command(0x75);\n    ssd1331_command(y);\n    ssd1331_command(y);\n\n    \/\/ Send pixel color (RGB565)\n    uint8_t data_buf[2] = {\n        (uint8_t)(color &gt;&gt; 8),\n        (uint8_t)(color &amp; 0xFF)\n    };\n    ssd1331_data_buffer(data_buf, 2);\n}<\/pre><\/div>\n\n\n\n<p>The function draws one pixel on the SSD1331 OLED at coordinates&nbsp;<code>(x, y)<\/code>&nbsp;with a 16-bit RGB565 color.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Bounds check<\/strong><br>The function first checks if\u00a0<code>x<\/code>\u00a0or\u00a0<code>y<\/code>\u00a0is outside the valid display area (<code>SSD1331_WIDTH = 96<\/code>,\u00a0<code>SSD1331_HEIGHT = 64<\/code>). If the pixel is out of range, it simply returns without doing anything.<\/li>\n\n\n\n<li><strong>Set column address<\/strong><br>It sends command\u00a0<code>0x15<\/code>\u00a0(SET COLUMN).\n<ul class=\"wp-block-list\">\n<li>The next two bytes define the start and end column.<\/li>\n\n\n\n<li>Both are set to\u00a0<code>x<\/code>, so the address window spans exactly one column.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Set row address<\/strong><br>It sends command\u00a0<code>0x75<\/code>\u00a0(SET ROW).<ul><li>The next two bytes define the start and end row.<\/li><li>Both are set to\u00a0<code>y<\/code>, so the address window spans exactly one row.<\/li><\/ul>At this point, the SSD1331 is configured to point to a 1\u00d71 pixel region at\u00a0<code>(x, y)<\/code>.<\/li>\n\n\n\n<li><strong>Send color data<\/strong><br>The\u00a0<code>color<\/code>\u00a0parameter is a 16-bit RGB565 value (5 bits red, 6 bits green, 5 bits blue).<ul><li>The function splits it into a high byte and a low byte.<\/li><li>Both bytes are sent as\u00a0<em>data<\/em>\u00a0(not commands) to the display.<\/li><\/ul>This fills the single pixel\u00a0<code>(x, y)<\/code>\u00a0with the chosen color.<\/li>\n<\/ol>\n\n\n\n<p>Thats all for the source file. Save it.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Main Firmware:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Open main.c.<\/p>\n\n\n\n<p>Within main.c in user code begin includes, include 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;ssd1331.h&quot;\n\n#include &quot;stdlib.h&quot;<\/pre><\/div>\n\n\n\n<p>The stdlib will allow us to use random function.<\/p>\n\n\n\n<p>In user code begin 2 in main 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;}\">ssd1331_init();<\/pre><\/div>\n\n\n\n<p>In user code begin 3 in we shall fill the display with random colors for each pixels 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;SSD1331_HEIGHT;i++)\n{\n  for (int j=0;j&lt;SSD1331_WIDTH;j++)\n  {\n    ssd1331_drawPixel(j,i,rand() % 65535);\n\n\n  }\n}\n\nHAL_Delay(1000);<\/pre><\/div>\n\n\n\n<p><\/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\/2024\/11\/image-1024x28.png\" alt=\"\" class=\"wp-image-2982\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/image-1024x28.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/image-300x8.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/image-768x21.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/image-1536x43.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/image-1150x32.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/image-750x21.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/image-400x11.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/image-250x7.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/image.png 1734w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7. Results:<\/h2>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"SSD1331 Demo on STM32\" width=\"1170\" height=\"658\" src=\"https:\/\/www.youtube.com\/embed\/xjF9bi-_Xkc?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, we shall use more efficient way to draw picture etc.<\/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 guide, we will focus on the firmware side by initializing the SSD1331 controller and preparing it for operation. Once initialized, we\u2019ll implement a simple routine to draw a single pixel on the OLED display as the foundation for more complex graphics. In this guide, we shall cover the following: 5. Initialization of the [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-3793","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3793"}],"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=3793"}],"version-history":[{"count":3,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3793\/revisions"}],"predecessor-version":[{"id":3799,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3793\/revisions\/3799"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3793"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3793"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3793"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}