
简介面向智能手表与穿戴设备显示开发的ST77903实战DEMO基于STM32H743、RT-Thread与LVGL构建重点解决Sitronix小体积LCD驱动IC无内置显存、QSPI必须连续传输的难点。工程在HOST侧设置专门刷屏线程演示QSPI持续搬运与LVGL刷新协同并内置3个手表表盘便于理解UI框架、显示驱动与RTOS任务划分的配合方式。压缩包共2591个文件、约13.66MB以C/H源码、汇编启动文件、链接脚本与ICF配置、SConscript构建脚本及说明文档为主兼有少量图片、PDF与工程配置目录覆盖驱动、系统移植和构建配置。已有2592人学习适合具备STM32与RT-Thread基础、希望掌握QSPI屏连续刷屏与LVGL穿戴UI落地的开发者参考。可从中获取表盘UI组织、刷屏线程设计、QSPI时序调试与多文件工程构建的完整思路。1. 拿到 ST77903 DEMO 却卡在第一步STM32H743 环境先列清上周帮一个做工业面板的团队处理 ST77903 点亮问题板子焊好了、屏也贴上了QSPI 一接上电却是满屏花点——他们并不是不会写代码问题在于 DEMO 的环境没有准备好RT-Thread 版本、LVGL 版本、QSPI 时钟和 ST77903 的初始化序列只要有一处对不上屏幕就会黑屏或花屏。矽创 ST77903 是 400×400 的圆形 AMOLED 常用驱动 IC接口走 QSPI自带显存对时序相当严格。看着只是“跑个 DEMO”实际却是 STM32H743 RT-Thread LVGL QSPI ST77903 五层环境叠在一起装不好就会变成一个难以排查的问题。这篇笔记写的是我按顺序把这套环境装过一遍的过程适合刚从仓库下载 DEMO 就想直接烧录的开发者也适合要在 H743 上复现 QSPI 屏驱动的熟手。2. 环境准备ST77903 SITRONIX LCD 依赖的版本与工具链在动手建工程之前先把“装什么”确定下来。ST77903 SITRONIX LCD 这套组合里最容易出错的就是版本之间的隐性依赖RT-Thread 的 SPI/QSPI 框架在 5.x 前后改动不小LVGL 8 和 9 的显示接口几乎不一样而 ST77903 的 DEMO 往往只针对某一个组合验证过。我一般会先做一张版本对照表再逐项安装避免边装边猜。2.1 版本对照H743 RT-Thread LVGL 的兼容矩阵下表是我在这块 STM32H743 上实际跑通的一组组合。它不代表唯一答案但作为起点是安全的如果已经在用更新的 LVGL请优先看lv_port_disp是否还保留原名而不是硬把旧代码搬过去。组件推荐版本说明STM32H743任意 H743VI/H743ZI 板主频 480MHzQSPI 内核时钟需在 200MHz 以下配置RT-Thread5.0.x 或 5.1.x使用BSP_USING_QSPI与RT_USING_SPI框架LVGL8.3.x显示接口为disp_drv.flush_cb与 9.x 不通用ST77903 驱动随 DEMO 附带的.c初始化序列初始化命令表必须与供应商给的版本一致工具链arm-none-eabi-gcc 10 及以上或 Keil MDK 5.3xGCC 与 MDK 二选一不要中途更换构建方式scons menuconfig用于裁剪 RT-Thread 与 LVGL 组件版本确定后还要确认一点STM32H743 的 QSPI 与常规 SPI 是两套外设。ST77903 走的是四线 QSPI不是 SPI1、SPI2如果 DEMO 的底层用rt_spi_*接口去驱动就要检查它有没有做单线模拟四线的“补丁”。这一点如果不先确认装完之后真是会排查很久。2.2 工具链与工程骨架搭建先安装工具链GCC 路径加进环境变量后用一行命令确认版本。这里给的是 Linux 和 macOS 下常见做法Windows 下建议用官方 ARM 工具链压缩包解压后手动加入 PATH不要用包管理器随意安装一个不匹配的版本。# 安装 arm-none-eabi 工具链以 10.3 为例版本以实际安装包为准 arm-none-eabi-gcc --version # 确认输出含 10.3 或以上 scons --version # RT-Thread 构建依赖 scons接下来拉取 RT-Thread 源码并切换到对应 BSP。STM32H743 的 BSP 一般位于bsp/stm32/stm32h743-xxx不同开发板的 BSP 目录名称略有差异以仓库实际结构为准不要照搬路径。# 获取 RT-Thread 主仓库源码 git clone https://github.com/RT-Thread/rt-thread.git cd rt-thread/bsp/stm32/stm32h743-xxx # 注意替换成自己板子的 BSP 目录 scons --menuconfig # 进入配置界面准备开启 QSPI 与 LVGL命令背后的逻辑不复杂scons --menuconfig负责裁剪组件决定编译哪些驱动进来scons负责按 Kconfig 生成.config并调用交叉编译。这里有个习惯可以省很多时间配置完成后先执行一遍scons让空工程完整编译通过再往里加 ST77903 驱动和 LVGL。如果空工程都编译不过就根本不是屏的问题。2.3 QSPI 与引脚配置先确认外设归属再写代码/* stm32h743 QSPI 引脚初始化片段具体引脚以板级原理图为准 */ static void qspi_pin_init(void) { /* QSPI_CLK / QSPI_NCS / QSPI_IO0~IO3 全部复用为 AF10 */ GPIO_InitTypeDef gpio {0}; gpio.Mode GPIO_MODE_AF_PP; gpio.Pull GPIO_NOPULL; gpio.Speed GPIO_SPEED_FREQ_VERY_HIGH; gpio.Alternate GPIO_AF10_QUADSPI; /* 逐个初始化 CLK/NCS/IO0..IO3漏掉 IO2/IO3 会退化成单线 */ HAL_GPIO_Init(QSPI_GPIO_PORT, gpio); }要注意的是QSPI 的四条数据线必须全部配置为复用功能只要漏掉 IO2 或 IO3驱动就只会以单线模式运行。可以正常显示图像但刷新速度会慢到让你怀疑人生。QSPI 内核时钟建议先降到 100MHz 左右调通再逐步提高到板子能稳定运行的频率不要一上来就拉满。3. 工程集成把 ST77903 驱动和 LVGL 接进 RT-Thread环境装好了接下来是“怎么装进去”。这一步的目标很明确让 QSPI 能发命令让 ST77903 能收到初始化序列再让 LVGL 的刷新回调最终写到屏上。三者串起来的关键是接口对齐任何一层接口签名不匹配编译能过但屏幕不会亮。3.1 开启 RT-Thread 的 QSPI 与 SPI 框架进入menuconfig后依次确认RT-Thread Components → Device Drivers → Using SPI Bus/Device device drivers打开同时在 BSP 的 board 配置里打开BSP_USING_QSPI。很多 BSP 默认只开了 SPI没开 QSPI编译时驱动源文件根本不会参与现象就是“函数找不到定义”。# 配置项检查编译前确认这两个宏在 rtconfig.h 里存在 grep -E RT_USING_SPI|BSP_USING_QSPI rtconfig.h如果BSP_USING_QSPI没有出现不用怀疑代码写错了回到 menuconfig 里的 BSP 外设选项逐级确认有些 BSP 把 QSPI 放在On-chip Peripheral下面位置与 SPI 不在一处找的时候得有耐心。3.2 ST77903 初始化序列的移植要点ST77903 的初始化是一张大命令表供应商给的 DEMO 里通常是st77903_init_cmd[]这样的数组每条包含命令、数据长度、数据内容。移植的时候最忌讳“看差不多就复制”因为里面包含像素格式、圆形屏的窗口设置和 Gamma 参数删几条可能还能亮但颜色会偏。/* ST77903 初始化先软复位再按顺序下发供应商命令表 */ static int st77903_init(void) { st77903_write_cmd(0x01); /* 软件复位等待 120ms 稳定 */ rt_thread_mdelay(120); for (int i 0; i ARRAY_SIZE(st77903_init_cmd); i) { /* 每条命令按 cmd len data 的结构依次下发 */ st77903_write_cmd(st77903_init_cmd[i].cmd); if (st77903_init_cmd[i].len) st77903_write_data(st77903_init_cmd[i].data, st77903_init_cmd[i].len); } return 0; }代码后要说明两点st77903_write_cmd与st77903_write_data在 QSPI 模式下通常是靠命令字的高位区分“命令/数据”不同 DEMO 写法不同移植时以原 DEMO 的底层实现为准。另外软复位后的延时不能省AMOLED 面板上电稳定需要时间时间不够时表现就是偶发白屏重启几次又能亮非常容易误判成焊接问题。3.3 LVGL 显示接口对接flush_cb 是唯一入口LVGL 8.x 只认一个显示接口disp_drv.flush_cb。ST77903 自带显存所以这里有两种接法——一种是让 LVGL 直接往屏幕坐标区域写另一种是 LVGL 画到内存 buffer 再整块刷过去。DEMO 里常见的是第二种配合圆形屏的窗口命令使用。/* LVGL 8.x 显示刷新回调把 LVGL 的缓冲区刷到 ST77903 指定窗口 */ static void disp_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_p) { /* 先设置窗口区域再连续写像素数据 */ st77903_set_window(area-x1, area-y1, area-x2, area-y2); st77903_write_pixels((uint8_t *)color_p, lv_area_get_width(area) * lv_area_get_height(area) * 2); lv_disp_flush_ready(drv); /* 必须调用否则 LVGL 停在等待状态 */ }这里最容易忽略的是最后那行lv_disp_flush_ready。如果忘了调用LVGL 会一直认为上一次刷新没结束界面就停在那里不动日志也没有报错。另一个参数是颜色深度ST77903 一般用 RGB565那么 LVGL 的LV_COLOR_DEPTH必须设成 16设成 32 会在屏上看到错位和偏色看起来像驱动坏了实则只是宏没对齐。3.4 编译下载与第一次点屏验证# 编译并生成可烧录文件具体输出名依赖 BSP 配置 scons -j8 # 使用 openocd 烧录接口与目标按实际调试器修改 openocd -f interface/stlink.cfg -f target/stm32h7x.cfg \ -c program rtthread.elf verify reset exit烧录后先看串口日志确认 ST77903 初始化函数返回成功、LVGL 心跳在跑。第一次点屏不要急着上复杂界面先刷纯色块红绿蓝各刷一次能稳定切换就说明 QSPI 写数据和窗口设置都对了。如果颜色对调那是 RGB565 的字节序问题改一下lv_conf.h里的交换选项即可不用动驱动。4. 避坑排查ST77903 QSPI 组合最常见的五种翻车这套环境能正常跑起来往往不是因为装得顺利而是因为遇到问题后知道该检查什么。下面几条都是我在 H743 上实际遇到过的按“现象 → 原因 → 解决”记录供对照排查。4.1 花屏或雪花点现象上电后屏幕不是黑屏而是随机彩色噪点有时重启一次就正常。原因多半在 QSPI 时序时钟频率超过面板能承受的范围或者初始化序列没有完整下发。解决是先降到 50~80MHz 调通再把st77903_init的命令表逐条对着供应商版本核对重点看软复位后有没有等待足够延时。还有一种情况是 QSPI 的 dummy cycles 设置不对读 ID 能过、写像素就乱这类问题必须回到 QSPI 参数里改。4.2 屏幕全黑但串口日志正常现象初始化函数返回成功LVGL 也在跑但屏幕一点反应都没有。原因通常是背光或供电没开AMOLED 面板一般有独立的使能脚和电压轨DEMO 里可能有一句st77903_display_on()藏在初始化末尾被裁剪掉了。解决是回到原理图确认使能引脚在初始化后手动拉高再发一次 Display ON 命令常见为 0x29。4.3 编译报错找不到 QSPI 相关函数现象驱动源文件里调用的 QSPI 接口全部报未定义。原因是没有打开 RT-Thread 的对应框架或者 BSP 没有把 QSPI 源文件加入编译。解决是回到 menuconfig 打开BSP_USING_QSPI与 SPI 设备框架然后执行一次scons --targetmdk5或重新生成 Makefile让新加的源文件进入工程。只改配置不重新生成工程是这一条最常见的遗漏。4.4 界面能显示但刷新极慢现象静态画面正常一动就卡顿帧率低到个位数。原因一般是 QSPI 退化成了单线模式或者 LVGL 缓冲区开得太小导致频繁分块刷新。解决是先确认 IO2、IO3 是否配置成复用再在lv_conf.h里把LV_DISP_DEF_REFR_PERIOD和缓冲区大小调整到合理值。H743 内存够用缓冲区开到屏幕的十分之一大小是常见做法。4.5 烧录后反复重启现象程序跑几秒就复位串口打印到一半断掉。原因大多在中断优先级或栈溢出QSPI 中断优先级高于 RT-Thread 的系统调度或者 LVGL 的绘制线程栈给小了。解决是检查NVIC优先级分组保证 QSPI 中断不高于系统节拍中断同时把 LVGL 线程栈从默认值加大到 8KB 以上再试。5. 装完怎么验证三个动作确认 ST77903 真的跑通环境装完不代表跑通必须有一组可以重复执行的验证动作。我一般在第一次调通后固定做三件事读 ID、刷色块、跑帧率三步都过才算这套 STM32H743 RT-Thread LVGL QSPI 环境真正可用。5.1 读 ID 与命令回读验证/* 读取 ST77903 的 ID确认 QSPI 双向通信正常 */ uint32_t id st77903_read_id(); rt_kprintf(ST77903 ID: 0x%06X\n, id); /* 与手册给出的 ID 值比对 */读 ID 通过说明命令通道没问题但它不能证明数据通道正常。有些板子读 ID 正常、写像素就异常所以必须继续做第二步。这里也是黑匣子思维的用处把 ID、初始化返回值、LVGL 心跳三行日志都打出来出问题时能立刻定位是通信还是刷新环节。5.2 色块与圆形屏边界验证验证项操作通过标准纯色填充依次刷红、绿、蓝全屏颜色正、无噪点、切换无残影圆形边界在四角与圆心各画一个矩形边缘不越界、圆形区域外不显示局部刷新只刷新屏幕中心 100×100 区域其余区域保持不变帧率持续刷新动画 30 秒无明显卡顿、日志无复位色块验证能暴露大部分窗口设置错误。ST77903 是圆形屏如果窗口命令里的坐标没有按屏的可见区域处理四角会出现本不该显示的像素这一点在纯黑背景上尤其明显。5.3 稳定性烤机与参数回退习惯最后一件事是让画面连续跑半小时以上同时观察串口有没有异常复位日志用手背轻触主控和屏排线附近确认没有明显发热。QSPI 频率如果是在临界值上调通的短时间看不出来跑久了才会偶发花屏所以烤机这一步不要省。从那以后我每次在新板子上跑 ST77903 的 DEMO都强制先走一遍“读 ID → 刷三色 → 烤机半小时”的流程再往上叠 UI。这套流程本身不复杂难的是忍住不跳步。希望这套顺序也能帮到你少在花屏和黑屏之间来回折腾。本文还有配套的精品资源点击获取