//******************************************************************** // Ver 1.0 // 2019.09.24 1、建立文件 //******************************************************************** #include "config.h" //字读取寄存器 INT8U SH367306_ReadReg(INT8U Reg, INT16U *ptr) { INT8U tValue[7]; SH367306_I2cReadWord(Reg, (INT8U *) & (tValue[3])); tValue[0] = SH367306_ADDR; tValue[1] = Reg; tValue[2] = SH367306_ADDR | 0x01; tValue[6] = CRC8((INT8U *) & (tValue[0]), 5); if(tValue[5] == tValue[6]) { *ptr = ((INT16U)(tValue[3]) << 8) | ((INT16U)(tValue[4])); //大端 return(1); } return(0); } //字节写寄存器 void SH367306_WriteReg(INT8U Reg, INT8U *ptr) { INT8U tValue[4]; tValue[0] = SH367306_ADDR; tValue[1] = Reg; tValue[2] = *ptr; tValue[3] = CRC8((INT8U *) & (tValue[0]), 3); SH367306_I2cWriteByte(Reg, (INT8U *) & (tValue[2])); } //读取状态标志 void SH367306_ReadFlag(void) { INT8U tValue[2]; SH367306_ReadReg(ADDR_FLAG1, (INT16U *) & (tValue[0])); #ifdef _C51 SH367306_Flag1 = tValue[0]; SH367306_Flag2 = tValue[1]; #else SH367306_Flag1 = tValue[1]; SH367306_Flag2 = tValue[0]; #endif if(SH367306_Flag1 != 0) { if(SH367306_FLAG_SC != 0) //2019.11.27 增加短路锁定MOS功能 { BATT_FetLock(DFET, Lock); } SH367306_CFG_LTCLR = 1; //清标志寄存器0 SH367306_WriteReg(ADDR_SCONF1, &SH367306_Sconf1); SH367306_CFG_LTCLR = 0; //清标志寄存器0 SH367306_WriteReg(ADDR_SCONF1, &SH367306_Sconf1); } //SH367306_ReadReg(ADDR_FLAG2, (INT16U *)&(tValue[0])); SH367306_ReadReg(ADDR_BSTATUS, (INT16U *) & (tValue[0])); #ifdef _C51 SH367306_Bstatus = tValue[0]; #else SH367306_Bstatus = tValue[1]; #endif } //中断配置 #if 0 void SH367306_IntConfig(INT8U Value) { INT8U tValue[2]; SH367306_WriteReg(ADDR_INTEN, &Value); SH367306_ReadReg(ADDR_INTEN, (INT16U *) & (tValue[0])); SH367306_IntEn = tValue[0]; } #endif //芯片进掉电模式 //先写0x33到寄存器SCONF10,再将SCONF1的PDEN修改为1,关闭LDO void SH367306_PowerDown(void) { SH367306_Sconf10 = 0x33; SH367306_CFG_PDEN = ENABLE; SH367306_WriteReg(ADDR_SCONF10, &SH367306_Sconf10); SH367306_WriteReg(ADDR_SCONF1, &SH367306_Sconf1); SH367306_Sconf10 = 0; } //初始化FLASH数据 void SH367306_FlashInfoInit(void) { //看门狗配置 //WDTEN=1,WDTT=WDT_10S //SH367306_CFG_WDTEN=ENABLE; //SH367306_CFG_WDTT=WDT_10S; //复位信号输出配置 //RESET=1,RSTT=RST_1S //SH367306_CFG_RESET=ENABLE; //SH367306_CFG_RSTT=RSTT_1S; // SH367306_Flag1=0; // SH367306_Flag2=0; // SH367306_Bstatus=0; //报警信号中断,默认打开所有中断 SH367306_IntEn = 0; SH367306_INT_TWI = DISABLE; SH367306_INT_WDT = ENABLE; SH367306_INT_VADC = DISABLE; SH367306_INT_CADC = DISABLE; SH367306_INT_CD = ENABLE; SH367306_INT_OV = ENABLE; SH367306_INT_SC = ENABLE; //系统检测功能, SH367306_Sconf1 = 0; SH367306_CFG_CHGREN = DISABLE; SH367306_CFG_LOADEN = DISABLE; SH367306_CFG_OVEN = ENABLE; SH367306_CFG_SCEN = ENABLE; SH367306_CFG_WDTEN = ENABLE; SH367306_CFG_PDEN = DISABLE; SH367306_CFG_CTLDEN = DISABLE; SH367306_CFG_LTCLR = DISABLE; //充电、放电MOS由硬件保护模块决定 SH367306_Sconf2 = 0; SH367306_CFG_CHGC = DISABLE; SH367306_CFG_DSGC = DISABLE; SH367306_CFG_ALARMC = ENABLE; SH367306_CFG_RESET = ENABLE; //ADC转换设置 SH367306_Sconf3 = 0; SH367306_CFG_SCANC = VADC_100mS; SH367306_CFG_VADCC = ENABLE; SH367306_CFG_VADCEN = ENABLE; SH367306_CFG_CBITC = ENABLE; SH367306_CFG_CADCM = ENABLE; SH367306_CFG_CADCEN = ENABLE; //均衡功能,默认全部关闭 SH367306_Sconf4 = 0x00; SH367306_Sconf5 = 0x00; //短路检测电压、短路保护延时,复位低电平时间,电流检测范围设置 SH367306_Sconf6 = 0; SH367306_CFG_SCT = SCT_100uS; SH367306_CFG_SCV = SCV_300mV; SH367306_CFG_RSTT = RSTT_1S; SH367306_CFG_RSNS = RSNS_100mV; //硬件过充延时、充放电检测阈值选择,看门狗溢出时间 SH367306_Sconf7 = 0; SH367306_CFG_WDTT = WDTC_10S; SH367306_CFG_CHS = CHS_12mV; SH367306_CFG_OVT = OVT_8T; //过充电压设置 SH367306_Sconf8 = (INT8U)((4300 * 100UL / 586UL) >> 8); SH367306_Sconf9 = (INT8U)((4300 * 100UL / 586UL) >> 0); // SH367306_Sconf10 = 0; } //初始化芯片 void SH367306_ChipInit(void) { INT8U tValue[2]; do { SH364306_ResetHigh(); DELAY_Ms(200); SH364306_ResetHigh(); DELAY_Ms(200); SH367306_WriteReg(ADDR_SCONF1, &SH367306_Sconf1); DELAY_Ms(100); SH367306_Flag1 = 0; #ifdef _C51 tValue[0] = 0x55; #else tValue[1] = 0x55; #endif SH367306_ReadReg(ADDR_SCONF1, (INT16U *) & (tValue[0])); #ifdef _C51 SH367306_Flag1 = tValue[0]; #else SH367306_Flag1 = tValue[1]; #endif } while(SH367306_Sconf1 != SH367306_Flag1); SH367306_Flag1 = 0; SH367306_WriteReg(ADDR_SCONF1, &SH367306_Sconf1); SH367306_WriteReg(ADDR_SCONF2, &SH367306_Sconf2); SH367306_WriteReg(ADDR_SCONF3, &SH367306_Sconf3); SH367306_WriteReg(ADDR_SCONF4, &SH367306_Sconf4); SH367306_WriteReg(ADDR_SCONF5, &SH367306_Sconf5); SH367306_WriteReg(ADDR_SCONF6, &SH367306_Sconf6); SH367306_WriteReg(ADDR_SCONF7, &SH367306_Sconf7); SH367306_WriteReg(ADDR_SCONF8, &SH367306_Sconf8); SH367306_WriteReg(ADDR_SCONF9, &SH367306_Sconf9); SH367306_WriteReg(ADDR_SCONF10, &SH367306_Sconf10); } //配置MOS状态 void SH367306_Mosfet(INT8U Fet, INT8U NewState) { INT8U tValue[2]; SH367306_ReadReg(ADDR_SCONF2, (INT16U *) & (tValue[0])); //读取配置寄存器状态 #ifdef _C51 SH367306_Sconf2 = tValue[0]; #else SH367306_Sconf2 = tValue[1]; #endif if(NewState == DISABLE) { if(Fet & SH367306_CFET) { SH367306_CFG_CHGC = 0; } if(Fet & SH367306_DFET) { SH367306_CFG_DSGC = 0; } } else { if(Fet & SH367306_CFET) { SH367306_CFG_CHGC = 1; } if(Fet & SH367306_DFET) { SH367306_CFG_DSGC = 1; } } SH367306_WriteReg(ADDR_SCONF2, &SH367306_Sconf2); BATT_FLAG_DFET = SH367306_CFG_DSGC; BATT_FLAG_CFET = SH367306_CFG_CHGC; } //操作均衡MOS,6串的均衡使能与8串的均衡使能冲突 void SH367306_Balance(INT16U BalanceMask) { //移位处理低位没有使用的电芯连接 BalanceMask = BalanceMask << (SH367306_CELL_MAX - CELL_SIZE_CHIP0); SH367306_Sconf5 = (INT8U)((BalanceMask) & 0x1f); //高5位 SH367306_Sconf4 = (INT8U)((BalanceMask >> 5) & 0x1f); //低5位 BATT_FLAG_BALF ^= 0x02; if(BATT_FLAG_BALF & 0x02) //第6串与第8串轮流均衡,修正此bug { if(SH367306_CFG_CB8 != 0) { SH367306_CFG_CB6 = 0; } } else if(SH367306_CFG_CB6 != 0) { SH367306_CFG_CB8 = 0; } SH367306_WriteReg(ADDR_SCONF4, &SH367306_Sconf4); SH367306_WriteReg(ADDR_SCONF5, &SH367306_Sconf5); } //休眠时检查MOS状态,防止出现死锁的情况 void SH367306_FetCheck(void) { //充电MOS和放电MOS同时关闭,或者无过充标志置位,打开充电MOS if(((SH367306_CFG_CHGC == 0) && \ (SH367306_CFG_DSGC == 0)) || \ (BATT_FLAG_OV == 0)) { BATT_FetLock(CFET, UnLock); SH367306_Mosfet(SH367306_CFET, ENABLE); } } //读取电芯电压 void SH367306_ReadCellVoltage(void) { INT8U i, j; SH367306_VcMask = CELL_MASK_CHIP0; //复制芯片0的参数到相应的寄存器缓冲区 for (i = 0, j = 0; i < SH367306_CELL_MAX; i++) { if (SH367306_VcMask & (1UL << i)) { SH367306_ReadReg((ADDR_CellV + i * 2), &(SH367306_Vc[j])); BATT_Vc[j] = (ADCGAIN_BYTE * SH367306_Vc[j]) >> 12; // / 4096; j++; } } } //BQ769x0读取温度传感器数据 void SH367306_ReadCellTemp(void) { INT8U i, j; SH367306_TsMask = NTC_MASK_CHIP0; for (i = 0, j = 0; i < 4; i++) { if (SH367306_TsMask & (1UL << i)) //显示温度为最后一个有效温度点的温度 { SH367306_ReadReg((ADDR_CellT + i * 2), &(SH367306_Ts[j])); if(i < 2) { BATT_Ts[j] = NTC_Temperature((SH367306_Ts[j]), ADC_SH36730x); } else { BATT_Ts[j] = (SH367306_Ts[j] * 17) / 100 - 270; } j++; } } //芯片只使用1个NTC,接在NTC2位置,其他位置贴电阻, //BATT_Ts[0]=BATT_Ts[1]; //BATT_Ts[2]=BATT_Ts[1]; //BATT_Ts[3]=BATT_Ts[1]; } //SH367306读取电流值,电流单位10mA //I=1000*CUR/(65536*Rsense) //I=CUR*BATT_CC_GAIN*RSNS_Tab[SH367306_CFG_RSNS] //BATT_CC_GAIN=1000*1000*1000/(65536*Rsense)=15258/Rsense __FLASH INT8S RSNS_Tab[] = {8, 4, 2, 1}; void SH367306_ReadCellCurrent(void) { INT32S tCurrent; INT8U tRSNS = 0; //默认情况下设置为0-400mV档位, //CC_BYTE = SH367306_ReadReg(ADDR_CC); SH367306_ReadReg(ADDR_CC, (INT16U *)&SH367306_CC); if(SH367306_CC & 0x1000) { SH367306_CC |= 0xe000; } else { SH367306_CC &= 0x0fff; } tCurrent = SH367306_CC - SH367306_CcOffset; tCurrent = tCurrent * SH367306_CcGain * RSNS_Tab[SH367306_CFG_RSNS]; //BATT_Current=CC_BYTE-BATT_Info.PACK.CC_Offset; //BATT_Current = BATT_Current * BATT_CC_GAIN * RSNS_Tab[SH367306_CFG_RSNS]; //20mA无指示 if((tCurrent > -2000) && (tCurrent < 2000)) tCurrent = 0; BATT_Current = tCurrent / 100; if((BATT_Current < 8000) && (BATT_Current > -8000)) //8A切换到50mV档, 50/5=10A { tRSNS = RSNS_50mV; } else if((BATT_Current < 16000) && (BATT_Current > -16000)) //16A切换到100mV档,100/5=20A { tRSNS = RSNS_100mV; } else if((BATT_Current < 32000) && (BATT_Current > -32000)) //32A切换到200mV档,200/5=40A { tRSNS = RSNS_200mV; } else //32A切换到200mV档,200/5=40A { tRSNS = RSNS_400mV; } if(tRSNS != SH367306_CFG_RSNS) { SH367306_CFG_RSNS = tRSNS; SH367306_WriteReg(ADDR_SCONF6, &SH367306_Sconf6); } } void SH367306_Init(void) { INT8U i = 20; SH367306_FlashInfoInit(); SH367306_I2cInit(); SH367306_GpioInit(); SH367306_ChipInit(); while(i--) { BATT_ReadInfo(); DELAY_Ms(20); } BATT_CellVoltageProcess(); } void SH367306_ResetChip(void) { SH364306_ResetLow(); DELAY_Ms(500); SH364306_ResetHigh(); SH367306_Init(); } /* INT8U AFE_UartInfoProcess(void) { if(BATT_Info.Uart.Crc == CRC8((INT8U *)&(BATT_Info.Uart), (sizeof(SH367306_UART_Str)-2))) { //复制电压数据 MEM_Copy((INT8U *)&(BATT_Info.Uart.Vx[0]), (INT8U *)&(BATT_Info.INFO.CELL_V[CELL_SIZE_CHIP0]), BATT_Info.Uart.CellNum*2); //复制外部温度数据 MEM_Copy((INT8U *)&(BATT_Info.Uart.Tx[0]), (INT8U *)&(BATT_Info.INFO.CELL_T[NTC_SIZE_CHIP0/2]), BATT_Info.Uart.TemNum*2); //复制芯片温度数据 MEM_Copy((INT8U *)&(BATT_Info.Uart.Tx[2]), (INT8U *)&(BATT_Info.INFO.CHIP_T[NTC_SIZE_CHIP0/2]), BATT_Info.Uart.TemNum*2); } return(1); } INT8U AFE_UartInfoFill(void) { BATT_Info.Uart.Addr=1; BATT_Info.Uart.Id=1; BATT_Info.Uart.CellNum=CELL_SIZE_CHIP1; BATT_Info.Uart.TemNum=NTC_SIZE_CHIP0/2; //复制电压数据 MEM_Copy((INT8U *)&(BATT_Info.INFO.CELL_V[0]), (INT8U *)&(BATT_Info.Uart.Vx[0]), BATT_Info.Uart.CellNum*2); //复制温度数据 MEM_Copy((INT8U *)&(BATT_Info.INFO.CELL_T[0]), (INT8U *)&(BATT_Info.Uart.Tx[0]), BATT_Info.Uart.TemNum*2); //复制芯片温度数据 MEM_Copy((INT8U *)&(BATT_Info.INFO.CHIP_T[0]), (INT8U *)&(BATT_Info.Uart.Tx[2]), BATT_Info.Uart.TemNum*2); BATT_Info.Uart.Crc=CRC8((INT8U *)&(BATT_Info.Uart), (sizeof(SH367306_UART_Str)-2)); return(1); } */