Files
STM32F4-Base/Drivers/BSP/UI/ui_page_dc.c
T
wandering1 a98d4e06e8 UI 其余五个实时页接入框架自动失效(按内容变化节拍分档取值)
- 描述符各加一行(机制 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 全补回。
2026-11-13 14:51:49 +08:00

158 lines
6.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 模块名称: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,
};