两轮车换电 BMS 的模拟前端中颖 SH367306 AFE 芯片详解

📅 2026/7/6 1:36:07
两轮车换电 BMS 的模拟前端中颖 SH367306 AFE 芯片详解
中颖 SH367306 AFE 芯片详解两轮车换电 BMS 的模拟前端基于量产 60V 20 串 BMSSTM32F072 SH367306 × 2从寄存器到数据流完整拆解这片 AFE 的硬件能力、软件驱动与工程细节。一、为什么需要 AFEBMS 的主控 MCU本项目为 STM32F072是一个纯数字芯片——它没有高压模拟前端无法直接测量 60V 电池包的每一节电芯电压。所以需要一个**模拟前端AFEAnalog Front End**来完成每节电芯的电压采集最高 4.2V × 20 串 84V 共模电压MCU 的 ADC 根本扛不住电流采样0.5mΩ 采样电阻上的 μV 级差分信号电芯均衡内置均衡 MOSFET 驱动硬件短路保护μs 级不依赖 MCU 软件充放电 MOSFET 驱动SH367306 是**中颖电子SinoWealth**为锂电池保护板设计的专用 AFE单颗最多管理10 串电芯。本项目是 20 串所以用了两片级联。二、硬件连接全景STM32F072 (Cortex-M0, 48MHz) │ ┌───────────────┼───────────────┐ │ │ │ TWI1 (PB6/PB7) TWI2 (PB10/PB11) TIM16_CH1 (PB1) I2C 400kHz I2C 400kHz GPIO 模拟 PWM │ │ │ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ CTLD 引脚 │SH367306 #1│ │SH367306 #2│ (限流硬件控制) │ 0x1B │ │ 0x1B │ │ Cell 1-10│ │ Cell 11-20│ └────┬─────┘ └────┬─────┘ │ │ ┌────┴────┐ ┌───┴─────┐ │TS1: MOS │ │TS1: 预充│ │TS2: 环境│ │TS2: 参考│ │SRP/SRN │ │SRP/SRN │ ← 同一条采样电阻 │CHG/DSG │ │CHG/DSG │ ← 并联驱动同一对 MOS └─────────┘ └─────────┘四根关键连线信号方向作用TWI (I2C)MCU ↔ AFE读写寄存器、获取采样数据、控制均衡ALARMAFE → MCU短路/过压/看门狗硬件故障中断CTLDMCU → AFE放电限流 PWM硬件直连不经过 I2CWAKEUPMCU → AFE休眠/唤醒控制三、I2C 通信不是普通 I2CSH367306 的 I2C 从机地址是0x1B7-bit写地址0x36读地址0x37。3.1 传输格式写操作START 0x36 RegAddr Data STOP 读操作START 0x36 RegAddr RESTART 0x37 [HiByte][LoByte] STOP每次读取固定 2 字节。电压/电流/温度数据均为低 12 位有效高 4 位是标志位。3.2 三层容错驱动代码中对 I2C 通信做了三层容错第一层 — 读写重试Sh367306_1_Drv.c:137-186// 每次读写失败最多重试 TRY_TIMES(5) 次while(timesTRY_TIMES){resultTwi1Drv_Write(SlaveAdd1,WrAddr,1,WrBuf);if(result1)break;// 成功立即返回}第二层 — 写入验证Sh367306_1_Drv.c:195-223// 写入后回读确认寄存器值确实被写入while(RegWriteFlg){AfeIf_Write(RdAddr,Data);AfeIf_Read(RdAddr,2,Buffer);if(Buffer[0]Data)break;// 读写一致OKif(RegWriteFlg20)return0;// 最多重试 20 次}第三层 — 运行时回读校验Sh367306_1_Drv.c:1041-1049// 每 4s 检测一次 SCONF1 是否与初始化值一致if(s_usCTLDPinChek%1001){AfeIf_Read(SCONF1,2,DataBuff);if(DataBuff[0]!g_Afe1Sconfig1.Data){AfeIf_RegWrite(SCONF1,g_Afe1Sconfig1.Data);// 被干扰了回写修复}}为什么要这么做BMS 的工作环境极其恶劣——大电流 PWM、MOSFET 开关的 EMI、振动——I2C 数据被干扰或 AFE 寄存器被静电打翻的事时有发生。三层容错保证在这种环境下数据依然可靠。四、寄存器全图谱SH367306 的寄存器分为三类状态标志、系统配置、采样数据。4.1 状态标志寄存器寄存器地址位域FLAG10x00TWI_INT | WDT | OV(过压) | SC(短路) | ReservedFLAG20x01VADC(电压采样完成) | CADC(电流采样完成) | RST | ReservedBSTATUS0x02CHGR(充电器插入) | LOAD(负载接入) | CHGING | DSGING | CHG(MOS状态) | DSG(MOS状态)FLAG1 和 FLAG2 是锁存标志— 置位后不会自动清零MCU 需要向SCONF1.LTCLR写 1→0 来手动清除。4.2 系统配置寄存器寄存器地址核心功能INT_EN0x03中断使能TWI/WDT/VADC/CADC/CD/OV/SC 各独立开关SCONF10x04硬件保护使能SC_EN/WDT_EN/CTLD_EN LTCLR 清除锁存SCONF20x05CHG_C(充电MOS) / DSG_C(放电MOS) / ALARM_C / RESET_PFSCONF30x06VADC_EN / CADC_EN / 转换周期 / 分辨率选择SCONF40x07均衡开关 CB6 ~ CB10电芯 6~10SCONF50x08均衡开关 CB1 ~ CB5电芯 1~5SCONF60x09短路保护阈值(SCV) / 延时(SCT) / 恢复延时(RST) / 增益(RSNS)SCONF70x0A看门狗溢出时间(WDTT) / 过压延时(OVT) / 充放电选择(CHS)SCONF80x0BOVD_8/OVD_9 过压检测延时SCONF90x0COVD_0~OVD_7 过压检测延时SCONF100x0D引脚功能配置 / 低功耗模式4.3 采样数据寄存器寄存器地址内容有效位REGCELL1 ~ REGCELL100x0E ~ 0x2010 路电芯电压 ADC 值12-bitREGTS1 ~ REGTS20x22 ~ 0x242 路外部 NTC 温度 ADC 值12-bitREGTEMP1 ~ REGTEMP20x26 ~ 0x282 路内部芯片温度 ADC 值12-bitREGCUR0x2A电流 ADC 值bit12 方向1放电 0充电16-bit五、电芯电压采集从 ADC 到 mV5.1 采样时序SH367306 内部有一个自动扫描的 VADC按SCONF3.SCAN_C配置的周期循环采样 10 路电芯电压。每完成一轮FLAG2.VADC置位。// 项目配置g_Afe1Sconfig3.B.SCAN_C_00;// VADC 转换周期 最快g_Afe1Sconfig3.B.SCAN_C_10;g_Afe1Sconfig3.B.SCAN_C_20;g_Afe1Sconfig3.B.VADC_EN1;// VADC 使能这意味着 MCU 不需要主动触发每次电压采样——只需要等FLAG2.VADC 1然后一口气读完 10 路电压。5.2 电压换算公式// AfeIf_Calculate.cCellVoltage_mV(1000× ADC_Value ×6/4096)-Offset// 1000: 单位转换为 mV// 6: 基准电压 6VAFE 内部 VREF对应 0~5V 量程// 4096: 12-bit ADC 满量程// Offset: 芯片 1 偏移 3mV芯片 2 偏移 5mV补偿 PCB 走线压降例如 ADC 读数为 2048CellVoltage 1000 × 2048 × 6 / 4096 - 3 2997mV ≈ 3.0V5.3 Cell1 的特殊校准Cell1 的 B- 采样线通常最长线上的压降不可忽略。本项目在工厂模式和运营模式下用了两种不同的校准策略工厂模式AfeIf_Calculate.c:199-216— 在线自校准// 电流 6A 时Cell1 电压 (总压 - Cell1) / 19用其他 19 节的平均值作为 Cell1 的参考if(abs(Current)6000){if(abs(CellVoltage[0]-AvgOfOther19)150mV){CellVoltage[0]AvgOfOther19;// 偏差 150mV 则自动校准}}运营模式AfeIf_Calculate.c:219-226— 固定系数补偿// 6020 电池包B- 线压降 0.50mV/ACellVoltage[0]-Current ×50/100000;// 6030 电池包B- 线压降 0.33mV/ACellVoltage[0]-Current ×33/100000;六、电流采集比电压复杂 10 倍电流是 BMS 所有决策的基础——SOC 估算、故障保护、模式切换都依赖它。SH367306 的 CADCCurrent ADC是整颗芯片中最精密的模拟电路。6.1 物理链路采样电阻 (0.5mΩ, 两端焊接在 PCB 大铜皮上) │ ├── SRP 引脚 (Kelvin 连接, 采样电阻正端) │ └── SRN 引脚 (Kelvin 连接, 采样电阻负端) │ ▼ SH367306 内部 PGA (可编程增益放大器) │ ▼ 16-bit ΣΔ ADC │ ▼ REGCUR 寄存器6.2 换算公式// AfeIf_Calculate.c: CalculateCurrent()// 第一步方向判断 补码转换if(CADC_Value bit121)// 放电方向RawValue-((0x10000-CADC_Value)0x1FFF);else// 充电方向RawValueCADC_Value0x1FFF;// 第二步零点偏移 温漂补偿CorrectedValueRawValue-ZeroOffsetTempDrift;// 第三步量纲转换Current_mACorrectedValue ×(50mV/4096)/0.5mΩCorrectedValue ×100A/4096≈ CorrectedValue ×24.4mA/LSB6.3 零点自学习上电后自动找零电流上电初始化时假设电池处于静止状态无充放电MCU 自动执行零点自学习Sh367306_1_Drv.c:880-9331. 等待 CADC 采样完成FLAG2.CADC 1 2. 读取 REGCUR计算零点偏移 3. 连续多次采样2~30 次取两次不同值的均值 4. 零点偏移限制在 ±10 LSB 以内约 ±240mA 5. 超时 200S 未完成则报 AFE 故障这个自学习的巧妙之处在于它取两次不同值的均值而不是所有采样的均值。这样即使有一个异常点也不会拉偏零点。6.4 温漂补偿电流零点会随温度漂移采样电阻和 AFE 内部运放都有温度系数。电流零点在 -25°C 和 75°C 之间可能漂移好几 A。驱动代码中有一张温度→偏移补偿表Sh367306_1_Drv.c:679-728int8_tGetTheTempOffset(int16_tChipTemp){// 低温漂负方向if(ChipTemp-44ChipTemp-40)return-6;if(ChipTemp-30)return-5;if(ChipTemp-20)return-4;if(ChipTemp-10)return-3;if(ChipTemp0)return-2;if(ChipTemp10)return-1;// 常温不漂if(ChipTemp10ChipTemp35)return0;// 高温漂正方向if(ChipTemp75)return4;if(ChipTemp65)return3;if(ChipTemp55)return2;if(ChipTemp35)return1;return0;}补偿精度每个 LSB ≈ 24.4mA低温最大补偿 -6 LSB ≈ -146mA高温最大补偿 4 LSB ≈ 98mA。6.5 电流滤波原始电流数据还要经过两级滤波AfeIf_Calculate.c:286-339原始电流 │ ├─ 相邻两次差值 30mA → 异常跳变丢弃旧值 │ ├─ 两次采样取平均值 │ ├─ 充/放分向校准系数默认 1.015可在 ±20% 标定 │ 放电方向 原始值 × ChgCurFactor / 1000 │ 充电方向 原始值 × DsgCurFactor / 1000 │ └─ |Current| 250mA → 强制归零消除噪声七、温度采集NTC 查表每个 SH367306 有两个外部 NTC 输入TS1/TS2本项目中的分配传感器物理位置测量对象AFE1 TS1MOS 管散热片旁MOS 温度AFE1 TS2电池包内部空间环境温度AFE2 TS1预充电阻旁预充电阻温度AFE2 TS2PCB 板上 10K 参考温度参考校验NTC 类型为10KΩ B3435搭配 10KΩ 上拉电阻接到 AFE 内部基准电压。7.1 ADC → 电阻值// AfeIf_Calculate.cR_NTC(10000×10× ADC_Value)/(4096-ADC_Value)// ↑ 10K 上拉电阻 ↑ 12-bit ADC 满量程7.2 电阻值 → 温度191 点 NTC RT 表-45°C ~ 145°C线性插值查表AfeIf_Calculate.c:46-88// 查表定位for(i1;i191;i){if(R_NTCTable[i])continue;// 还没找到elsebreak;// 找到了R_NTC 在 Table[i-1] 和 Table[i] 之间}// 线性插值Tempi ×10-10×(R_NTC-Table[i])/(Table[i-1]-Table[i]);returnTemp-450;// 偏移 -45°C表的第 0 点对应 -45°C7.3 分段校准查表得到的温度还要经分段校准AfeIf_Calculate.c:98-119if(Temp-43°C)→ 不校准超出线性范围elseif(Temp-25°C)→2°Celseif(Temp0°C)→1°Celse→ 不校准八、硬件短路保护不依赖 MCU 的最后防线这是 SH367306 最硬的功能——完全不经过 MCU 软件。采样电阻电压 SCV 阈值 (200mV ≈ 400A 0.5mΩ) │ ├─ 硬件延时 SCT (50μs) 去抖确认 │ ├─ AFE 硬件自动清零 SCONF2.DSG_C → 断开放电 MOS │ ├─ FLAG1.SC 锁存置位 │ └─ ALARM 引脚输出中断信号 → MCU 进入 AfeIf_AlarmPin() ISR为什么是 50μs太快如 5μs→ 正常负载突变的浪涌电流会误触发太慢如 500μs→ MOSFET 在短路电流下已经开始损坏50μs 是一个经验折中——足够避开浪涌又快到能救 MOSFET 的命MCU 侧的软件二次确认MCU 收到 ALARM 中断后并不直接采信——而是做软件去抖Sh367306_1_Drv.c:300-360if(FLAG1.SC1){Cnt;ShortCircuitPreChg_Cnt;ClearFlg();// 清除 AFE 锁存允许硬件重新判断if(Cnt12){// 连续 12 次 持续约 600msSCStatus1;// 确认真实短路Cnt0;}}if(Time14){// 14 个周期没达到 12 次Cnt0;// 重置 — 刚才可能是干扰}这个 12/14 的阈值设计很有意思如果每周期都触发短路12 个周期就锁定如果有间歇比如 14 个周期只触发了 10 次就重置。这避免了在某些接近短路但不完全是的工况下误锁。九、电芯均衡交错控制防止局部过热SH367306 内置 10 路均衡 MOSFET 驱动通过SCONF4和SCONF5两个寄存器控制。9.1 为什么交错如果相邻两节电芯同时开启均衡例如 Cell1 和 Cell2它们的均衡电流都流过 Cell2 的采样线导致 Cell2 电压读数偏高 20-30mV。更糟的是相邻均衡 MOSFET 同时导通会在局部产生热点。9.2 交错实现// BalanceOpen() — Sh367306_1_Drv.cif(i%20){// 偶数周期只开奇数电芯 (bit 0,2,4,6,8)SCONF4Config0x55;// 0b01010101SCONF5Config0x55;}else{// 奇数周期只开偶数电芯 (bit 1,3,5,7,9)SCONF4Config0xAA;// 0b10101010SCONF5Config0xAA;}9.3 均衡与电压采样互斥均衡开启时均衡电流流过电芯采样线电压读数不准。所以驱动代码做了一个关键设计——均衡开启和电压读取分时进行Sh367306_1_Drv.c:1070-1099周期 操作 0 空闲 1 空闲 2 GetVadcData() BalanceOpen(奇通道) ← 先读电压再开均衡 3 空闲 4 空闲 5 空闲 6 BalanceOpen(偶通道) ← 只开均衡不读电压 7 空闲 8 空闲 9 空闲 10 BalanceClose() ← 关均衡 11 清除 VADC 标志准备下一轮11 个周期 × 40ms 440ms 一个完整循环。均衡开启的最大占空比约 50%交错后每个通道的实际导通时间。十、CTLD 引脚放电限流的硬件捷径CTLDCurrent Limit Discharge是 SH367306 一个非常巧妙的设计。10.1 为什么不走 I2C一次 I2C 读写大约 1ms。如果要通过 I2C 来实现 PWM 关断放电 MOSPWM 周期至少得是 I2C 延迟的 10 倍以上 → PWM 频率只能做到 100Hz每个周期都要发起一次 I2C 通信 → MCU 被 I2C 中断淹没CTLD 是一个纯硬件引脚——拉低即关断放电 MOS拉高即导通。MCU 只需翻转 GPIO不经过任何通信协议。10.2 驱动代码// 拉低 → 关断放电 MOS限流生效staticvoidCURRENTLIMITPIN_GPIO_OUT_L(){Afe1_LimitCurrPwm_GPIO_Port-BSRRAfe1_LimitCurrPwm_Pin;}// 拉高 → 恢复导通staticvoidCURRENTLIMITPIN_GPIO_OUT_H(){Afe1_LimitCurrPwm_GPIO_Port-BRRAfe1_LimitCurrPwm_Pin;}10.3 波形生成在 100µs 的 TIM16 中断中voidAfeIf_CurrentLimit(){if(TimeCntDutyCycle)CURRENTLIMITPIN_GPIO_OUT_L();// 前 N 个 tick 关断elseCURRENTLIMITPIN_GPIO_OUT_H();// 后面导通TimeCnt;if(TimeCnt33)TimeCnt0;// 周期 33 × 100µs 3.3ms ≈ 303Hz}CTLD 让 BMS 可以用一个普通的 GPIO 定时器就实现 303Hz 的 PWM 限流不需要额外的 MOSFET 驱动电路也不需要高速通信总线。十一、上电初始化长达 2 秒的精密流程SH367306 的上电初始化是本项目中最长的单段代码Sh367306_1_Drv.c:736-959大约 200 行耗时 2~3 秒。0ms TWI 接口初始化 0ms WAKEUP 引脚拉高 0ms 写 SCONF20x00先关 MOS确保安全 0ms 延时 800ms等 AFE 内部振荡器起振 800ms CTLD 限流引脚初始化 800ms 配置寄存器初始化(RegisterInit) ├─ SCONF1: SC_EN1, WDT_EN1, CTLD_EN1 ├─ SCONF3: VADC_EN1, CADC_EN1 ├─ SCONF6: 短路 50μs/200mV, 恢复 32ms, 增益 100mV ├─ SCONF7: WDT ≈ 10s, OVT0 └─ INT_EN: VADC_INT1, CADC_INT1, SC_INT1 800ms 依次写入 SCONF1/2/3/6/7 INT_EN 任一写入失败 → 故障标志置位 1000ms 清除锁存标志 1000ms 关闭所有均衡 1000ms 延时 2s 3000ms 循环等待 VADC 和 CADC 首次采样完成 ├─ VADC: 10 路电压全在 0.5V~5.0V → OK ├─ CADC: 零点自学习 2~30 次取均值 └─ 超时 200s → 报 AFE 故障 3000ms 零点偏移 芯片温度补偿 3000ms 初始化完成这个流程有几个值得注意的点先关 MOS 再初始化防止初始化过程中 MOS 意外导通800ms 延时等 AFE 内部 LDO 和振荡器稳定不能省略寄存器回读验证每个配置寄存器写入后都回读不是 fire-and-forget零点学习多次取均值不是读一次就完而是反复采集直到两次不同值十二、低功耗休眠MCU 进入休眠前AFE 也要同步休眠Sh367306_1_Drv.c:1103-1116// 1. 关断 CHG/DSG MOSg_Afe1Sconfig2.B.CHG_C0;g_Afe1Sconfig2.B.DSG_C0;ChgAndDsgCtrl();// 2. 关闭所有均衡BalanceClose();// 3. WAKEUP 引脚拉低 → AFE 进入 PowerDownAfeDeWakeup();// 4. 写入低功耗寄存器EnterLowPower();// SCONF100x33, SCONF10x20休眠后 AFE 的静态功耗从 mA 级降到 μA 级。唤醒时只需要拉高 WAKEUP 引脚然后重新走初始化流程。十三、双芯片数据融合两片 SH367306 的数据在AfeIf_Calculate.c的CalculateValueRunnable()中统一处理voidAfeIf_CalculateValueRunnable(void){CalculateVoltage();// 20 路电压 → CellVoltage_mV[0..19]CalculateTemperature();// 4 路 NTC → MOS温度 / 环境温度 / 预充电阻温度 / 参考温度CalculateCurrent();// AFE1 电流 → CurrentRaw_mACalculateVolMaxMin();// 最高/最低单体电压MosFETState();// CHG/DSG MOS 状态BalanceState();// 20 路均衡状态Afe_StatusDignose();// AFE1 故障 | AFE2 故障}关键设计电流只用 AFE1。两片 AFE 的 SRP/SRN 并联到同一个采样电阻但只用 AFE1 的 CADC 数据。AFE2 的 CADC 虽然也在运行但不参与电流计算——避免两片芯片的零点偏移不同导致数据矛盾。十四、工程经验总结14.1 为什么要用两片 SH367306 而不是一片 20 串的芯片选型是 2021 年做的。当时国产 20 串 AFE 的选择很少中颖的 SH36730610 串是经过市场验证的成熟方案。两片 10 串比一片未经验证的 20 串更可靠。而且两片独立供电、独立通信单颗故障不会导致全部 20 串数据丢失。14.2 最容易被忽视的坑均衡时不能读电压。SH367306 内部只有一个 ADC均衡电流会干扰采样结果。如果均衡和采样同时进行电压读数可能偏差 50mV 以上——在 3.6V 满充附近50mV 足够把一节正常电芯误判为过压。电流零点漂移。0.5mΩ 采样电阻在 30A 时只有 15mV 压降而 AFE 内部的运放失调电压就可能达到几个 μV。温度从 -20°C 变到 60°C 时失调电压漂移几个 μV 就可能对应几百 mA 的零点偏移。温漂补偿表是必须的。I2C 在强干扰下不可靠。MOSFET 开关的 EMI 会耦合到 I2C 线上。三层容错重试验证回读修复是量产代码和实验室代码的最大区别。十五、关键参数速查参数数值说明管理串数10 串/片本项目 2 片级联 20 串I2C 地址0x1B两片共用总线硬件地址固定通过片选区分电压采样范围0.5V ~ 5.0V12-bit分辨率 ~1.47mV电流采样电阻0.5mΩ本项目选型电流分辨率~24.4mA/LSB50mV 量程 0.5mΩ短路保护响应50μs200mV 阈值 ≈ 400A短路恢复延时32ms硬件自动恢复尝试看门狗周期~10s超时硬件复位 AFE均衡方式内置 MOSFET 驱动交错控制50% 占空比休眠功耗μA 级WAKEUP 引脚拉低NTC 类型10KΩ B3435191 点 RT 表本文基于 STM32F072 SH367306 × 2 两轮车换电 BMS 量产代码APP-V02.01.20分析所有代码引用均可追溯到源文件对应行号。