STC单片机驱动ST7735显示中文:字模映射与全字库方案实践
2026/9/16 16:09:51 网站建设 项目流程

简介:一套完整的基于STC单片机与ST7735驱动芯片的1.8寸TFT彩屏中文显示工程,适用于嵌入式入门及小型彩屏界面开发场景,帮助开发者绕过繁琐的底层驱动配置,直接掌握SPI通信、LCD初始化、帧缓冲与汉字点阵显示等核心环节。压缩包共72个文件,包含12个C源码、21个头文件、Keil工程配置与编译输出文件(uvproj、hex、lst、map等),另附TFT彩屏显示中文效果的演示视频,整体约1.1MB,结构清晰,便于按模块查阅。目前已有1852人学习下载。资源内按功能模块组织,提供STC15系列基础库、GUI图形接口以及多尺寸汉字字库(8x16、16x16、16x32、32x32),并配有.h头文件声明,整体代码风格简洁,可快速适配到实际项目中。通过阅读代码和观看演示,读者能够理清单片机与ST7735之间的数据交互流程,解决中文取模、颜色填充与文本排版等常见问题,适合作为毕业设计、课程实验或产品原型的基础参考。

1. 一块 128×160 的屏,难点不在画点而在字形映射

STC 单片机上点亮 ST7735 几乎是两天就能做完的事:SPI 时序对着数据手册调几次,屏上就能画出彩条和色块。真正让项目停下来的,是「中文显示」这四个字——ST7735 并不知道“中文”是什么,它只认坐标和像素颜色,而单片机里也没有现成的字形。于是问题变成三条线:字符集用 GB2312 还是 UTF-8、16×16 点阵字模从哪里来、点阵数据如何按区位码映射到屏幕坐标。网上大量“tftlcd显示中文”“显示不出中文”的求助帖,基本都卡在字模的获取和地址换算上,而不是 SPI 驱动本身。下文以 STC8/STC15 为参照,按驱动点亮、字模提取、字符串解析、全字库扩展的顺序,讲一遍实际工程里最稳的做法。

2. ST7735 驱动点亮:SPI 时序、初始化序列与底层画图函数

2.1 引脚、电平与 SPI 模式:先排除两类“点不亮”

STC 单片机常见 5V 和 3.3V 两种供电,而市面上 1.8 寸 ST7735 模组几乎都是 3.3V 逻辑。直接拿 5V GPIO 去推模组的 SDA、SCL,轻则电平阈值不匹配导致读不到数据,重则烧坏驱动芯片。我一般在这几根线上做 1KΩ+2KΩ 分压,或者直接加一块 3.3V 电平转换模块;背光 LED 引脚可以经一个三极管由 5V 控制,避免从单片机引脚取太大电流。

模组引脚单片机 GPIO说明
VCC3.3V注意模组上是否已带稳压
GNDGND共地必须接
CSP1.2片选,低有效
RSTP1.3复位,低有效
DC/RSP1.4命令/数据选择
SDA/MOSIP1.5SPI 数据线
SCL/SCKP1.6SPI 时钟线

ST7735 支持的标准 SPI Mode 0:CPOL=0、CPHA=0,即空闲时钟为低电平,数据在上升沿被采样,8 位数据 MSB 先发。STC8 系列自带硬件 SPI 模块,但调试初期建议先用软件模拟 SPI,方便用逻辑分析仪抓时序。等字符显示稳定后再切到硬件 SPI,速度能提升一个量级。

2.2 软件 SPI 收发与命令/数据切换

sbit LCD_CS = P1^2; sbit LCD_DC = P1^3; sbit LCD_SDA = P1^4; sbit LCD_SCL = P1^5; sbit LCD_RST = P1^6; void SPI_WriteByte(uint8_t dat) { uint8_t i; for (i = 0; i < 8; i++) { LCD_SCL = 0; if (dat & 0x80) LCD_SDA = 1; else LCD_SDA = 0; LCD_SCL = 1; dat <<= 1; } } void LCD_WriteCmd(uint8_t cmd) { LCD_DC = 0; // DC 拉低表示传输的是命令 LCD_CS = 0; SPI_WriteByte(cmd); LCD_CS = 1; } void LCD_WriteData(uint8_t dat) { LCD_DC = 1; // DC 拉高表示传输的是数据 LCD_CS = 0; SPI_WriteByte(dat); LCD_CS = 1; }

逻辑说明:ST7735 通过 DC 引脚区分当前 SPI 字节是命令还是数据,CS 片选在每次传输前拉低、结束后拉高。SPI_WriteByte从最高位开始逐位输出,数据在 SCL 上升沿之前的低电平阶段被放到 SDA 上,正好满足 Mode 0。

参数说明:dat是要发送的 8 位数据;如果需要读取屏幕状态,需要额外实现SPI_ReadByte,但显示类项目基本用不到读操作。注意每发送一个字节后要有一小段延时或至少保持 SCL 高电平一个机器周期,否则在 12T 模式的 STC89 系列上容易丢位。

2.3 ST7735 最小初始化序列

void LCD_Init(void) { LCD_RST = 0; delay_ms(50); LCD_RST = 1; delay_ms(50); LCD_WriteCmd(0x01); // SWRESET 软件复位 delay_ms(120); LCD_WriteCmd(0x11); // SLPOUT 退出休眠模式 delay_ms(120); LCD_WriteCmd(0x36); // MADCTL 数据访问控制 LCD_WriteData(0x00); // RGB 顺序,正常扫描方向 LCD_WriteCmd(0x3A); // COLMOD 像素格式 LCD_WriteData(0x05); // 0x05 = RGB565,16 位色 LCD_WriteCmd(0x29); // DISPON 打开显示 delay_ms(20); }

这段初始化省掉了部分模组需要的帧率、伽马等寄存器配置,在不少 ST7735 模组上能直接点亮。如果显示偏色、对比度异常,再按商家提供的完整寄存器序列补齐,一般集中在 FRMCTR1、PWCTR1、GMCTRP1 这些地址。调试时优先确认的是0x3A寄存器:0x05表示 16 位 RGB565,0x03表示 12 位 RGB444。如果这里设错,画出来的颜色会明显偏色,甚至花屏。

2.4 开窗函数与画点:影响后续字模速度的基础操作

ST7735 的显存是按窗口写入的:先设置列地址范围,再设置行地址范围,然后连续写入像素数据。画单个像素就是连续三次命令加两字节 RGB565 数据。

void LCD_SetWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { LCD_WriteCmd(0x2A); // CASET 列地址 LCD_WriteData(x0 >> 8); LCD_WriteData(x0 & 0xFF); LCD_WriteData(x1 >> 8); LCD_WriteData(x1 & 0xFF); LCD_WriteCmd(0x2B); // RASET 行地址 LCD_WriteData(y0 >> 8); LCD_WriteData(y0 & 0xFF); LCD_WriteData(y1 >> 8); LCD_WriteData(y1 & 0xFF); LCD_WriteCmd(0x2C); // RAMWR 开始写显存 } void LCD_DrawPixel(uint16_t x, uint16_t y, uint16_t color) { if (x >= 128 || y >= 160) return; LCD_SetWindow(x, y, x, y); LCD_WriteData(color >> 8); // RGB565 先发高字节 LCD_WriteData(color & 0xFF); }

逻辑说明:LCD_SetWindow将后续的 RAM 写入限定在矩形区域内,写入指针会按从左到右、从上到下的顺序自动递增,直到到达(x1, y1)才会停止。这里color >> 8color & 0xFF表示 RGB565 的大端发送顺序,具体字节序取决于模组兼容的是哪种控制器,多数 ST7735 用这个顺序没有错误。

参数说明:分辨率 128×160,坐标原点在左上角;MADCTL寄存器可以翻转方向和交换 RGB/BGR 顺序,如果画面上的红色和蓝色互换了,把LCD_WriteData(0x00)改成0x080xC8试一下。

3. 中文字模原理:GB2312 区位码、16×16 点阵与取模参数

3.1 为什么 ST7735 显示中文容易“乱码”

ASCII 字符一个字节就能表示,显示时直接查一张 8×16 点阵表即可。而汉字在 GB2312/GBK 编码里占两个字节,例如“中”的机内码是0xD6 0xD0,两个字节都大于 0x80。如果把这两个字节当作两个 ASCII 字符直接查表,屏幕上就会出现两个无法识别的符号,这就是“乱码”的根源。所以真正要解决的,是把汉字机内码映射到字模数据所在地址。

GB2312 把汉字按区、位排列,一个汉字对应一个区位号。一级汉字 3755 个按拼音排序,放在 16~55 区;二级汉字 3008 个按部首排序,放在 56~87 区。机内码与区位码的关系是:机内码高字节 = 区号 + 0xA0,机内码低字节 = 位号 + 0xA0。反过来,已知机内码hilo,区号是hi - 0xA0,位号是lo - 0xA0

3.2 16×16 点阵字模的排列与 32 字节存储

16×16 点阵就是把每个汉字画在一个 16 行、16 列的网格里,每一行用 2 个字节表示:高字节对应左 8 点,低字节对应右 8 点,字节内的每一位对应一个像素点。整个汉字占16 行 × 2 字节 = 32 字节,这是嵌入式中文显示最常用的一种规格。如果想省存储,还有 12×12(24 字节)和 8×16(16 字节)点阵,但 16×16 是阅读最舒服、取模工具支持最好的选择。

全量 GB2312 汉字字模文件(如 HZK16)大小约为6763 × 32 ≈ 216KB,再加上符号区内容接近 230KB。STC8 系列内部 Flash 最大不过 64KB 左右,所以“全字库”在 STC 单片机上几乎不可能直接塞进内部 Flash,必须用外挂存储或内嵌少量字模。这决定了整套方案的走向。

方案存储占用适用场景主要限制
内嵌常用字模数组每字 32B菜单、仪表界面,汉字数量固定换字需要重新编译
外挂 SPI Flash 全字库约 220KB需要显示任意文本需要额外芯片和烧录流程
SD 卡 + 文件系统字库文件独立频繁更换字库内容文件系统占用资源多

3.3 取模软件参数与字模字节顺序

常用工具是 PCtoLCD2002,取模参数直接决定显示函数能不能正确还原字形。我的固定配置是:阴码、逐行式、顺向、16×16。“阴码”表示二进制位为 1 时点亮像素;“逐行式”表示按从上到下的顺序输出每一行;“顺向”表示每行从左到右输出,高字节在前。取模结果类似:

const uint8_t code zhong_16[] = { /* “中” 16×16 点阵,逐行式,阴码 */ // 数据由取模工具生成,这里省略实际 32 字节 };

取模工具生成的数据顺序必须与显示函数一致。如果你生成的数组在屏幕上左右颠倒,多半是字节内位序选成了“逆向”;如果上下颠倒,则是取模方向选成了“列行式”或“逐列式”。解决方法是固定一套参数,然后显示函数永远按这一套参数解析,排查时只改取模工具配置不动代码。

3.4 区位码换算成字模文件偏移

当字库文件按区位码连续存放时,一个汉字在文件中的偏移地址是:

uint32_t get_gb2312_offset(uint8_t hi, uint8_t lo) { uint16_t qu = hi - 0xA1; // 区号从 0 开始 uint16_t wei = lo - 0xA1; // 位号从 0 开始 return ((uint32_t)(qu * 94 + wei)) * 32; }

逻辑说明:GB2312 每个区最多 94 个字符,所以先算出汉字在字库文件中的第几个字符位置,再乘以 32 字节得到文件偏移。注意这里hi - 0xA1lo - 0xA1是基于区位从0xA1A1开始的算法,和前面机内码0xA0的公式只差 1,原因在于 GB2312 没有使用0xA0A0前面的编码空间,字库文件里第一个字符是从0xA1A1开始算的。

参数说明:hilo是字符串中连续两个字节的汉字编码;如果工程里同时存在 UTF-8 编码源文件,必须先把 UTF-8 转成 GB2312 再交给这个函数,否则偏移会落到错误位置。

4. 内嵌字模的中文显示:字符串解析、字库表与显示函数封装

4.1 字库表设计:机内码 + 32 字节点阵

STM32 或 Linux 上可以直接打开字库文件按偏移读取,但 STC 内部 Flash 装不下全字库,所以最直接的办法是把项目里实际用到的汉字提取出来,编译进代码。每个汉字由两部分组成:机内码和 32 字节点阵数据。用结构体组织成一张表:

#define FONT_MAX 64 struct ch_gb { uint8_t hi; // 机内码高字节 uint8_t lo; // 机内码低字节 const uint8_t code *matrix; // 指向 32 字节点阵 }; const uint8_t code zhong_16[] = { /* “中” 16×16 点阵数据 */ }; const struct ch_gb code font_table[] = { { 0xD6, 0xD0, zhong_16 }, // “中” // 项目里用到的其它汉字按同样方式加入 }; const uint8_t *find_font(uint8_t hi, uint8_t lo) { uint8_t i; for (i = 0; i < FONT_MAX; i++) { if (font_table[i].hi == hi && font_table[i].lo == lo) return font_table[i].matrix; } return (const uint8_t code *)0; }

逻辑说明:find_font是“线性查表”函数,遍历整张字库表找到匹配的机内码,返回点阵地址。菜单项目里几十个汉字,线性查找几十次对 STC8 的 1T 模式来说完全不是负担,不必引入哈希或二分。

参数说明:FONT_MAX要大于实际汉字数量;code是 Keil C51 的关键字,把数据放到程序 Flash 而不是 RAM。如果换用 SDCC 或标准 C 编译器,把code去掉改成const即可。

4.2 从汉字机内码到屏幕像素:逐行逐点映射

拿到了 32 字节点阵,显示函数要按取模参数还原字形。下面这段是配合“阴码、逐行式、顺向”配置的显示函数:

void LCD_ShowChinese16(uint16_t x, uint16_t y, uint8_t hi, uint8_t lo, uint16_t fg, uint16_t bg, uint8_t transparent) { const uint8_t *font = find_font(hi, lo); uint8_t i, j, hb, lb; if (font == (const uint8_t code *)0) return; for (i = 0; i < 16; i++) { hb = font[i * 2]; // 当前行左 8 个点 lb = font[i * 2 + 1]; // 当前行右 8 个点 for (j = 0; j < 16; j++) { uint8_t mask = (j < 8) ? (0x80 >> j) : (0x80 >> (j - 8)); uint8_t bit = (j < 8) ? (hb & mask) : (lb & mask); if (transparent && !bit) continue; // 透明模式跳过背景 if (bit) LCD_DrawPixel(x + j, y + i, fg); else if (!transparent) LCD_DrawPixel(x + j, y + i, bg); } } }

逻辑说明:外层循环遍历 16 行,每行取两个字节,hb对应左半边,lb对应右半边。内层循环遍历 16 列,当列号j < 8时从hb取位,否则从lb取位,位值为 1 画前景色,为 0 画背景色。取位顺序是0x80 >> j,正好对应“顺向、高位在前”的取模配置。

参数说明:fgbg是 RGB565 颜色值;transparent为 0 时每个像素不是前景就是背景,效果是汉字带底色;为 1 时只画前景,适合在图片或色块上叠加文字。

4.3 混合字符串解析:把“中英混排”当成扫描问题处理

实际界面几乎不会只有汉字,更常见的是“温度 25℃”这种中英混排。处理规则很简单:读取一个字节,如果最高位为 0,按 ASCII 处理;如果最高位为 1,说明是汉字机内码的第一个字节,再读下一个字节组成完整的 16 位机内码。

void LCD_ShowGBString(uint16_t x, uint16_t y, const char *str, uint16_t fg, uint16_t bg, uint8_t transparent) { while (*str) { if (*str & 0x80) { // 汉字双字节 uint8_t hi = *str++; uint8_t lo = *str++; if (x > (128 - 16)) { x = 0; y += 16; } LCD_ShowChinese16(x, y, hi, lo, fg, bg, transparent); x += 16; } else { // ASCII 单字节 if (x > (128 - 8)) { x = 0; y += 16; } LCD_ShowChar8x16(x, y, *str++, fg, bg, transparent); x += 8; } if (y > (160 - 16)) break; } }

逻辑说明:这里有三个关键判断:*str & 0x80判断中英文;汉字宽度 16、ASCII 宽度 8,所以换行阈值分别是128 - 16128 - 8;超出屏幕高度后直接 break 防止野指针。

参数说明:str必须是 GB2312/GBK 编码的字符串。Keil C51 默认按本地代码页处理中文字符串字面量,所以直接写LCD_ShowGBString(0, 0, "中文字符串", RED, WHITE, 0);在 Windows 上编译没问题。如果你在 Linux 或 VSCode 里编辑源文件,文件保存成 UTF-8 编码,那字符串在内存里是 UTF-8 字节流,显示前先转成 GB2312,否则就会出现“vscode输出中文显示乱码”类似的现象。

4.4 内嵌方案的边界与改造方向

内嵌方案最大的问题是字库表会随项目膨胀。一个 20 字的界面占 640 字节 Flash,看起来不多;但当页面增加到十几屏、需要“中英文名称”那种长列表时,手写结构体数组就变得难以维护,而且不同页面重复汉字会白白浪费空间。遇到这种情况,常见的改造方向是:把字模数据按区位顺序连续存放,把“线性查表”改成“按编码区间计算”,这一步做完,其实已经是在向全字库方案靠拢了。

5. 全字库显示方案:SPI Flash 字库、偏移计算与缓存设计

5.1 为什么 STC 上可以考虑外挂 SPI Flash

很多做产品的人问“STC 能不能显示任意汉字”,答案是可以,前提是字库必须放在外部。常见做法是用 W25Q16(2MB)或 W25Q32(4MB)存 HZK16 字库,字库文件占 220KB 左右,剩余空间放图片或其他配置数据。STC8 控制器的 SPI 硬件接口可以直接连接 SPI Flash,读速度比模拟 SPI 高很多,2MB 容量对于字库来说绰绰有余。

5.2 从 SPI Flash 读取 32 字节字模

外挂思路下不再需要内嵌字库表,而是在收到汉字机内码后,先算出在字库文件中的偏移,然后向 W25Q16 发送读取命令:

#define HZK16_BASE 0x000000 // 字库在 Flash 中的偏移 uint8_t spi_flash_read_byte(uint32_t addr) { uint8_t dat; FLASH_CS = 0; SPI_WriteByte(0x03); // W25Q 系列读数据命令 SPI_WriteByte((addr >> 16) & 0xFF); SPI_WriteByte((addr >> 8) & 0xFF); SPI_WriteByte(addr & 0xFF); dat = SPI_ReadByte(); // 同时产生时钟 FLASH_CS = 1; return dat; }

逻辑说明:W25Q 系列的读命令是0x03,其后跟 3 字节地址,高字节在前。发送完地址后,主控通过继续产生时钟读取数据,每读一个字节,Flash 内部地址自动加 1。

参数说明:HZK16_BASE表示字库烧录到 Flash 的起始地址;如果字库和其他数据共用 Flash,必须保证这个地址是 4KB 对齐的,因为 W25Q 的扇区擦除以 4KB 为单位。读取字模时,连续调用 32 次spi_flash_read_byte即可,注意调用之间不要拉高 CS,否则地址会复位。

读取 32 字节并显示汉字的完整流程:

void LCD_ShowChineseFromFlash(uint16_t x, uint16_t y, uint8_t hi, uint8_t lo, uint16_t fg, uint16_t bg, uint8_t transparent) { uint32_t offset = get_gb2312_offset(hi, lo) + HZK16_BASE; uint8_t i, j, hb, lb; for (i = 0; i < 16; i++) { hb = spi_flash_read_byte(offset + i * 2); lb = spi_flash_read_byte(offset + i * 2 + 1); for (j = 0; j < 16; j++) { uint8_t mask = (j < 8) ? (0x80 >> j) : (0x80 >> (j - 8)); uint8_t bit = (j < 8) ? (hb & mask) : (lb & mask); if (transparent && !bit) continue; LCD_DrawPixel(x + j, y + i, bit ? fg : bg); } } }

这种方案的代价是每次显示一个汉字都要发送几十条 SPI 命令,如果整屏刷新,SPI 总线上会有大量读操作。在 STC8 上打开硬件 SPI 后,一个汉字从读取到显示大约需要 1~3ms,基本能满足菜单切换的需求。

5.3 字库烧录:把 HZK16 写进 W25Q16

我一般用串口配合一个简单的 Bootloader 完成字库烧录,流程是:

  1. 用取字软件导出 HZK16 二进制文件,注意文件内从0xA1A1开始连续排布;
  2. 单片机侧运行一个“接收串口数据写入 Flash”的烧录程序;
  3. 串口每次接收 256 字节,先擦除目标扇区,再写入分配好的 Flash 页;
  4. 全部写完回读前 32 字节做校验,和源文件逐位比较。

如果不想自己写烧录器,也可以用 USB 转 SPI 工具直接在电脑上把 HZK16 写到 W25Q16,然后把 Flash 芯片焊到板子上。两种方式本质都是把字库文件按偏移 0 放入 Flash,运行时再通过HZK16_BASE调整起始位置。

5.4 给全字库方案加一个“常用字缓存”

从 Flash 读字模每次至少 32 字节,看上去不慢,但菜单切换时翻页会连续读几百个汉字,SPI Flash 的连续读速度和 STC 的 SPI 外设会成为瓶颈。常见的优化是加一个简单缓存:在 RAM 里开辟一个 8 条目的缓存表,每条记录“机内码 + 32 字节点阵”。显示汉字先查缓存,命中就直接用;未命中才去 Flash 读,同时把最旧的一条替换掉。

#define CACHE_NUM 8 struct cache_item { uint8_t hi; uint8_t lo; uint8_t matrix[32]; }; struct cache_item code cache_table[CACHE_NUM]; // Keil 下需要定位到 XRAM

逻辑说明:这个缓存表不需要 LRU 那么复杂的算法,因为界面文字通常按顺序刷新,直接用“最简单的 FIFO 替换”就能获得不错的命中率。RAM 占用是8 × 34 = 272字节,STC8 的 XRAM 一般有 1KB 以上,可以接受。

参数说明:CACHE_NUM越大命中率越高,但 STC 的 RAM 有限,8 条已经是常见折中。如果你的界面是按页面切换,缓存 8 个常用字足够覆盖一屏上的大部分汉字。

6. 验证与优化:自检点、画字速度与常见显示问题

6.1 用一组自检点快速定位“显示不出中文”的环节

遇到中文显示异常,不要先调字库,按下面的顺序逐级确认:

现象检查点处理方式
全屏白屏或黑屏背光、RST、CS 时序确认背光电压和复位延时
花屏、彩条混乱SPI 极性、时钟频率改 Mode 0,降低分频系数
红蓝色反了MADCTL 寄存器的 BGR 位0x000x08
能显示图形但不显示汉字字符串编码和字库编码不一致确认源文件是 GB2312 保存
汉字左右颠倒取模方向PCtoLCD2002 改“顺向”
汉字上下颠倒行扫描顺序取模方式从“逐行式”改“逐列式”再改回来

最容易忽略的是第二行:STC8 硬件 SPI 频率过高时,部分 ST7735 模组会花屏,把 SPI 时钟分频调低一档往往就好了。软件模拟 SPI 时则要注意每一拍之间加_nop_()避免信号太短。

6.2 一次 RAMWR 写入整行,替代逐点画像素

画一个 16×16 汉字,逐点调用LCD_DrawPixel意味着触发 256 次LCD_SetWindow,每次都要发送 12 个字节,效率很低。正确的做法是先把汉字按点阵展开成 RGB565 像素缓冲区,然后一次性设置窗口,连续发送全部 512 字节:

void LCD_ShowChineseBlock(uint16_t x, uint16_t y, const uint8_t *matrix, uint16_t fg, uint16_t bg) { uint8_t i, j, hb, lb; uint8_t pixel; LCD_SetWindow(x, y, x + 15, y + 15); // 固定 16×16 窗口 for (i = 0; i < 16; i++) { hb = matrix[i * 2]; lb = matrix[i * 2 + 1]; for (j = 0; j < 16; j++) { pixel = (j < 8) ? (hb & (0x80 >> j)) : (lb & (0x80 >> (j - 8))); LCD_WriteData((pixel ? fg : bg) >> 8); LCD_WriteData((pixel ? fg : bg) & 0xFF); } } }

逻辑说明:这个函数把“判断像素是否透明”和“写像素”拆开,整个汉字只调用一次LCD_SetWindow,后续 256 个像素全部通过连续 RAMWR 发送。ST7735 的显存写入指针会自动递增,不需要每写一个像素都重新设置坐标。实测在 STC8 上用 12MHz SPI 时钟,这种方式比逐点画快 8 倍以上。

参数说明:matrix指向 32 字节字模;fgbg必须是完整 RGB565 值,函数内部不再做任何坐标换算。

6.3 透明文字与反白显示的实用写法

中文菜单里高亮选中项一般用反白:前景色和背景色互换。利用上面的块写入函数,只需要交换fgbg参数,不需要改任何逻辑。透明文字则要在块写入前先把目标区域背景读回来——但 ST7735 一般不提供读显存功能,所以更常见的做法是:在应用程序里维护一个 128×160 的 RGB565 Shadow Buffer,所有绘制操作先画到缓冲区,再一次性刷到屏幕。这个方案对 RAM 要求高(128×160×2 = 40KB),STC8 系列部分型号有 32KB 以上 XRAM 才能支持;没有这么大 RAM 时,就退回原来的“画点不画背景”透明模式。最后一招是控制显示更新区域:只重绘文字附近的 16×16 小窗口,而不是全屏刷新,十六个汉字同时变化时画面依然能保持流畅。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询