Experiment on Closed-Loop Control of Encoded Motors Based on STM32F1 Series: OLED Code Porting (Part 2)

Detailed Explanation of OLED Character Dot Matrix Display Rules

1. Storage Rules Description

OLED typically displays characters in a dot matrix format. Taking the 8×16 dot matrix as an example, each character occupies a pixel area of 8 columns wide × 16 rows high.

Data Storage Format Description:

/**  * Data storage format:  * Vertical 8 dots, high bit at the bottom, first from left to right, then from top to bottom  * Each Bit corresponds to a pixel point  */
  • Vertical 8 dots: One <span>uint8_t</span> (8-bit byte) represents a column of 8 vertical pixel points.
  • High bit at the bottom: The byte’s high bit (bit7) corresponds to the lower pixel, low bit (bit0) corresponds to the upper pixel.
  • From left to right, then from top to bottom:
    • A character width is 8 pixels, height is 16 pixels.
    • First draw 8 columns from left to right.
    • The first 8 bytes represent the character’s upper half (first 8 rows).
    • The last 8 bytes represent the character’s lower half (last 8 rows).

2. Data Structure

Dot matrix data is usually stored in a two-dimensional array:

const uint8_t OLED_F8x16[][16] ={   { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // Space ' ' (ASCII 0x20)   { 0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // '!' (ASCII 0x21)   ...};

Structure Description:

  • Each character occupies 16 bytes.
    • The first 8 bytes → upper half (rows 0-7)
    • The last 8 bytes → lower half (rows 8-15)
  • Each byte represents a column, totaling 8 columns (width).
  • Array index corresponds to ASCII code: The first character is ASCII 0x20 (space), which is <span>OLED_F8x16[0]</span>.

3. Display Principle

When the MCU needs to display a character on the OLED:

Display Process:

  1. Input character, such as <span>'A'</span> (ASCII 0x41)
  2. The MCU calculates its index in the array:
    index = 'A' - 0x20;
  3. Find the corresponding 16-byte dot matrix data:
    const uint8_t* fontData = OLED_F8x16[index];
  4. Write to OLED memory:
  • The first 8 bytes are written to the current page (e.g., page 0), from left to right for 8 columns.
  • The last 8 bytes are written to the next page (e.g., page 1), in the same position.

Example: Letter ‘A’

{
  0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00,
  0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20  // A (ASCII 0x41)
}
  • The first 8 bytes → upper half (rows 0-7)
  • The last 8 bytes → lower half (rows 8-15)

These 16 bytes combine to display a capital letter A that is 16 pixels high and 8 pixels wide.

4. Application Scenarios

Common OLED display applications in embedded development:

OLED_ShowChar(x, y, 'A');
  • <span>x</span>, <span>y</span>: Specifies the starting position of the character.
  • <span>'A'</span>: The character to be displayed.

Internal Process:

  1. Look up the dot matrix data for <span>'A'</span> in <span>OLED_F8x16</span>.
  2. Control the OLED to write data to the corresponding coordinates.
  3. Achieve character display.

5. Similar Dot Matrix Tables

To accommodate different display needs, there are various specifications for dot matrix tables:

Type Size Description
6×8 Characters 6 columns × 8 rows Small footprint, suitable for small screens or information-rich scenarios
8×16 Characters 8 columns × 16 rows Common standard size, clear and easy to read
16×16 Chinese Characters 16 columns × 16 rows Used for displaying Chinese characters, requires additional font library support

6. Visual Understanding

Each character can be viewed as an image composed of pixel points. For example, the dot matrix of “A” is as follows:

⬛⬛⬛⬛⬛⬛⬛⬛
⬛⬛⬛⬛⬛⬛⬛⬛
⬛⬛⬛⬜⬜⬛⬛⬛
⬛⬛⬛⬜⬛⬛⬛⬛
⬛⬛⬛⬜⬜⬛⬛⬛
⬛⬛⬜⬛⬛⬜⬛⬛
⬛⬜⬛⬛⬛⬛⬜⬛
⬜⬜⬜⬜⬜⬜⬜⬜

Note: The actual display is written in byte columns, and the dot matrix should be understood by interpreting each bit from bottom to top.

7. Summary

  • Each character uses 16 bytes to represent an 8×16 dot matrix.
  • Data is arranged in a “vertical 8 dots” manner, with each byte representing a column.
  • High bit at the bottom, low bit at the top.
  • The MCU looks up the array by character encoding, extracts data, and writes it to the OLED buffer.
  • Commonly used in OLED display module development for STM32, Arduino, 51 microcontrollers, etc.

If you need to provide: OLED display driver code examples

Feel free to ask more questions!

OLED_Data.c

#include "OLED_Data.h"
/**  * Data storage format:  * Vertical 8 dots, high bit at the bottom, first from left to right, then from top to bottom  * Each Bit corresponds to a pixel point  *   *      B0 B0                  B0 B0  *      B1 B1                  B1 B1  *      B2 B2                  B2 B2  *      B3 B3  -------------&gt;  B3 B3 --  *      B4 B4                  B4 B4  |  *      B5 B5                  B5 B5  |  *      B6 B6                  B6 B6  |  *      B7 B7                  B7 B7  |  *                                    |  *  -----------------------------------  *  |     *  |   B0 B0                  B0 B0  *  |   B1 B1                  B1 B1  *  |   B2 B2                  B2 B2  *  --&gt; B3 B3  -------------&gt;  B3 B3  *      B4 B4                  B4 B4  *      B5 B5                  B5 B5  *      B6 B6                  B6 B6  *      B7 B7                  B7 B7  *   */
/*ASCII font data*********************/
/*Width 8 pixels, height 16 pixels*/const uint8_t OLED_F8x16[][16] ={    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//   0    0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,// ! 1    0x00,0x16,0x0E,0x00,0x16,0x0E,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// " 2    0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,    0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,// # 3    0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,    0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,// $ 4    0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,    0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,// % 5    0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,    0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,// &amp; 6    0x00,0x00,0x00,0x16,0x0E,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// ' 7    0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,    0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,// ( 8    0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,    0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,// ) 9    0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,    0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,// * 10    0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,    0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,// + 11    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,// , 12    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,// - 13    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,// . 14    0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,    0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,// / 15    0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,    0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,// 0 16    0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,    0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,// 1 17    0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,    0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,// 2 18    0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,    0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,// 3 19    0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,    0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,// 4 20    0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,    0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,// 5 21    0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,    0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,// 6 22    0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,    0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,// 7 23    0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,    0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,// 8 24    0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,    0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,// 9 25    0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,    0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,// : 26    0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,    0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,// ; 27    0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,    0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,// &lt; 28    0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,// = 29    0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,    0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,// &gt; 30    0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,    0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,// ? 31    0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,    0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,// @ 32    0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,    0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,// A 33    0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,    0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,// B 34    0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,    0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,// C 35    0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,    0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,// D 36    0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,    0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,// E 37    0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,    0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,// F 38    0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,    0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,// G 39    0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,    0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,// H 40    0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,    0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,// I 41    0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,    0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,// J 42    0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,    0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,// K 43    0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,    0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,// L 44    0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,    0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,// M 45    0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,    0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,// N 46    0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,    0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,// O 47    0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,    0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,// P 48    0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,    0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,// Q 49    0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,    0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,// R 50    0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,    0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,// S 51    0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,    0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,// T 52    0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,    0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,// U 53    0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,    0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,// V 54    0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,    0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,// W 55    0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,    0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,// X 56    0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,    0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,// Y 57    0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,    0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,// Z 58    0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,    0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,// [ 59    0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,// \ 60    0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,    0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,// ] 61    0x00,0x20,0x10,0x08,0x04,0x08,0x10,0x20,    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// ^ 62    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,// _ 63    0x00,0x02,0x04,0x08,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// ` 64    0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,    0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,// a 65    0x00,0x7F,0x48,0x44,0x44,0x38,// b 66    0x00,0x38,0x44,0x44,0x44,0x20,// c 67    0x00,0x38,0x44,0x44,0x48,0x7F,// d 68    0x00,0x38,0x54,0x54,0x54,0x18,// e 69    0x00,0x08,0x7E,0x09,0x01,0x02,// f 70    0x00,0x18,0xA4,0xA4,0xA4,0x7C,// g 71    0x00,0x7F,0x08,0x04,0x04,0x78,// h 72    0x00,0x00,0x44,0x7D,0x40,0x00,// i 73    0x00,0x40,0x80,0x84,0x7D,0x00,// j 74    0x00,0x7F,0x10,0x28,0x44,0x00,// k 75    0x00,0x00,0x41,0x7F,0x40,0x00,// l 76    0x00,0x7C,0x04,0x18,0x04,0x78,// m 77    0x00,0x7C,0x08,0x04,0x04,0x78,// n 78    0x00,0x38,0x44,0x44,0x44,0x38,// o 79    0x00,0xFC,0x24,0x24,0x24,0x18,// p 80    0x00,0x18,0x24,0x24,0x18,0xFC,// q 81    0x00,0x7C,0x08,0x04,0x04,0x08,// r 82    0x00,0x48,0x54,0x54,0x54,0x20,// s 83    0x00,0x04,0x3F,0x44,0x40,0x20,// t 84    0x00,0x3C,0x40,0x40,0x20,0x7C,// u 85    0x00,0x1F,0x20,0x40,0x20,0x1F,// v 86    0x00,0x3C,0x40,0x30,0x40,0x3C,// w 87    0x00,0x44,0x28,0x10,0x28,0x44,// x 88    0x00,0x1C,0xA0,0xA0,0xA0,0x7C,// y 89    0x00,0x44,0x64,0x54,0x4C,0x44,// z 90    0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,    0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,// { 91    0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,// | 92    0x00,0x00,0x41,0x7F,0x08,0x00,// } 93    0x00,0x08,0x04,0x08,0x10,0x08,// ~ 94};
/*********************ASCII font data*/

/*Chinese character font data*********************/
/*The same Chinese character only needs to be defined once, Chinese characters are not sorted in order*//*Must be all Chinese or full-width characters, do not add any half-width characters*/
/*Width 16 pixels, height 16 pixels*/const ChineseCell_t OLED_CF16x16[] = {
	",", 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x58,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	"。", 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x18,0x24,0x24,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	"你", 0x00,0x80,0x60,0xF8,0x07,0x40,0x20,0x18,0x0F,0x08,0xC8,0x08,0x08,0x28,0x18,0x00,
	0x01,0x00,0x00,0xFF,0x00,0x10,0x0C,0x03,0x40,0x80,0x7F,0x00,0x01,0x06,0x18,0x00,
	"好", 0x10,0x10,0xF0,0x1F,0x10,0xF0,0x00,0x80,0x82,0x82,0xE2,0x92,0x8A,0x86,0x80,0x00,
	0x40,0x22,0x15,0x08,0x16,0x61,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,
	"世", 0x20,0x20,0x20,0xFE,0x20,0x20,0xFF,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0x00,
	0x00,0x00,0x00,0x7F,0x40,0x40,0x47,0x44,0x44,0x44,0x47,0x40,0x40,0x40,0x00,0x00,
	"界", 0x00,0x00,0x00,0xFE,0x92,0x92,0x92,0xFE,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,0x00,
	0x08,0x08,0x04,0x84,0x62,0x1E,0x01,0x00,0x01,0xFE,0x02,0x04,0x04,0x08,0x08,0x00,
	/*Add new Chinese character data in this position according to the above format*/
	//...

	/*Default graphic displayed when the specified Chinese character is not found (a square with a question mark inside), ensure it is at the end of the array*/
	"", 0xFF,0x01,0x01,0x01,0x31,0x09,0x09,0x09,0x09,0x89,0x71,0x01,0x01,0x01,0x01,0xFF,
	0xFF,0x80,0x80,0x80,0x80,0x80,0x80,0x96,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0xFF,
};
/*********************Chinese character font data*/

/*Image data*********************/
/*Test image (a square with a diode symbol inside), width 16 pixels, height 16 pixels*/const uint8_t Diode[] = {    0xFF,0x01,0x81,0x81,0x81,0xFD,0x89,0x91,0xA1,0xC1,0xFD,0x81,0x81,0x81,0x01,0xFF,
	0xFF,0x80,0x80,0x80,0x80,0x9F,0x88,0x84,0x82,0x81,0x9F,0x80,0x80,0x80,0x80,0xFF,
};
/*Add new image data in this position according to the above format*/
//...
/*********************Image data*/

OLED_Data.h

#ifndef __OLED_DATA_H#define __OLED_DATA_H
#include &lt;stdint.h&gt;
/*Character set definition*//*Only one of the following two macro definitions can be uncommented*/#define OLED_CHARSET_UTF8            //Define character set as UTF8//#define OLED_CHARSET_GB2312        //Define character set as GB2312
/*Basic unit of font*/typedef struct {
#ifdef OLED_CHARSET_UTF8            //Define character set as UTF8	char Index[5];                    //Chinese character index, space for 5 bytes#endif
#ifdef OLED_CHARSET_GB2312            //Define character set as GB2312	char Index[3];                    //Chinese character index, space for 3 bytes#endif
	uint8_t Data[32];                //Font data} ChineseCell_t;
/*Declaration of ASCII font data*/extern const uint8_t OLED_F8x16[][16];extern const uint8_t OLED_F6x8[][6];
/*Declaration of Chinese character font data*/extern const ChineseCell_t OLED_CF16x16[];
/*Declaration of image data*/extern const uint8_t Diode[];/*Add new image data declarations in this position according to the above format*/
//...
#endif

Leave a Comment