资讯动态

STM32H743+RT-Thread+LVGL驱动ST77903:QSPI配置与避坑指南

发布时间:2026/10/20 8:12:09 来源:尧图企业网站定制
简介这份资源是矽创ST77903液晶驱动芯片的完整使用DEMO面向嵌入式显示开发工程师与穿戴设备方案开发者运行环境为STM32H743搭配RT-Thread与LVGL。ST77903为Sitronix小体积IC主打穿戴场景采用QSPI接口且内部不带RAM因此QSPI必须连续传输HOST端需使用专门线程完成LCD刷屏DEMO中已给出对应实现并包含3个手表表盘示例。压缩包共2591个文件以1090个h头文件、1016个c源文件为主辅以135个s汇编、69个sconscript与48个icf链接脚本另有ld、mk、Kconfig、md等构建与说明文件整体约13.66MB。目前已有2588人学习下载。读者可据此掌握QSPI连续刷屏的线程调度思路、LVGL在RT-Thread上的移植与表盘UI组织方式并参考完整工程目录快速搭建自己的穿戴显示方案。1. 拿到 ST77903 这块屏先别急着点编译STM32H743 跑 RT-Thread 再挂 LVGL最后通过 QSPI 点亮 ST77903这套组合在中小尺寸 LCD 驱动里算是相当典型的一条链路。我第一次拿到这块屏的时候以为把 DEMO 工程拖进 IDE、点一下编译下载就能亮结果屏幕黑得跟关机一样串口连个报错都没有。后来才发现问题根本不在代码而在环境——H743 的 QSPI 时钟树、RT-Thread 的 BSP 版本、LVGL 的显示缓冲区配置这三样只要有一个对不上ST77903 就是一块砖。这篇笔记就是把我踩过的坑按安装顺序重新捋一遍从工具链版本选型到 QSPI 参数配置再到烧录后怎么确认屏真的活了。适合手里有 H743 开发板、想跑通 ST77903 这套 DEMO 的开发者新手照着能走通熟手可以重点看版本差异和参数取舍那几段。2. 环境准备工具链版本和 BSP 选型2.1 工具链装什么版本STM32H743 是 Cortex-M7 内核主频能跑到 480MHz编译工具链我一般用 ARM GNU Toolchain 的 10.3 版本再新的版本在 RT-Thread 的某些 BSP 上会出现链接脚本不兼容的情况。安装方式看系统Linux 下直接解压到/opt然后加 PATH# 下载 arm-none-eabi 工具链并解压 tar -xjf gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2 -C /opt/ # 把 bin 目录加进环境变量 export PATH/opt/gcc-arm-none-eabi-10.3-2021.10/bin:$PATH # 验证版本 arm-none-eabi-gcc --version这里选 10.3 而不是更新的 12.x原因是 RT-Thread 的 H743 BSP 里有些汇编启动文件对 GCC 12 的默认优化行为敏感会出现启动阶段卡死。工具链装完后arm-none-eabi-gcc --version能正常输出就说明 PATH 生效了。如果你用 Windows装完记得把bin目录加到系统环境变量别只在当前终端set否则换个窗口就找不到编译器。2.2 RT-Thread 源码和 BSP 怎么拉RT-Thread 的源码用 git 拉但不要直接 clone masterH743 的 BSP 在特定 tag 上才稳定。我一般用 5.0.2 这个 release# 拉取 RT-Thread 源码指定稳定 tag git clone -b v5.0.2 https://github.com/RT-Thread/rt-thread.git # 进入 H743 的 BSP 目录 cd rt-thread/bsp/stm32/stm32h743-st-nucleo进到 BSP 目录后先别急着scons要确认rtconfig.py里的交叉编译工具链前缀和你的实际路径一致。常见做法是检查EXEC_PATH这一项如果它指向一个不存在的路径编译会直接报arm-none-eabi-gcc: not found。另外 H743 的 BSP 默认可能没开 QSPI需要在board/Kconfig里确认 QSPI 相关的选项存在后面用 menuconfig 才能勾上。2.3 LVGL 软件包怎么挂进来LVGL 在 RT-Thread 里是通过软件包管理器挂载的不是手动拷贝源码。在 BSP 目录下打开 env 工具执行menuconfig进到RT-Thread online packages→multimedia packages→LVGL选最新稳定版我用的 8.3.x。选完之后执行# 更新软件包把 LVGL 源码拉到 packages 目录 pkgs --update # 重新生成工程 scons --targetmdk5pkgs --update这一步会把 LVGL 的源码下载到packages/lvgl-v8.3.x目录下同时生成SConscript让构建系统能找到它。如果这一步卡住或者报网络错误常见原因是包管理器的源地址不通可以换成本地包或者手动把 LVGL 源码放到packages下再改SConscript。LVGL 挂进来之后还要在rtconfig.h里确认RT_USING_LVGL和LV_USING_...相关的宏被打开否则编译时 LVGL 的源文件根本不会被编进去。3. QSPI 和 ST77903 的配置参数一个都不能错3.1 QSPI 时钟和引脚配置STM32H743 的 QSPI 外设挂载在 AHB3 总线上时钟源一般选 PLL2Q 或者 HCLK3。我一般用 PLL2Q 分频到 100MHz 左右给 QSPI太快了 ST77903 可能吃不消。在board/CubeMX_Config里或者直接用 CubeMX 重新生成初始化代码时要确认这几个参数// QSPI 初始化关键参数在 stm32h7xx_hal_qspi.c 的 MSP 里 hqspi.Instance QUADSPI; hqspi.Init.ClockPrescaler 2; // 分频系数实际时钟 源时钟 / (21) hqspi.Init.FifoThreshold 4; // FIFO 阈值一般设 4 或 8 hqspi.Init.SampleShifting QSPI_SAMPLE_SHIFTING_HALFCYCLE; hqspi.Init.FlashSize 24; // 寻址范围ST77903 命令地址用 24 位 hqspi.Init.ChipSelectHighTime QSPI_CS_HIGH_TIME_2_CYCLE; hqspi.Init.ClockMode QSPI_CLOCK_MODE_0;ClockPrescaler这个值直接决定 QSPI 的 SCLK 频率设 2 的时候如果源时钟是 200MHz实际输出就是 66MHz 左右。ST77903 的 datasheet 里对 SCLK 上限有要求超了会出现花屏或者完全不响应。SampleShifting设半周期是为了在高速下采样更稳如果发现读回来的数据偶尔错位可以改成QSPI_SAMPLE_SHIFTING_NONE试试。引脚方面H743 的 QSPI 一般用 PB2、PB6、PD11、PD12、PE2 这几组具体看你的板子原理图别照抄 Nucleo 的引脚定义不同板子布线不一样。3.2 ST77903 初始化命令序列ST77903 是矽创的 LCD 驱动芯片初始化需要发一串厂商命令。DEMO 里一般会有一个st77903_init.c或者类似的文件里面是一张命令表。关键点在于 QSPI 发送命令时的地址模式和数据模式要匹配// 发送 ST77903 初始化命令的典型写法 static void st77903_write_cmd(uint8_t cmd, uint8_t *data, uint32_t len) { QSPI_CommandTypeDef s_command {0}; s_command.Instruction cmd; // 命令字节 s_command.InstructionMode QSPI_INSTRUCTION_1_LINE; // 命令用单线发 s_command.AddressMode QSPI_ADDRESS_NONE; // 无地址阶段 s_command.DataMode QSPI_DATA_1_LINE; // 数据单线 s_command.NbData len; s_command.DummyCycles 0; HAL_QSPI_Command(hqspi, s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE); if (len 0) { HAL_QSPI_Transmit(hqspi, data, HAL_QPSI_TIMEOUT_DEFAULT_VALUE); } }这里InstructionMode和DataMode都设成单线是因为 ST77903 的初始化阶段通常用单线模式发命令等初始化完成后再切到四线模式传像素数据。如果一开始就设成四线芯片可能还没进入 QSPI 模式命令根本收不到。DummyCycles设 0 是因为初始化命令不需要等待周期但读 ID 或者读状态的时候可能要设几个 dummy cycle具体看 ST77903 的手册。初始化命令表里一般包含软复位、像素格式设置、显示窗口设置这几组顺序不能乱尤其是软复位之后要延时足够时间再发下一条。3.3 LVGL 显示缓冲区和刷新接口对接LVGL 需要一个显示缓冲区并且要注册一个flush_cb回调把 LVGL 渲染好的像素数据通过 QSPI 发给 ST77903。缓冲区大小我一般设成屏幕宽度的 1/10 或者 1/4太小了刷新会闪太大了吃 RAM// LVGL 显示缓冲区定义和 flush 回调注册 #define DISP_BUF_SIZE (480 * 20) // 假设屏宽 480缓冲 20 行 static lv_color_t buf1[DISP_BUF_SIZE]; void lv_port_disp_init(void) { static lv_disp_draw_buf_t draw_buf; lv_disp_draw_buf_init(draw_buf, buf1, NULL, DISP_BUF_SIZE); static lv_disp_drv_t disp_drv; lv_disp_drv_init(disp_drv); disp_drv.hor_res 480; disp_drv.ver_res 320; disp_drv.flush_cb st77903_flush; // 对接 QSPI 发送函数 disp_drv.draw_buf draw_buf; lv_disp_drv_register(disp_drv); }DISP_BUF_SIZE的计算方式是屏宽乘以缓冲行数这里假设屏是 480x320。如果 RAM 紧张可以只开 10 行但刷新大面积区域时会看到明显的撕裂。flush_cb里要做的事是把lv_color_t格式的像素转成 RGB565 字节流然后调用 QSPI 的发送函数发送前记得设置 ST77903 的显示窗口坐标。常见坑是 LVGL 默认用 RGB888 或者 ARGB8888而 ST77903 初始化时设的是 RGB565两边格式对不上就会颜色错乱需要在lv_conf.h里把LV_COLOR_DEPTH改成 16。4. 避坑排查ST77903 不亮的几种典型情况4.1 屏幕全黑串口无报错现象是上电后背光亮但屏幕全黑串口没有任何 RT-Thread 的启动日志。原因通常是 QSPI 初始化失败导致系统卡在HAL_QSPI_Init里或者 ST77903 的复位引脚没被正确拉高。解决方法是先用示波器量 QSPI 的 SCLK 和 CS 引脚看初始化阶段有没有波形如果没有检查board/CubeMX_Config里 QSPI 的 GPIO 时钟是否使能。另外确认 ST77903 的 RESET 引脚在初始化前被拉低至少 10ms 再拉高很多 DEMO 里这个延时写得太短芯片没复位成功。4.2 屏幕亮但花屏颜色错乱现象是屏幕有显示但颜色明显不对比如红色显示成蓝色。原因是 LVGL 的颜色格式和 ST77903 的像素格式不匹配。ST77903 初始化命令里设的是 RGB565而lv_conf.h里LV_COLOR_DEPTH可能是 32。解决方法是把LV_COLOR_DEPTH改成 16同时确认flush_cb里发送数据时没有做多余的字节交换。如果改完还是偏色检查 QSPI 发送时的字节序STM32 的 QSPI 默认是大端发送而 LVGL 的缓冲区是小端排列需要在发送前做一次字节交换。4.3 编译报错找不到 lvgl.h现象是scons编译时提示lvgl.h: No such file or directory。原因是 LVGL 软件包没有正确更新或者SConscript里的头文件路径没包含进去。解决方法是回到 BSP 目录执行pkgs --update然后检查packages/lvgl-v8.3.x目录是否存在。如果存在但还报错手动在rtconfig.h里加上#define RT_USING_LVGL并在SConscript里确认CPPPATH包含了 LVGL 的源码根目录。4.4 烧录后跑不起来卡在 HardFault现象是下载完程序后串口输出 HardFault 信息或者直接卡死。原因可能是 H743 的 MPU 配置和 QSPI 内存映射冲突或者栈大小不够。解决方法是先在rtconfig.h里把RT_MAIN_THREAD_STACK_SIZE调大到 4096 以上LVGL 的渲染比较吃栈。如果还不行检查board/board.c里的SystemClock_Config确认 PLL2 的配置和 QSPI 时钟源一致PLL2 没使能的话 QSPI 根本拿不到时钟。4.5 QSPI 读数据偶尔出错现象是屏幕大部分正常但偶尔出现几条噪点或者局部闪烁。原因是 QSPI 采样相位不对高速下数据建立时间不够。解决方法是在hqspi.Init.SampleShifting里从QSPI_SAMPLE_SHIFTING_HALFCYCLE改成QSPI_SAMPLE_SHIFTING_NONE或者把ClockPrescaler从 2 改成 3 降低 SCLK 频率。我一般先降频验证是不是时序问题确认后再逐步调回去。5. 装完怎么验证 ST77903 真的跑通了验证这套环境不能只看屏幕亮没亮得从底层到上层逐级确认。我一般按这个顺序走一遍每一步都有明确的判断依据。第一步确认 QSPI 通信正常。在 ST77903 初始化之后加一段读 ID 的代码把读回来的值通过串口打印出来。ST77903 的 ID 一般是固定的几个字节如果读回来全是 0 或者全是 0xFF说明 QSPI 的读时序有问题回去检查DummyCycles和AddressMode。这一步能过说明硬件链路和 QSPI 配置没问题。第二步确认 ST77903 初始化命令全部生效。在发完初始化命令表之后往显示窗口里写几个纯色块比如红、绿、蓝各写一屏。如果颜色正确说明像素格式和窗口设置都对。这一步我一般直接调用st77903_write_cmd发0x2C写显存命令然后连续发几 KB 的固定颜色数据看屏幕反应。第三步确认 LVGL 能正常渲染。跑一个 LVGL 自带的lv_demo_widgets或者简单的 label 显示看文字和控件能不能画出来。如果 LVGL 画不出来但纯色块能显示问题就在flush_cb或者显示缓冲区配置上。重点检查disp_drv.hor_res和ver_res是否和实际屏幕一致以及flush_cb里有没有正确设置 ST77903 的窗口坐标。第四步确认刷新率和稳定性。让 LVGL 跑一个动画比如一个方块来回移动观察有没有撕裂或者卡顿。如果撕裂明显把DISP_BUF_SIZE调大如果卡顿检查 QSPI 的实际时钟频率和 LVGL 的LV_DISP_DEF_REFR_PERIOD设置。我一般会把刷新周期设成 30ms兼顾流畅度和 CPU 占用。验证项判断依据失败时先查QSPI 读 ID读回固定 ID 值DummyCycles、AddressMode纯色块显示红绿蓝颜色正确像素格式、窗口坐标LVGL 渲染控件和文字正常flush_cb、缓冲区大小动画刷新无撕裂、无明显卡顿缓冲区行数、QSPI 时钟这套流程走完基本能确定 ST77903 在 H743 RT-Thread LVGL 这套环境下是真的跑通了而不是碰巧亮了一下。从那以后我每次调新屏都强制先走一遍读 ID 和纯色块这两步确认底层通了再往上叠 LVGL省得在应用层瞎猜。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑