轻量级 ST7789 240x240 彩色 TFT 驱动(RGB565 / 4-wire SPI),专为小 RAM 单片机设计的无帧缓冲架构。
作者:mark756-66 | 抖音:九十一颗鱼丸
主流方案在小 RAM 芯片上跑彩色屏会直接碰壁:
| 方案 | RAM 需求 | 20KB SRAM 芯片(如 STM32F103C8) |
|---|---|---|
| LVGL | >= 48KB + 堆 | 装不下 |
| U8g2 | 单色库(1bpp),无彩色能力 | 不适用 |
| 常规自写驱动(全帧缓冲) | 240x240x2 = 115.2KB | 装不下 |
| 本库(无帧缓冲) | 480B 行缓冲 | 轻松运行 |
ST7789 自带 GRAM 并支持窗口寻址(CASET/RASET/RAMWR):设置一个矩形窗口后,像素数据流按行自动填充。屏幕 GRAM 本身就是帧缓冲,MCU 无需在片内再存一份——驱动只维护一行 480B 缓冲,"填一行、发一行"。
设窗口 -> 单行缓冲填色 -> SPI 发送 -> 循环 -> 收窗口
| 指标 | 数值 |
|---|---|
| 驱动常驻 RAM | 480B 行缓冲 + <120B 状态 |
| Flash 占用 | < 4KB(含图形库 + 字库) |
| 全屏刷新 | 约 51ms(约 19fps) |
| 局部刷新(30x44 数字区域) | 约 1.2ms |
1.54 寸 ST7789 模块,排线顺序:GND VCC SCL SDA RES DC CS BLK
| 屏幕引脚 | STM32 引脚 | 说明 |
|---|---|---|
| GND | GND | 共地 |
| VCC | 3.3V | 勿接 5V |
| SCL | PA5 | SPI1_SCK |
| SDA | PA7 | SPI1_MOSI |
| RES | PB1 | 硬复位,必须接 |
| DC | PB0 | 数据/命令选择 |
| CS | PA4 | 软件片选 |
| BLK | 悬空/3.3V | 背光,悬空常亮 |
lcd_st7789.c / lcd_st7789.h 驱动 + 图形库(核心,平台无关)
spi_st7789.c / spi_st7789.h STM32F103 HAL 参考移植层(SPI1 + 控制脚)
examples/example_basic.c RT-Thread 示例
Keil MDK:把两个 .c 加入工程,IncludePath 加入头文件目录。
#include <rtthread.h>
#include "lcd_st7789.h"
static void ui_entry(void *p)
{
lcd_init(); /* 内含 SPI 初始化 + 硬复位 + 初始化序列 */
lcd_fill_screen(COLOR_BLACK);
while (1)
{
lcd_fill_screen(lcd_rgb565(10, 20, 40));
lcd_fill_rect_hgrad(20, 40, 200, 30, COLOR_RED, COLOR_BLUE);
lcd_draw_text(20, 100, "HELLO ST7789", 3, COLOR_WHITE);
lcd_draw_digit7(60, 130, 8, 40, 72, 8, COLOR_CYAN);
rt_thread_mdelay(1000);
}
}完整演示(渐变、圆角卡片、七段计数器、彩虹页)见 examples/example_basic.c。
COLOR_BLACK / COLOR_WHITE / COLOR_RED / COLOR_GREEN / COLOR_BLUE
COLOR_YELLOW / COLOR_CYAN / COLOR_MAGENTA / COLOR_ORANGE / COLOR_GRAY
uint16_t lcd_rgb565(uint8_t r, uint8_t g, uint8_t b); /* 0~255 分量转 RGB565 */| 函数 | 说明 |
|---|---|
lcd_init(void) |
SPI + 硬复位 + 寄存器初始化,上电调用一次 |
lcd_set_area(x0,y0,x1,y1) |
设置写入窗口(配对 lcd_end_area,期间连续发像素) |
lcd_end_area(void) |
结束窗口写入 |
lcd_draw_pixel(x,y,c) |
画点 |
| 函数 | 说明 |
|---|---|
lcd_fill_rect(x,y,w,h,c) |
实心矩形(核心原语) |
lcd_fill_screen(c) |
全屏填充 |
lcd_draw_hline / lcd_draw_vline |
水平/垂直线 |
lcd_draw_line(x0,y0,x1,y1,c) |
任意直线(Bresenham) |
lcd_draw_rect |
空心矩形 |
lcd_fill_round_rect / lcd_draw_round_rect |
实心/空心圆角矩形(逐行扫描真圆角) |
lcd_fill_circle / lcd_draw_circle |
实心/空心圆 |
lcd_fill_rect_hgrad / lcd_fill_rect_vgrad |
水平/垂直渐变 |
/* 3x5 点阵字体:0-9、A-Z(小写自动转大写)、: . % - / + ! > < */
void lcd_draw_text(x, y, str, scale, color);
int16_t lcd_text_width(str, scale);
/* 七段数码管风格大数字:w 位宽 / h 位高 / t 笔画厚,推荐 h=2.4w, t=w/6 */
void lcd_draw_digit7(x, y, digit, w, h, t, color);
void lcd_draw_colon7(x, y, h, t, color);驱动对硬件的全部依赖只有 spi_st7789.c 里的三件事:
- SPI 发送:
HAL_SPI_Transmit(&hspi1, ...); - 三根控制脚:
TFT_CS / TFT_DC / TFT_RES的 GPIO 宏与初始化; MX_SPI1_Init():SPI1 主模式、8bit、Mode0。
换芯片(F4/GD32/软件 SPI)只需替换这三处实现,图形层零改动。旋转屏幕改 lcd_init_seq 中 MADCTL 参数(0x60/0xC0/0xA0 对应 90/180/270 度)。
- SPI 速率:默认 18MHz(72MHz/4)。排线长出现花屏时退回 9MHz(分频 8);
- IPS 反显:初始化序列含
0x21 INVON,IPS 面板必需,勿删; - 字节序:像素流为高字节在前,驱动已处理(勿改为 uint16_t 直发,小端内存会红蓝互换);
- 只写不读:SPI 单向配置,无读回能力;
- 无中文字库:3x5 字库覆盖 ASCII 子集,中文可外挂字库或自行扩表。
ST7789-RGB565-Lite/
├── README.md 本文档
├── LICENSE MIT
├── lcd_st7789.c 驱动实现(初始化序列/图形/字库)
├── lcd_st7789.h 驱动 API
├── spi_st7789.c STM32F103 HAL 参考移植层
├── spi_st7789.h 移植层头文件(控制脚宏)
└── examples/
└── example_basic.c RT-Thread 完整演示
MIT (c) 2026 mark756-66
mark756-66
抖音:九十一颗鱼丸 邮箱 2985414724@qq.com
如果对你有帮助,点个 Star~