C51 COMPILER V9.01 CALCULATE 02/06/2025 15:28:45 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/06/2025 15:28:45 PAGE 2 52 3 { 53 4 if(Tempcalcu <= NTC103AT[i]) //NTC103AT[i+1] NTC103AT[i]) //NTC103AT[i-1] 5) //6~10串应用时 119 1 { 120 2 if(!AFEReadReg(AFE_TEMP2H, 2, (U8 xdata *)&AFE.uiICTempe[1])) 121 2 { 122 3 Result = 0; 123 3 } 124 2 } 125 1 126 1 return Result; 127 1 } 128 129 130 /************************************************************************************************* 131 * 函数名: AfeCalcuTempe 132 * 参 数: 无 133 * 返回值: 无 134 * 描 述: 计算温度,更新uiTempeMax、uiTempeMin 135 *************************************************************************************************/ 136 void AfeCalcuTempe(void) 137 { 138 1 U16 TempeData; 139 1 140 1 if(AfeGetTempe()) 141 1 { 142 2 TempeData = CalcuTemp(AFE.uiTS[0]) + E2siTS0Offset; //计算外部温度1 143 2 #if (UART0_DEFINE != 0) 144 2 IrqUart0Dis(); 145 2 #endif 146 2 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 149 2 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 152 2 Info.uiTS[0] = TempeData; 153 2 #if (UART0_DEFINE != 0) 154 2 IrqUart0En(); //开启uart0中断 155 2 #endif 156 2 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 159 2 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 162 2 TempeData = (U32)AFE.uiICTempe[0]*17/10+31; //计算内部温度1 163 2 #if (UART0_DEFINE != 0) 164 2 IrqUart0Dis(); 165 2 #endif 166 2 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 169 2 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 172 2 Info.uiICTempe[0] = TempeData; 173 2 174 2 #if (UART0_DEFINE != 0) 175 2 IrqUart0En(); //开启uart0中断 C51 COMPILER V9.01 CALCULATE 02/06/2025 15:28:45 PAGE 4 176 2 #endif 177 2 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 180 2 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 183 2 184 2 if(ucCellNum > 5) //6~10串应用时 185 2 { 186 3 TempeData = (U32)AFE.uiICTempe[1]*17/10+31; //计算内部温度2 187 3 #if (UART0_DEFINE != 0) 188 3 IrqUart0Dis(); 189 3 #endif 190 3 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 193 3 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 196 3 Info.uiICTempe[1] = TempeData; 197 3 #if (UART0_DEFINE != 0) 198 3 IrqUart0En(); //开启uart0中断 199 3 #endif 200 3 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 203 3 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 206 3 } 207 2 208 2 uiTempeMin = Info.uiTS[0]; 209 2 uiTempeMax = Info.uiTS[0]; 210 2 if(bTempNum) 211 2 { 212 3 TempeData = CalcuTemp(AFE.uiTS[1]) + E2siTS1Offset; //计算外部温度2 213 3 #if (UART0_DEFINE != 0) 214 3 IrqUart0Dis(); 215 3 #endif 216 3 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 219 3 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 222 3 Info.uiTS[1] = TempeData; 223 3 #if (UART0_DEFINE != 0) 224 3 IrqUart0En(); //开启uart0中断 225 3 #endif 226 3 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 229 3 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 232 3 233 3 if(TempeData < uiTempeMin) 234 3 { 235 4 uiTempeMin = TempeData; 236 4 } 237 3 else C51 COMPILER V9.01 CALCULATE 02/06/2025 15:28:45 PAGE 5 238 3 { 239 4 uiTempeMax = TempeData; 240 4 } 241 3 } 242 2 } 243 1 } 244 245 246 /************************************************************************************************* 247 * 函数名: AfeCalcuVol 248 * 参 数: 无 249 * 返回值: 无 250 * 描 述: 计算电压,同步更新最大值最小值uiVadcVmax、uiVadcVmin,用于断线判断 251 当没有平衡时,才更新uiCellVmax、uiCellVmin,用于保护判断 252 *************************************************************************************************/ 253 void AfeCalcuVol(void) 254 { 255 1 U8 i; 256 1 U32 TempPackVol=0, TempCellVol=0; 257 1 uiVadcVmax = 0; 258 1 uiVadcVmin = 6000; 259 1 260 1 if(AfeGetVol()) 261 1 { 262 2 for(i=ucCellNumOffset; i<(ucCellNum+ucCellNumOffset); i++) 263 2 { 264 3 TempCellVol = (U32)AFE.uiCell[i]*CALIVOL/E2uiVPackGain; 265 3 266 3 if(TempCellVol > uiVadcVmax) //计算最大值&最小值 267 3 { 268 4 uiVadcVmax = TempCellVol; 269 4 } 270 3 if(TempCellVol < uiVadcVmin) 271 3 { 272 4 uiVadcVmin = TempCellVol; 273 4 } 274 3 275 3 if(!bBalancingFlg) //if bCellOpenDecFlag this data will throw away 276 3 { 277 4 #if (UART0_DEFINE != 0) 278 4 IrqUart0Dis(); 279 4 #endif 280 4 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 283 4 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 286 4 Info.uiVCell[i] = TempCellVol; 287 4 #if (UART0_DEFINE != 0) 288 4 IrqUart0En(); //开启uart0中断 289 4 #endif 290 4 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 293 4 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 296 4 TempPackVol += TempCellVol; 297 4 } 298 3 } 299 2 C51 COMPILER V9.01 CALCULATE 02/06/2025 15:28:45 PAGE 6 300 2 if(!bBalancingFlg) 301 2 { 302 3 uiCellVmax = uiVadcVmax; 303 3 uiCellVmin = uiVadcVmin; 304 3 305 3 #if (UART0_DEFINE != 0) 306 3 IrqUart0Dis(); 307 3 #endif 308 3 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 311 3 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 314 3 Info.ulVoltage = TempPackVol; //Calculate the total voltage 315 3 #if (UART0_DEFINE != 0) 316 3 IrqUart0En(); //开启uart0中断 317 3 #endif 318 3 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 321 3 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 324 3 } 325 2 } 326 1 } 327 328 329 /************************************************************************************************* 330 * 函数名: CurTempOffset 331 * 参 数: 无 332 * 返回值: 无 333 * 描 述: 不同芯片温度下ADC的补偿值 334 *************************************************************************************************/ 335 S16 code siCurTempOffset[2][13]= 336 { /**0****1****2****3***4***5***6***7***8***9**10**11**12**/ 337 {-40, -30, -20, -10, 0, 10, 25, 35, 45, 55, 65, 75, 85}, 338 { -5, -4, -3, -2, -1, -1, 0, 1, 1, 2, 3, 4, 5}, 339 }; 340 341 /************************************************************************************************* 342 * 函数名: OffsetCalculate() 343 * 参 数: 无 344 * 返回值: 无 345 * 描 述: 根据芯片内部温度实时调整0电流补偿值,以便消除温度对ADC采集产生的影响 346 *************************************************************************************************/ 347 S16 OffsetCalculate(void) 348 { 349 1 S16 xdata siCadcTempOffset=0; //20220620 350 1 U8 xdata i; 351 1 352 1 for(i=0; i<12; i++) 353 1 { 354 2 if(Info.uiICTempe[0] <= (((S32)siCurTempOffset[0][i] + siCurTempOffset[0][i+1]) / 2 * 10 + 2731)) 355 2 { 356 3 siCadcTempOffset = siCurTempOffset[1][i]; 357 3 break; 358 3 } 359 2 } 360 1 return siCadcTempOffset; 361 1 } C51 COMPILER V9.01 CALCULATE 02/06/2025 15:28:45 PAGE 7 362 363 /************************************************************************************************* 364 * 函数名: AfeCalcuCurr 365 * 参 数: 无 366 * 返回值: 无 367 * 描 述: 计算CADC采集的电流数据 368 *************************************************************************************************/ 369 void AfeCalcuCurr(void) 370 { 371 1 U8 i; 372 1 S32 Tempdata=0; 373 1 374 1 AFEReadReg(AFE_CURH, 2, (U8 xdata *)&AFE.siCurr); //通过TWI读取CADC采集的电流值 375 1 376 1 if((AFE.siCurr&0x1000) != 0) //根据bit12判断是否为负数(放电电流为负值),如为负值高位补0 377 1 { 378 2 AFE.siCurr|=0xE000; 379 2 } 380 1 slCadcCurrent = (S32)CALICUR*(AFE.siCurr-E2siCadcOffset+OffsetCalculate())/E2siCadcGain; 381 1 382 1 slCadcCurBuf[ucCadcCnt] = slCadcCurrent; //对连续采集的16次电流取平均值,作为当前电流值 383 1 if(++ucCadcCnt >= 16) 384 1 { 385 2 ucCadcCnt = 0; 386 2 } 387 1 for(i=0; i<16; i++) 388 1 { 389 2 Tempdata += slCadcCurBuf[i]; 390 2 } 391 1 slCadcCurAverage = Tempdata/16; 392 1 393 1 bDSGING = 0; //根据电流判定充放电状态 394 1 bCHGING = 0; 395 1 if(slCadcCurAverage < (-E2siDfilterCur)) 396 1 { 397 2 if(++ucDsgingCheckCnt >= TIME_50MS_500MS) //充放电状态检测延时10*50mS 398 2 { 399 3 ucDsgingCheckCnt = TIME_50MS_500MS; 400 3 bDSGING = 1; 401 3 #if (UART0_DEFINE != 0) 402 3 IrqUart0Dis(); 403 3 #endif 404 3 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 407 3 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 410 3 Info.slCurr = slCadcCurAverage; 411 3 #if (UART0_DEFINE != 0) 412 3 IrqUart0En(); //开启uart0中断 413 3 #endif 414 3 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 417 3 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 420 3 } 421 2 } 422 1 else if(slCadcCurAverage > E2siDfilterCur) 423 1 { C51 COMPILER V9.01 CALCULATE 02/06/2025 15:28:45 PAGE 8 424 2 if(++ucChgingCheckCnt >= TIME_50MS_500MS) //充放电状态检测延时10*50mS 425 2 { 426 3 ucChgingCheckCnt = TIME_50MS_500MS; 427 3 bCHGING = 1; 428 3 McuPWM2Set(4000, 100); 429 3 #if (UART0_DEFINE != 0) 430 3 IrqUart0Dis(); 431 3 #endif 432 3 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 435 3 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 438 3 Info.slCurr = slCadcCurAverage; 439 3 #if (UART0_DEFINE != 0) 440 3 IrqUart0En(); //开启uart0中断 441 3 #endif 442 3 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 445 3 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 448 3 } 449 2 } 450 1 else 451 1 { 452 2 #if (UART0_DEFINE != 0) 453 2 IrqUart0Dis(); 454 2 #endif 455 2 #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif 458 2 #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif 461 2 Info.slCurr = 0; 462 2 #if (UART0_DEFINE != 0) 463 2 IrqUart0En(); //开启uart0中断 464 2 #endif 465 2 #if (UART1_DEFINE != 0) IrqUart1En(); //开启uart1中断 #endif 468 2 #if (UART2_DEFINE != 0) IrqUart2En(); //初始化UART2中断使能,根据具体使用UART模块来进行选择 #endif 471 2 } 472 1 } 473 474 475 /************************************************************************************************* 476 * 函数名: AFEInfoProcess 477 * 参 数: 无 478 * 返回值: 无 479 * 描 述: 每50mS读取AFE信息,并更新电压、电流、温度数据 480 *************************************************************************************************/ 481 void AFEInfoProcess(void) 482 { 483 1 AFERdFlg(); 484 1 485 1 bVADCFlg = 0; C51 COMPILER V9.01 CALCULATE 02/06/2025 15:28:45 PAGE 9 486 1 AfeCalcuVol(); 487 1 AfeCalcuTempe(); 488 1 489 1 if(bCADCFlg) //当CADC转换完成后,才读取AFE电流信息并计算 490 1 { 491 2 bCADCFlg = 0; 492 2 AfeCalcuCurr(); 493 2 } 494 1 } 495 496 MODULE INFORMATION: STATIC OVERLAYABLE CODE SIZE = 1760 ---- 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)