中颖SH367309锂电池保护板是一款针对锂电池组设计的智能保护方案,主要用于监测和管理锂电池的工作状态。作为一名嵌入式开发工程师,我将从源码层面详细解析这个保护板的实现原理和关键技术点。
这个方案的核心功能包括:
整个项目包含135个源文件,约2.1万行代码,基于STM32F10x系列MCU开发。下面我将从底层到上层逐步解析关键代码实现。
项目选用STM32F103C8T6作为主控芯片,主要基于以下考虑:
保护板的硬件设计包含以下几个关键部分:
电压检测电路:
电流检测电路:
温度检测:
保护执行电路:
启动文件startup_stm32f10x_hd.s是系统上电后执行的第一段代码,主要完成以下工作:
assembly复制__Vectors DCD __initial_sp ; 主堆栈指针初始值
DCD Reset_Handler ; 复位向量
DCD NMI_Handler ; NMI中断
DCD HardFault_Handler ; 硬件错误中断
关键点说明:
Reset_Handler的主要工作流程:
assembly复制Reset_Handler PROC
IMPORT __main ; C运行时库初始化
IMPORT SystemInit ; 时钟初始化
LDR R0, =SystemInit
BLX R0 ; 调用时钟初始化
LDR R0, =__main
BX R0 ; 跳转到C运行时库
ENDP
注意:
[WEAK]修饰符允许用户在其他文件中重新定义Reset_Handler,这在BootLoader设计中非常有用。
ADC驱动实现多通道循环采样,关键配置如下:
c复制RCC_ADCCLKConfig(RCC_PCLK2_Div6); // 72MHz/6=12MHz
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5);
设计考虑:
采样状态机实现:
c复制void TIME_to_CAdc(void) {
if(cad_nox == 0) {
cad_temp1[cad_noy] = ADC_GetConversionValue(ADC1);
ADC_RegularChannelConfig(ADC1, 1, 1, ADC_SampleTime_239Cycles5);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
// 其他通道处理...
}
由于STM32F103没有内置EEPROM,使用Flash模拟实现:
c复制void STMFLASH_Write(u32 WriteAddr, u16 *pBuffer, u16 NumToWrite) {
// 先读取整个扇区
STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,
STMFLASH_BUF, STM_SECTOR_SIZE/2);
// 检查是否需要擦除
for(i=0; i<secremain; i++) {
if(STMFLASH_BUF[secoff+i] != 0XFFFF) need_erase = 1;
}
if(need_erase) {
FLASH_ErasePage(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);
// 重新写入数据
}
}
关键优化:
过充保护实现代码:
c复制if(cell_max > OV1_TH && ov1_cnt < OV1_DELAY) ov1_cnt++;
else if(cell_max < OV1_RECOVER) ov1_cnt = 0;
if(ov1_cnt >= OV1_DELAY) SET_BIT(protect_flag, OV1_BIT);
保护参数说明:
放电过流三级保护实现:
c复制if(I_dis > OCD3_TH && ocd3_cnt < OCD3_DELAY) ocd3_cnt++;
else if(I_dis < OCD3_RECOVER) ocd3_cnt = 0;
参数设计考虑:
硬件短路保护由专用保护IC实现,响应时间<10μs;软件主要负责长时过载保护。
温度保护采用双阈值设计:
c复制if(temp > OT_CHG_TH) SET_BIT(protect_flag, OT_CHG_BIT);
if(temp > OT_DIS_TH) SET_BIT(protect_flag, OT_DIS_BIT);
典型参数:
核心积分算法:
c复制int32_t dQ = (int32_t)(I_inst * 0.02f * 1000); // 20ms转mAs
Remain_mAs -= dQ; // 剩余容量更新
关键点:
满充判断条件:
c复制if(cell_max > 4200 && I_abs < 50 && T > 10 && T < 45) {
FCC = Remain_mAs; // 更新满充容量
UpdateEEPROM(FCC_ADDR, FCC);
}
学习条件严格限制:
SMBus中断处理核心:
c复制void I2C1_EV_IRQHandler(void) {
// 地址匹配中断
if(I2C_GetITStatus(I2C1, I2C_IT_ADDR)) {
if(I2C_GetFlagStatus(I2C1, I2C_FLAG_TRA) == RESET)
rx_idx = 0; // 主机读,准备发送
else
tx_idx = 0; // 主机写,准备接收
I2C_ClearITPendingBit(I2C1, I2C_IT_ADDR);
}
// 接收中断
if(I2C_GetITStatus(I2C1, I2C_IT_RXNE)) {
rx_buf[rx_idx++] = I2C_ReceiveData(I2C1);
if(rx_idx == 1) reg_addr = rx_buf[0]; // 首字节为寄存器地址
}
// 发送中断
if(I2C_GetITStatus(I2C1, I2C_IT_TXE)) {
I2C_SendData(I2C1, smb_reg[reg_addr++]);
}
}
协议特点:
ADC采样优化:
通信协议增强:
SOC算法升级:
保护逻辑优化:
ADC采样不准:
SMBus通信失败:
Flash写入异常:
低功耗设计:
可靠性增强:
量产测试:
在实际开发中,我发现保护板软件最关键的三个点是:采样精度、保护响应速度和通信可靠性。特别是在高干扰环境中,需要特别注意ADC参考电压的稳定性和通信线路的抗干扰设计。