ARM:0015 STM32CubeMX screen libraries, part 2

Continued from Part 1.
There are lots of different LCD or OLED screens in the market. Typically, it is possible to define 3 types of screens according to interface type: I2C, SPI and parallel data bus. There are also analog and LVDS (HDMI) types too, but they are typically not used with weak MCU. Parallel types use many wires for the interface, but are much faster. I2C type is slow, but very useful for a small screen as it can be on the same bus as some sensors. Many I2C type screens do not have a RESET pin, so the init sequence may be very slow. SPI interface is fast (not very fast when refreshing the whole screen) and uses CS pin for device select and D/C pin for data or command selection. Some screens from China do not have CS pin.
The logic of graphic chips is the same, but init sequence and commands may be different. Also, there are some options about the “glass” type, so there is no universal screen driver. Here is some screen collection connected to the same STM32F103 chip and using all the screens simultaneously.
LCD SPI I2C color screens gcc library for STM32F103 ARM bluepill
From left to right: ILI9341 (320 x 240), ST7789W (240 x 240), oldest ST7735R (160 x 128, other configurations optional), SSD1306 (128 x 64), SSD1306 (128 x 32, I2C).

Small screens do not have a full graphics library implemented (who needs to draw a circle on a 32 lines screen?). The font in the library has an error (lost small “A”).
Typically library can do:

  • Draw arbitrary pixel
  • Draw color data to rectangle: fill with color or image data (sprite)
  • Draw horizontal or vertical lines
  • Draw rectangle
  • Print text using fixed size font
  • Print text using proportional font with lame sizing (vertical or horizontal)
  • Print large proportional text (limited font data)
  • Do some hardware tricks: scroll, inverse, change intensity, flip image…

Many libraries use source code from the internet, but some errors are fixed and I added optimization for speed and size. Also, I introduced my errors too.

For example there is some simplification in source code. First line is from popular “programming language”, second is mine:

//was:
 for (pixels = 0; pixels < x1 - x0 ; pixels++) { ili9341_send_word(color); }
//now:
 for(x0=x0;x0<x1;x0++){ILI9341_send_word(color);}


We save one variable and useless calculations.

Other example. It is more important in speed optimization (for the screens it is very important):

//was, original:
 for(i=0;i < (w * h);i++)
 {
 c1 = *buffer++;
 c2 = *buffer++;
 ili9341_send_byte(c1);
 ili9341_send_byte(c2);
 }

//new:
 ILI9341_write_buffer(buffer, w*h*2);


Instead of sending thousand separated bytes, why not to use HAL library to send whole buffer using DMA or interrupt driven routine. Even sending buffer in blocking mode is much faster, than sending thousand of separate calls to procedure for just one byte of data.

There was problem in demo program- the function names for different screens used same variables and macros. In the real word program it is not the problem, because nobody use several different screens in the same project.

All source code for libraries, demo program for STM32F103 (bluepill), compiled binaries are included in archive.
Not all tricks are implemented in libraries- especially hardware scrolling and specific controller chip features.

About Administrator

I am owner of this site.
This entry was posted in Anything, MCU. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>