Skip to content
F. Nakata Studios F. Nakata StudiosK.K.
Journal · F. Nakata Studios

What is a standard SPI display and how does it work for embedded projects?

admin Published by F. Nakata Studios

A standard SPI display is a type of screen that uses the Serial Peripheral Interface (SPI) protocol to communicate with a microcontroller or single-board computer. In embedded projects, it works by sending data over a synchronous serial bus, typically using four wires: MOSI (Master Out Slave In), MISO (Master In Slave Out), SCLK (Serial Clock), and CS (Chip Select). The display controller, such as the popular ILI9341 or ST7789, interprets the serial data to control each pixel, refresh rates, and color depth. For a deeper dive into the hardware specifics, check out this standard SPI display reference.

The core advantage of a standard SPI display in embedded systems is its balance between speed and pin count. Unlike parallel interfaces that require 8 to 16 data lines plus control signals, SPI uses only three to four lines for data transfer. This is critical for resource-constrained microcontrollers like the ESP32, STM32, or Arduino Uno, which have limited GPIO pins. For example, the Arduino Uno has only 20 digital I/O pins, and a parallel 8-bit display would consume 11 pins (8 data + 3 control), leaving little room for sensors or actuators. An SPI display, in contrast, uses just 4 pins, freeing up 7 pins for other peripherals. This pin efficiency is a major reason why SPI displays dominate in compact projects like wearable devices, portable meters, and IoT nodes.

Data transfer rates are a key performance metric. SPI can operate at clock speeds up to 40 MHz or higher, depending on the display controller and PCB layout. The ILI9341 controller, for instance, supports a maximum SPI clock of 40 MHz. At this speed, you can achieve a theoretical data rate of 40 Mbps. For a 320x240 pixel display with 16-bit color (RGB565), each frame requires 320 * 240 * 2 = 153,600 bytes. At 40 Mbps, the raw transfer time for one frame is about 30.7 milliseconds, yielding a theoretical maximum refresh rate of roughly 32 Hz. However, real-world factors like command overhead, display initialization, and MCU processing reduce this to around 20-25 Hz in practice. That's sufficient for static UIs, sensor dashboards, or slow animations, but not for high-frame-rate video.

Color depth is another differentiator. Most standard SPI displays support 16-bit color (65,536 colors) or 18-bit color (262,144 colors) via RGB565 or RGB666 formats. The ILI9341, for example, uses 18-bit color internally but accepts 16-bit data per pixel, dithering the remaining 2 bits. This is a trade-off: 16-bit color reduces memory bandwidth by 25% compared to 18-bit, which is beneficial for MCUs with limited RAM. The ST7789 controller, commonly found in 1.3-inch and 1.54-inch displays, also uses 16-bit color and supports a resolution of 240x240 pixels. For comparison, a 1.54-inch ST7789 display at 240x240 resolution requires 115,200 bytes per frame. With a 20 MHz SPI clock, the transfer time is about 46 milliseconds, giving a practical refresh rate of 21 Hz. These numbers are important when designing responsive user interfaces.

Power consumption is a critical factor for battery-powered embedded projects. SPI displays can operate in low-power modes, drawing as little as 0.5 mA in sleep mode and 10-20 mA during active operation at 3.3V. The ILI9341, for instance, has a typical active current of 15 mA at 3.3V with a 40 MHz clock. In contrast, a parallel TFT display of the same size might draw 30-50 mA due to the higher number of switching I/O lines. For a project running on a 2000 mAh LiPo battery, an SPI display could extend runtime by 30-50% compared to a parallel interface. This efficiency stems from the lower capacitive load on fewer signal lines, reducing dynamic power dissipation.

Resolution options vary widely. Common SPI display sizes include 0.96-inch (80x160), 1.3-inch (240x240), 1.44-inch (128x128), 1.8-inch (128x160), 2.0-inch (240x320), 2.4-inch (240x320), and 2.8-inch (320x240). The 0.96-inch OLED SPI displays, like the SSD1306, offer 128x64 pixels and draw only 20 mA, making them ideal for low-power text displays. The 2.8-inch ILI9341 displays are popular for full-color GUIs in projects like weather stations or smart home controllers. The trade-off is that larger displays require more RAM for the frame buffer. An MCU like the STM32F103C8T6 has 20 KB of SRAM, which is insufficient for a 320x240 frame buffer (153.6 KB). Developers often use external SRAM or rely on the display's internal RAM, which is common in SPI TFTs. The ILI9341 has 172,800 bytes of internal GRAM, enough for a full 320x240 frame at 18-bit color. This offloads memory from the MCU, a key advantage for low-cost designs.

Command set and initialization are standardized across many controllers. The ILI9341 uses a set of 8-bit commands, such as 0x36 (Memory Access Control), 0x3A (Pixel Format Set), and 0x11 (Sleep Out). Initialization sequences typically involve 20-30 commands, taking about 100-200 milliseconds at 10 MHz SPI. For example, a typical initialization for a 2.4-inch ILI9341 display includes setting the pixel format to 16-bit, configuring the display orientation, and turning on the backlight. The ST7789 uses a similar command set but with different register addresses. This standardization means that library code (e.g., Adafruit_GFX, TFT_eSPI) can be reused across many displays with minor tweaks. The TFT_eSPI library, for instance, supports over 20 SPI controllers and can auto-detect the display type by reading the controller ID register.

Physical interface considerations matter for reliability. SPI displays typically use a 4-wire interface (MOSI, MISO, SCLK, CS) plus a data/command (DC) pin and a reset (RST) pin, totaling 6 pins. Some displays omit MISO to save a pin, using a 3-wire interface (MOSI, SCLK, CS) with DC and RST, totaling 5 pins. The chip select (CS) pin is critical for bus sharing. If multiple SPI devices are on the same bus, each needs a unique CS line. For example, an SPI display and an SD card module can share MOSI, MISO, and SCLK, but must have separate CS pins. This is common in data logging projects where the display shows live data while the SD card logs it. The SPI bus also supports daisy-chaining, but this is rarely used in displays due to the need for per-device CS.

Timing diagrams reveal the protocol's strictness. SPI is a synchronous protocol where the master (MCU) generates the clock. The display samples data on the rising or falling edge, depending on the SPI mode (CPOL and CPHA). Most SPI displays use Mode 0 (CPOL=0, CPHA=0) or Mode 3 (CPOL=1, CPHA=1). The ILI9341 datasheet specifies a minimum SCK high/low time of 12.5 ns at 40 MHz, corresponding to a 50% duty cycle. The data setup time (tSU) is 10 ns, and the hold time (tHD) is 10 ns. These timings are easily met by modern MCUs like the ESP32, which can generate SPI clocks with 1 ns precision. However, long PCB traces or poor grounding can introduce signal integrity issues, especially at 40 MHz. A 10 cm trace at 40 MHz has a propagation delay of about 0.5 ns, which is negligible, but impedance mismatches can cause reflections. Adding a 33-ohm series resistor on the SCK line can dampen ringing.

Backlight control is often integrated into SPI displays. Most modules include a backlight LED with a series resistor, controlled by a separate pin (BL). This pin can be driven by a PWM signal from the MCU to adjust brightness. The typical backlight current is 20-40 mA at 3.3V, consuming 66-132 mW. For a 2.8-inch display, the backlight accounts for 60-70% of total power consumption. Dimming the backlight to 50% duty cycle reduces power by 50%, a common technique in battery-powered devices. Some displays, like the ILI9341-based modules, include a built-in boost converter for the backlight, allowing operation from a 3.3V supply. The boost converter efficiency is typically 80-85%, meaning 20% of the backlight power is lost as heat.

Temperature range is another specification. Most standard SPI displays are rated for -20°C to +70°C, but industrial-grade versions can handle -40°C to +85°C. The LCD fluid's viscosity changes with temperature, affecting response time. At -20°C, the response time (rise + fall) can increase from 10 ms to 50 ms, causing ghosting. This is a consideration for outdoor applications like automotive dashboards or cold-chain monitors. The ILI9341 datasheet specifies a typical response time of 10 ms at 25°C, but this degrades at temperature extremes. For extreme environments, OLED SPI displays are better, as they have faster response times (1 ms) and wider temperature ranges (-40°C to +85°C). The SSD1306 OLED, for example, has a response time of 1 ms and operates down to -40°C.

Software libraries abstract away the low-level protocol. The Adafruit_GFX library, for instance, provides a common API for drawing pixels, lines, circles, and text. Under the hood, it calls the display's SPI write function, which sends 8-bit or 16-bit data over the bus. The library supports hardware SPI (using the MCU's SPI peripheral) or bit-banged SPI (using GPIO pins). Hardware SPI is faster, as it offloads timing to the peripheral. On an ESP32, hardware SPI can achieve 40 MHz, while bit-banged SPI is limited to 1-2 MHz due to CPU overhead. The TFT_eSPI library, optimized for ESP32, can achieve 40 MHz with DMA (Direct Memory Access), reducing CPU usage to near zero during frame transfers. This is critical for real-time applications like oscilloscopes or game consoles.

DMA support is a game-changer for high-performance embedded projects. With DMA, the MCU can transfer a full frame buffer to the display without CPU intervention. For example, an ESP32 with DMA can send a 320x240 frame (153,600 bytes) in 3.8 ms at 40 MHz, leaving the CPU free to handle sensor data or network communication. Without DMA, the CPU would be busy for 30 ms, blocking other tasks. The ESP32's SPI controller supports DMA with descriptors, allowing chained transfers. This is why many advanced embedded projects, like the M5Stack or LILYGO modules, use SPI displays with DMA. The trade-off is that DMA requires a contiguous memory buffer, which can be a challenge on MCUs with fragmented RAM.

Frame buffer management is a design decision. Some developers use a full frame buffer (e.g., 153,600 bytes for 320x240), while others use partial updates. Partial updates send only changed regions of the screen, reducing SPI traffic. The ILI9341 supports windowed addressing, where you define a rectangular region and send only that region's data. This is useful for updating a gauge or text field without redrawing the entire screen. For example, updating a 50x50 pixel region at 16-bit color requires 5,000 bytes, which takes 1 ms at 40 MHz. This allows for smooth animations even on low-end MCUs. The trade-off is that partial updates require more complex software logic to track dirty regions.

Cost is a decisive factor. A 2.4-inch SPI TFT display costs $8-$12 in single quantities, while a parallel interface version of the same size costs $10-$15. The difference is due to the simpler PCB layout and fewer pins on the connector. For high-volume production, SPI displays can be $3-$5 each, making them cost-effective for consumer electronics. The 0.96-inch OLED SPI displays are even cheaper, at $2-$4 each. This cost advantage, combined with pin efficiency, makes SPI the default choice for hobbyist and commercial embedded projects. In contrast, HDMI or MIPI displays cost $20-$50 and require more powerful processors, limiting their use to high-end devices.

Compatibility with development boards is excellent. The Raspberry Pi Pico, for example, has two SPI peripherals, each with dedicated pins. The Pico's SPI can run at 62.5 MHz, but the ILI9341 limits it to 40 MHz. The Arduino Uno has one SPI peripheral on pins 10-13, but its 16 MHz clock limits SPI speed to 8 MHz (half the system clock). The STM32 "Blue Pill" (STM32F103C8T6) has two SPI peripherals, each capable of 18 MHz. These variations mean that the same display can perform differently across platforms. For example, a 2.8-inch display on an ESP32 can achieve 25 fps, while on an Arduino Uno it might only achieve 8 fps. This is a critical consideration when choosing a platform for a GUI-intensive project.

Signal integrity at high speeds is a practical concern. At 40 MHz, the SPI clock signal has a rise time of 2-3 ns, which can cause crosstalk on adjacent wires. In a ribbon cable, 10 cm of parallel wires can have 5-10 pF of mutual capacitance, leading to signal coupling. This can cause false clock edges or data corruption. To mitigate this, designers often use twisted-pair wires or add ground wires between signal lines. On a PCB, keeping SPI traces short (under 5 cm) and using a ground plane reduces noise. The maximum trace length for 40 MHz SPI is about 20 cm before signal degradation becomes significant. For longer distances, differential SPI (e.g., RS-422) or LVDS can be used, but this adds cost and complexity.

Display driver ICs vary in features. The ILI9341 supports 16-bit, 18-bit, and 24-bit color modes, while the ST7789 supports 12-bit, 16-bit, and 18-bit modes. The SSD1351 OLED driver supports 65K colors and a 128x128 resolution. The choice of driver affects the library support and available features. For example, the ILI9341 has a built-in touch controller interface (XPT2046), while the ST7789 does not. This is why many 2.8-inch displays include a separate touch controller chip. The touch controller uses SPI as well, sharing the same bus with a different CS pin. This adds complexity but enables touch input without extra GPIOs.

Real-world examples illustrate the trade-offs. A weather station project using an ESP32 and a 2.8-inch ILI9341 display can show temperature, humidity, and pressure with a 10-second update rate. The SPI bus runs at 40 MHz, and the display updates a 100x100 pixel region for the numbers, taking 2 ms. The total CPU load for display updates is under 1%, leaving 99% for Wi-Fi and sensor polling. In contrast, a portable game console using the same display and a 40 MHz SPI bus can achieve 30 fps by using DMA and a full frame buffer. The game logic runs on the second core of the ESP32, while the display updates happen on the first core via DMA. This parallel processing is only possible with SPI's low CPU overhead.

Power management strategies include turning off the display when not in use. The ILI9341 has a sleep mode command (0x10) that reduces current draw to 0.5 mA. The backlight can be turned off via PWM or a MOSFET switch. In a battery-powered sensor node, the display might be on for 5 seconds per minute, reducing average power consumption. For example, a display drawing 20 mA active and 0.5 mA sleep, with a 10% duty cycle, averages 2.45 mA. This extends battery life from 100 hours to 800 hours on a 2000 mAh battery. This is a common technique in IoT devices that only need to display data when a user presses a button.

Future trends include higher resolution SPI displays. Newer controllers like the ILI9488 support 480x320 resolution with 16-bit color, requiring 307,200 bytes per frame. At 40 MHz, the transfer time is 61 ms, limiting refresh to 16 Hz. To improve this, some controllers use quad-SPI (QSPI), which uses four data lines instead of one, quadrupling the data rate. The ILI9488 supports QSPI at 80 MHz, achieving a theoretical 320 Mbps, reducing frame transfer time to 7.7 ms. This allows 60 fps refresh rates. However, QSPI requires more pins (4 data lines + 1 clock + 1 CS = 6 pins) and is not yet widely supported in low-cost MCUs. The ESP32-S3 supports QSPI, but the Arduino Uno does not. This is a niche but growing segment for high-performance embedded displays.

Reliability testing reveals common failure modes. SPI displays can suffer from initialization failures if the reset timing is incorrect. The ILI9341 requires a reset pulse of at least 10 microseconds, followed by a 120 ms wait. If the MCU resets too quickly, the display may not initialize. This is a common issue with power-on reset circuits. Another failure mode is missing the CS assertion, causing the display to ignore data. This happens when the CS pin is left floating or is driven by a slow GPIO. Adding a 10k ohm pull-up resistor on the CS line prevents this. Thermal cycling can cause solder joint cracks on the FPC connector, especially in displays with 0.5 mm pitch connectors. Using a reinforced connector or adding strain relief reduces this risk.

Documentation quality varies by manufacturer. The ILI9341 datasheet is 290 pages, detailing every command, timing diagram, and register

For institutional clients

Commission a Studio Conversation

F. Nakata Studios accepts fewer than four commissioned projects each year. Begin with a confidential conversation from Tokyo or Montréal — for landmark civic, cultural, and high-density residential work across Asia and North America.

Commission a Studio Conversation