news 2026/9/24 6:58:04

RT-Thread 下 GD32F470 立创开发板 RGB LCD 触摸驱动实践:TLI 显示、SDRAM 帧缓冲与 FT5206 电容触摸全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RT-Thread 下 GD32F470 立创开发板 RGB LCD 触摸驱动实践:TLI 显示、SDRAM 帧缓冲与 FT5206 电容触摸全解析
  • 操作系统
  • 嵌入式
  • 物联网
  • 嵌入式OS
  • RTOS

【免费下载链接】rt-thread

RT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/

项目地址:https://gitcode.com/gh_mirrors/rt/rt-thread
点击查看免费下载

导读

本指南围绕 RT-Thread 仓库中bsp/gd32/arm/gd32470i-eval/board/ports/目录下的 RGB LCD 配套驱动展开,该驱动为 GD32F470 立创开发板(LCKFB)配套的 800×480 RGB LCD 屏幕提供完整显示与触摸能力。读完本文你将掌握:如何在 ENV/menuconfig 中一键开启 TLI、SDRAM、TOUCH、GPU 与绘图面板示例;lcd_disp_config()背后 TLI 控制器、PLLSAI 时钟与 Layer0 的初始化细节;FT5206 电容触摸芯片基于 GPIO 模拟 I2C 的轮询扫描机制;以及如何通过draw_panel_test直接上手一个可运行的触摸绘图应用,并解决刷新抖动、触摸连点等实战问题。

驱动总览:从 LCKFB 到 RT-Thread BSP

该驱动最初由立创开发板团队(LCKFB)开发,由维护者 godmial 移植到gd32470i-evalgd32470z-lckfb两个 BSP(见 驱动说明),随后按 RT-Thread 代码规范重构(drv_lcd.cdrv_touch.c头部 Change Log 均标注 2025-05-23 重构记录)。

board/ports/目录下共包含 8 个文件,分工如下:

文件职责
drv_lcd.cTLI 显示控制器初始化、GPIO 复用配置、绘图 API(点/线/矩形/圆/三角形/字符/图片/按钮/开关)
drv_lcd.hLCD 分辨率、时序、帧缓冲地址、RGB565 颜色宏与 API 声明
drv_touch.cFT5206 电容触摸驱动:GPIO 模拟 I2C、寄存器读写、轮询扫描
drv_touch.h触摸引脚定义、FT5206 寄存器地址、触摸数据结构
draw_panel.c触摸绘图面板示例(颜色选择/画笔粗细/橡皮擦/清屏)
font.hASCII 16×8 点阵字库(asc2_1608
SConscript依据BSP_USING_LCD / BSP_USING_TOUCH / BSP_USING_DRAW_PANEL_EXAMPLE宏条件编译
README.md本文所依据的官方说明

从构建脚本可以清晰看到驱动的模块化组织:BSP_USING_LCD决定是否编译drv_lcd.cBSP_USING_TOUCH决定drv_touch.cBSP_USING_DRAW_PANEL_EXAMPLE决定draw_panel.c,三者相互独立、可单独裁剪。

在 ENV 中开启 LCD 相关功能

驱动通过 Kconfig 菜单向用户暴露开关。在 BSP 根目录(bsp/gd32/arm/gd32470i-eval)打开 ENV 工具执行menuconfig,按如下路径配置(建议全部开启):

Hardware Drivers Config ---> Board extended module Drivers ---> Enable LCD ---> - [*]Enable TLI - [*]Enable SDRAM - [*]Enable TOUCH - [*]Enable GPU - [*]Enable DRAW PANEL EXAMPLE

对应配置项定义在 board/Kconfig 中:

  • BSP_USING_LCD:总开关,默认关闭;
  • BSP_USING_TLI:TLI 显示控制器,默认开启,且select RT_USING_LCD
  • BSP_USING_SDRAM:外部 SDRAM,默认开启(同时select RT_USING_SDRAM),用于承载帧缓冲;
  • BSP_USING_TOUCH:触摸,默认关闭;
  • BSP_USING_GPU:GPU(IPA 图像处理加速器),默认开启;
  • BSP_USING_DRAW_PANEL_EXAMPLE:绘图面板示例,默认关闭。

配置完成后执行scons --target=mdk5(或iar/默认 GCC 构建)重新生成工程。注意BSP_USING_SDRAM在 Kconfig 中同时出现在"On-chip Peripheral Drivers"(默认关闭)和 LCD 子菜单(默认开启)两处,两者语义相同,均为开启外部 SDRAM 支持。

硬件基础:SDRAM 帧缓冲与显示通路

RGB LCD 与 MCU 屏的最大区别在于:屏幕没有显存,控制器必须通过 RGB 并行接口持续不断地刷新每一帧像素。因此驱动把帧缓冲放置在外部 SDRAM 中,由 TLI 外设按时序自动搬运。

在 board.h 中定义了外部 SDRAM 的地址区间:

#define EXT_SDRAM_BEGIN (0xC0000000U) /* the begining address of external SDRAM */ #define EXT_SDRAM_END (EXT_SDRAM_BEGIN + (32U * 1024 * 1024)) /* the end address of external SDRAM */

drv_lcd.h 则将帧缓冲固定指向 SDRAM 起始地址:

#define LCD_WIDTH 800 #define LCD_HEIGHT 480 #define LCD_FB_BYTE_PER_PIXEL 1 ... #define LCD_FRAME_BUF_ADDR 0xC0000000 /* SDRAM address for LCD frame buffer */

800×480 分辨率 + RGB565(每像素 2 字节)共需约 800×480×2 = 768 KB 连续内存,内部 SRAM(GD32F470 仅 512 KB)无法容纳,这正是必须借助外部 SDRAM 的原因。同时由于 SDRAM 位于 EXMC 总线空间,TLI 可以以 DMA 方式直接读取,无需 CPU 逐像素搬运,绘图时 CPU 只需写帧缓冲即可。

编译器适配:__CC_ARM__GNUC__

为避免scons(GCC 工具链)编译失败,驱动针对不同编译器声明了不同形式的帧缓冲(见 drv_lcd.c):

#if defined(__CC_ARM) || defined(__ARMCC_VERSION) /* Keil MDK Compiler */ uint16_t ltdc_lcd_framebuf0[800][480] __attribute__((at(LCD_FRAME_BUF_ADDR))); #elif defined(__GNUC__) /* GCC Compiler (used by RT-Thread) */ uint16_t ltdc_lcd_framebuf0[10][10]; #endif
  • Keil MDK(__CC_ARM/__ARMCC_VERSION:通过__attribute__((at(...)))将 800×480 数组绝对定位到 SDRAM 帧缓冲地址;
  • GCC(RT-Thread 默认工具链):仅声明一个 10×10 的哑数组以通过编译,SDRAM 区域的实际分配由 GCC 链接脚本处理,哑数组声明仅为满足符号引用。

使用 GCC 构建时,需保证链接脚本将外部 SDRAM 空间纳入可寻址内存映射;若你换用其他工具链(如 IAR),也需确认帧缓冲符号的放置方式与硬件布局一致。

TLI 显示控制器初始化:时序、时钟与 Layer0

lcd_disp_config()(drv_lcd.c)是 LCD 初始化的总入口,调用流程为:

  1. lcd_disp_en_config():配置 PD13 为推挽输出,作为 DISP 使能脚;
  2. lcd_disp_off()/lcd_disp_on():先关屏再开屏,控制背光/电源时序;
  3. tli_gpio_config():配置全部 RGB 信号与同步信号引脚为复用功能;
  4. tli_config():配置 PLLSAI 时钟、TLI 时序、背景色与 Layer0;
  5. tli_layer_enable(LAYER0)+tli_reload_config(TLI_FRAME_BLANK_RELOAD_EN)+tli_enable():使能图层并启动控制器;
  6. ipa_config():使能 IPA(GPU)时钟并打开其中断。

TLI 像素时钟的产生

TLI 的像素时钟由 PLLSAI 生成(drv_lcd.c):

if (ERROR == rcu_pllsai_config(192, 2, 3)) { while (1); } rcu_tli_clock_div_config(RCU_PLLSAIR_DIV2);

rcu_pllsai_config(192, 2, 3)中三个参数对应 PLLSAI 的倍频/分频系数,PLLSAIR 输出经 DIV2 分频后作为 TLI 像素时钟。驱动中保留了被注释的rcu_pllsai_config(216, 2, 3)写法,供不同刷新率需求时替换;修改后必须确保tli_init_struct中的水平/垂直时序与之匹配,否则会出现画面偏移或撕裂。

水平与垂直同步时序

时序参数定义在 drv_lcd.h:

/* Horizontal: HSW=10, HBP=150, Active=800, HFP=15 */ #define HORIZONTAL_SYNCHRONOUS_PULSE 10 #define HORIZONTAL_BACK_PORCH 150 #define ACTIVE_WIDTH 800 #define HORIZONTAL_FRONT_PORCH 15 /* Vertical: VSW=10, VBP=140, Active=480, VFP=40 */ #define VERTICAL_SYNCHRONOUS_PULSE 10 #define VERTICAL_BACK_PORCH 140 #define ACTIVE_HEIGHT 480 #define VERTICAL_FRONT_PORCH 40

这些参数在tli_config()中被换算为 GD32 固件库要求的"减 1"格式并写入同步、后肩、有效区、总长寄存器(drv_lcd.c):

tli_init_struct.synpsz_hpsz = HORIZONTAL_SYNCHRONOUS_PULSE - 1; tli_init_struct.backpsz_hbpsz = HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH - 1; tli_init_struct.activesz_hasz = HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH + ACTIVE_WIDTH - 1; tli_init_struct.totalsz_htsz = ... + HORIZONTAL_FRONT_PORCH - 1;

同步极性同时配置为低有效:TLI_HSYN_ACTLIVE_LOWTLI_VSYN_ACTLIVE_LOWTLI_DE_ACTLIVE_LOW,并选择TLI_PIXEL_CLOCK_TLI作为像素时钟源。这些参数必须与屏幕规格书一致,若更换为其他型号的 RGB 屏,这是第一处需要修改的地方

Layer0 图层与帧缓冲绑定

TLI 支持多图层混合,驱动仅使用 Layer0(drv_lcd.c):

  • 窗口位置:按HSW+HBPVSW+VBP计算活动区起点,与显示时序严格对齐;
  • 像素格式LAYER_PPF_RGB565
  • 透明度layer_sa = 255(完全不透明),混合因子LAYER_ACF1_SA/LAYER_ACF2_SA
  • 帧缓冲绑定layer_frame_bufaddr = (uint32_t)ltdc_lcd_framebuf0,即 SDRAM 起始地址;
  • 行长与跨度layer_frame_line_length = ACTIVE_WIDTH * 2 + 3(RGB565 每行 1600 字节),layer_frame_buf_stride_offset = ACTIVE_WIDTH * 2
  • 总行数ACTIVE_HEIGHT
  • 抖动tli_dither_config(TLI_DITHER_ENABLE)开启颜色抖动以改善低位数色深下的条带现象。

背景色被配置为白色(backcolor_red/green/blue = 0xFF),与绘图面板清屏后的底色一致。

TLI 信号引脚映射(GPIO 复用)

tli_gpio_config()将 6 组 GPIO 的时钟使能后,按 AF14(多数 RGB 信号)/ AF9(PB0、PG10、PG12)配置复用(drv_lcd.c)。关键引脚分配如下:

信号引脚复用
HSYNCPC6AF14
VSYNCPA4AF14
PCLKPG7AF14
DEPF10AF14
R7PG6AF14
G7PD3AF14
B7PB9AF14

全部输出配置为推挽、50MHz 速度、无上下拉。若所接屏幕的信号定义不同(如 DE 极性相反),需同步修改 GPIO 映射与 TLI 极性配置。

DISP 背光控制

lcd_disp_en_config()/lcd_disp_off()/lcd_disp_on()(drv_lcd.c)通过 PD13 控制屏幕的 DISP 使能信号:初始化时先复位(关)再置位(开),保证上电时序安全。如果你的硬件将 DISP 接到其他引脚,需同步修改这几处 GPIO 宏。

绘图 API:从像素到完整控件

驱动在帧缓冲之上提供了一套完整的软件绘图接口,全部直接写 SDRAM 帧缓冲,由 TLI 自动刷新到屏幕,CPU 不参与显示搬运:

API功能算法/说明
tli_draw_point(x, y, color)单像素直接写framebuf0[0] + LCD_WIDTH*y + x
tli_draw_line(sx, sy, ex, ey, color)直线Bresenham 算法
tli_draw_rectangle(sx, sy, ex, ey, color, fill)矩形fill=1填充,否则只画四条边
tli_draw_circle(xc, yc, color, r, fill)中点画圆算法,8 对称点
tli_draw_triangle(x0..x2, y0..y2, color, fill)三角形扫描线光栅化填充
tli_point_enlarge(x, y, color, magnify)放大像素4 个矩形组成十字块,最小 1
tli_show_char(x, y, fc, bc, num, size, mode)ASCII 字符16×8 点阵,支持放大与覆盖模式
tli_show_string(x, y, fc, bc, size, p, mode)ASCII 字符串自动处理越界与非法字符
tli_show_picture(x, y, w, h, pic[])图片RGB565 字节序(高字节在前)
tli_show_button(x, y, w, h, radius, color)圆角按钮4 圆角 + 矩形拼接,radius < h/2
tli_show_switch(x, y, w, h, on_c, off_c, sw)开关圆角底座 + 滑块指示开关状态

颜色宏在 drv_lcd.h 中按 RGB565 格式定义,例如RED=0xF800GREEN=0x07E0BLUE=0x001FWHITE=0xFFFFBLACK=0x0000,并额外提供了LGRAY(面板背景浅灰)等 GUI 常用色。

注意:由于代码格式审查原因,本驱动未包含中文显示函数(见 README.md 注意事项第 2 条)。需要中文显示时,可直接移植官方源码中的中文显示函数到本驱动中,字体数据格式参考font.hasc2_1608的 16×8 点阵组织方式。

触摸驱动:FT5206 与 GPIO 模拟 I2C

屏幕配套的是 FT5206 电容触摸控制器,通过 I2C 与 MCU 通信。驱动在 drv_touch.h 中定义了引脚与寄存器:

#define SCL_PORT GPIOB #define SCL_PIN GPIO_PIN_6 #define SDA_PORT GPIOB #define SDA_PIN GPIO_PIN_7 #define INT_PORT GPIOD #define INT_PIN GPIO_PIN_11 /* 触摸中断脚,本驱动以轮询方式使用 */ #define RST_PORT GPIOD #define RST_PIN GPIO_PIN_12 /* 复位脚 */

I2C 采用 GPIO 位操作软件模拟实现(SCL=PB6、SDA=PB7),CT_IIC_Init()将两根线配置为带上拉的推挽输出,通过CT_IIC_Start/Stop/Send_Byte/Read_Byte/Wait_Ack/Ack/NAck完成完整 I2C 时序。关键 FT5206 寄存器(drv_touch.h):

寄存器地址含义
FT_DEVIDE_MODE0x00工作模式
FT_REG_NUM_FINGER0x02触摸点数/触摸状态
FT_TP1_REG ~ FT_TP5_REG0x03 / 0x09 / 0x0F / 0x15 / 0x1B5 个触摸点的坐标数据(每点 4 字节)
FT_ID_G_THGROUP0x80触摸灵敏度阈值
FT_ID_G_PERIODACTIVE0x88采样活跃周期
FT_ID_G_LIB_VERSION0xA1固件版本号

FT5206_Init()完成:初始化 I2C → 写设备模式/中断模式寄存器 → 设置灵敏度THGROUP=22、活跃周期PERIODACTIVE=12→ 回读固件版本并打印CTP ID。每次上电串口终端都会输出类似CTP ID:xxxx的信息,可用来确认触摸芯片通信正常。

触摸扫描与状态管理

FT5206_Scan(mode)以轮询方式工作(drv_touch.c):

  1. FT_REG_NUM_FINGER得到本次触点个数;
  2. 触点有效时,按FT5206_TPX_TBL[]依次读取各点 4 字节坐标数据,解析 12 位 X/Y 坐标(高 4 位在首字节低半字节);
  3. 写入全局触摸设备结构tp_dev_m_tp_dev类型,含x[5]/y[5]/sta/xfac/yfac/xoff/yoff/touchtype字段);
  4. 返回1表示检测到触摸,0表示无触摸;
  5. 当检测到坐标超出屏幕范围(> ACTIVE_WIDTH/ACTIVE_HEIGHT)时,自动切换到备用触点或恢复上一状态,防止误触点。

状态标志位TP_PRES_DOWN(0x80)表示按下、TP_CATH_PRES(0x40)表示捕获到触点。letgo_scan()则用于阻塞等待手指离开指定矩形区域,绘图面板用它实现"按下按钮、松手后触发"的交互语义。

触摸自测命令

驱动通过MSH_CMD_EXPORT(touch_test, touch test)(drv_touch.c)向 RT-Thread FinSH 控制台导出了touch_test命令。编译后进入msh,输入:

msh /> touch_test

程序会进入无限循环轮询触摸,每次检测到按下就在串口打印touch。这是一个快速验证触摸硬件通路是否正常的最小测试,无需 LCD 参与。

绘图面板示例:draw_panel_test

draw_panel.c提供了一个完整的触摸绘图应用,通过INIT_COMPONENT_EXPORT(draw_panel_test)(draw_panel.c)在系统组件初始化阶段自动启动。draw_panel_test()的执行逻辑:

  1. lcd_disp_config()初始化显示通路;
  2. FT5206_Init()初始化触摸;
  3. tli_draw_rectangle(0, 0, 800, 480, WHITE, 1)清屏为白色;
  4. 在屏幕底部创建 4 个功能按钮(各 120×70):
    • color(左上):点击切换画笔颜色,颜色取自 14 色调色板color_buf[]GRAYBLUE/BLACK/BLUE/.../GRAY,见 draw_panel.c);
    • pixel(中下):点击循环调整笔刷放大倍数,范围 1~20(PIXEL_SIZE_MAX);
    • eraser(右二):点击切换橡皮擦模式,用白色擦除;
    • clear(右下):点击整屏清为白色;
  5. 主循环轮询FT5206_Scan(0),触点落在按钮区域时调用letgo_scan()等待松手再执行动作;落在绘图区时调用tli_point_enlarge()以当前颜色与笔刷大小绘制(橡皮擦模式则画白色)。

各按钮的矩形命中检测逻辑为:

if (tp_dev.x[0] >= button_color.x && tp_dev.x[0] <= (button_color.x + button_color.w)) { if (tp_dev.y[0] >= button_color.y && tp_dev.y[0] <= (button_color.y + button_color.h)) { ... } }

编译烧录后,屏幕会直接进入可交互的触摸绘图面板,用手指即可书写、换色、调粗细、擦除与清屏,是验证"显示 + 触摸 + SDRAM"整条链路最直观的演示。

实战问题排查

根据 README.md 注意事项,以下两个问题在高频使用中最常见:

1. 刷新抖动与触摸连点

若屏幕出现刷新抖动、触摸屏出现连点现象,可将 libraries 目录下 GD32F4xx 固件库中的system_gd32f4xx.c的系统时钟宏修改为 240 MHz:

#define __SYSTEM_CLOCK_240M_PLL_25M_HXTAL (uint32_t)(240000000)

然后重新编译即可。该问题通常源于 PLL 配置与 SDRAM/TLI 时序的匹配不佳:系统时钟偏低时,TLI 刷新与 SDRAM 读写带宽的竞争加剧,表现为画面抖动;触摸扫描节拍异常则表现为连点。将主频提升到 GD32F470 标称的 240 MHz 后,总线带宽与时序裕量得到改善。修改后需确认board目录的时钟初始化代码同样按 240 MHz 配置(gd32470i-eval/board/board.c),并同步核对drv_lcd.c中 PLLSAI 的像素时钟分频。

2. 中文显示缺失

由于代码格式审查原因,本驱动未包含中文显示函数。若项目需要中文,直接移植官方源码中的中文显示函数(通常基于 GB2312 点阵字库)即可,现有tli_show_char/string的绘图框架可复用,无需改动 TLI 与帧缓冲逻辑。

源码路径速查

内容路径
驱动官方说明board/ports/README.md
LCD 驱动实现board/ports/drv_lcd.c
LCD 驱动头文件board/ports/drv_lcd.h
触摸驱动实现board/ports/drv_touch.c
触摸驱动头文件board/ports/drv_touch.h
绘图面板示例board/ports/draw_panel.c
条件编译脚本board/ports/SConscript
Kconfig 菜单board/Kconfig
SDRAM 内存布局board/board.h
评估板 BSP 说明gd32470i-eval/README.md

总结

该驱动为 GD32F470 立创开发板提供了完整的 RGB LCD 显示与触摸解决方案:显示侧由 TLI 控制器配合外部 SDRAM 帧缓冲完成 800×480 画面刷新,触摸侧由 FT5206 芯片通过 GPIO 模拟 I2C 提供 5 点电容触摸,两者经draw_panel_test示例闭环成一个可直接运行的绘图应用。若需将该方案迁移到其他 GD32F4xx 评估板或屏幕,重点核对三处:屏幕时序参数与极性(drv_lcd.h)、TLI 引脚复用映射(drv_lcd.ctli_gpio_config)、以及触摸引脚与寄存器定义(drv_touch.h)。

  • 操作系统
  • 嵌入式
  • 物联网
  • 嵌入式OS
  • RTOS

【免费下载链接】rt-thread

RT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/

项目地址:https://gitcode.com/gh_mirrors/rt/rt-thread
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

TICS Pro实战:LMX2594寄存器配置与导出全流程详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 6:52:48

Boost.Asio异步网络编程实战:从Echo服务端到多线程消息转发

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 6:50:38

TMS320F280049开发选型指南:C2000Ware与MotorControl SDK深度对比

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华