一、为什么要进行绝缘检测
前言:BMS绝缘检测是指对电池组与车体之间的绝缘状态进行实时监测和检测。为了确保电池组与车体之间的绝缘性能良好,防止漏电和短路等安全隐患,BMS绝缘检测系统能够及时发现绝缘故障,并采取相应的措施进行处理。
BMS绝缘检测的原理是基于电阻测量的方法。绝缘检测装置通过测量电池组与车体之间的电阻值来判断绝缘状态。在正常情况下,电池组与车体之间的电阻值应该是无穷大,即电流无法通过。而当发生绝缘故障时,电池组与车体之间会出现漏电现象,电阻值就会变小。
总结:
1、绝缘检测是判断动力(正、负)总线与外壳“地”是否存在连接
2、理想状态下,电池包的高压+ 和 高压- 对 车身地的绝缘阻值应该 ∞
二、绝缘检测国标标准
当BMS工作时,绝缘电阻的要求如下。
耐电压测试条件如下图(GB/T 18384.3),如果动力电池标称电压500V,那么需要2000VAC来进行测试。
三、绝缘检测不平衡电桥方法
1、闭合S3和S4,等待继电器吸合(延时)
2、闭合S2,等待继电器吸合(延时)
3、读取R4两端的电压,记作U1
4、断开S2,等待继电器断开(延时)
5、闭合S1和S2,等待继电器吸合(延时)
6、读取R4两端的电压,记作U2
7、根据Rz和Rf求出Rx和Ry(Rx是Rz和R5并联电阻,Ry同理)
四、公式计算精确度处理
#include <stdio.h>
#include <math.h>
#include <stdlib.h>#define uint64_t unsigned long long/**************************************************************
//闭合K1b(JY_IO3)及K2b(JY_IO4)
//VBAT:电池电压
//U1:K4b(JY_IO2)闭合后的采样电压值
//U2:K4b(JY_IO2)、K3b(JY_IO1)都闭合后的采样电压值
//Ra:6M+20K = 6020K
//R2:499K*6 = 2994K
//a:20K/(6M+20K)=0.003322
//负极对地的电阻:Rf=(2*Ra*R2*a*VBAT*(U1-U2))/(a*VBAT*Ra*(a*VBAT+U2-U1)+2*a*VBAT*R2*(U2-U1)-Ra*U1*U2)
//正极对地的电阻:Rz=(2*(a*VBAT-U2)*Ra*R2*Rf)/(Rf*(2*R2*U2+2*Ra*U2)+2*Ra*R2*U2)//测试完成后断开K1b(JY_IO3)、K2b(JY_IO4)、K4b(JY_IO2)、K3b(JY_IO1)
*******************************************************************/uint64_t vbat=0x1b6d;
uint64_t u1=0x1b58;
uint64_t u2=0x1a73;/*
1、电阻精确到KΩ,电压精确到MV,计算结果不变(因为公式中完美抵消)
2、U1和U2精确到10mv,为防止溢出,每一小步计算完后精确度恢复到1mv
3、求Rf和Rz最后一步分子除以分母时,为提高精确度,让分子扩大十倍在除以分母,最后结果缩小10倍
4、根据多处例子可知,精确度还可以
*/
void InsulationResCheck(void)
{uint64_t VBAT=vbat*112.687; //vbat/65535*6.144*12.02/0.02*2*1000; 单位是1mvuint64_t U1=u1*10*0.1875; //1000/65535*6.144*2; 单位是10mvuint64_t U2=u2*10*0.1875;uint64_t Ra=6020; //单位KΩuint64_t R2=3000; //单位KΩ double a=0.003322; uint64_t Rf=0,Rz=0,Rx=0,Ry=0; //正负极对地电阻(kΩ) uint64_t tempdat1=0,tempdat2=0,tempdat3=0,tempdat4=0,tempdat5=0,tempdat6=0,tempdat7=0;//Rf=(2*Ra*R2*a*VBAT*(U1-U2))/(a*VBAT*Ra*(a*VBAT+U2-U1)-2*a*VBAT*R2*(U1-U2)-Ra*U1*U2);//break; //step9:计算负极对地的电阻/求出分子(缩小10000倍)tempdat1 = 2*Ra*a*R2; printf("tempdat1 : %lld\r\n",tempdat1);tempdat2 = VBAT*(U1-U2)/10;printf("tempdat2 : %lld\r\n",tempdat2);tempdat1 = tempdat1/100; printf("tempdat1 : %lld\r\n",tempdat1);tempdat2 = tempdat2/100;printf("tempdat2 : %lld\r\n",tempdat2);tempdat3 = tempdat1*tempdat2;printf("tempdat3 : %lld\r\n",tempdat3);/求出分母(缩小10000倍) tempdat4 = a*VBAT*Ra*(a*VBAT-(U1-U2)/10); printf("tempdat4 : %lld\r\n",tempdat4);tempdat5 = 2*a*VBAT*R2*(U1-U2)/10; printf("tempdat5 : %lld\r\n",tempdat5);tempdat6 = Ra*U1/10*U2/10; //溢出printf("tempdat6 : %lld\r\n",tempdat6);tempdat7 = (tempdat4-tempdat5-tempdat6)/10000;printf("tempdat7 : %lld\r\n",tempdat7);/BAT-对地电阻(缩小倍数抵消) Rf = tempdat3*10/tempdat7; printf("Rf : %lld\r\n",Rf);//Rz=(2*(a*VBAT-U2)*Ra*R2*Rf)/(Rf*(2*R2*U2+2*Ra*U2)+2*Ra*R2*U2);//break; //step8:计算正极对地的电阻 /求出分子(缩小10000倍)tempdat1 = 2*(a*VBAT-U2/10)*Ra; printf("tempdat1 : %lld\r\n",tempdat1);tempdat2 = R2*Rf/10;printf("tempdat2 : %lld\r\n",tempdat2);tempdat1 = tempdat1/100; printf("tempdat1 : %lld\r\n",tempdat1);tempdat2 = tempdat2/100;printf("tempdat2 : %lld\r\n",tempdat2);tempdat3 = tempdat1*tempdat2; printf("tempdat3 : %lld\r\n",tempdat3); /求出分母(缩小10000倍) tempdat4 = (2*R2*U2/10+2*Ra*U2/10)/10000; printf("tempdat4 : %lld\r\n",tempdat4);tempdat5 = Rf/10*tempdat4; printf("tempdat5 : %lld\r\n",tempdat5);tempdat6 = 2*Ra*R2/10000;printf("tempdat6 : %lld\r\n",tempdat6);tempdat6 = tempdat6*U2/10;printf("tempdat6 : %lld\r\n",tempdat6);tempdat7 = tempdat5+tempdat6; printf("tempdat7 : %lld\r\n",tempdat7);/BAT+对地电阻(缩小倍数抵消) Rz = tempdat3*10/tempdat7; printf("Rz : %lld\r\n",Rz);if(Rz==2000) { Rx=0;}else{Rx = ((Rz*2000)/abs(2000-Rz)) / 10;}if(Rf==2000) {Ry=0;}else{Ry = ((Rf*2000)/abs(2000-Rf)) / 10;}printf("\nVBAT = %lld mv\n" ,VBAT); printf("U1 = %lld mv\n" ,U1); printf("U2 = %lld mv\n" ,U2); printf("Rx = %lld kΩ\n" ,Rx); printf("Ry = %lld kΩ\n" ,Ry);
}int main()
{InsulationResCheck();while(1);return 0;
}
五、电压采样之SGM58031(16位精度)
GD32F303RET6读取SGM58031电压值-CSDN博客