LCD 触摸屏项目架构与开发规范–进阶版

本文档说明本工程(STC32G + RA6809/RA8889 + GT911)的架构、目录职责、数据流、接口约定与开发规范,便于按同一套架构实现需求与维护。
更细的「新增页面手把手步骤」与「页面内成员(显示参数、点击反馈、设置参数)」见超详细版本:
菜单逻辑架构工程手把手教程

我们这套菜单逻辑架构做的事可以概括成三句:

  1. 屏幕上有很多“页”,每页上有若干“可点区域”(像手机 App 的各个页面,每页上有按钮、输入框)。
  2. 用户点哪里,系统就判断“点的是哪个区域”,然后执行两件事:先给一个点击反馈(比如按键高亮),再跳转到对应页面在本页刷新显示
  3. 有的页面会显示实时数据(如电压、电流、功率),有的页面让用户输入或选择(如键盘输入数字、点应用生效),数据在页面之间按设定好的规则传递。

整体就像一本电子菜单:主页是目录,点某一项就进入子页;子页里可以看数据、改参数、再点“应用”或“返回”,系统按设计好的路线跳转并更新显示。

一、项目架构

1.1 项目概述

项目 说明
工程名称 STC32G_RA6809_HMI
硬件平台 STC32G 单片机 + RA6809/RA8889 显示驱动 + GT911 触摸 IC
编译器 Keil C251(推荐 Memory Model XSmall,edata 留约 1K 给堆栈)
功能 LCD 触摸屏 UI 系统:页面切换、触摸区域响应、动态显示参数、键盘/应用等业务逻辑

1.2 目录结构与职责

STC32G_RA6809_HMI/
├── LCD_Menu_logic_architecture/     【LCD 页面与菜单逻辑】
│   ├── ui_page_base.c/h              - UI 基础框架(页面链表、触摸事件分发、ui_page_switch_to)
│   ├── ui_page_main.c/h              - 页面配置表 ui_page_def_conf、图片表 _Pic、page_worked、ui_page_init
│   ├── lcdts_LCD_Pic.h               - 图片结构 INFO_Pic、枚举 PICTURE_NAME_Pic(与 NOR 图资顺序一致)
│   ├── Main_Page.c/h                 - 主页(开机首屏),入口跳转
│   ├── Main_control_input_parameters_display.c/h  - 主控输入参数页(电压/电流/功率显示,应用→参数页)
│   ├── Parameter_control_and_display.c/h         - 参数控制页(电压/电流设定入口、应用写回主控)
│   ├── Keyboard_input.c/h            - 键盘输入页(数字/小数点/OK/Cancel,写回参数页)
│   ├── Equipment_parameter_settings_display.c/h - 设备参数设定页
│   ├── Device_selection.c/h          - 设备选择页
│   ├── Parameter_settin_and_passing.c/h          - 参数设定与传递页(加/减键、长按)
│   ├── host_comm.c/h                 - 主机通讯(主控参数上报/下发)
│   ├── ui_page_color_cycle.c/h       - 示例页面 PAGE1~PAGE4
│   ├── UI框架与触摸交互说明文档.md
│   └── 新增页面手把手教程.md
│
├── Touch_Demo/                       【触摸驱动】
│   └── GT911.c/h                     - GT911 触摸驱动(坐标、按下/抬起)
│
├── RA6809/                           【显示驱动层】
│   ├── RA8889_51.c/h                 - RA8889 底层通信
│   ├── RA8889_API_51.c/h             - 显示 API(BTE、画图、图层等)
│   ├── RA8889_MCU_IF.c/h             - MCU 接口(SPI 等)
│   ├── delay.c/h                     - 延时
│   └── UserDef.h                     - 分辨率、canvas_image_width 等宏
│
├── All_8889_Pic_NOR.h                - 工具生成的图资信息(需与 lcdts_LCD_Pic、_Pic 同步)
├── ui_mempool.c/h                    - UI 内存池(xdata,xmalloc/xinit_mempool)
├── main.c                            - 主循环、初始化、触摸轮询、防抖、长按、1s 刷新
├── uart1.c/h                         - 串口调试(可选)
└── 项目架构与开发规范2.md            - 本文档

1.3 分层与依赖

应用层
  Main_Page, Main_control_*, Parameter_control_*, Keyboard_input, Equipment_*, Device_*, Parameter_settin_*
  host_comm(主控参数上报/下发)
        ↓
UI 框架层
  ui_page_base(页面链表、g_current_page_id、ui_touch_select_process、ui_page_switch_to)
  ui_page_main(ui_page_def_conf、_Pic、ui_page_init、ui_image_load)
        ↓
硬件/驱动层
  RA8889_API_51(显示)、GT911(触摸)、main(tp_flag、防抖、轮询)
        ↓
底层外设
  SPI、GPIO、INT2、定时器

1.4 触摸事件流

触摸屏 (GT911) → INT2 拉低
  → INT2_ISR() 置 tp_flag = 1
  → 主循环检测 tp_flag,调用 GT911_Scan() 更新 LCD_X, LCD_Y, TouchFlag
  → 防抖、有效按下且未 touch_processed 时调用 ui_touch_select_process()
  → 根据 g_current_page_id 查当前页
  → 当前页 touch_select_judgment(&coordinate) 返回 response_area_id
  → 在 page_response_area[] 中匹配 response_area_id
  → 若匹配:先执行 config_function(config_param)(可选),再执行 page_switch_function(page_id)
  → page_switch_function 一般为 ui_page_switch_to(page_id)
  → 更新 g_current_page_id,调用目标页 page_display(target_page)
  → 显示层刷新(JPG 背景 + 可选 PNG/数值等)

1.5 核心数据结构

页面结构(ui_page_base.h)

  • page_id:唯一 ID,UI_PAGE_ID_BY_IMAGE_PARAM(image_id, param_id)
  • image_reference_id:背景图资源 ID(对应 _Pic 下标)。
  • touch_select_judgment:根据坐标返回区域 ID。
  • page_display:绘制本页内容。
  • page_response_area:响应区域数组;response_area_num 与配置表一致。

响应区域(ui_page_base.h)

  • response_area_id:与 touch_select_judgment 返回值一致。
  • config_function / config_param:点击时先执行(如备份图矩形拷贝、写参数);不用则 NULL
  • page_switch_function / page_id:通常为 ui_page_switch_to 与目标页 ID;目标可为本页以实现“只刷新不跳转”。

页面配置表(ui_page_main.c)

  • ui_page_def_conf[]:每项含 image_reference_id、page_type、touch_select_judgment、func_detail_init、response_area_num
  • page_worked[]:与配置表下标对应,0 禁用、1 启用。
  • _Pic[]:与 lcdts_LCD_Pic.h 枚举顺序一致,每项为宽、高、大小、NOR 起始地址。

二、开发规范

2.1 命名规则

  • UI 框架ui_ 前缀(如 ui_page_switch_to、ui_touch_select_process、ui_page_init)。
  • 全局变量g_ 前缀(如 g_current_page_id、g_ui_page_list、g_keyboard_edit_which)。
  • 页面三函数(每交互页必须实现):
    • 触摸判断:ui_tsj_<页面名>(lcd_coordinate_t *pCoordinate)
    • 页面初始化:ui_init_<页面名>(ui_page_t *ui_page)
    • 页面显示:ui_display_<页面名>_page(ui_page_t *ui_page)(可为 static)
  • 区域 ID:在页面头文件中用宏定义,如 MAIN_PAGE_AREA_ID_PARAM_DISPLAYDEMO_AREA_ID_BACK_PREV,且与 ui_tsj 返回值、response_area_id 一一对应。
  • 图片 IDIMAGE_ID_<页面名>,取值与 lcdts_LCD_Pic.h 中枚举一致(如 IMAGE_ID_MAIN_PAGE → Main_Page)。

2.2 页面三函数职责

  1. ui_tsj_XXX
    仅做几何判断:根据 pCoordinate->xpCoordinate->y 与各区域矩形比较,返回对应 AREA_ID_*,未命中返回 AREA_ID_NONE_SELECT。不在此处做业务逻辑。

  2. ui_init_XXX

    • 设置 ui_page->page_display = ui_display_XXX_page
    • 为每个响应区域填写:response_area_idconfig_functionconfig_parampage_switch_functionpage_id
    • 不使用的 config 必须显式置为 NULL
  3. ui_display_XXX_page
    负责把本页画到屏幕:加载背景图(ui_image_load)、拷贝到显示层,若有动态内容(如电压电流功率)再叠加绘制。切换或刷新本页时由框架调用。

2.3 点击反馈与 config_function

  • 需要“按键按下态”时:使用备份图(与背景同尺寸、可点击区画成高亮),在 config_function 中从备份图拷贝对应矩形到显示层(参考 Main_Page、Parameter_control、Main_control 的 backup_rect_to_display 写法)。
  • 需要“先写数据再跳转”时:在 config_function 中调用 set/get 或业务接口,再由 page_switch_function 切页。
  • 同页刷新:将响应区域的 page_id 设为本页 ID,则点击后仍执行本页的 page_display,用于键盘页按数字键刷新上方显示等。

2.4 代码与 C251 注意点

  • 局部变量在块开头统一声明(C251 要求)。
  • 缩进与括号风格与现有工程一致(如 4 空格)。
  • 文件头注释说明本文件职责;关键函数可写“函数名、功能、形参、返回值”。
  • 使用工程提供的 xmallocxinit_mempool,勿用标准库 malloc/free。
  • 新增页的 init/tsj 若未被显式引用,在 main.c 中可通过静态指针强制引用,避免被链接器剔除。

2.5 页面启用与配置表

  • page_worked[]:与 ui_page_def_conf[] 下标一一对应,0 表示不创建该页,1 表示启用。
  • response_area_num:必须与本页 ui_init 中实际填写的响应区域数量一致,否则触摸匹配会错位或越界。
  • 新增页时需同时:在 lcdts_LCD_Pic.h 增加枚举、在 _Pic[] 增加对应行(与图资工具输出同步)、在 ui_page_def_conf 增加一项、在 page_worked 对应下标置 1。

三、本工程与旧项目的差异(简要)

项目 旧项目 本工程
触摸 IC XPT2046 GT911
坐标更新 lcdts_coordinate_update(x,y) GT911_Scan() 写 LCD_X/LCD_Y
触摸触发 轮询/定时 INT2 中断 + tp_flag,主循环中 GT911_Scan
防抖/抬手 可有独立逻辑 main 中 touch_debounce_counter、touch_processed
坐标结构体 axis_x, axis_y x, y (lcd_coordinate_t)
目录命名 lcdts / cpm 等 Touch_Demo / RA6809 / LCD_Menu_logic_architecture

架构思想一致:配置表 + 三函数(tsj / init / display)+ 触摸 → 区域 ID → config(可选)→ page_switch → page_display


四、新增页面开发流程(概要)

  1. 图资与枚举
    图资导入 NOR 后,在 lcdts_LCD_Pic.h 增加枚举项(含背景与备份),在 ui_page_main.c 的 _Pic[] 中按相同顺序增加两行。

  2. 页面头文件
    定义 IMAGE_ID_XXX、本页各区域矩形宏 (X,Y,W,H)、区域 ID 宏(与 ui_tsj 返回值一致)。

  3. 页面源文件
    实现 ui_display_XXX_page、ui_tsj_XXX、ui_init_XXX;需要点击变色则实现“备份图矩形拷贝”回调并绑定到对应 config_function/config_param。

  4. 注册与启用
    在 ui_page_main.c 的 ui_page_def_conf[] 中增加一项(含 response_area_num),在 page_worked[] 对应下标置 1。

  5. 入口
    在需要跳转到新页的页面(如 Main_Page)增加一块区域:矩形、ui_tsj 判断、response_area 且 page_id = UI_PAGE_ID_BY_IMAGE_PARAM(IMAGE_ID_XXX, 0),并将该页的 response_area_num 加 1。

  6. main.c
    包含新页头文件,必要时增加静态引用防止 init/tsj 被剔除;将新页 .c 加入工程编译。

详细步骤与代码示例见 LCD_Menu_logic_architecture/新增页面手把手教程.md


五、新功能开发检查清单

  • 图资同步:All_8889_Pic_NOR.h / 图资工具更新后,lcdts_LCD_Pic.h 枚举与 ui_page_main.c 中 _Pic[] 已同步(顺序、宽高、大小、地址)。
  • 页面头文件:IMAGE_ID_XXX、区域矩形宏、区域 ID 宏已定义,且区域 ID 与 ui_tsj 返回值一致。
  • 三函数:ui_tsj_XXX、ui_init_XXX、ui_display_XXX 已实现;init 中未使用的 config_function/config_param 为 NULL;response_area_num 与 init 中填写数量一致。
  • 配置表与启用:ui_page_def_conf 已增加/修改表项,page_worked 对应下标已设置。
  • 入口:若从其他页进入新页,入口页已增加区域矩形、tsj 判断、response_area 及 page_id,且该页 response_area_num 已加 1。
  • main.c:已包含新页头文件,必要时已加静态引用;新页 .c 已加入工程。
  • 编译与触摸测试:编译通过,切换与触摸区域、点击反馈、跳转目标正确。

六、快速参考

  • 触摸流:GT911 → tp_flag → GT911_Scan → ui_touch_select_process → tsj → config(可选) → page_switch_to → page_display。
  • 新增页:图资与枚举 → 头文件(ID、矩形、区域ID)→ 三函数(display/tsj/init)→ 配置表与 page_worked → 入口页增加区域与 response_area_num → main 引用与编译。
  • 规范:三函数命名统一、config 不用则 NULL、变量块首声明、response_area_id 与 ui_tsj 一致、response_area_num 与 init 一致。
  • 延伸阅读LCD_Menu_logic_architecture/UI框架与触摸交互说明文档.mdLCD_Menu_logic_architecture/新增页面手把手教程.md

本文档随工程架构调整而更新,新需求开发时请按此架构与规范实现,如需更细的操作步骤说明或工程代码(可与深圳市瑞福科技联系)。。

  • 人机交互HMIDEMO视频可见:

    RA6809 的 HMI(人机交互) 开发:菜单逻辑架构设计

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐