C51 COMPILER V9.01 CALCULATE 02/08/2025 15:18:20 PAGE 1 C51 COMPILER V9.01, COMPILATION OF MODULE CALCULATE OBJECT MODULE PLACED IN .\output\Calculate.obj COMPILER INVOKED BY: D:\Tool\Keil\C51\BIN\C51.EXE code_drv\Calculate.c LARGE OPTIMIZE(7,SIZE) REGFILE(.\output\MCUCore_L -oad.ORC) BROWSE INTVECTOR(0X1000) INCDIR(.\header_app;.\header_drv;.\code_gasguage;.\code_classb\iec60730_lib\include;.\ -code_classb\iec60730_proc\Include;.\code_classb\config) DEBUG OBJECTEXTEND PRINT(.\output\Calculate.lst) OBJECT(.\output -\Calculate.obj) line level source 1 /******************************************************************************** 2 Copyright (C), Sinowealth Electronic. Ltd. 3 Author: Sino 4 Version: V0.0 5 Date: 2020/04/26 6 History: 7 V2.0 2020/04/26 Preliminary 8 ********************************************************************************/ 9 #include "Main.h" 10 11 12 U8 xdata ucChgingCheckCnt; 13 U8 xdata ucDsgingCheckCnt; 14 15 /************************************************************************************************* 16 * 函数名: CalcuTemp 17 * 参 数: 无 18 * 返回值: 无 19 * 描 述: 根据计算的阻值来查表,获取对应温度。温度变量保存的为开尔文温度*10 20 例如摄氏度25°,温度变量保存的值为2731+250 21 *************************************************************************************************/ 22 U16 CalcuTemp(U16 getdata) 23 { 24 1 U8 i; 25 1 U16 Temperature; 26 1 U32 Tempcalcu; 27 1 28 1 #if (AFE_ID == 0x34) Tempcalcu = (U32)getdata*REF_RES_VAL/(32768-getdata); #else 31 1 Tempcalcu= (U32)getdata*REF_RES_VAL/(4096-getdata); //calculte the resistance value of 103AT 32 1 if(Tempcalcu > 10) 33 1 { 34 2 Tempcalcu -= 10; 35 2 } 36 1 #endif 37 1 38 1 if(Tempcalcu >= NTC103AT[0]) //look up table to find the resieter correspond -temp 39 1 { 40 2 Temperature = 2731+(TEMP_LOWER_LIMIT *10); 41 2 } 42 1 else if(Tempcalcu <= NTC103AT[NTC103AT_ARRAY_LEN-1]) 43 1 { 44 2 Temperature = 2731+(TEMP_UPPER_LIMIT *10); 45 2 } 46 1 else 47 1 { 48 2 i = ucTempeMiddle; //the ucTempeMiddle must be initialized in InitVar() 49 2 if(Tempcalcu > NTC103AT[i]) 50 2 { 51 3 for(i=ucTempeMiddle-1; i>=0; i--) C51 COMPILER V9.01 CALCULATE 02/08/2025 15:18:20 PAGE 2 52 3 { 53 4 if(Tempcalcu <= NTC103AT[i]) //NTC103AT[i+1] NTC103AT[i]) //NTC103AT[i-1] 5) //6~10串应用时 122 1 { 123 2 if(!AFEReadReg(AFE_TEMP2H, 2, (U8 xdata *)&AFE.uiICTempe[1])) 124 2 { 125 3 Result = 0; 126 3 } 127 2 } 128 1 129 1 return Result; 130 1 } 131 132 133 /************************************************************************************************* 134 * 函数名: AfeCalcuTempe 135 * 参 数: 无 136 * 返回值: 无 137 * 描 述: 计算温度,更新uiTempeMax、uiTempeMin 138 *************************************************************************************************/ 139 void AfeCalcuTempe(void) 140 { 141 1 U16 TempeData; 142 1 143 1 if(AfeGetTempe()) 144 1 { 145 2 TempeData = CalcuTemp(AFE.uiTS[0]) + E2siTS0Offset; //计算外部温度1 146 2 #if (UART0_DEFINE != 0) 147 2 IrqUart0Dis(); 148 2 #endif 149 2 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 152 2 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 155 2 Info.uiTS[0] = TempeData; 156 2 #if (UART0_DEFINE != 0) 157 2 IrqUart0En(); //开启uart0中断 158 2 #endif 159 2 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 162 2 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 165 2 TempeData = (U32)AFE.uiICTempe[0]*17/10+31; //计算内部温度1 166 2 #if (UART0_DEFINE != 0) 167 2 IrqUart0Dis(); 168 2 #endif 169 2 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 172 2 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 175 2 Info.uiICTempe[0] = TempeData; C51 COMPILER V9.01 CALCULATE 02/08/2025 15:18:20 PAGE 4 176 2 177 2 #if (UART0_DEFINE != 0) 178 2 IrqUart0En(); //开启uart0中断 179 2 #endif 180 2 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 183 2 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 186 2 187 2 if(ucCellNum > 5) //6~10串应用时 188 2 { 189 3 TempeData = (U32)AFE.uiICTempe[1]*17/10+31; //计算内部温度2 190 3 #if (UART0_DEFINE != 0) 191 3 IrqUart0Dis(); 192 3 #endif 193 3 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 196 3 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 199 3 Info.uiICTempe[1] = TempeData; 200 3 #if (UART0_DEFINE != 0) 201 3 IrqUart0En(); //开启uart0中断 202 3 #endif 203 3 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 206 3 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 209 3 } 210 2 211 2 uiTempeMin = Info.uiTS[0]; 212 2 uiTempeMax = Info.uiTS[0]; 213 2 if(bTempNum) 214 2 { 215 3 TempeData = CalcuTemp(AFE.uiTS[1]) + E2siTS1Offset; //计算外部温度2 216 3 #if (UART0_DEFINE != 0) 217 3 IrqUart0Dis(); 218 3 #endif 219 3 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 222 3 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 225 3 Info.uiTS[1] = TempeData; 226 3 #if (UART0_DEFINE != 0) 227 3 IrqUart0En(); //开启uart0中断 228 3 #endif 229 3 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 232 3 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 235 3 236 3 if(TempeData < uiTempeMin) 237 3 { C51 COMPILER V9.01 CALCULATE 02/08/2025 15:18:20 PAGE 5 238 4 uiTempeMin = TempeData; 239 4 } 240 3 else 241 3 { 242 4 uiTempeMax = TempeData; 243 4 } 244 3 } 245 2 } 246 1 } 247 248 249 /************************************************************************************************* 250 * 函数名: AfeCalcuVol 251 * 参 数: 无 252 * 返回值: 无 253 * 描 述: 计算电压,同步更新最大值最小值uiVadcVmax、uiVadcVmin,用于断线判断 254 当没有平衡时,才更新uiCellVmax、uiCellVmin,用于保护判断 255 *************************************************************************************************/ 256 void AfeCalcuVol(void) 257 { 258 1 U8 i; 259 1 U32 TempPackVol=0, TempCellVol=0; 260 1 uiVadcVmax = 0; 261 1 uiVadcVmin = 6000; 262 1 263 1 if(AfeGetVol()) 264 1 { 265 2 for(i=ucCellNumOffset; i<(ucCellNum+ucCellNumOffset); i++) 266 2 { 267 3 TempCellVol = (U32)AFE.uiCell[i]*CALIVOL/E2uiVPackGain; 268 3 269 3 if(TempCellVol > uiVadcVmax) //计算最大值&最小值 270 3 { 271 4 uiVadcVmax = TempCellVol; 272 4 } 273 3 if(TempCellVol < uiVadcVmin) 274 3 { 275 4 uiVadcVmin = TempCellVol; 276 4 } 277 3 278 3 if(!bBalancingFlg) //if bCellOpenDecFlag this data will throw away 279 3 { 280 4 #if (UART0_DEFINE != 0) 281 4 IrqUart0Dis(); 282 4 #endif 283 4 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 286 4 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 289 4 Info.uiVCell[i] = TempCellVol; 290 4 #if (UART0_DEFINE != 0) 291 4 IrqUart0En(); //开启uart0中断 292 4 #endif 293 4 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 296 4 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 299 4 TempPackVol += TempCellVol; C51 COMPILER V9.01 CALCULATE 02/08/2025 15:18:20 PAGE 6 300 4 } 301 3 } 302 2 303 2 if(!bBalancingFlg) 304 2 { 305 3 uiCellVmax = uiVadcVmax; 306 3 uiCellVmin = uiVadcVmin; 307 3 308 3 #if (UART0_DEFINE != 0) 309 3 IrqUart0Dis(); 310 3 #endif 311 3 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 314 3 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 317 3 Info.ulVoltage = TempPackVol; //Calculate the total voltage 318 3 #if (UART0_DEFINE != 0) 319 3 IrqUart0En(); //开启uart0中断 320 3 #endif 321 3 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 324 3 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 327 3 } 328 2 } 329 1 } 330 331 332 /************************************************************************************************* 333 * 函数名: CurTempOffset 334 * 参 数: 无 335 * 返回值: 无 336 * 描 述: 不同芯片温度下ADC的补偿值 337 *************************************************************************************************/ 338 S16 code siCurTempOffset[2][13]= 339 { /**0****1****2****3***4***5***6***7***8***9**10**11**12**/ 340 {-40, -30, -20, -10, 0, 10, 25, 35, 45, 55, 65, 75, 85}, 341 { -5, -4, -3, -2, -1, -1, 0, 1, 1, 2, 3, 4, 5}, 342 }; 343 344 /************************************************************************************************* 345 * 函数名: OffsetCalculate() 346 * 参 数: 无 347 * 返回值: 无 348 * 描 述: 根据芯片内部温度实时调整0电流补偿值,以便消除温度对ADC采集产生的影响 349 *************************************************************************************************/ 350 S16 OffsetCalculate(void) 351 { 352 1 S16 xdata siCadcTempOffset=0; //20220620 353 1 U8 xdata i; 354 1 355 1 for(i=0; i<12; i++) 356 1 { 357 2 if(Info.uiICTempe[0] <= (((S32)siCurTempOffset[0][i] + siCurTempOffset[0][i+1]) / 2 * 10 + 2731)) 358 2 { 359 3 siCadcTempOffset = siCurTempOffset[1][i]; 360 3 break; 361 3 } C51 COMPILER V9.01 CALCULATE 02/08/2025 15:18:20 PAGE 7 362 2 } 363 1 return siCadcTempOffset; 364 1 } 365 366 /************************************************************************************************* 367 * 函数名: AfeCalcuCurr 368 * 参 数: 无 369 * 返回值: 无 370 * 描 述: 计算CADC采集的电流数据 371 *************************************************************************************************/ 372 void AfeCalcuCurr(void) 373 { 374 1 U8 i; 375 1 S32 Tempdata=0; 376 1 377 1 AFEReadReg(AFE_CURH, 2, (U8 xdata *)&AFE.siCurr); //通过TWI读取CADC采集的电流值 378 1 379 1 if((AFE.siCurr&0x1000) != 0) //根据bit12判断是否为负数(放电电流为负值),如为负值高位补0 380 1 { 381 2 AFE.siCurr|=0xE000; 382 2 } 383 1 slCadcCurrent = (S32)CALICUR*(AFE.siCurr-E2siCadcOffset+OffsetCalculate())/E2siCadcGain; 384 1 385 1 slCadcCurBuf[ucCadcCnt] = slCadcCurrent; //对连续采集的16次电流取平均值,作为当前电流值 386 1 if(++ucCadcCnt >= 16) 387 1 { 388 2 ucCadcCnt = 0; 389 2 } 390 1 for(i=0; i<16; i++) 391 1 { 392 2 Tempdata += slCadcCurBuf[i]; 393 2 } 394 1 slCadcCurAverage = Tempdata/16; 395 1 396 1 bDSGING = 0; //根据电流判定充放电状态 397 1 bCHGING = 0; 398 1 if(slCadcCurAverage < (-E2siDfilterCur)) 399 1 { 400 2 if(++ucDsgingCheckCnt >= TIME_50MS_500MS) //充放电状态检测延时10*50mS 401 2 { 402 3 ucDsgingCheckCnt = TIME_50MS_500MS; 403 3 bDSGING = 1; 404 3 #if (UART0_DEFINE != 0) 405 3 IrqUart0Dis(); 406 3 #endif 407 3 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 410 3 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 413 3 Info.slCurr = slCadcCurAverage; 414 3 #if (UART0_DEFINE != 0) 415 3 IrqUart0En(); //开启uart0中断 416 3 #endif 417 3 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 420 3 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 423 3 } C51 COMPILER V9.01 CALCULATE 02/08/2025 15:18:20 PAGE 8 424 2 } 425 1 else if(slCadcCurAverage > E2siDfilterCur) 426 1 { 427 2 if(++ucChgingCheckCnt >= TIME_50MS_500MS) //充放电状态检测延时10*50mS 428 2 { 429 3 ucChgingCheckCnt = TIME_50MS_500MS; 430 3 bCHGING = 1; 431 3 McuPWM2Set(4000, 100); 432 3 #if (UART0_DEFINE != 0) 433 3 IrqUart0Dis(); 434 3 #endif 435 3 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 438 3 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 441 3 Info.slCurr = slCadcCurAverage; 442 3 #if (UART0_DEFINE != 0) 443 3 IrqUart0En(); //开启uart0中断 444 3 #endif 445 3 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 448 3 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 451 3 } 452 2 } 453 1 else 454 1 { 455 2 #if (UART0_DEFINE != 0) 456 2 IrqUart0Dis(); 457 2 #endif 458 2 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 461 2 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 464 2 Info.slCurr = 0; 465 2 #if (UART0_DEFINE != 0) 466 2 IrqUart0En(); //开启uart0中断 467 2 #endif 468 2 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 471 2 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 474 2 } 475 1 } 476 477 478 /************************************************************************************************* 479 * 函数名: AFEInfoProcess 480 * 参 数: 无 481 * 返回值: 无 482 * 描 述: 每50mS读取AFE信息,并更新电压、电流、温度数据 483 *************************************************************************************************/ 484 void AFEInfoProcess(void) 485 { C51 COMPILER V9.01 CALCULATE 02/08/2025 15:18:20 PAGE 9 486 1 AFERdFlg(); 487 1 488 1 bVADCFlg = 0; 489 1 AfeCalcuVol(); 490 1 AfeCalcuTempe(); 491 1 492 1 if(bCADCFlg) //当CADC转换完成后,才读取AFE电流信息并计算 493 1 { 494 2 bCADCFlg = 0; 495 2 AfeCalcuCurr(); 496 2 } 497 1 } 498 499 MODULE INFORMATION: STATIC OVERLAYABLE CODE SIZE = 1772 ---- CONSTANT SIZE = 52 ---- XDATA SIZE = 2 25 PDATA SIZE = ---- ---- DATA SIZE = ---- ---- IDATA SIZE = ---- ---- BIT SIZE = ---- 2 END OF MODULE INFORMATION. C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)