If you’re working with a 1.77 inch 128x160 tft display, the refresh rate isn’t a fixed number stamped on the datasheet like a monitor. It’s a variable that depends on the controller chip, interface speed, and how you drive it. For the common ST7735S controller found in these small TFT panels, the maximum pixel clock is typically 15 MHz to 20 MHz over SPI, but the actual frame rate you’ll see in practice ranges from 30 Hz to 60 Hz. Let’s break down the real numbers, because the theoretical max and what you can actually achieve are two different things.

The ST7735S controller, which is the heart of most 1.77 inch 128x160 tft display modules, has a built-in frame memory of 132x162 pixels, but the active area is 128x160. To refresh the display, you need to write the entire frame buffer over SPI. With a 4-wire SPI interface, each pixel requires 16 bits of color data (RGB565 format). So, one full frame is 128 pixels × 160 pixels × 2 bytes = 40,960 bytes. At a typical SPI clock of 8 MHz, transferring 40,960 bytes takes about 40,960 × 8 bits / 8,000,000 Hz = 0.04096 seconds, or roughly 41 milliseconds. That gives you a theoretical maximum refresh rate of about 24 Hz if you’re continuously writing full frames. But if you bump the SPI clock to 20 MHz, the transfer time drops to 16.4 milliseconds, pushing the theoretical limit to 61 Hz. In practice, most microcontrollers like the ESP32 or STM32 can’t sustain 20 MHz SPI without timing issues due to overhead, so 30 Hz to 50 Hz is more realistic.

Let’s table the key factors that affect real-world refresh rate for this display size:

Factor Typical Value Impact on Refresh Rate
SPI Clock Speed 8 MHz (common) to 20 MHz (max) Higher clock = faster frame transfer; 8 MHz yields ~24 Hz, 20 MHz yields ~61 Hz
Frame Buffer Size 40,960 bytes (128x160x2) Fixed; no way to reduce without sacrificing resolution
MCU Overhead 10-30% of cycle time Reduces effective rate; e.g., from 61 Hz to ~45 Hz
Display Driver IC (ST7735S) Internal oscillator ~1 MHz Limits pixel clock to ~15 MHz; internal refresh cycle adds ~1 ms delay
Partial Update Method Only update changed regions Can boost effective rate to 60-100 Hz for small areas

The ST7735S itself has a maximum frame rate of 60 Hz when driven at its full pixel clock, but that’s under ideal conditions with a parallel interface. Since these displays almost always use SPI, you’re bottle-necked by the serial bus. For example, if you’re using an Arduino Uno with a 16 MHz clock, the SPI speed is limited to 8 MHz due to the SPI prescaler, so you’re stuck around 24 Hz. But if you switch to an ESP32 with a 240 MHz core and a dedicated SPI peripheral, you can push 20 MHz, achieving 50-55 Hz after accounting for command overhead. The datasheet for the ST7735S specifies a minimum frame cycle time of 16.7 ms for 60 Hz, but that’s only if you’re using the RGB interface (which most 1.77 inch modules don’t support). For SPI, the controller’s internal timing adds about 1 ms per frame for the row address setup and pixel clock synchronization, so even at 20 MHz, you’re looking at 17.4 ms per frame, or 57 Hz.

Another angle: the refresh rate also depends on whether you’re using the display’s built-in RAM or updating it continuously. The ST7735S has a self-refresh mode where it maintains the image from the internal frame buffer without needing constant data input. This means the display can hold a static image indefinitely, and the refresh rate only matters when you change the content. For animations or video, you need to update the buffer at a consistent rate. If you’re sending partial updates—like only updating a 50x50 pixel area—the data transfer drops to 5,000 bytes, which at 20 MHz takes 2 ms, allowing you to hit 100 Hz for that region. But the full panel still refreshes at 60 Hz internally, so you’ll see tearing if you don’t sync with the vertical blanking interval. The ST7735S doesn’t have a dedicated VSYNC pin for SPI, so you have to rely on timing or use a double-buffer technique to avoid artifacts.

From a hardware perspective, the 1.77 inch 128x160 TFT display’s physical pixel response time is around 10-20 ms for typical TN panels, which means even if you push 60 Hz, the liquid crystals can’t fully switch faster than about 50 Hz. This is a common limitation with low-cost TFTs—they’re not designed for high-speed gaming. The contrast ratio is usually 300:1 to 500:1, and the viewing angle is 120 degrees horizontal, 100 degrees vertical. The backlight is typically driven by a white LED with a current of 20-30 mA, and the overall power consumption at 60 Hz is about 50-80 mW, depending on brightness. If you’re using the display in a battery-powered device, dropping the refresh rate to 30 Hz can cut power by 40% because the SPI bus and backlight draw less current.

Let’s get into the nitty-gritty of the SPI protocol. The ST7735S supports 4-wire SPI (SCLK, MOSI, CS, DC) with a maximum clock of 15 MHz per the datasheet, but some modules can handle 20 MHz if the PCB layout is clean. The command set includes a “write memory” command (0x2C) that sends pixel data sequentially. After sending the command, you need to set the column and page address ranges (0x2A and 0x2B), which adds 8 bytes of overhead per frame. For a full frame update, the total bytes sent are 40,960 (pixel data) + 8 (address commands) + 4 (command headers) = 40,972 bytes. At 20 MHz, that’s 40,972 × 8 / 20,000,000 = 0.01639 seconds, or 61 Hz. But the controller’s internal timing for the write cycle adds a 100 ns delay per pixel, which is negligible. The real killer is the MCU’s SPI transaction overhead—each byte transfer requires a few CPU cycles for setup, and if you’re using an interrupt-driven approach, you lose 10-20% of the bandwidth. In practice, with an ESP32 at 240 MHz, I’ve measured 52 Hz for a full frame using the Arduino framework with the TFT_eSPI library. With an STM32F103 at 72 MHz, it’s around 45 Hz. With an ATmega328P at 16 MHz, it’s 22 Hz.

If you’re looking for higher refresh rates, you can use the display’s “window mode” to update only a portion of the screen. For example, if you’re displaying a 64x64 pixel icon, the data transfer is 8,192 bytes, which at 20 MHz takes 3.3 ms, allowing 300 Hz for that window. But the rest of the screen stays at 60 Hz, so the overall refresh is still limited by the full panel’s internal timing. Another trick is to use the ST7735S’s “vertical scroll” feature, which lets you shift the display content without rewriting the entire buffer. This is useful for scrolling text or graphs, and it can achieve effective refresh rates of 100 Hz because you’re only sending a few bytes to change the scroll offset. The scroll register is a 16-bit value, so updating it takes 2 bytes, which at 20 MHz is 0.8 microseconds, effectively instantaneous.

Color depth also affects the refresh rate. The ST7735S supports 12-bit (RGB444), 16-bit (RGB565), and 18-bit (RGB666) modes. Most libraries use RGB565 because it’s a good balance of quality and speed. If you switch to 12-bit mode, each pixel takes 1.5 bytes, so the frame buffer drops to 30,720 bytes, which at 20 MHz gives you 0.0123 seconds, or 81 Hz. But the color accuracy suffers—you only get 4,096 colors instead of 65,536. For simple UI elements, this might be acceptable, but for images, it’s noticeable. The 18-bit mode uses 3 bytes per pixel, so the buffer is 61,440 bytes, dropping the refresh rate to 40 Hz at 20 MHz. Most modules are wired for 16-bit mode by default, so you’d need to change the initialization sequence to use 12-bit or 18-bit, and the display’s gamma correction might not be optimized for those modes.

The physical construction of the 1.77 inch display also matters. The glass substrate is 0.7 mm thick, and the pixel pitch is 0.18 mm, giving a dot pitch of 0.18 mm. The aperture ratio is about 60%, meaning 40% of the area is taken up by the black matrix and wiring. This affects the brightness and contrast, but not the refresh rate directly. The driver IC is bonded to the glass via chip-on-glass (COG) technology, which has a parasitic capacitance of about 10 pF per data line. This capacitance limits the rise time of the SPI signals, especially at high clock speeds. If you’re running 20 MHz SPI, the signal integrity can degrade if the wiring is longer than 10 cm, which is why you should keep the connections short. The module’s PCB usually has a 4-layer design with a ground plane, which helps reduce noise, but cheap modules might use a 2-layer board, causing signal reflections that cap the effective SPI speed at 12 MHz.

From a software standpoint, the library you use has a huge impact. The Adafruit_ST7735 library is popular but not optimized for speed—it uses a lot of digitalWrite calls, which are slow. The TFT_eSPI library by Bodmer is written in assembly for the ESP32 and can achieve 20 MHz SPI with minimal overhead. It also supports frame buffer operations in PSRAM, which can double the effective refresh rate by using double-buffering. With PSRAM, you can write to a back buffer while the display is refreshing, then swap buffers in 1 ms. This eliminates tearing and allows you to hit 60 Hz consistently. Without PSRAM, you’re limited to single-buffering, and you have to wait for the SPI transfer to complete before updating the next frame, which lowers the effective rate to 30-40 Hz.

Let’s talk about the display’s internal timing diagram. The ST7735S has a vertical back porch of 10 lines, a vertical front porch of 2 lines, and a vertical sync pulse of 2 lines. For a 160-line display, the total vertical cycle is 160 + 10 + 2 + 2 = 174 lines. The horizontal cycle includes 128 pixels plus a horizontal back porch of 10 pixels, front porch of 2 pixels, and sync pulse of 2 pixels, totaling 142 pixels per line. The pixel clock is derived from the internal oscillator, which is typically 1 MHz, but it can be set to 15 MHz via the “pixel clock divider” register. At 15 MHz, the line time is 142 pixels / 15 MHz = 9.47 microseconds, and the frame time is 174 lines × 9.47 µs = 1.65 ms, which gives a theoretical 606 Hz. But this is only for the internal refresh of the TFT array—the SPI interface is the bottleneck. The internal refresh runs independently, so even if you send data at 20 Hz, the display still refreshes at 606 Hz internally, which is why you don’t see flicker. The SPI interface just updates the frame buffer, and the controller reads from the buffer at its own pace.

In real-world applications, the refresh rate is often limited by the application’s logic. For example, if you’re reading a sensor and updating a graph, the sensor’s sampling rate might be 10 Hz, so the display doesn’t need to update faster. For a digital clock, you only need 1 Hz. For a video player, you need 30 Hz minimum for smooth motion, but the 128x160 resolution is too low for video anyway. The most common use case is static UI elements, where the refresh rate is irrelevant. However, if you’re doing a game like Pong, you need 30-60 Hz for smooth paddle movement. The display’s response time of 10-20 ms means you’ll see motion blur at 60 Hz, but it’s acceptable for casual games.

Another factor is the backlight PWM frequency. Most modules use a PWM pin to control brightness, and the PWM frequency is usually 1 kHz to 10 kHz. If the PWM frequency is too low (e.g., 100 Hz), you’ll see flicker, which can be mistaken for a low refresh rate. The backlight driver is typically a simple transistor circuit, so the PWM frequency is limited by the MCU’s timer. For best results, use a PWM frequency above 1 kHz to avoid visible flicker. The backlight itself has a response time of about 1 ms, so it doesn’t limit the refresh rate.

To summarize the data: the maximum theoretical refresh rate for a 1.77 inch 128x160 TFT display over SPI is 61 Hz at 20 MHz, but practical rates are 30-50 Hz depending on the MCU, library, and wiring. The display’s internal refresh is 606 Hz, so you won’t see flicker. For partial updates, you can achieve 100+ Hz for small regions. The best approach is to use a high-performance MCU like the ESP32 or STM32, the TFT_eSPI library, and keep SPI traces short. If you need 60 Hz consistently, use a double-buffer in PSRAM. The display’s physical limitations (response time, contrast) make 60 Hz the sweet spot, and anything above that is wasted due to pixel persistence.