news 2026/1/15 4:55:22

STM32驱动ST7789V显示屏:手把手入门教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32驱动ST7789V显示屏:手把手入门教程

STM32驱动ST7789V显示屏:从零开始的实战指南

你有没有遇到过这样的场景?手头有一块小小的彩色TFT屏,想用STM32点亮它,却发现网上资料零碎、初始化代码莫名其妙、屏幕就是不亮——黑屏、花屏、闪屏轮番上演。

别急,今天我们不讲套话,不堆术语,就来手把手带你把一块基于ST7789V的1.3英寸TFT屏真正点亮。无论你是学生、电子爱好者,还是嵌入式工程师,只要你用的是STM32 + ST7789V组合,这篇文章都能让你少走一周弯路。


为什么是 ST7789V?

市面上常见的TFT驱动IC不少,比如 ILI9341、SSD1351、GC9A01……那为啥选ST7789V

因为它够“新”,也够“省”。

  • 支持240×320 分辨率,色彩为65K色(RGB565),画面细腻;
  • 常见于1.14”、1.3”、1.54” 圆形或矩形小屏,适合穿戴设备和紧凑型产品;
  • 内置升压电路,仅需3.3V供电即可驱动LCD偏压,外围元件极少;
  • 支持SPI接口,四线制就能搞定,比并行总线省IO;
  • 刷新速度快,静态功耗低,特别适合电池供电项目。

更重要的是,它的寄存器结构清晰,初始化流程标准化,非常适合拿来练手嵌入式图形编程。


硬件怎么接?一张图说清所有连线

我们先解决最实际的问题:STM32 和 ST7789V 模块之间到底怎么连?

大多数ST7789V模块都是以FPC或者排针形式存在,引出以下关键信号:

屏幕引脚功能说明推荐连接到 STM32
VCC电源(3.3V)MCU 3.3V 输出
GND共地
SCL / SCKSPI时钟PA5 (SPI1_SCK)
SDA / MOSI主发从收数据PA7 (SPI1_MOSI)
RES / RST复位控制PB1(任意GPIO)
DC / A0数据/命令选择PB0(任意GPIO)
CS片选PA4(可与SPI共用)
BLK / LED背光控制PA6(PWM调光更好)

✅ 提示:如果你使用的是STM32F103C8T6(蓝 pill 板),以上引脚均可用。若使用CubeMX配置,请确保启用SPI1,并设置为Mode 0 (CPOL=0, CPHA=0)

不需要MISO?对!因为这块屏只“听”不“说”,所以三线SPI完全够用。


SPI通信的核心逻辑:谁在说话?命令还是数据?

这是很多初学者卡住的第一个坑:为什么发了命令屏幕没反应?

关键在于DC 引脚的控制

  • DC = 0:你正在发送一条“命令”,比如“我要开始画图了”(0x2C);
  • DC = 1:你正在发送“数据”,比如具体的颜色值(0xF800红色);

STM32不能靠SPI自动识别这个状态,必须由软件控制一个GPIO来切换。

举个例子:

// 发送命令 HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); // 发送数据 HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, GPIO_PIN_SET); HAL_SPI_Transmit(&hspi1, &data, 1, HAL_MAX_DELAY);

这就像打电话时要说“喂”确认对方在线,再开始讲正事。漏掉这一步,屏幕根本不知道你在干嘛。


初始化序列:别照抄,要理解!

网上随便一搜,到处都是“ST7789初始化代码”,但很多人直接复制粘贴,结果屏幕不亮也不排查。

其实每款模组可能略有差异,尤其是伽马校正和电压设置部分。我们必须明白每一行在做什么。

下面这段是我经过多次调试验证后的标准初始化流程,适用于主流240x320 ST7789V模组:

void ST7789_Init(void) { // === 硬件复位 === HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, GPIO_PIN_RESET); HAL_Delay(10); HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, GPIO_PIN_SET); HAL_Delay(120); // 必须等待足够时间让内部电路稳定 // === 设置存储访问方向 === ST7789_Write_Cmd(0x36); ST7789_Write_Data(0x00); // 正常显示,RGB顺序 // === 设置颜色格式为16位 === ST7789_Write_Cmd(0x3A); ST7789_Write_Data(0x05); // RGB565 模式 // === Porch 控制(影响刷新稳定性)=== ST7789_Write_Cmd(0xB2); uint8_t porch[] = {0x0C, 0x0C, 0x00, 0x33, 0x33}; ST7789_Write_Data_Array(porch, 5); // === 门控与时序参数 === ST7789_Write_Cmd(0xB7); ST7789_Write_Data(0x35); // Gate Control ST7789_Write_Cmd(0xBB); ST7789_Write_Data(0x19); // VCOM 设定,典型值1.35V ST7789_Write_Cmd(0xC0); ST7789_Write_Data(0x2C); // AVDD = 6.8V, VRH=4.1V ST7789_Write_Cmd(0xC2); ST7789_Write_Data(0x01); // VDV enable ST7789_Write_Cmd(0xC3); ST7789_Write_Data(0x12); // VRH set to 4.1V ST7789_Write_Cmd(0xC4); ST7789_Write_Data(0x20); // VDV set ST7789_Write_Cmd(0xC6); ST7789_Write_Data(0x0F); // 帧率设为60Hz // === 功率控制 === ST7789_Write_Cmd(0xD0); ST7789_Write_Data(0xA4); ST7789_Write_Data(0xA1); // === 伽马校正(正负极性)=== ST7789_Write_Cmd(0xE0); uint8_t pos_gamma[] = {0xD0,0x04,0x0D,0x11,0x13,0x2B,0x3F,0x54,0x4C,0x18,0x0D,0x0B,0x1F,0x23}; ST7789_Write_Data_Array(pos_gamma, 14); ST7789_Write_Cmd(0xE1); uint8_t neg_gamma[] = {0xD0,0x04,0x0C,0x11,0x13,0x2C,0x3F,0x44,0x51,0x2F,0x1F,0x1F,0x20,0x23}; ST7789_Write_Data_Array(neg_gamma, 14); // === 退出睡眠模式 === ST7789_Write_Cmd(0x11); HAL_Delay(120); // === 开启显示 === ST7789_Write_Cmd(0x29); }

📌重点提醒
-HAL_Delay(120)不可省略!尤其在Sleep Out后必须延时,否则GRAM未准备好;
- 伽马表不要乱改,除非你知道自己在调色温;
- 如果你的屏幕是倒置安装,可在0x36寄存器中写入0x70实现旋转。


如何高效刷屏?地址窗口机制详解

你以为初始化完就能随便画点了?错。如果不设置“绘图区域”,你写的数据可能会被丢弃。

ST7789V 使用列地址(Column Address Set, 0x2A)行地址(Page Address Set, 0x2B)来划定一块显存区域,然后通过Memory Write (0x2C)连续写入颜色数据。

这就是所谓的地址窗口机制

void ST7789_Set_Address_Window(uint16_t x, uint16_t y, uint16_t w, uint16_t h) { uint16_t xe = x + w - 1; uint16_t ye = y + h - 1; ST7789_Write_Cmd(0x2A); // Column Address Set ST7789_Write_Data(x >> 8); ST7789_Write_Data(x & 0xFF); ST7789_Write_Data(xe >> 8); ST7789_Write_Data(xe & 0xFF); ST7789_Write_Cmd(0x2B); // Row Address Set ST7789_Write_Data(y >> 8); ST7789_Write_Data(y & 0xFF); ST7789_Write_Data(ye >> 8); ST7789_Write_Data(ye & 0xFF); ST7789_Write_Cmd(0x2C); // Prepare to write pixels }

一旦设置了窗口,接下来的所有数据都会按行优先顺序填入该区域。你可以把它想象成“选区工具”,只有在这个框里的像素才会更新。


最常用的几个绘图函数

有了地址窗口,我们就可以实现基础绘图功能了。

1. 清屏函数(快速填充整个屏幕)

void ST7789_Clear(uint16_t color) { ST7789_Set_Address_Window(0, 0, 240, 320); uint32_t count = 240 * 320; uint8_t hi = color >> 8; uint8_t lo = color & 0xFF; HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, GPIO_PIN_SET); for (uint32_t i = 0; i < count; i++) { HAL_SPI_Transmit(&hspi1, &hi, 1, HAL_MAX_DELAY); HAL_SPI_Transmit(&hspi1, &lo, 1, HAL_MAX_DELAY); } HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET); }

⚠️ 性能提示:这种方式CPU占用极高!全屏刷新约需几十毫秒(取决于SPI速率)。建议后期改用DMA传输优化。

2. 画点函数(单个像素绘制)

void ST7789_Draw_Pixel(uint16_t x, uint16_t y, uint16_t color) { if (x >= 240 || y >= 320) return; ST7789_Set_Address_Window(x, y, 1, 1); ST7789_Write_Color(color); }

虽然简单,但频繁调用会严重拖慢系统。应尽量用于调试或绘制少量元素。

3. 区域填充(推荐用于背景更新)

void ST7789_Fill_Rect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) { ST7789_Set_Address_Window(x, y, w, h); uint32_t count = w * h; uint8_t hi = color >> 8; uint8_t lo = color & 0xFF; HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, GPIO_PIN_SET); for (uint32_t i = 0; i < count; i++) { HAL_SPI_Transmit(&hspi1, &hi, 1, HAL_MAX_DELAY); HAL_SPI_Transmit(&hspi1, &lo, 1, HAL_MAX_DELAY); } HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET); }

这才是日常开发中最实用的功能:局部刷新进度条、数值框、图标底色等。


常见问题与避坑指南

别以为代码写完就万事大吉。以下是我在调试过程中踩过的坑,帮你提前绕开:

❌ 屏幕全黑,无任何反应

  • 检查RST 是否正常释放,有些模块需要持续拉低10ms以上;
  • 查看SPI是否启用 Mode 0,ST7789V要求空闲低电平、第一个边沿采样;
  • 确认CS 是否接地或始终无效,片选必须由MCU控制。

❌ 屏幕花屏、乱码、颜色异常

  • 检查SPI速率是否过高,初次测试建议不超过20MHz;
  • 验证DC引脚控制是否正确,命令和数据混淆会导致寄存器错配;
  • 确保电源干净,加0.1μF陶瓷电容靠近模块VCC引脚。

❌ 刷屏慢如蜗牛

  • 当前采用轮询方式发送每个字节,效率低下;
  • 解决方案:启用DMA + 双缓冲机制,将CPU解放出来做其他事;
  • 或者使用FSMC/QUAD-SPI(高端型号)加速传输。

❌ 背光亮但无图像

  • 很可能是未执行 0x11(Sleep Out) 或 0x29(Display On)
  • 或者延迟不足,MCU太快进入下一步操作;
  • 加上HAL_Delay(120)再试一次!

软件设计最佳实践

为了让代码更健壮、易移植,建议遵循以下原则:

✅ 封装底层操作

#define WRITE_CMD(cmd) ST7789_Write_Cmd(cmd) #define WRITE_DATA(d) ST7789_Write_Data(d)

便于将来更换平台(如ESP32、GD32)。

✅ 使用宏定义管理屏幕尺寸

#define TFT_WIDTH 240 #define TFT_HEIGHT 320

适配不同分辨率模组(如240x240圆形屏)。

✅ 添加错误日志输出(串口打印)

方便定位哪一步失败,特别是在初始化阶段。

✅ 合理安排刷新策略

  • 全屏刷新 → 每秒 ≤ 1次
  • 局部刷新 → 可达10~20fps
  • 动画效果 → 建议配合定时器+状态机

下一步可以做什么?

当你成功点亮屏幕后,真正的乐趣才刚刚开始。

🔹 接入触摸屏(XPT2046)

搭配电阻屏或电容屏,实现按钮、滑动条交互。

🔹 移植轻量级GUI库

  • LVGL :功能强大,支持动画、主题、字体渲染;
  • GUI-Guider 快速生成UI界面;
  • 甚至可以在STM32F4上跑TouchGFX(资源要求高)。

🔹 显示实时数据

  • 读取传感器(温湿度、MPU6050)并在屏幕上绘图;
  • 实现简易示波器、仪表盘、健康监测界面。

🔹 加入PWM背光调节

通过定时器输出PWM,实现亮度调节,延长续航。


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

掌握STM32驱动ST7789V的过程,本质上是在学习如何与一个复杂的外设“对话”。你需要懂硬件连接、理解通信协议、读懂数据手册、调试时序问题。

这个过程很磨人,但一旦突破,你会发现:

原来我能亲手做出一个有画面的智能设备。

无论是做一个天气时钟、迷你游戏机,还是工业HMI面板,这一切都始于今天这一块小小的彩屏。

如果你已经跟着做出来了,欢迎在评论区晒图交流。如果还有哪里卡住了,也可以留言,我们一起解决。

毕竟,每一个优秀的嵌入式工程师,都是从点亮第一块屏幕开始的。

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

ColorUI:打造惊艳小程序界面的终极视觉组件库

ColorUI&#xff1a;打造惊艳小程序界面的终极视觉组件库 【免费下载链接】coloruicss 鲜亮的高饱和色彩&#xff0c;专注视觉的小程序组件库 项目地址: https://gitcode.com/gh_mirrors/co/coloruicss 还在为小程序界面设计而苦恼吗&#xff1f;ColorUI作为一款专注于高…

作者头像 李华
网站建设 2026/1/7 7:00:46

WorkshopDL:免Steam客户端下载创意工坊模组的终极指南

WorkshopDL&#xff1a;免Steam客户端下载创意工坊模组的终极指南 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 还在为无法使用Steam创意工坊的丰富模组而烦恼吗&#xff1f;…

作者头像 李华
网站建设 2026/1/7 7:00:20

Nucleus Co-Op:单机游戏分屏多人化的技术革命

Nucleus Co-Op&#xff1a;单机游戏分屏多人化的技术革命 【免费下载链接】nucleuscoop Starts multiple instances of a game for split-screen multiplayer gaming! 项目地址: https://gitcode.com/gh_mirrors/nu/nucleuscoop 还在为那些优秀的单机游戏只能单人体验而…

作者头像 李华
网站建设 2026/1/7 6:59:58

OBS-RTSPServer插件:构建专业流媒体服务的完整指南

OBS-RTSPServer插件&#xff1a;构建专业流媒体服务的完整指南 【免费下载链接】obs-rtspserver RTSP server plugin for obs-studio 项目地址: https://gitcode.com/gh_mirrors/ob/obs-rtspserver OBS-RTSPServer是一款专为OBS Studio设计的开源插件&#xff0c;能够将…

作者头像 李华
网站建设 2026/1/7 6:59:55

城通网盘解析工具:从限速困境到高速下载的完整解决方案

城通网盘解析工具&#xff1a;从限速困境到高速下载的完整解决方案 【免费下载链接】ctfileGet 获取城通网盘一次性直连地址 项目地址: https://gitcode.com/gh_mirrors/ct/ctfileGet 还在为城通网盘那令人沮丧的下载速度而烦恼吗&#xff1f;每次看到文件下载进度条缓慢…

作者头像 李华
网站建设 2026/1/13 17:33:47

TegraRcmGUI Switch注入终极完整教程:从入门到精通

TegraRcmGUI Switch注入终极完整教程&#xff1a;从入门到精通 【免费下载链接】TegraRcmGUI C GUI for TegraRcmSmash (Fuse Gele exploit for Nintendo Switch) 项目地址: https://gitcode.com/gh_mirrors/te/TegraRcmGUI TegraRcmGUI作为基于C开发的Nintendo Switch图…

作者头像 李华