417 lines
12 KiB
C
417 lines
12 KiB
C
#include "../main/SystemInclude.h"
|
||
//==============================================================================
|
||
#define FR_FILTER_MAX 8
|
||
#define FR_FILTER_SHIFT 3
|
||
#define FR_FILTER_MASK (FR_FILTER_MAX-1)
|
||
|
||
u32 flowSample[8], DisSample[8];
|
||
u16 FIndexSample[8];
|
||
u16 DisIndex, FRIndex, FIndex, filterShift, dataMask, filterDepth;
|
||
u32 maxAlarmFlowRate;
|
||
|
||
#ifndef ENABLE_LEAK_DETECT
|
||
#pragma message("[undefined] ENABLE_LEAK_DETECT")
|
||
#elif(ENABLE_LEAK_DETECT)
|
||
u16 leakDetectLowCounter, leakDetectHighCounter, leakDetectCounter;
|
||
#endif
|
||
|
||
|
||
|
||
/******************************************************************************/
|
||
u32 GetFlowRate(u16 flowIndex, u16 curveType)
|
||
{
|
||
u16 indexL, dataCompFac;
|
||
u8 temp[12];
|
||
|
||
|
||
switch(curveType)
|
||
{
|
||
case CURVE_1ST:
|
||
// if(flowIndex > 32767) return 0;
|
||
// else if(flowIndex < zeroSuppression) return 0;
|
||
// else if(flowIndex >= CALIB_MAX_INDEX) flowIndex = CALIB_MAX_INDEX;
|
||
// dataCompFac = DATA_COMP_FAC;
|
||
// indexL = CALI_DATA_ADDR;
|
||
if(flowIndex > 32767) return 0;
|
||
// else if(flowIndex < zeroSuppression) return 0;
|
||
else if(flowIndex >= CALIB_MAX_INDEX) flowIndex = CALIB_MAX_INDEX; //MAX_INDEX
|
||
dataCompFac = CALIB_COMP_FAC;
|
||
//indexL = (CORRECT_DATA_ADDR&0xFFFF);
|
||
indexL = 0 ;//从CORRECT_DATA[0]开始,相当于从0地址开始取
|
||
break;
|
||
|
||
//------------------------------------------------------------------------
|
||
#ifndef ENABLE_2ND_CURVE
|
||
#pragma message("[undefined] ENABLE_2ND_CURVE")
|
||
#elif(ENABLE_2ND_CURVE)
|
||
case CURVE_2ND:
|
||
|
||
break;
|
||
#endif
|
||
|
||
//------------------------------------------------------------------------
|
||
#ifndef ENABLE_3RD_CURVE
|
||
#pragma message("[undefined] ENABLE_3RD_CURVE")
|
||
#elif(ENABLE_3RD_CURVE)
|
||
case CURVE_3RD:
|
||
if(flowIndex > 32767) return 0;
|
||
else if(flowIndex < zeroSuppression) return 0;
|
||
else if(flowIndex >= MAX_INDEX3) flowIndex = CALIB_MAX_INDEX;
|
||
dataCompFac = DATA_COMP_FAC3;
|
||
indexL = CALI_DATA3_ADDR;
|
||
break;
|
||
#endif
|
||
|
||
default: return 0;
|
||
}
|
||
|
||
if(flowIndex > (CALIB_MAX_INDEX - dataCompFac*4))//240000-3*4 2*4096*6=48828-6*4
|
||
{
|
||
indexL += (CALIB_MAX_INDEX / dataCompFac - 1)*3;
|
||
//ReadMultiByteFromEEPROM(indexL, &tempDev.Byte[0], 3, PARA_EEPROM);
|
||
ReadDataFromFlash(indexL, &tempDev.Byte[0], 3);
|
||
|
||
tempDev.Byte[3] = 0;
|
||
return tempDev.DWord[0];
|
||
}
|
||
|
||
u16 index0, indexD, IndexA, IndexB, J=0, K;
|
||
u32 tempFR[4];
|
||
//u32
|
||
|
||
index0 = flowIndex / dataCompFac;
|
||
indexL += index0*3;
|
||
|
||
//ReadMultiByteFromEEPROM(indexL-3, temp, 12, PARA_EEPROM);
|
||
ReadDataFromFlash(indexL-3, temp, 12);
|
||
|
||
tmpLA = 0;
|
||
tmpLB = 0xffffffff;
|
||
for(K=0, J=0; K<4; K++)
|
||
{
|
||
tempL.Byte[0] = temp[J++];
|
||
tempL.Byte[1] = temp[J++];
|
||
tempL.Byte[2] = temp[J++];
|
||
tempL.Byte[3] = 0;
|
||
tempFR[K] = tempL.DWord;
|
||
|
||
if(tempL.DWord > tmpLA)
|
||
{
|
||
tmpLA = tempL.DWord;
|
||
IndexA = K;
|
||
}
|
||
|
||
if(tempL.DWord < tmpLB)
|
||
{
|
||
tmpLB = tempL.DWord;
|
||
IndexB = K;
|
||
}
|
||
}
|
||
|
||
for(K=0, J=0; K<4; K++)
|
||
{
|
||
if(K == IndexA) continue;
|
||
if(K == IndexB) continue;
|
||
temp[J] = K;
|
||
J++;
|
||
}
|
||
|
||
IndexA = temp[0];
|
||
IndexB = temp[1];
|
||
|
||
tmpSLA = (u32)tempFR[IndexA];
|
||
tmpSLB = (u32)tempFR[IndexB];
|
||
IndexB = (IndexB - IndexA)*dataCompFac;
|
||
IndexA *= dataCompFac;
|
||
|
||
// (tmpLB-tmpLA)*indexD/dataCompFac + tmpLA
|
||
indexD = flowIndex - index0 * dataCompFac;
|
||
indexD += dataCompFac;
|
||
|
||
tmpSLB -= tmpSLA;
|
||
if(indexD > IndexA)
|
||
{
|
||
tmpSLB *= (u32)(indexD-IndexA);
|
||
tmpSLB /= (u32)IndexB;
|
||
tmpSLA += tmpSLB;
|
||
}
|
||
else
|
||
{
|
||
tmpSLB *= (u32)(IndexA-indexD);
|
||
tmpSLB /= (u32)IndexB;
|
||
tmpSLA -= tmpSLB;
|
||
}
|
||
|
||
if(tmpSLA < 0) return 0;
|
||
else return (u32)tmpSLA;
|
||
}
|
||
|
||
//******************************************************************************
|
||
u16 HalfWordMovingAverage(u16 *TPFilter, u16 shiftCompare, u16 updateScale)
|
||
{
|
||
u16 I, tempDelta;
|
||
|
||
//for(I=0; I<sumLen; I++) tempSum += (u32)*TPFilter++;
|
||
//return tempSum >> shiftBit;
|
||
|
||
tmpLA = 0;
|
||
for(I=0; I<filterDepth; I++) tmpLA += (u32)*(TPFilter+I);
|
||
tmpIA = (u16)(tmpLA >> filterShift);
|
||
|
||
if(shiftCompare > tmpIA) tempDelta = shiftCompare - tmpIA;
|
||
else tempDelta = tmpIA - shiftCompare;
|
||
|
||
tmpLA = (u32)tmpIA;
|
||
tmpLA *= (u32)updateScale;
|
||
tmpLA >>= 10;
|
||
|
||
if(tempDelta < (u16)tmpLA) return tmpIA;
|
||
for(I=0; I<filterDepth; I++) *TPFilter++ = shiftCompare;
|
||
|
||
return shiftCompare;
|
||
}
|
||
|
||
//******************************************************************************
|
||
u32 WordMovingAverage(u32 *TPFilter, u32 shiftCompare, u16 updateScale)
|
||
{
|
||
u16 I;
|
||
u32 tempDelta;
|
||
|
||
tmpLA = 0;
|
||
for(I=0; I<filterDepth; I++) tmpLA += (u32)*(TPFilter+I);
|
||
tmpLA >>= filterShift;
|
||
|
||
if(shiftCompare > tmpLA) tempDelta = shiftCompare - tmpLA;
|
||
else tempDelta = tmpLA - shiftCompare;
|
||
|
||
tmpLB = (u32)tmpLA;
|
||
tmpLB *= (u32)updateScale;
|
||
tmpLB >>= 10;
|
||
|
||
if(tempDelta < (u16)tmpLB) return tmpLA;
|
||
for(I=0; I<filterDepth; I++) *TPFilter++ = shiftCompare;
|
||
|
||
return shiftCompare;
|
||
}
|
||
|
||
//******************************************************************************
|
||
void GetFilterDepth(u16 timeIndex)
|
||
{
|
||
filterDepth = FilterMax[timeIndex] / FilterMax[samplingInterval];
|
||
switch(filterDepth)
|
||
{
|
||
case 1: filterShift = 0; break;
|
||
case 2: filterShift = 1; break;
|
||
case 4: filterShift = 2; break;
|
||
case 8: filterShift = 3; break;
|
||
case 16: filterShift = 4; break;
|
||
case 32: filterShift = 5; break;
|
||
default:
|
||
filterDepth = 1;
|
||
filterShift = 0;
|
||
break;
|
||
}
|
||
|
||
dataMask = filterDepth-1;
|
||
}
|
||
|
||
//******************************************************************************
|
||
u16 FlowRateIndexFilter(u16 filterANX, u16 updateScale)
|
||
{
|
||
FIndex++;
|
||
FIndex &= dataMask;
|
||
FIndexSample[FIndex] = voltageDetected[filterANX];
|
||
|
||
return HalfWordMovingAverage(&FIndexSample[0], voltageDetected[filterANX], updateScale);
|
||
}
|
||
|
||
/******************************************************************************/
|
||
void FlowRateMoving(void)
|
||
{
|
||
FRIndex++;
|
||
FRIndex &= dataMask;
|
||
flowSample[FRIndex] = flowRate;
|
||
flowRate = WordMovingAverage(&flowSample[0], flowRate, FLOWRATE_UPDATE_SCALE); // 1.5%
|
||
|
||
#ifndef ENABLE_LCD_DISPLAY
|
||
#pragma message("[undefined] ENABLE_LCD_DISPLAY")
|
||
#elif(ENABLE_LCD_DISPLAY)
|
||
GetFilterDepth(DISPLAY_FILTER_DEFAULT);
|
||
DisIndex++;
|
||
DisIndex &= dataMask;
|
||
DisSample[DisIndex] = displayUpdate;
|
||
displayUpdate = WordMovingAverage(&DisSample[0], displayUpdate, FLOWRATE_UPDATE_SCALE);
|
||
#endif
|
||
}
|
||
|
||
/******************************************************************************/
|
||
void CurrentFlowRateMoving(void)
|
||
{
|
||
FRIndex++;
|
||
FRIndex &= dataMask;
|
||
flowSample[FRIndex] = currentFlowRate;
|
||
currentFlowRate = WordMovingAverage(&flowSample[0], currentFlowRate, FLOWRATE_UPDATE_SCALE); // 1.5%
|
||
}
|
||
|
||
/******************************************************************************/
|
||
void DisplayFlowRateMoving(void)
|
||
{
|
||
GetFilterDepth(DISPLAY_FILTER_DEFAULT);
|
||
DisIndex++;
|
||
DisIndex &= dataMask;
|
||
DisSample[DisIndex] = displayUpdate;
|
||
displayUpdate = WordMovingAverage(&DisSample[0], displayUpdate, FLOWRATE_UPDATE_SCALE);
|
||
}
|
||
|
||
//******************************************************************************
|
||
void FlowRateAlarmJudgment(void)
|
||
{
|
||
u32 minAlarmFlowRate;
|
||
unsigned long long int alarmFlowRate;
|
||
|
||
// float tempFlow;
|
||
//maxFlowRate = 3500000;
|
||
// tempFlow = (float)maxFlowRate;
|
||
// tempFlow *= (float)MAX_ALRAM_FR_DEFAULT;
|
||
// maxAlarmFlowRate = (u32)tempFlow;
|
||
|
||
|
||
|
||
//===========================================================================
|
||
// 判断最大流量门限值,考虑校准时流量的放大倍数
|
||
//maxAlarmFlowRate = maxFlowRate;
|
||
//maxAlarmFlowRate *= (u32)MAX_ALRAM_FR_DEFAULT; // 1.25*128 = 160;
|
||
//maxAlarmFlowRate >>= 7;
|
||
|
||
alarmFlowRate = (unsigned long long int)maxFlowRate;
|
||
alarmFlowRate *= (unsigned long long int)MAX_ALRAM_FR_DEFAULT;
|
||
alarmFlowRate >>= 7;
|
||
maxAlarmFlowRate = (u32)alarmFlowRate;
|
||
minAlarmFlowRate = minFlowRate;
|
||
|
||
//===========================================================================
|
||
#ifndef ENABLE_FLOW_GAIN
|
||
#pragma message("[undefined] ENABLE_FLOW_GAIN")
|
||
#elif(ENABLE_FLOW_GAIN)
|
||
maxAlarmFlowRate *= calibFlowGain;
|
||
minAlarmFlowRate *= calibFlowGain;
|
||
#endif
|
||
|
||
//===========================================================================
|
||
systemAlarm.Bit.FRAlarm = 0;
|
||
if(currentFlowRate > maxAlarmFlowRate) //1.25Qmax
|
||
{
|
||
systemAlarm.Bit.FRAlarm = 1;
|
||
currentFlowRate = maxAlarmFlowRate;
|
||
}
|
||
else if(currentFlowRate < minAlarmFlowRate) currentFlowRate = 0; // V2004
|
||
}
|
||
|
||
//******************************************************************************
|
||
#ifndef ENABLE_LEAK_DETECT
|
||
#pragma message("[undefined] ENABLE_LEAK_DETECT")
|
||
#elif(ENABLE_LEAK_DETECT)
|
||
void FlowRateLeakDetect(void)
|
||
{
|
||
if((alarmState1 & LEAK_ALARM)== LEAK_ALARM)
|
||
{
|
||
leakDetectCounter = 0;
|
||
leakDetectHighCounter = 0;
|
||
leakDetectLowCounter = 0;
|
||
#ifndef ENABLE_ERROR_PIN_FOR_VALVE_CONTROL
|
||
#pragma message("[undefined] ENABLE_ERROR_PIN_FOR_VALVE_CONTROL")
|
||
#elif(ENABLE_ERROR_PIN_FOR_VALVE_CONTROL)
|
||
ERROR_PIN_OUTPUT();
|
||
TURN_OFF_VALVE();
|
||
alarmState1 |= VALVE_OFF_ALARM;
|
||
#endif
|
||
return;
|
||
}
|
||
|
||
if((leakDetectTime == 0) || (sampleState.EnableRoughTest))
|
||
{
|
||
leakDetectCounter = 0;
|
||
leakDetectHighCounter = 0;
|
||
leakDetectLowCounter = 0;
|
||
return;
|
||
}
|
||
|
||
//---------------------------------------------------------------------------
|
||
if(flowRate < minLeakFlowRate)
|
||
{
|
||
leakDetectLowCounter++;
|
||
leakDetectHighCounter = 0;
|
||
if(leakDetectLowCounter > 4)
|
||
{
|
||
leakDetectLowCounter = 0;
|
||
leakDetectCounter = 0;
|
||
}
|
||
return;
|
||
}
|
||
else if(flowRate > maxLeakFlowRate)
|
||
{
|
||
leakDetectHighCounter++;
|
||
leakDetectLowCounter = 0;
|
||
if(leakDetectHighCounter > 4)
|
||
{
|
||
leakDetectHighCounter = 0;
|
||
leakDetectCounter = 0;
|
||
}
|
||
return;
|
||
}
|
||
|
||
leakDetectHighCounter = 0;
|
||
leakDetectLowCounter = 0;
|
||
if(leakDetectCounter > leakDetectTime)
|
||
{
|
||
leakDetectCounter = leakDetectTime;
|
||
alarmState1 |= LEAK_ALARM;
|
||
|
||
#ifndef ENABLE_ERROR_PIN_FOR_VALVE_CONTROL
|
||
#pragma message("[undefined] ENABLE_ERROR_PIN_FOR_VALVE_CONTROL")
|
||
#elif(ENABLE_ERROR_PIN_FOR_VALVE_CONTROL)
|
||
ERROR_PIN_OUTPUT();
|
||
TURN_OFF_VALVE();
|
||
alarmState1 |= VALVE_OFF_ALARM;
|
||
#endif
|
||
}
|
||
}
|
||
#endif
|
||
|
||
|
||
//******************************************************************************
|
||
#ifndef ENABLE_USER_UART
|
||
#pragma message("[undefined] ENABLE_USER_UART")
|
||
#elif(ENABLE_FLOW_GAIN)
|
||
u16 JudgeFlowRateGain(u16 flowGain)
|
||
{
|
||
switch(flowGain)
|
||
{
|
||
case 1: return 0;
|
||
|
||
//--------------------------------------------------------------------------
|
||
#ifndef FLOW_GAIN_MAX
|
||
#pragma message("[undefined] FLOW_GAIN_MAX")
|
||
#elif(FLOW_GAIN_MAX >= 10)
|
||
case 10: return 0;
|
||
#endif
|
||
|
||
//--------------------------------------------------------------------------
|
||
#ifndef FLOW_GAIN_MAX
|
||
#pragma message("[undefined] FLOW_GAIN_MAX")
|
||
#elif(FLOW_GAIN_MAX >= 100)
|
||
case 100: return 0;
|
||
#endif
|
||
|
||
//--------------------------------------------------------------------------
|
||
#ifndef FLOW_GAIN_MAX
|
||
#pragma message("[undefined] FLOW_GAIN_MAX")
|
||
#elif(FLOW_GAIN_MAX >= 1000)
|
||
case 1000: return 0;
|
||
#endif
|
||
|
||
default: return 1;
|
||
}
|
||
}
|
||
#endif
|