feat(adc): 新增变比维 r 三维折算,录波段格式升 v2

采样板注入 Ua=5V/Ia=0.5A 读数偏小,根因是固件只输出引脚电压、
缺「端子→引脚」变比。折算改三维:

工程量 = (code + b) × k[µV/码] × 1e-6 × r

k 保持 ROM 引脚 LSB,b 为零点,r 为端子变比(int32 Q16)。
变比不能并进 k:UA 端子域 k 达 1.5e5 µV/码、Q16 溢出 int32;
r 单独存 Q16 不溢出。两点标定改标 r,k 仍是板级事实。

- 新开单段 [adc_cal_sec](8 键 r_ua..r_in),cfg 段数达 8/8 上限
- 一次变比复用 prot_set 四项,不新开段;r=0 表示本路不折算
- ROM 默认带台架实测变比(电压族 1000、电流族 29.4118),
  烧进固件即显二次值;VALID 仍须两点标定,两者互不派生
- eng 判据改「每路要么已配变比、要么削顶不显示」,不再看 VALID
- 104 地址 0x8050~0x8057 写 r,run_par_cal_r_set 写值与置脏同函数
- 录波 v2:通道表加 int32 r_q16,头 128→160、整段 5250→5282;
  code_to_milli 用余数分解换等价单次圆整,20 万组大整数对拍 0 不符
- 文档同步:采集与算法层/通道映射/故障录波/网络配置/配置文件/
  产品需求/内存台账,历史带日期实测数字按冻结口径不改
- 单测 13 套全绿,/keil-build 0 错误 0 警告(256024/31760/
  2080/152368),RAM 实测回填内存内容分配策略 §6.1
This commit is contained in:
2026-11-11 11:31:34 +08:00
parent 8115fb9a87
commit 3675b89e8e
35 changed files with 1653 additions and 505 deletions
+52 -1
View File
@@ -15,6 +15,10 @@
* ROM 系数覆写(#undef/#define):把"板级理论系数"替换为合成端子侧口径
* (10 mV/码,K_DIM),模拟两点标定完成后的 ROM/默认状态——合法带随之
* 锚定合成值,adc_cal_set 走正规路径置 VALID,测试不白盒改引擎内存。
* 变比 r 同步合成化为 1.0:本套件证的是「折算链别丢量纲」,不是变比数值;
* r = 1.0 让上面那对互逆换算(eng ↔ code)继续成立,也就与
* docs/算法/采集与算法层设计说明.md §13.6 的合成口径一致。r ≠ 1.0 的
* 放大效应单独由 TC-PROTDIM-011 钉(那时故意让判据输入被放大 1000 倍)。
*
* 覆盖点(族 TC-HOST-PROTDIM,属主登记处 = 本目录):
* TC-PROTDIM-001 标定链基线:0.5 A/100 V/0 V 注入 → 七类元件全静默(含
@@ -36,6 +40,11 @@
* 14.4 保持(ret 14.25)、14.1 释放
* TC-PROTDIM-010 聚合与独立性:OC1+OV 同拍动作位图 = 双位;撤 IA →
* OC1 返回、OV 保持(互不污染)
* TC-PROTDIM-011 变比确实进折算(不是只存在配置里):把 IA 的 r 从合成 1.0
* 改成 1000.0 后,同一批码值的判据输入被放大 1000 倍 →
* 0.5 A 立刻顶穿 OC1(10 A);改回 1.0 后恢复静默。
* 反错配方向:若哪天有人把 r 从 apply() 里摘掉、只留配置段,
* 本用例立刻翻红。
*
* 通过:全部 TC PASS(main 返回 0)。
* 创建日期:2026-10-25(道A 量纲回归用例)
@@ -91,12 +100,17 @@ static int s_total = 0, s_passed = 0, s_failed = 0;
* K_DIM = 655360000 Q16 = 10000 µV/码 = 10 mV/码:
* 电压类 100 V rms → 峰值 141.42 V → 14142 码(TPAFE 半量程内,量级刻意
* 贴近端子变比两点标定完成后的真实形态);电流类二次值经变换器落到同一定标。
* B_IA = -30 码(零点偏移,经 apply 精确对消——验证 b 参与全链而非仅落盘)。 */
* B_IA = -30 码(零点偏移,经 apply 精确对消——验证 b 参与全链而非仅落盘)。
* r 的合成口径 = 1.0(Q16 = 65536):见文件头「变比 r 同步合成化为 1.0」那段。 */
#include "adc_cal.h"
#undef ADC_CAL_K_Q16_TPAFE
#undef ADC_CAL_K_Q16_STM32
#undef ADC_CAL_R_Q16_VOLT
#undef ADC_CAL_R_Q16_CURR
#define ADC_CAL_K_Q16_TPAFE (655360000L)
#define ADC_CAL_K_Q16_STM32 (655360000L)
#define ADC_CAL_R_Q16_VOLT (65536L) /* 合成口径 r = 1.0:本套件证"链条别丢量纲",不是变比数值 */
#define ADC_CAL_R_Q16_CURR (65536L)
#define K_DIM ADC_CAL_K_Q16_TPAFE
#define B_IA_DIM (-30L)
@@ -456,6 +470,42 @@ static void tc_010_mask(void) {
CHECK(prot_elm_active_mask() == (1uL << PE_OV), "010: mask = OV only");
}
/* ===================== TC-PROTDIM-011 变比确实进折算 ===================== */
/* 这条是「r 进折算」的反错配锁:配置段里写着 1000.0 还不够,必须证明它真的
* 乘进了 adc_cal_apply——否则 r 就退化成「只存在配置里的一个数」,屏上与判据
* 都会拿着引脚电压冒充二次值。手法:同一批码值,只改 IA 的变比,OC 判据
* 收到的量必须恰好放大 1000 倍(期望值独立写出,不引实现常量)。 */
static void tc_011_ratio_scales(void) {
uint32_t i;
double got;
printf("[TC-PROTDIM-011] ratio enters apply(): 1000x on IA trips OC1\n");
dim_setup();
isolate_oc_family(); /* 只留 OC1(10 A,dly=0 出厂档) */
/* 基线:合成口径 r = 1.0 -> 0.5 A 远低于 OC1 定值,静默 */
for (i = 0u; i < 45u; i++) { dim_beat(0.5, 100.0, 0.0); }
CHECK((pick_of(PE_OC1) == 0) && (assert_of(PE_OC1) == 0),
"011: r = 1.0 -> 0.5 A silent (baseline)");
/* 把 IA 变比改成 1000.0(Q16 = 1000 x 65536):同一码值,折算输出 x1000 */
CHECK(adc_cal_set_ratio(ADC_SEM_IA, 65536000L) == 0, "011: IA ratio set to 1000.0");
got = (double)adc_cal_apply(ADC_SEM_IA, dim_code(0.5, (double)B_IA_DIM));
CHECK((got > 0.5 * 1000.0 * 0.999) && (got < 0.5 * 1000.0 * 1.001),
"011: apply(code for 0.5 A) = 500 A (ratio really multiplies)");
/* 同一物理注入现在应顶穿 OC1(10 A) —— 变比真到了判据手里 */
for (i = 0u; i < 5u; i++) { dim_beat(0.5, 100.0, 0.0); }
CHECK((pick_of(PE_OC1) != 0) && (assert_of(PE_OC1) != 0),
"011: same 0.5 A now trips OC1(10 A) -> ratio reached the criteria");
/* 改回 1.0:判据看到的又只是 0.5 A,应当返回 */
CHECK(adc_cal_set_ratio(ADC_SEM_IA, 65536L) == 0, "011: IA ratio back to 1.0");
for (i = 0u; i < 45u; i++) { dim_beat(0.5, 100.0, 0.0); }
CHECK((pick_of(PE_OC1) == 0) && (assert_of(PE_OC1) == 0),
"011: ratio back to 1.0 -> OC1 returns (the effect is reversible)");
}
int main(void) {
printf("=== Prot Dim Regression Tests ===\n");
adc_cal_init(); /* 先把 RAM 系数置成合成 ROM(各 TC 内还会重跑) */
@@ -469,6 +519,7 @@ int main(void) {
tc_008_uv();
tc_009_3u0();
tc_010_mask();
tc_011_ratio_scales();
printf("\n=== Prot Dim Regression Tests: %d/%d PASSED (failed=%d) ===\n",
s_passed, s_total, s_failed);
return (s_failed == 0) ? 0 : 1;