NUCLEO-H5E5ZJ 移植 ST7735 SPI LCD 驱动
* D# j- m- c6 L5 L" n4 ] 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 引脚复用功能D13 (SCK)PE12SPI4_SCK D12 (MISO)PE13SPI4_MISO D11 (MOSI)PE14SPI4_MOSI D10 (NSS)PE11SPI4_NSS& ^) |0 Y' U0 E4 Q) Y9 L: o D9PF4TIM2_CH4 D8PA9TIM1_CH22 p5 U3 S! B- l7 Z3 w# z; A1 x D7PE9TIM1_CH17 B2 E& W' v6 ^ }% g 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/8 l# Q) N+ o5 ]! m% }3 i) U├── CMakeLists.txt0 G% p- y$ E* @# J1 e' ^$ O7 R ├── prj.conf3 K) }9 r1 V% n4 ^' g& m4 A/ r ├── boards/ │ └── nucleo_h5e5zj.overlay ├── dts/bindings/display/% I6 e$ O: d& U; @ │ ├── uniknect,lcd-bare.yaml # display shim 绑定! U3 S9 L f; m │ └── uniknect,lcd-io.yaml # DC/CS GPIO 绑定(见第 3 步)! b. W7 x& s4 e6 U: Y7 s1 c └── src/ ├── main.c # 演示:刷屏 + 文字 ├── lcd_bare.c / lcd_bare.h # ST7735 裸 SPI 驱动3 J; Z. P; t9 O" a i, l3 w: p ├── display_bare.c # 包装成 Zephyr display API 的 shim(供 LVGL)9 [8 Y8 \9 `2 d4 T+ t- _/ E └── font_petme128_8x8.h # 8×8 字库第 2 步:写板级 overlay(boards/nucleo_h5e5zj.overlay)/ {5 Q$ s1 r5 V/ C( C5 H* r chosen {8 S- R4 w5 t' d zephyr,display = &lcd_bare;- o) S' p, T( A9 u$ r* } }; 2 U6 ?2 g! Y; S /* display shim:供 LVGL */1 L) h% z6 a) _% Z' S& e: G lcd_bare: lcd-bare { compatible = "uniknect,lcd-bare";% x& U4 i, z3 }) z- m width = <160>; height = <128>;% j0 I6 d) q! F$ F status = "okay";. }: p! O! F( q9 E4 S' Q }; 4 Q- S3 \# H* i# R4 a /* lcd_bare 驱动的板级 IO 配置 */ lcd_io: lcd-io { compatible = "uniknect,lcd-io"; dc-gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>; /* Arduino D8 */ cs-gpios = <&gpioe 11 GPIO_ACTIVE_LOW>; /* Arduino D10 */) z9 Y& G: n8 Q };3 k5 ^( V$ I( J- _! ?, F * I- h- C9 V* k( ]5 m* [8 p1 F o" v aliases { lcd-spi = &spi4;1 Y( \, K+ t! c0 k8 U6 M) ]8 F2 s };9 R4 @ n v. z* O };$ l! e2 Q3 S$ ]1 d3 J+ J /* Arduino SPI(D11~D13),本板为 SPI4 */& w7 _; t; x9 e6 d$ ] &spi4 { pinctrl-0 = <&spi4_sck_pe12 &spi4_miso_pe13 &spi4_mosi_pe14>; pinctrl-names = "default"; status = "okay"; };第 3 步:驱动通过设备树取资源(板级无关设计) 驱动不硬编码任何引脚/总线,全部从设备树读取: static const struct device *const spi_dev = DEVICE_DT_GET(DT_ALIAS(lcd_spi));& W/ g, L$ H% V# Zstatic const struct gpio_dt_spec lcd_dc = GPIO_DT_SPEC_GET(DT_NODELABEL(lcd_io), dc_gpios); 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)- m+ G" x9 r" ~/ fcompatible: "uniknect,lcd-io" properties:7 Z5 R( {% Q; d% y7 J" C' s- F dc-gpios: type: phandle-array required: true cs-gpios: type: phandle-array required: true 并在节点上加 compatible = "uniknect,lcd-io";。经验:自定义节点的 GPIO 属性必须在绑定里声明 type: phandle-array,不能依赖类型猜测。 第 5 步:应用骨架prj.conf: CONFIG_GPIO=yCONFIG_SPI=y+ w6 O3 v1 h e0 i) x CONFIG_DISPLAY=y CMakeLists.txt: cmake_minimum_required(VERSION 3.20.0)) o1 u% M: l$ ] `( yfind_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(lcd_demo)& h0 G6 j) T0 V& \4 r- G L 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/luglZephyrproject& k$ x2 P3 c8 f1 F1 D! N. Gexport ZEPHYR_SDK_INSTALL_DIR=/d/luglZephyrproject/zephyr-sdk-1.0.1/zephyr-sdk-1.0.1' I9 v5 B- _! X" e 1 F( }/ P- X9 p' `+ Y 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 west flash -d build_h5e5_lcd 实测结果:LCD 正常点亮,文字与四色刷屏显示正确,SPI4 @ 10 MHz 工作正常,串口日志同步输出 lcd_demo: fill RED/GREEN/BLUE/WHITE。 3. 引脚速查表LCD 信号Arduino 位H5E5ZJ 引脚外设, ^! ?! v& B6 I2 h, }4 A( ]7 F$ vSPI_SCKD13PE12SPI4_SCK SPI_MISOD12PE13SPI4_MISO SPI_MOSID11PE14SPI4_MOSI LCD CSD10PE11GPIO(软件控制)7 v* X$ V5 I* p5 F4 i LCD DCD8PA9GPIO% ?/ _* g8 y3 M. U6 i 背光—硬件常亮无需控制3 s) Z& Y9 a: M# c/ B6 M& ?3 l& N7 C RST—板级复位线无需控制4. 经验总结
nucleo_h5e5zj_lcd_demo.zip
(11.16 KB, 下载次数: 0)
|
【STM32H5 评测】基础硬件加密与随机数性能 - STM32H5E5实测硬件AES加解密、HASH运算、TRNG真随机数输出速率与稳定性
【STM32H5 评测】内存读写性能 - STM32H5E5实测Flash,SRAM读写速度,用DMA搬运大块数据
【STM32H5 评测】CPU核心性能 - STM32H5E5跑 RTOS,观察任务切换速度、中断响应快慢
【STM32H5 评测】3、STM32H5 Lwip 移植、官方例程和UDP发送数据
【STM32H5 评测】基于NUCLEO_H5E5ZJ+Zephyr数字电源
【STM32H5 评测】2、Keil中添加RTX5 RTOS和Event Record
STM32C542RC开发板PWM呼吸灯及多功能按键实验
NUCLEO-H5E5ZJ 移植 LVGL
NUCLEO-H5E5ZJ 以太网(Ethernet)移植记录
【STM32H5 评测】1、移植记录(LED / Shell)
微信公众号
手机版