Files
STM32F4-Base/App/algo/adc_input.h
T
wandering1 d59c2198eb feat(adc): L1 采集层落地——STM32 ADC1 扫描 + 语义通道映射
新增 App/algo/adc_input.c/h(L1 采集与预处理层,落实 L1-3/L1-4):
- L1-4 语义通道映射表 k_adc_map[]:UA/UN/IA → TPAFE buf[6]/[5]/[2];
  UB/UC/IB/IC/IN/TEMP → STM32 ADC1 CH14/3/6/1/2/5。消费侧一律经
  adc_input_raw() 按语义取数,不写死下标(V0.2 改版只改表内容)。
- L1-3 STM32 ADC1 9 通道软件触发顺序扫描:HAL_ADC_Start + 逐通道
  PollForConversion/GetValue(EOC_SINGLE_CONV + 无 DMA,可逐通道轮询)。
- adc_input_poll() 统一"TPAFE 原子快照 + STM32 扫描";
  adc_input_init() 做映射自检(STM32 映射通道必落在扫描序列内,否则
  返回 -1),挡住"映射到不扫描的通道 → 恒读陈旧值"的静默错。

集成:
- adc_task.c 取数改走 L1 层(首帧日志补全 8 路 + 温度;心跳增
  adc1_rc/adc1_err 观测 STM32 侧健康度)。
- app_main.c 在 tpafe5160_init() 之后调 adc_input_init(),失败记
  SYSLOG_SELFTEST("ADC map fault")。
- Keil 工程挂 adc_input.c 并加 ../App/algo 包含路径。
- 文档同步:继电保护规划 §1.2/§3.1(L1-3/L1-4 改 ✅)、ADC通道映射说明
  §7/§8/§9、产品需求 §5.9/§9、架构总览 §7、AGENTS.md、App/README.md、
  App/task/README.md、新增 App/algo/README.md、boot_log_data 清单。

验证:
- @build 0 错 0 警;镜像无源文件新于 hex。
- 台架 @test PASS:ADC input layer init OK、adc1_rc=0/adc1_err=0
  (30 s ≈27 万次转换零超时)、seq 仍 1000.0 Hz、adc 栈峰值
  528→584 B(余 71%)、回读一致、零 [ERR]/HardFault。
  证据 docs/测试说明/boot_log_data/20261010_prod_adc_l1_boot_log.txt
- 内存快照已刷新(Flash 269,404→270,712 B)。
2026-10-10 16:06:31 +08:00

128 lines
5.2 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)。
* 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(语义映射)
*/
#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 最近一次扫描状态码 */
#define ADC_INPUT_RC_OK (0) /* 扫描成功 */
#define ADC_INPUT_RC_START (-1) /* HAL_ADC_Start 失败 */
#define ADC_INPUT_RC_TIMEOUT (-2) /* 转换轮询超时 */
#define ADC_INPUT_RC_NOT_RUN (-3) /* 尚未扫描过 */
/*
* 函数功能:ADC 输入层初始化
* 入口参数:无
* 返 回 值:0 - 成功;-1 - 语义映射表自检失败(映射指向了不会被扫描的通道)
* 限定条件:内核启动前调用(无 RTOS 依赖);STM32 ADC1 外设已由 MX_ADC1_Init 配好
* 函数说明:清空原始码值缓冲与统计,并做一次映射表自洽性自检;本层不重复配置外设。
*/
int adc_input_init(void);
/*
* 函数功能:采集一拍(TPAFE 原子快照 + STM32 ADC1 顺序扫描)
* 入口参数:无
* 返 回 值:TPAFE 快照结果(1=有新帧 0=无新帧 -1=参数错);STM32 侧状态另见
* adc_input_stm32_rc()
* 限定条件:仅**任务上下文**调用(TPAFE 快照走临界区)
* 函数说明:本函数只搬运原始码值,不做标定/运算。STM32 侧扫描失败不阻断 TPAFE
* 快照,也不影响返回值语义。
*/
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 扫描累计失败次数
* 入口参数:无
* 返 回 值:累计失败次数(启动失败或转换超时均计入)
* 限定条件:无
* 函数说明:单调递增,供心跳日志观测。
*/
uint32_t adc_input_stm32_errs(void);
#ifdef __cplusplus
}
#endif
#endif /* ADC_INPUT_H */