#include "../main/SystemInclude.h" //============================================================================== u32 dcoefNode[DCOEF_MAX]; u16 dcoef, dcoefVal[DCOEF_MAX]; float GCFParaA, GCFParaB, GCFParaC; u16 GCFCoefB; s32 GCFCoefA, GCFCoefC; float GCFParaA, GCFParaB, GCFParaC; //u16 dcoefNum; //****************************************************************************** // Routines for device coefficients //保存二次修正曲线节点流量 void StoreDevCoefNodeAndValue(unsigned char I) { tempL.DWord= dcoefNode[I]; tempDev.Word[2] = tempL.Word[1]; tempDev.Word[1] = tempL.Word[0]; tempDev.Word[0] = dcoefVal[I]; WriteMultiByteToMemory(DCOEF_BASE+I*DCOEF_WIDTH, tempDev.Byte, DCOEF_WIDTH); } //****************************************************************************** //读二次修正曲线节点流量 bool ReadDevCoefNodeAndValue(unsigned char I) { ReadMultiByteFromMemory(DCOEF_BASE + I * DCOEF_WIDTH, tempDev.Byte, DCOEF_WIDTH); if(tempDev.Byte[DCOEF_CRC] == CRC8(tempDev.Byte, DCOEF_CRC)) { tempDev.Byte[DCOEF_CRC] = 0; dcoefVal[I] = tempDev.Word[0]; tempL.Word[0] = tempDev.Word[1]; tempL.Word[1] = tempDev.Word[2]; dcoefNode[I] = tempL.DWord; return 0; } else { dcoefNode[I] = 0; dcoefVal[I] = 0; return 1; } } //****************************************************************************** //默认的二次修正曲线参数 void DefaultDevCoef(void) { unsigned char I; //u32 flowRateMax; dcoefNode[0] = (maxFlowRate * 1) / 100; // 1% 1028 dcoefNode[1] = 1000; dcoefNode[2] = (maxFlowRate * 10) / 100; // 10% //dcoefNode[3] = (maxFlowRate * 20) / 100; //dcoefNode[4] = (maxFlowRate * 40) / 100; dcoefNode[3] = maxFlowRate >> 1; // 50% dcoefNode[4] = maxFlowRate; // 100% if(dcoefNode[0] < 500) dcoefNode[0] = 500; if(dcoefNode[1] <= dcoefNode[0]) dcoefNode[1] = (maxFlowRate * 5) / 100; //dcoefNode[1] = (dcoefNode[0] + dcoefNode[2])>>1; if(dcoefNode[2] <= dcoefNode[1]) dcoefNode[2] = (dcoefNode[1] + dcoefNode[3]) >> 1; if(dcoefNode[3] <= dcoefNode[2]) dcoefNode[3] = (dcoefNode[2] + dcoefNode[4]) >> 1; dcoefNum = 5; tempL.Byte[0] = dcoefNum; // WriteShortParameterToEEPROM(DCOEF_NUM, DCOEF_NUM_WIDTH); WriteShortParameterToEEPROM(DCOEF_NUM); for (I = 0; I < dcoefNum; I++) { dcoefVal[I] = METER_PARAMETER_DEFAULT; //dcoefNode[I] = ConvertFlowrate(dcoefNode[I]); StoreDevCoefNodeAndValue(I); } } //****************************************************************************** //读二次修正曲线参数 void RetriveDevCoef(void) { u32 I; // u32 flowRateMax; ReadShortParameterFromMemory(DCOEF_NUM, PARA_EEPROM); // if(tempL.Byte[1] != CRC8(tempL.Byte, 1)) goto RetResetDevCoef; dcoefNum = tempL.Byte[0]; if((dcoefNum > DCOEF_MAX)||(dcoefNum < 3)) goto RetResetDevCoef; if(ReadDevCoefNodeAndValue(0)) goto RetResetDevCoef; for (I = 1; I < dcoefNum; I++) { if(ReadDevCoefNodeAndValue(I)) goto RetResetDevCoef; if(dcoefNode[I] <= dcoefNode[I-1]) goto RetResetDevCoef; // if(dcoefNode[I] > flowRateMax) goto RetResetDevCoef; } return; RetResetDevCoef: DefaultDevCoef(); return; } //****************************************************************************** void JudgeDevCoef(void) { u16 I; for (I = 1; I < dcoefNum; I++) { if(dcoefNode[I] <= dcoefNode[I-1]) { RetriveDevCoef(); return; } } } //****************************************************************************** //根据流量计算二次修正值 u16 GetDevCoefFactor(u32 dcoefFlowRate) { // u32 tmp; u16 nodeVal = METER_PARAMETER_DEFAULT; u32 nodeFR = 0; unsigned char I; for(I = 0; I < dcoefNum; I++) { if(dcoefNode[I] < dcoefFlowRate) continue; if(I != 0) { nodeVal = dcoefVal[I-1]; nodeFR = dcoefNode[I-1]; } tmpSLA = (u32)dcoefVal[I]; tmpSLA -= (u32)nodeVal; tmpSLB = (u32)dcoefFlowRate; tmpSLB -= (u32)nodeFR; tmpSLA *= tmpSLB; tmpSLB = (u32)dcoefNode[I]; tmpSLB -= (u32)nodeFR; tmpSLA /= tmpSLB; tmpSLA += (u32)nodeVal; return (u16)tmpSLA; } return dcoefVal[dcoefNum-1]; } //****************************************************************************** // Routines for calculating the following expression without overflow: u32 CorrectionExpression(u32 target, u16 factor, u16 base) { float tempF; tempF = (float)target; #ifndef CORRECT_METHOD #pragma message("[undefined] CORRECT_METHOD") #elif(CORRECT_METHOD) tempF *= (float)base; tempF /= (float)factor; #else tempF /= (float)base; tempF *= (float)factor; #endif return (u32)tempF; } //****************************************************************************** void GCFCorrection(void) { if(currentMode.Bit.CalibMode) return; //---------------------------------------------------------------------------- #ifndef ENABLE_GAS_RECOGNITION #pragma message("[undefined] ENABLE_GAS_RECOGNITION") #elif(ENABLE_GAS_RECOGNITION) //FY if(!isCurrentGas) return; #endif //---------------------------------------------------------------------------- float floatA, floatB; //---------------------------------------------------------------------------- #ifndef ENABLE_A_TYPE_FLOWRATE #pragma message("[undefined] ENABLE_A_TYPE_FLOWRATE") #elif(ENABLE_A_TYPE_FLOWRATE) if(FRType == ATYPE_FR) { floatA = (float)GDCFactorAType; floatA *= (float)currentFlowRate; floatA /= (float)GCF_PARAMETER_STD; currentFlowRate = (u32)floatA; return; } #endif //---------------------------------------------------------------------------- #ifndef ENABLE_GCF_POWER_CORR #pragma message("[undefined] ENABLE_GCF_POWER_CORR") #elif(ENABLE_GCF_POWER_CORR) // Power function correction // GCF if(GCFCoefC == 0) { floatB = (float)currentFlowRate; floatB = (float)GCFParaB; } else { floatA = GCFParaC; // GCFParaC : area m2 floatB = (float)currentFlowRate; if(FR_STD_UNIT == SL) floatA *= 60000000; // 0000SLPM - 0.000 m3/s (3bit): (FR/1000) else floatA *= 3600000; // 0000m3/H - 0.000 m3/s (3bit): (FR/1000) floatA = floatB/floatA; // 0.000 m/s floatA = pow(floatA, GCFParaA); // compute GCF floatA *= GCFParaB; floatB *= floatA; } currentFlowRate = (u32)floatB; #else // Quadratic correction coefficient // GCF floatB = (float)currentFlowRate; floatA = floatB * floatB; floatA *= (float)GCFParaA; floatB *= (float)GCFParaB; floatA += floatB; floatA += (float)GCFParaC; currentFlowRate = (u32)floatA; #endif } //****************************************************************************** void FlowRateSecondaryCorrection(void) { // retrieve the GDCF factor & device coefficients // account in the GDCF factor & device coefficients #ifndef ENABLE_DCOEF #pragma message("[undefined] ENABLE_DCOEF") #elif(ENABLE_DCOEF) if(HWState.EnableCheckCorr) JudgeDevCoef(); //---------------------------------------------------------------------------- #ifndef ENABLE_FLOW_GAIN #pragma message("[undefined] ENABLE_FLOW_GAIN") #elif(ENABLE_FLOW_GAIN) dcoef = GetDevCoefFactor(currentFlowRate/(u32)calibFlowGain); #else dcoef = GetDevCoefFactor(currentFlowRate); #endif //---------------------------------------------------------------------------- currentFlowRate = CorrectionExpression(currentFlowRate, dcoef, METER_PARAMETER_STD); #endif currentFlowRate = CorrectionExpression(currentFlowRate, MeterFactor, METER_PARAMETER_STD); } /******************************************************************************/ void ComputeGCFFactor(void) { // Quadratic correction coefficient // GCF GCFParaA = (float)GCFCoefA; GCFParaA /= (float)GCF_A_DOT; GCFCoefB = GDCFactor; GCFParaB = (float)GCFCoefB; GCFParaB /= (float)GCF_B_DOT; GCFParaC = (float)GCFCoefC; GCFParaC /= (float)GCF_C_DOT; }