EIS电池阻抗测量芯片验证系统(四):STM32命令转发与协议

1. 角色定位

STM32F407IICBridge 是串口到 I2C 的协议桥

  • 上游:PC 通过 UART 发送二进制命令
  • 下游:STM32 将命令转换为 I2C 读写,与 EIS 芯片(0x58)通信
1
PC (PyComSender)  →  UART  →  STM32  →  I2C  →  EIS FPGA (0x58)

2. 硬件连接

接口 引脚 说明
UART USART2 (PA2/PA3) 与 PC 通信,115200 8N1
I2C I2C1 (PB6/PB7) 与 EIS 芯片通信,100kHz
调试 USART1 可选 Debug_Printf 输出

3. 命令协议

3.1 命令头部(4 字节)

每次命令先接收 4 字节头部:

字节 含义
[0] cmd_type:1=写 2=读 3=比较 4=范围比较
[1] slave_addr:I2C 从机地址(7bit,如 0x58)
[2] reg_addr:寄存器地址
[3] data_length:数据长度

3.2 数据部分(按需)

  • 写命令 (1):再接收 data_length 字节写入数据
  • 比较命令 (3):再接收 data_length 字节期望值
  • 范围比较 (4):再接收 6 字节(低3+高3)范围值
  • 读命令 (2):无额外数据

3.3 响应

  • 所有命令:先返回 1 字节 status(0=成功,非0=错误码)
  • 读/比较命令:成功时再返回读取的 data_length 字节(含 CRC8)

4. CRC8 校验

  • 多项式:0x07 (x^8 + x^2 + x + 1)
  • 计算范围:slave_addr + reg_addr + data
  • 读命令和比较命令的数据部分最后 1 字节为 CRC8

5. ProcessCommand 流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// main.c - ProcessCommand()
// 1. 接收 4 字节命令头
HAL_UART_Receive(&huart2, cmd_buffer, 4, UART_TIMEOUT);

// 2. 若有数据部分,再接收
if (cmd_type == WRITE || COMPARE || COMPARE_RANGE)
HAL_UART_Receive(&huart2, dataBuffer, data_length, UART_TIMEOUT);

// 3. 执行对应 I2C 操作
switch (cmd_type) {
case CMD_TYPE_WRITE: ExecuteI2CWrite(...); break;
case CMD_TYPE_READ: ExecuteI2CRead(...); break;
case CMD_TYPE_COMPARE: ExecuteI2CReadCompare(...); break;
case CMD_TYPE_COMPARE_RANGE: ExecuteI2CReadCompareRange(...); break;
}

// 4. 发送响应
SendResponse(status);
if (status == 0 && (READ || COMPARE))
SendData(read_data, data_length);

6. 命令类型详解

6.1 写命令 (1)

  • HAL_I2C_Mem_Write:写寄存器
  • 用于配置 EIS 芯片的 CONF、CTRL、EIS_Current 等寄存器

6.2 读命令 (2)

  • HAL_I2C_Mem_Read:读寄存器
  • 返回 data_length 字节(含 CRC)
  • 用于读取 EIS_Cell 中的 ADC 结果

6.3 比较命令 (3)

  • 先读,再与期望值逐字节比较
  • 不一致则返回 ERROR_COMPARE_FAILED

6.4 范围比较命令 (4)

  • 先读 3 字节 ADC 值
  • 与 [low_min, low_max] 和 [high_min, high_max] 比较
  • 实际值在对应范围内即 Pass

7. 与上位机的配合

PyComSender 发送格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1. 先发 4 字节头部
header = [cmd_type, slave_addr, reg_addr, data_length]
serial_port.write(header)

# 2. 若有数据,再发
if command.has_data_part():
serial_port.write(command.get_command_data())

# 3. 等待 1 字节 status
status = serial_port.read(1)

# 4. 若读/比较成功,再读 data_length 字节
if status == 0 and (READ or COMPARE):
data = serial_port.read(data_length)

8. 错误码

含义
0 成功
1 无效命令
2 I2C 写失败
3 I2C 读失败
4 比较失败
5 数据过长
6 CRC 校验失败

STM32 负责将底层 I2C 错误、比较失败等转换为统一错误码,便于上位机判断测试结果。


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