news 2026/4/16 12:37:48

手把手教程:STM32连接ST7789彩色屏

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手把手教程:STM32连接ST7789彩色屏

从零开始点亮一块彩色屏:STM32驱动ST7789实战全解析

你有没有过这样的经历?手里的STM32板子跑得飞快,传感器数据一串串往外冒,可就是“看不见”结果。没有屏幕,一切交互都像在黑暗中摸索。

直到有一天,你在某宝花十几块钱买了块1.3英寸的圆形或矩形小彩屏,标着“ST7789驱动”,心想:“这玩意儿能接上吗?”
答案是:不仅能接,还能玩出花来。

今天我们就以最典型的场景——STM32通过SPI驱动ST7789 TFT彩屏——展开一次深度实战教学。不讲空话,只说你怎么一步步把黑屏变Logo,再变成图形界面。全程基于真实开发经验,连坑带路一起奉上。


为什么是 ST7789?

市面上的TFT驱动芯片不少,ILI9341、SSD1351、ILI9488……但如果你最近买过小尺寸彩屏模块(尤其是1.14”~2.0”),大概率会发现背面印着“ST7789”。这不是巧合。

它火是有原因的:

  • 体积小:常见于COG封装,适合紧凑设备;
  • 速度快:SPI支持高达60MHz,刷屏比很多前辈快一倍;
  • 功耗低:待机电流不到10μA,电池项目友好;
  • 分辨率适中:主流240×320,刚好够用又不吃内存;
  • RGB565原生支持:每像素2字节,颜色够真,存储压力小;
  • 旋转无裁剪:MADCTL寄存器一设,横竖屏自由切换,不像某些老IC转了就缺角。

更关键的是——便宜量足,资料齐全。正适合我们这种想快速做出效果又不想烧脑的设计者。


硬件怎么连?一张表搞定

先别急着写代码,先把线接对。错一个引脚,后面全是白忙活。

我们以最常见的STM32F103C8T6(蓝pill) + ST7789 SPI接口模块为例,使用四线SPI模式(SCK、MOSI、CS、DC、RST),这是最通用也最稳妥的选择。

STM32 引脚连接到模块功能说明
PB13SCL / SCKSPI时钟
PB15SDA / DIN数据输入(主发从收)
PB12CS片选,低有效
PB11DC高=数据,低=命令
PB10RST复位,低电平重启
3.3VVCC注意!不是5V供电!
GNDGND共地必接
BLK / LED背光控制(可悬空或接PWM)控制亮度

⚠️ 重要提醒:
- 所有信号线建议加1kΩ上拉或串联电阻防干扰;
- 模块供电务必为3.3V!虽然有些标称兼容5V逻辑,但IO耐压可能不足;
- 若使用杜邦线调试,请尽量短且远离电机、继电器等噪声源。

连接完成后,通电前再检查一遍。我曾因把VCC接到5V烧掉三块屏——别问我是怎么知道的。


初始化不是“发几条命令”那么简单

你以为初始化就是照着手册抄一堆WriteCmd(0x11); WriteCmd(0x3A); ...
错。顺序、延时、参数配置,一步都不能少。

ST7789上电后处于睡眠状态,必须按特定流程唤醒并配置内部寄存器。否则你会看到一片灰屏、花屏,甚至完全没反应。

关键初始化步骤拆解

void ST7789_Init(void) { // 步骤1:硬件复位 RESET_HIGH(); HAL_Delay(10); RESET_LOW(); // 拉低至少10ms HAL_Delay(10); RESET_HIGH(); // 释放复位 HAL_Delay(120); // 等待内部电路稳定 // 步骤2:退出睡眠模式 ST7789_WriteCmd(0x11); // Sleep Out HAL_Delay(120); // 必须等待足够时间! // 步骤3:设置颜色格式为 RGB565 ST7789_WriteCmd(0x3A); uint8_t pixel_format = 0x55; // 16-bit/pixel ST7789_WriteData(&pixel_format, 1); // 步骤4:配置显示方向(重点!) ST7789_WriteCmd(0x36); uint8_t madctl = 0xC0; // 示例:正常竖屏显示 ST7789_WriteData(&madctl, 1); // 步骤5:开启显示 ST7789_WriteCmd(0x29); // Display ON }

到底什么是 MADCTL?

很多人卡在这里:明明代码没错,为啥图像倒着、歪着、被切了一半?

答案就在0x36命令——Memory Access Control,简称 MADCTL。

它控制GRAM(显存)如何映射到物理屏幕坐标。8个bit各有含义:

Bit含义
7MY: 行地址递增方向(0=自顶向下)
6MX: 列地址递增方向(0=从左到右)
5MV: 行列交换(旋转90度)
4ML: 扫描方向(很少用)
3RGB/BGR 顺序(0=RGB, 1=BGR)
2-0保留

常用组合如下:

显示方向MADCTL值效果
竖屏,正常0x000xC0上下左右正确
横屏,顺时针旋转90°0x70宽高互换,适合横向布局
竖屏,上下翻转0x40图像颠倒
横屏,镜像0xA0左右反向

你可以根据实际安装方向调整这个值,无需改动绘图逻辑。


如何画一个矩形?别小看这一步

有了初始化,下一步就是让屏幕“动起来”。最基础的操作是填充区域。

下面这个函数实现任意矩形区域的颜色填充,是后续所有图形绘制的基础。

void ST7789_FillRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) { uint8_t buf[4]; // 设置列范围 (CASET) ST7789_WriteCmd(0x2A); buf[0] = (x >> 8) & 0xFF; buf[1] = x & 0xFF; buf[2] = ((x + w - 1) >> 8) & 0xFF; buf[3] = (x + w - 1) & 0xFF; ST7789_WriteData(buf, 4); // 设置行范围 (RASET) ST7789_WriteCmd(0x2B); buf[0] = (y >> 8) & 0xFF; buf[1] = y & 0xFF; buf[2] = ((y + h - 1) >> 8) & 0xFF; buf[3] = (y + h - 1) & 0xFF; ST7789_WriteData(buf, 4); // 开始写GRAM ST7789_WriteCmd(0x2C); // RAMWR DC_HIGH(); CS_LOW(); uint8_t color_bytes[2]; color_bytes[0] = (color >> 8) & 0xFF; color_bytes[1] = color & 0xFF; // 循环发送 w * h 次颜色 for (int i = 0; i < w * h; i++) { HAL_SPI_Transmit(&hspi2, color_bytes, 2, HAL_MAX_DELAY); } CS_HIGH(); }

性能瓶颈在哪?

上面这段代码有个致命问题:逐像素发送,效率极低

假设你要填满整个240×320屏幕(共76,800像素),每个像素传2字节,总共要调用HAL_SPI_Transmit()76,800 次!即使SPI跑在18MHz,也要接近半秒才能刷完一帧——卡成幻灯片。

怎么办?两个字:批量传输 + DMA


提速秘诀:DMA让CPU解放出来

STM32的SPI支持DMA,意味着你可以告诉外设:“我要发一大段数据,你自己去搬,别打扰我。”

改写后的高效版本:

void ST7789_FillRectangle_DMA(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) { // 设置区域(同上) ST7789_SetAddressWindow(x, y, x+w-1, y+h-1); ST7789_WriteCmd(0x2C); // 准备缓冲区(静态或DMA专用SRAM) static uint16_t line_buffer[128]; // 每次发128像素 for (int i = 0; i < 128; i++) { line_buffer[i] = color; } uint32_t total_pixels = w * h; DC_HIGH(); CS_LOW(); while (total_pixels > 0) { uint16_t chunk = (total_pixels > 128) ? 128 : total_pixels; HAL_SPI_Transmit_DMA(&hspi2, (uint8_t*)line_buffer, chunk * 2); // 等待DMA完成(实际应用可用中断) while (HAL_SPI_GetState(&hspi2) != HAL_SPI_STATE_READY); total_pixels -= chunk; } CS_HIGH(); }

这样,CPU只需启动几次DMA传输,就能完成整屏刷新,刷屏速度提升3~5倍,动画流畅多了。

💡 小贴士:更高阶玩法可以用双缓冲+定时器自动翻页,实现类似“垂直同步”的效果。


实战技巧:绕开RAM不足的大坑

STM32F1系列只有20KB SRAM,而一帧240×320×2B = 153,600 字节 ≈150KB,根本放不下!

难道就不能做复杂UI了吗?当然可以,关键是策略:

✅ 策略一:局部刷新(Partial Update)

只更新变动的部分。比如时钟界面,数字变了才重绘那一块区域,背景不动。

// 只刷新时间区域 ST7789_FillRectangle(50, 100, 140, 40, BLACK); ST7789_DrawString("14:25:36", 50, 100, WHITE, &Font16);

✅ 策略二:虚拟帧缓冲(Virtual Framebuffer)

开辟一个小缓存(如一行或一列),边渲染边发送,节省内存。

✅ 策略三:直接绘图法

不用存整帧,而是每次根据状态重新绘制所有元素。虽然重复计算,但省空间。

void Redraw_Screen(float temp, float humi) { ST7789_FillScreen(BLACK); ST7789_DrawText("Temp:", 10, 10, GREEN, &Font12); ST7789_DrawNumber(temp, 80, 10, RED, &Font12); ST7789_DrawText("Humi:", 10, 30, BLUE, &Font12); ST7789_DrawNumber(humi, 80, 30, CYAN, &Font12); }

对于静态或低频更新界面,完全够用。


常见问题与避坑指南

❌ 问题1:屏幕一闪而过就黑了

原因:忘记发0x29(Display ON)或者初始化延时不够。
解决:确保HAL_Delay(120)0x11之后。

❌ 问题2:颜色不对,偏红或偏蓝

原因:RGB/BGR顺序错误。
解决:检查 MADCTL 第4位是否设置正确;或在软件层面交换R/B分量。

❌ 问题3:SPI通信失败,HAL返回BUSY

原因:SPI时钟太快,或线路干扰。
解决:降低波特率预分频(如fPCLK/16),增加100Ω串联电阻。

❌ 问题4:背光亮但无图像

原因:DC引脚接错或未正确切换。
解决:用示波器测DC线,确认命令/数据切换正常。

❌ 问题5:屏幕发热严重

原因:长时间全白显示 + 高亮度背光。
解决:启用自动休眠,或PWM调光至60%以下。


加点料:让它不只是“显示器”

当你掌握了基本驱动,就可以往上叠加功能了:

🔹 加触摸屏(XPT2046)

用SPI另一组引脚接电阻式触摸控制器,实现按钮点击、滑动检测。

🔹 接LVGL图形库

将ST7789驱动注册为LVGL的显示接口,轻松做出按钮、进度条、图表。

lv_disp_draw_buf_init(&draw_buf, buffer, NULL, BUFFER_SIZE); lv_disp_drv_init(&disp_drv); disp_drv.flush_cb = my_flush_cb; // 绑定到 ST7789_WritePixels disp_drv.draw_buf = &draw_buf; lv_disp_drv_register(&disp_drv);

🔹 显示图片(BMP/JPEG)

把图片转为C数组存Flash,解码后逐行写入GRAM。圆形屏还能做圆形裁剪。

🔹 动态图表

采集传感器数据,用线条或柱状图实时展示趋势,比数字直观得多。


写在最后:这不是终点,而是起点

“STM32 + ST7789”看似只是一个简单的彩屏方案,但它背后是一整套嵌入式图形系统的核心能力训练:

  • 外设驱动编写
  • 时序控制理解
  • 内存管理权衡
  • 性能优化实践
  • HMI设计思维

这些经验,远比“点亮LED”深刻得多。

下次当你看到一块小小的圆形彩屏,不要再觉得它只是装饰品。
它是你通往智能设备人机交互世界的第一扇门。

而现在,钥匙已经在你手里了。

如果你正在做一个需要本地显示的项目,不妨试试这块十几块钱的小屏幕。也许你会发现,让机器“看得见”,才是真正的开始。

有疑问?遇到花屏、乱码、刷不动?欢迎留言交流,我们一起踩过的坑,都是成长的印记。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/5 5:23:35

Qwen3-VL支持多语言混合OCR:中英日韩混排文本准确提取

Qwen3-VL支持多语言混合OCR&#xff1a;中英日韩混排文本准确提取 在跨境电商平台审核商品标签时&#xff0c;一张包装图上往往同时出现中文品牌名、英文成分表、日文产地信息和韩文保质期说明。传统OCR工具面对这种多语言混排场景时&#xff0c;常常因为语种切换失败而产生乱码…

作者头像 李华
网站建设 2026/4/16 10:41:40

Qwen3-VL识别UltraISO界面元素:制作新手引导教程自动化

Qwen3-VL识别UltraISO界面元素&#xff1a;制作新手引导教程自动化 在日常使用电脑软件的过程中&#xff0c;很多人可能都遇到过这样的场景&#xff1a;第一次打开某个工具&#xff0c;面对密密麻麻的按钮和菜单不知所措。比如用 UltraISO 制作启动U盘时&#xff0c;“新建”在…

作者头像 李华
网站建设 2026/4/15 22:37:56

Qwen3-VL支持高级具身AI:结合空间接地实现机器人指令生成

Qwen3-VL支持高级具身AI&#xff1a;结合空间接地实现机器人指令生成 在智能体不再满足于“看”和“说”&#xff0c;而是要真正“做”的今天&#xff0c;AI系统正从被动响应走向主动干预物理世界。这一跃迁的核心挑战在于&#xff1a;如何让模型不仅理解图像中的物体&#xf…

作者头像 李华
网站建设 2026/4/15 20:30:43

突破百度网盘下载瓶颈:直链解析技术深度揭秘

还在忍受百度网盘的龟速下载吗&#xff1f;当别人已经在享受高速下载的流畅体验时&#xff0c;你是否还在为几十KB的下载速度而焦虑&#xff1f;今天&#xff0c;我们将深入探讨一项能够彻底改变你下载体验的技术——百度网盘直链解析。这项技术通过获取真实的文件下载地址&…

作者头像 李华
网站建设 2026/4/15 18:00:59

iOS微信助手终极指南:解锁自动抢红包与功能增强

iOS微信助手终极指南&#xff1a;解锁自动抢红包与功能增强 【免费下载链接】WeChatRedEnvelopesHelper iOS版微信抢红包插件,支持后台抢红包 项目地址: https://gitcode.com/gh_mirrors/we/WeChatRedEnvelopesHelper 还在为错过微信群里的红包而烦恼吗&#xff1f;2025…

作者头像 李华
网站建设 2026/4/15 17:21:20

downkyi视频下载工具:小白也能轻松掌握的B站高清资源获取方法

downkyi作为一款专为哔哩哔哩用户设计的视频下载工具&#xff0c;让普通用户也能轻松获取从标清到8K超高清的完整视频资源。无论是日常学习资料还是高清娱乐内容&#xff0c;都能快速保存到本地永久收藏。 【免费下载链接】downkyi 哔哩下载姬downkyi&#xff0c;哔哩哔哩网站视…

作者头像 李华