a98d4e06e8
- 描述符各加一行(机制 task-2 已建,本轮零框架代码改动):dc 300ms(电气量与 ac 同账);yx 500ms(遥信变位按 1s 内上屏到位,比 300 档少 40% 稳态重绘); clock 1000ms(快变项只有墙钟秒尾);device_info / runreport 1000ms 并把新鲜度 源换到通道二 .auto_seq = ui_data_info_seq(info 与 rt 同拍 200ms 发布) ——各页取值账目在该页描述符注释 - docs/UI设计:供给说明 §5.5 改六页全接终态(用户裁定 2026-11-13);内容页架构 字段表/内存表/变更记录同步;自动化测试流程补 rtlive 覆盖行;页面扩充方案 追加 74 张现势注(带日期史实行冻结不动) - .dsh/skills/lvgl-simulator:开关表加 --rtlive 行、黄金参考计数 66→74 同步 验证:模拟器 0错0警;菜单 8 状态 + 内容页 74 张 + rtlive PASS(lead 独立复跑 RC=0,池水位 5368/5448B 均不漂移——timer 开页创建关页销毁、分配归还); Keil 0错0警且 Code/RO/RW/ZI 与 task-2 基线逐字节一致(只改常量值);BOM 全补回。
158 lines
6.4 KiB
C
158 lines
6.4 KiB
C
/*
|
||
* 模块名称:UI Page DC (直流量内容页)
|
||
* 模块功能:直流量叶子节点(node 4)内容页——2 行动态列表:温度(STM32 片内 ADC 透传码值,
|
||
* 未标定)+ 直流通道(V0.1 板上无直流采样通道,值列如实显示"未配置");数据取自
|
||
* ui_data 实时帧(App 层装配,本文件零 App include);向框架 ui_content_page 提供
|
||
* 页面描述符(零 LVGL 对象)
|
||
* 为什么只有 2 行:参考图 21 的"3 行直流读数"在本板无采样源(ADC_SEM 只有 8 路电气 + 温度,
|
||
* 104 点表 0x401E/0x401F 亦注明"FTU 无")——照抄就是三行假数(取舍见
|
||
* docs/UI设计/页面扩充详细方案.md §3.1.2 方案①,菜单语义与点表保持一致)
|
||
* 空值口径:温度通道无效时显 "--";码值一律不挂单位(挂上"℃"就是替用户完成了没做的标定)
|
||
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用)
|
||
* 作者:王建锋
|
||
* 创建日期:2026-09-09
|
||
* 修改记录:
|
||
* 2026-09-09 王建锋 创建:自 ui_content_page 单体拆出(数据原样迁移,零改动)
|
||
* v2.0 2026-10-25 王建锋 道E task-15 回炉:3 行 Flash 假数(ZL01/ZL02/Pa1)→ 2 行快照
|
||
* 真值;温度取 yc[ADC_SEM_TEMP] 并显式标注是码值
|
||
*/
|
||
|
||
/* 头文件包含区 */
|
||
#include <string.h>
|
||
|
||
#include "ui_page_dc.h"
|
||
|
||
#include "ui_data.h"
|
||
#include "ui_tokens.h"
|
||
#include "ui_w_editor.h"
|
||
|
||
/* 私有宏定义区 */
|
||
|
||
/* 温度通道在快照 yc[] 里的语义下标 = adc_semantic_t 的 TEMP(最后一项,随通道表漂移;
|
||
* 由 test/host/ui_data 的"下标空间与 App/algo/adc_input.h 逐行一致"断言兜住) */
|
||
#define DC_YC_TEMP 8u
|
||
#define DC_ROW_N 2u
|
||
#define DC_INVALID "--"
|
||
/* 温度值列前缀:一个"码"字把"这是 12 位原始码、不是温度"写进屏上而不是注释里 */
|
||
#define DC_CODE_PREFIX "码"
|
||
|
||
/* 静态变量定义区 */
|
||
|
||
/* 帧缓存(按发布序号门控,同交流量页) */
|
||
static ui_data_rt_t s_rt;
|
||
static uint32_t s_seq;
|
||
|
||
/* 函数定义区 */
|
||
|
||
/*
|
||
* 函数功能:把常量串安全搬进显示缓冲(替代 strcpy,规范 7.5)
|
||
* 入口参数:a_dst - 目标缓冲(框架 UI_BUF_STRLEN) char *
|
||
* a_lit - 源字面量(长度由宏用 sizeof 算好) const char *
|
||
* a_len - 需拷贝字节数(不含 NUL) uint32_t
|
||
* 返回值:无
|
||
* 限定条件:a_dst/a_lit 非 NULL;a_len 超缓冲按缓冲截断
|
||
* 函数说明:代码规范 7.5 禁 strcpy;长度来自调用点 sizeof,写串与算长同一处
|
||
*/
|
||
static void dc_put(char *a_dst, const char *a_lit, uint32_t a_len) {
|
||
if (a_len > ((uint32_t)UI_BUF_STRLEN - 1u)) {
|
||
a_len = (uint32_t)UI_BUF_STRLEN - 1u;
|
||
}
|
||
(void)memcpy(a_dst, a_lit, a_len);
|
||
a_dst[a_len] = (char)0;
|
||
}
|
||
|
||
#define DC_PUT(a_dst, a_lit) dc_put((a_dst), (a_lit), (uint32_t)(sizeof(a_lit) - 1u))
|
||
|
||
/*
|
||
* 函数功能:取用最新实时帧(只在发布序号变化时整帧拷)
|
||
* 入口参数:无
|
||
* 返回值:1 - 有可用帧;0 - 首帧未到或本帧无效 uint8_t
|
||
* 限定条件:uiTask 绘制上下文
|
||
*/
|
||
static uint8_t dc_frame_ready(void) {
|
||
uint32_t now = ui_data_rt_seq();
|
||
|
||
if (now != s_seq) {
|
||
s_seq = now;
|
||
if (ui_data_rt(&s_rt) != 0) {
|
||
(void)memset(&s_rt, 0, sizeof(s_rt));
|
||
return 0u;
|
||
}
|
||
}
|
||
return (s_rt.valid != 0u) ? 1u : 0u;
|
||
}
|
||
|
||
/*
|
||
* 函数功能:开页复位缓存(强制重取最新帧)
|
||
* 入口参数:无
|
||
* 返回值:无
|
||
*/
|
||
static void dc_init(void) {
|
||
s_seq = 0u;
|
||
(void)memset(&s_rt, 0, sizeof(s_rt));
|
||
}
|
||
|
||
/*
|
||
* 函数功能:逐行取数(第 1 行温度码值、第 2 行直流通道未配置)
|
||
* 入口参数:a_row - 全局行下标 0..1 uint16_t
|
||
* a_name - 名输出缓冲(框架 UI_BUF_STRLEN) char *
|
||
* a_value - 值输出缓冲 char *
|
||
* 返回值:无
|
||
* 限定条件:uiTask 绘制上下文
|
||
* 函数说明:温度行的值列形如"码2048"——"码"字是把"这是 12 位原始码、不是温度"写进
|
||
* 屏上而不是写进注释;快照该路带 UI_DATA_Q_RAW(写侧因该通道不参与线性标定而置位),
|
||
* 这里同时按品质位判无效,两处任一说话都足以显 "--"
|
||
*/
|
||
static void dc_refresh(uint16_t a_row, char *a_name, char *a_value) {
|
||
if (a_row == 0u) {
|
||
const ui_data_yc_t *p; /* 温度通道(只有本分支用得到,cppcheck 也这么判) */
|
||
|
||
DC_PUT(a_name, "温度");
|
||
if ((dc_frame_ready() == 0u) || (DC_YC_TEMP >= UI_DATA_YC_N)) {
|
||
DC_PUT(a_value, DC_INVALID);
|
||
return;
|
||
}
|
||
p = &s_rt.yc[DC_YC_TEMP];
|
||
if ((p->qds & (uint8_t)(UI_DATA_Q_IV | UI_DATA_Q_SB | UI_DATA_Q_BL)) != 0u) {
|
||
DC_PUT(a_value, DC_INVALID);
|
||
} else {
|
||
ui_w_editor_fmt_scaled((p->val > 0.0f) ? (int32_t)(p->val + 0.5f) : 0, 0u,
|
||
a_value, (uint32_t)UI_BUF_STRLEN);
|
||
/* 前缀"码":单位由品质位说话,不靠读的人猜(长度取 sizeof,改字不脱节) */
|
||
(void)memmove(a_value + (sizeof(DC_CODE_PREFIX) - 1u), a_value,
|
||
strlen(a_value) + 1u);
|
||
(void)memcpy(a_value, DC_CODE_PREFIX, sizeof(DC_CODE_PREFIX) - 1u);
|
||
}
|
||
return;
|
||
}
|
||
|
||
DC_PUT(a_name, "直流通道");
|
||
DC_PUT(a_value, "未配置");
|
||
}
|
||
|
||
/*
|
||
* 页面描述符(外部链接:生成物 ui_page_registry.c 按菜单树 #page=dc 绑定引用):
|
||
* 2 行单页列表页;band_h 必须 >0(选中行黑字需白带,同交流量页约定)
|
||
*/
|
||
const content_page_def_t ui_page_dc_desc = {
|
||
.id = "dc",
|
||
.title = "直流量",
|
||
.selectable = 1u,
|
||
.top_y = UI_LIST_TOP,
|
||
.pitch = UI_ROW_PITCH,
|
||
.band_h = UI_ROW_BAND_H,
|
||
.text_dy = 0,
|
||
.left_x = UI_LIST_LEFT_X,
|
||
.right_x = UI_LIST_RIGHT_X,
|
||
.rows_per_page = UI_LIST_ROWS,
|
||
.row_count = DC_ROW_N,
|
||
.rows = NULL,
|
||
.init_cb = dc_init,
|
||
.refresh = dc_refresh,
|
||
/* 自动失效轮询(框架级机制见 ui_content_page.h 的 auto_ms 注;口径见供给说明 §5.5):
|
||
* 直流/站温/温度行随 rt 帧每 200ms 推进,可见内容与电气量同拍——周期账目与
|
||
* ac 页同构(300 = 15 × LVGL 整刷周期 20ms,最坏屏上滞后 200 + 300 = 500ms),
|
||
* 四点账全文在 ui_page_ac.c 的 AC_AUTO_MS 注释,此处不复述 */
|
||
.auto_ms = 300u,
|
||
};
|