Files
STM32F4-Base/App/algo/adc_input.h
T
wandering1 5a9988b557 chore(注释): 清掉源码里不可检索的过程编码
清掉的(读者无从解析、且所指文档已不存在)
- 已删任务文档的编号:Task #32、其内部 §5 / §4.3、P1-5、P0-2、P1-4a、
  "方案 a"、"Lead 批准 2026-10-12"
- 正文里当代词用的文件版本号:"(v2.7 起为 AboveNormal)""已随 v2.0 事件
  驱动改造删除""(v2.0:DMA 消费)""见文件头 v1.3 说明"等 → 改写成陈述现状
- 测试与脚本同类:adc_input 桩头"v2.0:DMA 模型"、stub/adc.h 的 v2.0、
  check_cubemx_survival.py 段头的"2026-10-10 v2.8"、run_all_suites.py 的"方案 A"

刻意保留
- 可检索登记簿锚点:P-AUDIT 真条目(P0-1/P1-8/P2-1/P2-9/P3-11)、S6/S11、
  E-31/E-44、N-18/N-23/N-32、B1/B5/B7/B8、L1-x~L5-x 功能号
- 文件头修改记录块内的 vN.M(规范 V1.0 §2.1/§2.2 要求保留该块;块内编号
  在本文件内自洽可读)

顺带纠正注释与代码已经不一致的过时事实
- 仍把 TIM6 写成现行节拍源:Src/main.c 的 include 注释与回调注释、
  Src/freertos.c 的 adcTask 块 → 改 TIM3;adc_input.h 修订条目里"ADC1 只认
  TIM2/TIM3/TIM8 的 TRGO"不准确 → 换成指向判据(ADC采样节拍设计说明 §3.2)
- App/algo/phasor.c 双区注释称"唯一消费者是 adcTask、为后续保护任务预留",
  实际 protectTask 已跨上下文读(prot_elm_run -> phasor_get)→ 改为"读者跨
  adcTask 心跳与 protectTask 判据两个上下文,勿改加锁、勿取消双区",并同步
  修正 docs/算法/采集与算法层设计说明.md 同一句
- adc_tick_irq_notify() 的"拒绝 ISR 内计算"理由仍写"内含 2 ms 忙等"(DMA 化
  后已无忙等)→ 换成三条真实理由:任务级共享数据 / 计算量 / 生成区回调
- 裸 §5(指代不明)与"规划 §1.6 / 规划 §4"昵称式 → 写成完整路径紧邻式

字节卫生(Edit 会静默剥 BOM)
- App/task/ui_task.c 与 Drivers/BSP/UI/ui_net_sink.c 被剥掉 BOM 两次,均按
  3 字节 EF BB BF 前缀补回并复验;全部 20 个文件 CR=0、U+FFFD=0、无行尾空白

门禁
- @build 0 错误 0 警告,且 Program Size 与清理前逐项相同
  (Code=213356 RO=18580 RW=1184 ZI=131480)→ 纯注释改动、中文未被误重编码
- ui-golden 首跑红:新工作树缺被 gitignore 的黄金参考 simulator/tests/ref/
  (不入库、只在主工作树生成过);从主工作树复制该基线后复跑通过 → 注释改动
  零像素影响
- 全套 pre-commit 在这 20 个文件上 Passed(coding-standard / cppcheck /
  6 个主机单测 / doc-links / task-table / mem-numbers / cubemx-survival /
  registration-check / mem-budget / font-charset / ui-golden / id-check)
- id-check 可判定比例 82.71% -> 82.88%(删掉的是"形似 P-AUDIT 但查无定义"的
  假锚点),悬空引用 863 -> 854
2026-10-21 11:39:53 +08:00

165 lines
7.3 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.
/*
* 模块名称:ADC 输入层(L1 采集与预处理)
* 模块功能:把两片转换器的原始码值按**语义**(UA/UB/UC/UN/IA/IB/IC/IN/温度)统一
* 暴露,使上层(UI / 自检 / 保护算法)**按语义取数,不写死下标**:
* ① 语义通道映射表(L1-4)——权威口径 docs/硬件平台/ADC通道映射说明.md;
* ② STM32 ADC1 9 通道采样(L1-3)——由 **TIM3 TRGO 硬件触发 + DMA 双缓冲
* 搬运**,本层只消费、不触发、不等待。
* V0.1 上 8 路电气量分属两片转换器(硬件缺陷 N-18):UA/UN/IA 走
* TPAFE5160(16 位 / ±5 V 双极性),UB/UC/IB/IC/IN 走 STM32 ADC1
* (12 位 / 0~3.3 V 单极性)。V0.2 改版(8 路电气量全部接 TPAFE)
* 只改映射表内容,本层 API 与上层语义不动。
* 适用平台:STM32F407ZGTx + TPAFE5160
* 作者:王建锋
* 创建日期:2026-10-10
* 修改记录:
* v1.0 2026-10-10 王建锋 创建:L1-3(STM32 ADC1 扫描)+ L1-4(语义映射)
* v2.0 2026-10-10 王建锋 STM32 侧改 TIM3 TRGO 硬件触发 + DMA 双缓冲消费:
* 消除逐通道轮询的 2 ms 忙等;节拍源 TIM6 -> TIM3
* (换源判据:F4 上 ADC1 收不到 TIM6/TIM7 的 TRGO,见
* docs/子系统设计/ADC采样节拍设计说明.md §3.2);新增
* adc_input_stm32_seq() / _hw_errs()
*/
#ifndef ADC_INPUT_H
#define ADC_INPUT_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* 语义通道(V0.1:8 路电气量 + 温度)。枚举值即语义编号,顺序不得随意变更;
* 备用通道(RESERVED)不接入语义,故不在此枚举内。 */
typedef enum {
ADC_SEM_UA = 0, /* A 相电压(TPAFE) */
ADC_SEM_UB, /* B 相电压(STM32) */
ADC_SEM_UC, /* C 相电压(STM32) */
ADC_SEM_UN, /* 零线电压(TPAFE) */
ADC_SEM_IA, /* A 相电流(TPAFE) */
ADC_SEM_IB, /* B 相电流(STM32) */
ADC_SEM_IC, /* C 相电流(STM32) */
ADC_SEM_IN, /* 零线电流(STM32) */
ADC_SEM_TEMP, /* 温度(STM32,V_ZL2) */
ADC_SEM_COUNT /* 语义通道数(哨兵) */
} adc_semantic_t;
/* 数据来源:V0.1 的 8 路电气量分属两片转换器(N-18) */
typedef enum {
ADC_SRC_TPAFE = 0, /* TPAFE5160:16 位、±5 V 双极性、8 通道同步 */
ADC_SRC_STM32 /* STM32 ADC1:12 位、0~3.3 V 单极性、9 通道顺序扫描 */
} adc_source_t;
/* 语义通道 → 物理通道描述 */
typedef struct {
adc_source_t source; /* 数据来源 */
uint8_t index; /* TPAFE 源:驱动 buf 下标 0..7;STM32 源:ADC1 通道号 0..15 */
} adc_channel_desc_t;
/* TPAFE5160 一帧通道数(= 驱动 buf 长度) */
#define ADC_INPUT_TPAFE_CH_NUM 8U
/* STM32 ADC1 顺序扫描通道数(Rank 1..9) */
#define ADC_INPUT_STM32_CH_NUM 9U
/* STM32 ADC1 最近一次取帧状态码(DMA 消费,已无"轮询超时"这一档) */
#define ADC_INPUT_RC_OK (0) /* 取到新一帧 */
#define ADC_INPUT_RC_START (-1) /* HAL_ADC_Start_DMA 挂载失败 */
#define ADC_INPUT_RC_STALL (-2) /* 本拍无新帧(TIM3 未启动 / ADC 停摆 / DMA 出错) */
#define ADC_INPUT_RC_NOT_RUN (-3) /* 尚未取过帧 */
/*
* 函数功能:ADC 输入层初始化
* 入口参数:无
* 返 回 值:0 - 成功;-1 - 语义映射表自检失败(映射指向了不会被扫描的通道);
* -2 - STM32 ADC1 的 DMA 挂载失败
* 限定条件:内核启动前调用(无 RTOS 依赖);STM32 ADC1 外设已由 MX_ADC1_Init 配好
* 函数说明:清缓冲与统计 + 映射表自洽性自检 + 挂载一次 ADC1 DMA(此后转换由
* TIM3 TRGO 硬件触发、DMA 自动搬运)。须在启动采样节拍之前调用。
*/
int adc_input_init(void);
/*
* 函数功能:采集一拍(TPAFE 原子快照 + 消费一帧 STM32 ADC1 DMA 采样)
* 入口参数:无
* 返 回 值:TPAFE 快照结果(1=有新帧 0=无新帧 -1=参数错);STM32 侧状态另见
* adc_input_stm32_rc() / adc_input_stm32_seq()
* 限定条件:仅**任务上下文**调用(TPAFE 快照走临界区)
* 函数说明:本函数只搬运原始码值,不做标定/运算;STM32 侧**零忙等**(不触发、
* 不等待转换)。STM32 侧无新帧不阻断 TPAFE 快照,也不影响返回值语义。
* ⚠ STM32 侧数据滞后 1 拍(乒乓双缓冲固有延迟,9 路一致)。
*/
int adc_input_poll(void);
/*
* 函数功能:取语义通道的物理描述
* 入口参数:ch - 语义通道
* 返 回 值:指向静态描述表的指针;ch 越界返回 NULL
* 限定条件:无
* 函数说明:供自检注入 / UI 通道序等需要"语义 → 物理通道"映射的场景使用。
*/
const adc_channel_desc_t *adc_input_desc(adc_semantic_t ch);
/*
* 函数功能:读取语义通道的原始码值(未标定)
* 入口参数:ch - 语义通道
* out - 输出原始码值(TPAFE 侧为 16 位二进制补码;STM32 侧为 0..4095)
* 返 回 值:0 - 成功;-1 - 参数错;-2 - 该来源当前无有效数据
* 限定条件:无
* 函数说明:消费侧取数的唯一入口(按语义,不写死下标)。取数前须先成功
* adc_input_poll() 一次。
*/
int adc_input_raw(adc_semantic_t ch, int32_t *out);
/*
* 函数功能:读取 STM32 ADC1 最近一次取帧状态码
* 入口参数:无
* 返 回 值:ADC_INPUT_RC_xxx
* 限定条件:无
* 函数说明:供心跳日志 / 自检观测 STM32 侧健康度。
*/
int adc_input_stm32_rc(void);
/*
* 函数功能:读取 STM32 ADC1 停摆故障累计次数
* 入口参数:无
* 返 回 值:DMA 挂载失败次数 + "连续 >=2 拍无新帧"的次数
* 限定条件:无
* 函数说明:单调递增,供心跳日志观测。单拍无新帧(消费者相位伪影)不计入。
*/
uint32_t adc_input_stm32_errs(void);
/*
* 函数功能:读取 STM32 ADC1 的丢帧次数
* 入口参数:无
* 返 回 值:DMA 完成计数一次前进 >1 的次数(中间那帧已被覆盖,未及消费)
* 限定条件:无
* 函数说明:与 errs 分开——gap = 消费者超拍(单拍耗时 > 1 ms),
* err = 节拍源/ DMA 停摆。两类故障处置不同,混在一起就查不了。
*/
uint32_t adc_input_stm32_gaps(void);
/*
* 函数功能:读取 STM32 ADC1 的 DMA 整帧完成计数
* 入口参数:无
* 返 回 值:DMA 半区/整区完成中断的累计次数(正常时每拍 +1)
* 限定条件:无
* 函数说明:与 tpafe5160_frame_seq() 对称的 STM32 侧"节拍是否还在喂数据"观测量。
*/
uint32_t adc_input_stm32_seq(void);
/*
* 函数功能:读取 STM32 ADC1 的 HAL 层错误回调累计次数
* 入口参数:无
* 返 回 值:HAL_ADC_ErrorCallback 触发次数(DMA 传输错误等)
* 限定条件:无
* 函数说明:与 adc_input_stm32_errs() 分开计数,用于区分"节拍源停了"与"DMA 出错"。
*/
uint32_t adc_input_stm32_hw_errs(void);
#ifdef __cplusplus
}
#endif
#endif /* ADC_INPUT_H */