4. 采集芯片通信接口选型

任务定义

在电池模组采集芯片选型中,通信接口决定了数据吞吐量、线束复杂度与抗干扰能力。本案例针对一款典型采集芯片(以LTC6813-1为参考模型),完成其通信接口的选型分析,并给出SPI菊花链与isoSPI两种拓扑的驱动初始化代码,最终通过逻辑分析仪观测报文验证时序正确性。

接口选型约束分析

采集芯片需将12~18串电芯电压、温度数据上传至BMS主控。选型需满足:

  • 隔离耐压:≥1kV(动力电池侧与控制器侧电气隔离);
  • 速率:≥1Mbps(18串×3字节×10ms周期);
  • 线束:≤4根(减少连接器与屏蔽成本);
  • 拓扑:支持多片级联(≥15片)。

对比三种候选接口:

接口速率隔离方式线束级联结论
SPI(非隔离)4MHz需外置数字隔离器4+2菊花链成本低,但隔离器件增加延迟
isoSPI2Mbps内置变压器隔离2(双绞线)菊花链推荐:线束最少,隔离集成
I²C400kHz需隔离2+2不支持长距离速率不足,排除

本案例选定isoSPI主模式作为主通信接口,SPI菊花链作为备选方案。以下代码实现两种模式的驱动初始化与单次读取命令帧构造。

驱动实现(C语言,基于STM32F4 HAL库)

// isoSPI_interface.h
#ifndef ISO_SPI_H
#define ISO_SPI_H
#include "stm32f4xx_hal.h"

// LTC6813-1命令定义(节选)
#define CMD_RDCV   0x0404  // 读所有电压寄存器组
#define CMD_RDAUX  0x0406  // 读辅助寄存器(温度)

typedef struct {
    SPI_HandleTypeDef *hspi;   // 已初始化的SPI外设
    GPIO_TypeDef *cs_port;
    uint16_t cs_pin;
    uint8_t  chain_len;        // 菊花链中芯片数量
} ISOSPI_Handle;

void ISOSPI_Init(ISOSPI_Handle *dev);
uint8_t ISOSPI_ReadReg(ISOSPI_Handle *dev, uint16_t cmd,
                       uint8_t *rx_buf, uint8_t reg_group);
#endif
// isoSPI_interface.c
#include "isoSPI_interface.h"

// LTC6813-1 isoSPI帧格式:8位命令低字节 + 8位命令高字节 + 4位PEC + 4位填充
// 此处使用简化的无PEC校验帧(教学演示),实际产品需附加CRC
void ISOSPI_Init(ISOSPI_Handle *dev) {
    // 配置CS为推挽输出,默认高电平
    GPIO_InitTypeDef gpio = {0};
    gpio.Pin = dev->cs_pin;
    gpio.Mode = GPIO_MODE_OUTPUT_PP;
    gpio.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(dev->cs_port, &gpio);
    HAL_GPIO_WritePin(dev->cs_port, dev->cs_pin, GPIO_PIN_SET);

    // SPI已由CubeMX配置为:2Mbps,CPOL=1,CPHA=1(isoSPI模式要求)
    // 使能SPI
    __HAL_SPI_ENABLE(dev->hspi);
}

uint8_t ISOSPI_ReadReg(ISOSPI_Handle *dev, uint16_t cmd,
                       uint8_t *rx_buf, uint8_t reg_group) {
    uint8_t tx_cmd[2];
    uint8_t dummy[2] = {0x00, 0x00};

    // 构造命令字(低字节在前)
    tx_cmd[0] = (uint8_t)(cmd & 0xFF);
    tx_cmd[1] = (uint8_t)((cmd >> 8) & 0xFF);

    // 片选拉低
    HAL_GPIO_WritePin(dev->cs_port, dev->cs_pin, GPIO_PIN_RESET);

    // 发送命令 + 2字节填充(等待芯片内部处理)
    HAL_SPI_Transmit(dev->hspi, tx_cmd, 2, 10);
    HAL_SPI_Transmit(dev->hspi, dummy, 2, 10);

    // 读取数据:每个寄存器组6字节,菊花链每片累加
    uint8_t bytes_per_chip = 6;
    uint8_t total_bytes = bytes_per_chip * dev->chain_len;
    HAL_SPI_Receive(dev->hspi, rx_buf, total_bytes, 50);

    // 片选拉高
    HAL_GPIO_WritePin(dev->cs_port, dev->cs_pin, GPIO_PIN_SET);
    return 0; // 成功
}
// main.c 调用示例(单芯片,chain_len=1)
#include "isoSPI_interface.h"

ISOSPI_Handle iso_dev;
uint8_t voltage_buf[6];  // 存储一组电压原始数据

void BMS_ReadVoltage(void) {
    iso_dev.hspi = &hspi2;
    iso_dev.cs_port = GPIOB;
    iso_dev.cs_pin = GPIO_PIN_12;
    iso_dev.chain_len = 1;

    ISOSPI_Init(&iso_dev);
    ISOSPI_ReadReg(&iso_dev, CMD_RDCV, voltage_buf, 0);
    // 此时voltage_buf[0..5]为第1组电压的6字节原始数据
    // 实际工程需解析为电压值:V = (raw * 0.0001) V(LTC6813-1的16位ADC)
}

SPI菊花链备选驱动(关键差异)

// 菊花链模式:所有芯片CS并联,数据从最后一片串行移出
// 初始化时需将每片的配置位写入,此处仅展示命令发送时序差异
void SPI_DaisyChain_Read(SPI_HandleTypeDef *hspi, uint16_t cmd,
                         uint8_t *rx_buf, uint8_t chip_count) {
    uint8_t tx_cmd[2] = {(uint8_t)(cmd & 0xFF), (uint8_t)(cmd >> 8)};
    uint8_t dummy[2] = {0, 0};

    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); // CS低

    // 发送命令后,需发送 (chip_count-1)*2 个填充字节以驱动数据移出
    HAL_SPI_Transmit(hspi, tx_cmd, 2, 10);
    for (uint8_t i = 0; i < chip_count - 1; i++) {
        HAL_SPI_Transmit(hspi, dummy, 2, 10);
    }

    // 接收:每片6字节,共 chip_count*6 字节
    HAL_SPI_Receive(hspi, rx_buf, chip_count * 6, 50);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
}

验证方法与判定标准

硬件连接:将LTC6813-1评估板的isoSPI端口(A/B引脚)通过双绞线连接至LTC6820隔离收发器,再接入STM32F4的SPI2引脚(SCK=PB13,MOSI=PB15,MISO=PB14,CS=PB12)。

测试步骤:

  1. 编译烧录后,用逻辑分析仪(采样率≥10MHz)夹在SPI2的SCK与MOSI线上;
  2. 触发BMS_ReadVoltage(),捕获一段通信波形;
  3. 观察MOSI线上是否出现0x04 0x04(CMD_RDCV命令)后跟2字节0x00;
  4. 观察MISO线上在命令后约2字节延迟后返回6字节非零数据(芯片有供电且电芯接入时)。

判定通过标准:

  • 命令字节顺序正确(低字节0x04先发,高字节0x04后发);
  • CS低电平持续时间≥命令+填充+读取总时长(约20μs@2MHz);
  • MISO返回的数据长度等于6×chain_len字节,且非全0xFF(若全0xFF说明通信失败或芯片未响应)。

预期输出(基于代码逻辑直接推出):当chain_len=1且芯片正常供电时,voltage_buf数组将包含6字节数据,其中前2字节为第1组电压的16位ADC值(高位在前),后4字节为后续通道数据。具体数值取决于实际电芯电压,无法预先确定。

选型结论:本案例推荐isoSPI接口,因其在2Mbps速率下仅需2根双绞线即可实现隔离通信,且驱动代码与SPI兼容,仅需调整CPOL/CPHA配置。SPI菊花链模式适合成本敏感且无需隔离的场合,但需额外增加数字隔离器,且线束增加至6根。
isoSPI通信拓扑与验证观测点 STM32F4 SPI2主机 2Mbps CPOL=1 CPHA=1 LTC6820 isoSPI隔离收发器 变压器隔离 ≥1kV LTC6813-1 采集芯片 12~18串电芯 SCK MOSI MISO CS A线 B线 双绞线 逻辑分析仪观测点(采样率≥10MHz) ① SCK波形 ② MOSI命令帧 ③ MISO数据返回 ④ CS片选时序 判定:命令0x0404低字节先发 → 2字节填充 → MISO返回6×N字节非0xFF数据 CS低电平持续 ≥ (4+2+6×N) bit时间 @2MHz