RA6809 的 HMI(人机交互) 开发:菜单逻辑架构设计与实现详解(2)
LCD 触摸屏项目架构与开发规范–进阶版
本文档说明本工程(STC32G + RA6809/RA8889 + GT911)的架构、目录职责、数据流、接口约定与开发规范,便于按同一套架构实现需求与维护。
更细的「新增页面手把手步骤」与「页面内成员(显示参数、点击反馈、设置参数)」见超详细版本:菜单逻辑架构工程手把手教程;
我们这套菜单逻辑架构做的事可以概括成三句:
- 屏幕上有很多“页”,每页上有若干“可点区域”(像手机 App 的各个页面,每页上有按钮、输入框)。
- 用户点哪里,系统就判断“点的是哪个区域”,然后执行两件事:先给一个点击反馈(比如按键高亮),再跳转到对应页面或在本页刷新显示。
- 有的页面会显示实时数据(如电压、电流、功率),有的页面让用户输入或选择(如键盘输入数字、点应用生效),数据在页面之间按设定好的规则传递。
整体就像一本电子菜单:主页是目录,点某一项就进入子页;子页里可以看数据、改参数、再点“应用”或“返回”,系统按设计好的路线跳转并更新显示。
一、项目架构
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_DISPLAY、DEMO_AREA_ID_BACK_PREV,且与 ui_tsj 返回值、response_area_id 一一对应。 - 图片 ID:
IMAGE_ID_<页面名>,取值与 lcdts_LCD_Pic.h 中枚举一致(如IMAGE_ID_MAIN_PAGE→ Main_Page)。
2.2 页面三函数职责
-
ui_tsj_XXX
仅做几何判断:根据pCoordinate->x、pCoordinate->y与各区域矩形比较,返回对应AREA_ID_*,未命中返回AREA_ID_NONE_SELECT。不在此处做业务逻辑。 -
ui_init_XXX
- 设置
ui_page->page_display = ui_display_XXX_page。 - 为每个响应区域填写:
response_area_id、config_function、config_param、page_switch_function、page_id。 - 不使用的 config 必须显式置为 NULL。
- 设置
-
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 空格)。
- 文件头注释说明本文件职责;关键函数可写“函数名、功能、形参、返回值”。
- 使用工程提供的 xmalloc 与 xinit_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。
四、新增页面开发流程(概要)
-
图资与枚举
图资导入 NOR 后,在 lcdts_LCD_Pic.h 增加枚举项(含背景与备份),在 ui_page_main.c 的 _Pic[] 中按相同顺序增加两行。 -
页面头文件
定义 IMAGE_ID_XXX、本页各区域矩形宏 (X,Y,W,H)、区域 ID 宏(与 ui_tsj 返回值一致)。 -
页面源文件
实现 ui_display_XXX_page、ui_tsj_XXX、ui_init_XXX;需要点击变色则实现“备份图矩形拷贝”回调并绑定到对应 config_function/config_param。 -
注册与启用
在 ui_page_main.c 的 ui_page_def_conf[] 中增加一项(含 response_area_num),在 page_worked[] 对应下标置 1。 -
入口
在需要跳转到新页的页面(如 Main_Page)增加一块区域:矩形、ui_tsj 判断、response_area 且 page_id = UI_PAGE_ID_BY_IMAGE_PARAM(IMAGE_ID_XXX, 0),并将该页的 response_area_num 加 1。 -
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框架与触摸交互说明文档.md、LCD_Menu_logic_architecture/新增页面手把手教程.md。
本文档随工程架构调整而更新,新需求开发时请按此架构与规范实现,如需更细的操作步骤说明或工程代码(可与深圳市瑞福科技联系)。。
- 人机交互HMIDEMO视频可见:
RA6809 的 HMI(人机交互) 开发:菜单逻辑架构设计
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)