feat(adc): UN 标定完成、标定脚本归集到 test/host/cal/
CI / 静态门禁 (pre-commit) (push) Failing after 4m15s
CI / 主机侧单测 (MSVC) (push) Failing after 1m41s

- UN 通道 5 点最小二乘标定完成:r=555.382141, b=-1, 残差 0.038%, R²=0.99999967
- UA/IA/UN 三路 VALID 置位,保护解卡
- ROM 默认值更新为当前标定值(ADC_CAL_R_Q16_VOLT=555.144958)
- UB/UC/UN 通过 104 写入 ROM 默认值,config.ini 同步
- cal_fit.py 新增 ROLD 表自动读取,不再需要手传 --r-old
- 执行卡精简至 126 行,新增 cal_collect.py 采集脚本与 ROLD 填表
- 标定脚本(cal_fit/cal_write/cal_collect)归集到 test/host/cal/
- 全库文档路径引用同步更新(8 文件)
- UN 当前态文档改写:明确零序电压 U0 语义、本台架未接线状态
- 删除已失效的外部知识底座文档链接
This commit is contained in:
2026-11-13 11:26:36 +08:00
parent 7c505b2457
commit 40a2816a99
23 changed files with 327 additions and 331 deletions
+92
View File
@@ -0,0 +1,92 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""两点标定写入器:C_SE_NC_1 两段写下发 r/b,C_RD 读回复核。
复用台架已验收主站库 test/host/iec104_master.py(不重写协议层)。
地址(App/algo/run_par.c run_par_104_write):r = 0x8050+slot,
b = 0x8048+slot;slot UA0/UN3/IA4。执行卡:
docs/测试说明/专项验证/ADC多点标定执行流程.md §4。
用法:
python test/host/cal_write.py --r 0x8050=995.99 --b 0x8048=-1 \
--read 0x8050,0x8048 --expect 995.99,-1
python test/host/cal_write.py --read 0x8050,0x8054 --expect 995.99,29.52
写入顺序刻意**先 r 后 b**:b 走 adc_cal_set() 置 VALID 位,而 VALID 要求
r 已在带——先让 r 就位,语义干净。--b 必须是整数码值。
PN(否定确认)= 执行段拒绝:看串口 `[ERR] set ch=... rejected` 行。
输出纯 ASCII,可直接重定向归档为台架证据;exit 0 全过 / 1 有失败 / 2 连接或协议错误。
"""
import argparse
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import bench_defaults # noqa: E402
import iec104_master as m104 # noqa: E402
def parse_pair(text):
addr_s, val_s = text.split("=", 1)
return int(addr_s, 0), float(val_s)
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--ip", default=bench_defaults.DEVICE_IP)
ap.add_argument("--port", type=int, default=2404)
ap.add_argument("--r", action="append", default=[],
help="0xADDR=FLOAT ratio write (repeatable, issued first)")
ap.add_argument("--b", action="append", default=[],
help="0xADDR=INT zero-code write (repeatable, sets VALID)")
ap.add_argument("--read", default="",
help="comma-separated IOA list, C_RD readback")
ap.add_argument("--expect", default="",
help="comma-separated expected values, same order as --read")
a = ap.parse_args()
reads = [x.strip() for x in a.read.split(",") if x.strip()]
expects = [float(x) for x in a.expect.split(",")] if a.expect else []
if not a.r and not a.b and not reads:
ap.error("need at least one --r / --b / --read")
ck = m104.Checks()
try:
m = m104.Master(a.ip, a.port)
except Exception as exc:
print("CONNECT FAIL: %r" % (exc,))
return 2
try:
m._send(m104.u_frame(m104.U_STARTDT_ACT), "U STARTDT act")
ck.add("startdt_con", m.wait_event(
lambda e: e[0] == "startdt_con", 5.0) is not None)
for text in a.r: # 1) ratio first
addr, val = parse_pair(text)
m104.se_write(m, ck, addr, val, "r_%04X" % addr)
for text in a.b: # 2) zero + VALID
addr, val = parse_pair(text)
if abs(val - round(val)) > 1e-6:
print("WARN b=%s not an integer code, truncated to %.0f"
% (text, round(val)))
val = float(round(val))
m104.se_write(m, ck, addr, val, "b_%04X" % addr)
for i, addr_s in enumerate(reads):
want = expects[i] if i < len(expects) else 0.0
m104.rd_set(m, ck, int(addr_s, 0), want, "rd_%s" % addr_s)
finally:
m.close()
bad = [n for n, ok, _ in ck.items if not ok]
print("SUMMARY %s total=%d fail=%d" %
("PASS" if not bad else "FAIL", len(ck.items), len(bad)))
if bad:
print("FAILED: %s" % ", ".join(bad))
return 0 if not bad else 1
if __name__ == "__main__":
sys.exit(main())