EIS电池阻抗测量芯片验证系统(二):FPGA激励与ADC采集原理

1. 系统架构概览

EIS验证芯片(FPGA/ASIC)采用寄存器映射架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌─────────────────────────────────────────────────────────────────────┐
│ Host (I2C 总线) │
└────────────────────────────────┬────────────────────────────────────┘

┌───────────────────────┴───────────────────────┐
│ Register Table │
│ CONF | STAT | CTRL | EIS_Current | EIS_Cell │
└───────┬───────────────┬───────────────────────┘
│ │
┌───────▼───────┐ ┌─────▼─────┐
│ EIS-Gen │ │ EIS-Test │
│ (正弦激励) │ │ (ADC解算) │
└───────┬───────┘ └─────┬─────┘
│ 同步控制 │
│◄──────────────►│
┌───────▼───────┐ ┌─────▼─────┐
│ DAC │ │ Filter │
└───────┬───────┘ └─────┬─────┘
│ │
▼ ▼
┌─────────────────────┐
│ Battery │
└─────────────────────┘

2. EIS-Gen:正弦激励生成

2.1 原理

EIS-Gen根据 EIS current Register 中的参数,生成数字正弦波数据:

  • 频率:由 FREQ_INDEX、BASE_FREQ_INDEX 查表得到
  • 幅值:可配置
  • 相位:256点离散化一个周期

2.2 DAC查表

PyEisAdcCreator 中的 DAC_INDEX_TABLE 是256点正弦采样表:

1
2
3
# 256点 sin 曲线离散值 (0~255 归一化)
data = [125, 122, 119, ..., 128] # 一个完整周期
DAC_INDEX_TABLE = data[::-1] # 逆序,index 0 对应起始相位

DAC根据当前采样索引查表输出对应电压,驱动电流源对电池施加正弦激励。

2.3 频率与周期

1
2
3
FREQ_TABLE[freq_index][base_freq_index]  # Hz
T_sin = 1 / freq # 正弦周期(秒)
t = T_sin / 256 # 每个DAC采样点间隔

3. ADC采集与EIS-Test

3.1 同步控制

关键:激励(DAC)与采集(ADC)必须严格同步,否则无法准确计算相位差。

  • EIS-Gen 与 EIS-Test 通过同步控制模块互联
  • 同一时钟基准,确保采样点与激励点的相位关系已知

3.2 采样时序

  • TABLE_START_INDEX:正弦表起始索引
  • EISDLY_OFFSET:激励到采样的延迟(补偿硬件链路延迟)
  • OSR (Over-Sampling Ratio):过采样率,提高ADC分辨率

采集的17个点对应正弦波上等间隔的17个相位,用于后续解算实部/虚部。

3.3 ADC期望值计算

PyEisAdcCreator 根据 DAC 查表序列和 ADC_DATA_OFFSET,计算每个采样点的期望ADC值

1
2
base_value = (DAC_data << 10)  # 19bit
final_value = base_value + ADC_DATA_OFFSET # 带符号偏移

验证时,将实际ADC读数与期望范围比较,判断芯片功能是否正确。

4. 寄存器配置流程

一次单频率测量的典型流程:

步骤 寄存器 说明
1 0x42 FREQ_INDEX + BASE_FREQ_INDEX
2 0x3F OSR_SEL
3 0x45~0x48 EISDLY_OFFSET (32bit)
4 0x43 TABLE_START_INDEX
5 0x4D~0x4F ADC_DATA_OFFSET
6 0x3E Dither
7 0x51~0x54 VADC TRIM (校准)
8 0x41 ADC_GO (启动测量)

写 0x80 到 0x41 后,芯片开始一次完整测量。软件必须等待测量完成(DELAY:10 秒)再读取结果。

5. 测试到底在测什么?

这是理解整个系统的关键:测试的不是寄存器,而是物理信号

5.1 物理信号路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
配置寄存器 (I2C写)

┌─────────────────────────────────────────────────────────────┐
│ FPGA / ASIC │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ EIS-Gen │ ──→ │ DAC │ ──→ │ 电流源 │ ──→ Battery │
│ │ (数字正弦)│ │ (DA转换)│ │(V→I转换)│ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ ↑ ↓ │
│ 同步控制 ┌─────────┐ │
│ │ │ ADC │ ← 电池电压采样│
│ │ │ (AD转换)│ │
│ │ └────┬────┘ │
│ │ ↓ │
│ ┌────┴────┐ ┌─────────┐ │
│ │ EIS-Test│ ← 接收ADC数字量 │EIS-Cell │ │
│ │(同步解算)│ │寄存器 │ │
│ └────┬────┘ └────┬────┘ │
│ │ ↓ │
└───────┼────────────────────────────────────────────── I2C读 ─┘

计算结果

信号流

  1. DAC 输出:FPGA 内部产生 256 点离散正弦数字信号 → DAC 转为模拟电压
  2. V→I 转换:电压信号通过运放电路转为对电池的交流激励电流 I(t)
  3. ADC 采样:同时,ADC 在电池两端采样电压信号 V(t)
  4. 同步解算:EIS-Test 在同一时钟基准下,知道激励和采样的相位关系,计算出阻抗

5.2 测试验证的是什么?

测试验证的是 ADC 采样值 —— 即 ADC 在电池两端采集到的电压响应。

为什么是验证 ADC 值?

  • ADC 是整个测量链路的核心:DAC 输出的是确定的数字正弦波(已知),但电池是未知的被测对象
  • ADC 值 = 电池对激励的响应:若芯片工作正常,ADC 在正确的时刻采样,应该得到一个预期的值
  • 验证 ADC 值 = 验证整个信号链路:DAC → 运放 → 电池 → ADC 采样 → 同步控制

具体验证什么?

假设激励是 I(t) = I₀·sin(ωt),ADC 采样到 V(n),理论上:

1
V(n) = Z(ω) × I₀ × sin(ωt + φ)

其中 Z(ω) 是电池在频率 ω 下的阻抗。

但我们怎么知道 Z(ω) 是多少?

答案是:我们不知道真实的 Z(ω),但我们知道在理想条件下 ADC 应该落在哪个范围内。范围由 PyEisAdcCreator 根据 DAC 查表序列和 ADC_DATA_OFFSET 计算出来。

5.3 PyEisAdcCreator 计算期望值的逻辑

1
2
3
4
5
6
7
DAC Index → DAC Data → 期望的 ADC 值

已知: DAC 在 t0 时刻输出电压 Vdac(0)
已知: 电池阻抗 Z(ω)(假设为标称值)
已知: ADC_DATA_OFFSET(ADC 偏置校准值)

期望 ADC = Vdac(0) / Z(ω) × Gain + ADC_DATA_OFFSET

也就是说

  • DAC 查表输出是已知的(FPGA 内部)
  • 电池假设是标准电芯(已知标称阻抗)
  • 于是期望 ADC 值是可以计算的

5.4 读比较 vs 范围比较

读命令 (类型2)

1
,2,0x58,0x14,4,,  # ADC_DATA_OFFSET[18:0] @ 0x14 寄存器
  • 芯片完成一次 EIS 测量后,ADC 结果存在 EIS-Cell 寄存器中
  • 上位机通过 I2C 读 读取实际 ADC 值
  • 用于:当 ADC 值接近 0 时,范围比较无意义(无法判断正负),直接读回具体值

范围比较命令 (类型4)

1
,4,0x58,0x0b,6,"0xa5,0xaf,0x05,0xde,0x48,0x06"
  • 0x0b 是第一个 ADC 数据寄存器的地址
  • 6 = 3字节(实际值) + 3字节(期望范围上界)
  • STM32 内部:
    1. I2C 读回芯片寄存器的 3 字节 ADC 值
    2. 与低/高范围边界比较
    3. 在范围内 → Pass,不在 → Fail
  • 不需要上位机参与比较逻辑,STM32 直接返回 Pass/Fail 状态

为什么需要范围比较?

  • 工艺波动:不同电芯的阻抗有 ±5% 左右的偏差
  • 温度影响:电芯阻抗随温度变化
  • 允许误差:范围比较允许 ±5% 误差,而非精确值

5.5 测试场景

场景 验证什么 命令类型
芯片功能验证 给定已知电芯,ADC 值是否在预期范围 范围比较
寄存器读写 配置寄存器后能否正确锁存 写→读回比较
量产筛选 电芯阻抗是否在合格范围内 范围比较
调试阶段 直接读回 ADC 原始值查看 读命令
近零点判断 ADC 值接近 0,无法判断正负 读命令

5.6 一次完整测试的物理含义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1. 配置寄存器 (I2C 写)
→ 设置激励频率、FREQ_INDEX、OSR 等

2. 写 ADC_GO (I2C 写)
→ FPGA 开始:
DAC 输出正弦激励 → 电池响应 → ADC 采样 → EIS-Test 解算

3. 延时等待 (DELAY:10)
→ ADC 完成需要一定时间

4. 验证 17 个 ADC 点 (I2C 范围比较)
→ 每个 ADC 点对应正弦波的 17 个等间隔采样时刻
→ 17 个点的期望值组成完整的正弦波包络
→ 全部通过 → 该频率点 Pass

精髓:验证的不是寄存器值,而是 ADC 在物理上采样到的电压信号。寄存器只是配置和控制手段,信号链路才是核心。


6. 一个频率的 Test

“一个频率的 Test”:在单一频率配置下,完成一次”配置→启动→采集→验证”的完整流程。

多个频率需要:

  1. 修改 FREQ_INDEX 等参数
  2. 重新配置寄存器
  3. 再次写 ADC_GO
  4. 等待并读取

因此,FPGA 不自动扫频,每次频率切换都由上位机通过 CSV 脚本驱动

7. 与 PyEisAdcCreator 的关系

PyEisAdcCreator 根据 config.yml 中的 FREQ_INDEX: 0~0xF 等参数:

  1. 生成16组配置(FREQ_INDEX 0~15)
  2. 每组计算对应的 ADC 期望值范围
  3. 输出 output_pycomsender.csv,供 PyComSender 执行

CSV中每组配置包含:

  • 约20条寄存器写命令
  • 1条 DELAY:10
  • 17条 ADC 结果验证命令(范围比较或读命令)

下一篇文章将介绍上位机 PyQt 架构与 CSV 加载、解析流程。


系列目录
01. EIS原理与电池阻抗谱
02. FPGA ADC激励与电池阻抗扫描原理(本文)
03. 上位机架构:PyQt与CSV脚本解释器
04. STM32命令转发与串口-I2C桥接
05. CSV脚本解释器实现精髓