NUCLEO-H5E5ZJ 移植 ST7735 SPI LCD 驱动
3 `2 F8 P6 G( c+ p* I* S: ^ 0. 效果 LCD 显示黑底三行文字(NUCLEO-H5E5ZJ / ST7735 160x128 / SPI4 10MHz OK),下半屏每秒循环刷红→绿→蓝→白色块;串口同步打印进度。已在实物上验证通过。 1. 硬件分析1.1 LCD 扩展板
UM3601 的 Arduino 表格是双栏排版,PDF 文本提取后行列错位无法直接使用,因此直接渲染 MB2129 原理图第 5 页(Connectors)确认:
放大 CN5(Arduino D8~D15)/ CN9(D0~D7)区域:
读图结果(左侧青色为 Arduino 丝印,右侧为 MCU 引脚与复用功能): Arduino 位H5E5ZJ 引脚复用功能6 Y |6 R! }! T0 \, sD13 (SCK)PE12SPI4_SCK D12 (MISO)PE13SPI4_MISO3 D* m) D7 p" F6 s% A2 H% `$ C; E D11 (MOSI)PE14SPI4_MOSI: k. D* ?4 e: G, p- g: V# n, M D10 (NSS)PE11SPI4_NSS0 o+ x% [, G' e# _- @ D9PF4TIM2_CH4/ [5 y k; C/ z9 s4 i D8PA9TIM1_CH25 g! @' F0 ^: U- A D7PE9TIM1_CH1" b: u% v; \2 d B8 g& o1 e* ?* d D6PF3TIM2_CH3 结论:H5E5ZJ 的 Arduino SPI 是 SPI4(PE12/PE13/PE14)。LCD CS 用 D10=PE11(GPIO 软件控制),DC 用 D8=PA9(GPIO)。 1.3 pinctrl 可行性与资源冲突核对在 hal_stm32 模块的 dts/st/h5/stm32h5e5zjtx-pinctrl.dtsi 中确认四个 SPI4 引脚节点都存在: spi4_sck_pe12 / spi4_miso_pe13 / spi4_mosi_pe14 / spi4_nss_pe11同时确认无资源冲突:已移植的以太网(RMII)占用 PA1/PA2/PA5/PB12/PC1/PC4/PC5/PD1/PG12,与 SPI4 引脚、PE11、PA9 均无交叠。 2. 逐步实现第 1 步:准备驱动源码应用目录 apps/lcd_demo/ 结构如下: apps/lcd_demo/+ S. c5 R6 O- @) O( K├── CMakeLists.txt ├── prj.conf) `7 Z) L! V3 f! R6 }/ z7 I ├── boards/# V# e1 U% ~# |+ ]+ ^. n │ └── nucleo_h5e5zj.overlay ├── dts/bindings/display/# \5 x/ T: k1 I) J │ ├── uniknect,lcd-bare.yaml # display shim 绑定; a6 B' X7 e9 t# a/ m9 a) a ? U+ f │ └── uniknect,lcd-io.yaml # DC/CS GPIO 绑定(见第 3 步) └── src/ ├── main.c # 演示:刷屏 + 文字 ├── lcd_bare.c / lcd_bare.h # ST7735 裸 SPI 驱动, P0 s H' }; P+ ?* ~' _9 o5 S ├── display_bare.c # 包装成 Zephyr display API 的 shim(供 LVGL), v, h9 w0 J& [2 h └── font_petme128_8x8.h # 8×8 字库第 2 步:写板级 overlay(boards/nucleo_h5e5zj.overlay)/ { chosen { zephyr,display = &lcd_bare; };0 `- n% ] Q5 m& o , R+ d: k. r; _/ L; w /* display shim:供 LVGL */ lcd_bare: lcd-bare {& _( Q! _2 }+ ?: H0 a( N compatible = "uniknect,lcd-bare";& g( u* d5 ^7 w2 {! X- p# ]; b" ^ width = <160>; height = <128>;( C, t g# g/ y& Q! h. E status = "okay"; }; /* lcd_bare 驱动的板级 IO 配置 */ lcd_io: lcd-io { compatible = "uniknect,lcd-io";' b+ x: J- y3 j dc-gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>; /* Arduino D8 */ cs-gpios = <&gpioe 11 GPIO_ACTIVE_LOW>; /* Arduino D10 */ };$ f0 j; c; K; A! [! a - x s. F# X( @4 S; q aliases {! x3 r$ W8 ?; r7 C lcd-spi = &spi4;) [) q+ O4 c' |! F! G1 Z }; };: b! O8 c' E1 ]& Y % G$ @0 Z9 ?! b6 \# d. O5 S /* Arduino SPI(D11~D13),本板为 SPI4 */4 @/ ?( N b" @% D) T( s" ? &spi4 { pinctrl-0 = <&spi4_sck_pe12 &spi4_miso_pe13 &spi4_mosi_pe14>; pinctrl-names = "default"; status = "okay";6 }. t$ M/ _- | };第 3 步:驱动通过设备树取资源(板级无关设计) 驱动不硬编码任何引脚/总线,全部从设备树读取: static const struct device *const spi_dev = DEVICE_DT_GET(DT_ALIAS(lcd_spi));static const struct gpio_dt_spec lcd_dc = GPIO_DT_SPEC_GET(DT_NODELABEL(lcd_io), dc_gpios);: x1 |0 y/ ^; R0 i9 q1 R static const struct gpio_dt_spec lcd_cs = GPIO_DT_SPEC_GET(DT_NODELABEL(lcd_io), cs_gpios); GPIO 操作用 gpio_pin_set_dt(&lcd_dc, x) 这类按逻辑电平的 API:cs-gpios 声明为 GPIO_ACTIVE_LOW 后,set_dt(1) 即"选中",语义清晰。以后换板子只改 overlay,驱动一行不动。 第 4 步:自定义节点必须配绑定文件(踩坑点)第一次编译报错: error: 'DT_N_S_lcd_io_P_dc_gpios_IDX_0_VAL_pin' undeclared原因:lcd-io 节点若没有绑定文件,devicetree 对 <&gpioa 9 GPIO_ACTIVE_HIGH> 这种带宏的属性值无法猜出类型,GPIO_DT_SPEC_GET 需要的 VAL_pin 宏就不会生成。 修复:新建 dts/bindings/display/uniknect,lcd-io.yaml(Zephyr 会自动把应用源码目录下的 dts/bindings 加入绑定搜索路径): description: UniKnect bare LCD IO config (SPI alias + DC/CS GPIOs)2 ?4 l1 l% n6 e6 O, D1 r5 mcompatible: "uniknect,lcd-io" properties: dc-gpios: type: phandle-array% o# Y3 c6 m* y4 U/ U7 P required: true: K. g8 ^2 @# w; O! }1 A1 s7 r cs-gpios:8 u+ v8 A+ l. f6 G. q s2 _ type: phandle-array required: true 并在节点上加 compatible = "uniknect,lcd-io";。经验:自定义节点的 GPIO 属性必须在绑定里声明 type: phandle-array,不能依赖类型猜测。 第 5 步:应用骨架prj.conf: CONFIG_GPIO=y, d3 [8 \ O- _8 J- L! x$ OCONFIG_SPI=y# a: u* }, ^7 m. C CONFIG_DISPLAY=y CMakeLists.txt: cmake_minimum_required(VERSION 3.20.0)find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(lcd_demo) target_sources(app PRIVATE src/main.c src/lcd_bare.c src/display_bare.c) main.c 演示逻辑:display shim 在 POST_KERNEL 阶段自动完成 LCD 初始化(display_bare_init → lcd_bare_init),main 延时 500 ms 后直接调 lcd_bare_fill / lcd_bare_text / lcd_bare_fill_rect 刷屏和写文字。 第 6 步:编译、烧录、验证cd /d/luglZephyrprojectexport ZEPHYR_SDK_INSTALL_DIR=/d/luglZephyrproject/zephyr-sdk-1.0.1/zephyr-sdk-1.0.1/ c; i% ~6 x2 t3 C west build -b nucleo_h5e5zj /d/STM32/STM32H5E5/NUCLEO_H5E5ZJ/apps/lcd_demo \ -d build_h5e5_lcd -p always -- -DBOARD_ROOT=D:/STM32/STM32H5E5/NUCLEO_H5E5ZJ% h# L9 I$ {" q, S/ I west flash -d build_h5e5_lcd 实测结果:LCD 正常点亮,文字与四色刷屏显示正确,SPI4 @ 10 MHz 工作正常,串口日志同步输出 lcd_demo: fill RED/GREEN/BLUE/WHITE。 3. 引脚速查表LCD 信号Arduino 位H5E5ZJ 引脚外设; b- C! J. J; k9 K$ F/ qSPI_SCKD13PE12SPI4_SCK SPI_MISOD12PE13SPI4_MISO6 ]. L$ `% D, V6 | SPI_MOSID11PE14SPI4_MOSI LCD CSD10PE11GPIO(软件控制) LCD DCD8PA9GPIO 背光—硬件常亮无需控制6 H( p, K! }. Z' J( {! y RST—板级复位线无需控制4. 经验总结
nucleo_h5e5zj_lcd_demo.zip
(11.16 KB, 下载次数: 0)
|
NUCLEO-H5E5ZJ 移植 LVGL
NUCLEO-H5E5ZJ 以太网(Ethernet)移植记录
【STM32H5 评测】1、移植记录(LED / Shell)
【STM32H5 评测】介绍、环境搭建、工程测试
架构革新篇:单芯片 GUI 方案原理与核心优化技术
【新品发布】STM32H543/H553 新品登场
STM32C542RC开发板实现长短按键识别功能
STM32C542RC开发板PWM呼吸灯实验
STM32C542RC开发板的串口不定长数据接收实验
《STM32CubeMX2 实战课程》学习笔记——STM32C562RE开发测试
微信公众号
手机版