
#include "Data_Processor.h"

/******************************************************************************
  变量声明
 ******************************************************************************/
/*** 发动机转速 ***/
uint16_t                DataESpeedActual;
uint16_t                DataESpeedDisp;
uint8_t                 DataESpeedValid;
DataESpeedSamplerStruct DataESpeedSampler;
DataESPeedDampingStruct DataESPeedDamping;
DataESpeedIdleStruct    DataESpeedIdle;
uint16_t DataFuelVolRemaining;
/*** 车速 ***/
uint16_t  DataVSpeedActual;
uint16_t  DataVSpeedDisp;
uint16_t  DataVSpeedHysteresis;
uint8_t   DataVSpeedValid;
uint8_t   DataOverSpeed;
DataVSpeedSamplerStruct DataVSpeedSampler;
DataVSPeedDampingStruct DataVSPeedDamping;

/*** AirO ***/
uint16_t  DataCoolantAirOSegDisp;
uint32_t  DataCoolantAirO;
uint8_t   DataCollantAirOValid;
uint8_t   DataHiCollantAirOWarning;
DataCoolantTempCalcStruct   DataCoolantAirOCalc;
uint8_t   FrontPress;
uint8_t   RearPress;
/*** AirT ***/
uint16_t  DataCoolantAirTSegDisp;
uint32_t  DataCoolantAirT;
uint8_t   DataCollantAirTValid;
uint8_t   DataHiCollantAirTWarning;
DataCoolantTempCalcStruct   DataCoolantAirTCalc;

/*** 水温 ***/
uint16_t  DataCoolantTempSegDisp;
uint16_t  DataCoolantTemp;
uint8_t   DataCollantTempValid;
uint8_t   DataHiCollantTempWarning;
//uint16_t  DataCoolantTempSegUpTable[DATA_COOLANT_TEMP_TOTAL_SEG + 1];
//uint16_t  DataCoolantTempSegDnTable[DATA_COOLANT_TEMP_TOTAL_SEG + 1];
DataCoolantTempCalcStruct   DataCoolantTempCalc;

/*** ADblue ***/
uint16_t  DataCoolantADblueSegDisp;
uint16_t  DataCoolantADblue;
uint8_t   DataCollantADblueValid;
uint8_t   DataHiCollantADblueWarning;
//uint16_t  DataCoolantADblueSegUpTable[DATA_COOLANT_ADBLUE_TOTAL_SEG + 1];
//uint16_t  DataCoolantADblueSegDnTable[DATA_COOLANT_ADBLUE_TOTAL_SEG + 1];
DataCoolantADblueCalcStruct   DataCoolantADblueCalc;

/*** 机油压力 ***/
uint16_t  DataCoolantOilSegDisp;
uint16_t  DataCoolantOil;
uint8_t   DataCollantOilValid;
uint8_t   DataHiCollantOilWarning;
//uint16_t  DataCoolantTempSegUpTable[DATA_COOLANT_TEMP_TOTAL_SEG + 1];
//uint16_t  DataCoolantTempSegDnTable[DATA_COOLANT_TEMP_TOTAL_SEG + 1];
DataCoolantOilCalcStruct   DataCoolantOilCalc;

/*** 断电计时 ***/
uint16_t                DataIGNOffTimerSec;
DataIGNOffTimingStruct  DataIGNOffTimer;

/*** 室外温度 ***/
uint8_t                 DataAmbientTempDispMode;
uint8_t                 DataAmbientTemp;
uint8_t                 DataAmbientTempUnit;
/*** 燃油温度 ***/
uint8_t                 DataoilTempDispMode;
uint8_t                 DataoiltTemp;
uint8_t                 DataoilTempUnit;
/*** 里程滚动计数器 ***/
uint16_t                DataMileageRollingCounter;
DataMileageCalcStruct   DataMileage;

/*** 总计里程 ***/
uint8_t                 DataODOValid;
DataODOStruct           DataODOCalc;
uint8_t                 Maintain_alarm;
/*** 小计里程 ***/
uint16_t                DataTrip;
uint8_t                 DataTripUnit;
uint8_t                 DataTripValid;
DataTripStruct          DataTripCalc;

/*** TPMS ***/
uint8_t   DataTpmsUpdateTimer;

uint8_t   DataTPMSPrFL;
uint8_t   DataTPMSPrFR;
uint8_t   DataTPMSPrRL;
uint8_t   DataTPMSPrRR;

uint8_t   DataTPMSTempFL;
uint8_t   DataTPMSTempFR;
uint8_t   DataTPMSTempRL;
uint8_t   DataTPMSTempRR;


uint16_t  TireTEMPL;
uint16_t  TireTEMPR;
uint16_t  TirePL;
uint16_t  TirePR;

/***气压**/
_MeterPos				g_gas1Meter;
_MeterPos				g_gas2Meter;
_EE_MeterInfo		g_gas1MeterInfo;
_EE_MeterInfo		g_gas2MeterInfo;

/**************************/
ESPWMCaptureStruct  ESPWMCapture;
ESPWMFilterStruct   ESPWMFilter;

uint8_t  IO_DISP_TEST_OFF_TIME;   //自检结束延时
uint16_t VEH_TIME;
uint16_t FuelConsumptionRate;
/******************************/
void Data_Power_On_Init(void)
{
  //uint8_t i;

	//发动机转速
	DataESpeedActual          = 0;
	DataESpeedDisp            = 0;
	DataESpeedValid           = 0;
	DataESpeedSampler.Cnt     = 0;
	DataESPeedDamping.Speed   = 0;
	DataESPeedDamping.Delta   = 0;
	DataESPeedDamping.Dir     = DATA_APPR_DIR_INC;
  Fuel_Seg = 0; //燃油段数初始化
  //Espeed_Seg_Disp[0] = 0;
  //Espeed_Seg_Disp[1] = 0;
  //Espeed_Seg_Disp[2] = 0;
  //Espeed_Seg_Disp[3] = 0;
  //Espeed_Seg_Disp[4] = 0;
	//车速
	DataVSpeedActual            = 0;
	DataVSpeedDisp              = 0;
	DataVSpeedHysteresis        = 0;
	DataVSpeedValid             = 0;
	DataOverSpeed               = 0;
	DataVSpeedSampler.Timer     = 0;
	DataVSpeedSampler.Backup    = 0;
	DataVSpeedSampler.UseBackup = 0;
	DataVSpeedSampler.Cnt       = 0;
	DataVSPeedDamping.Speed     = 0;
	DataVSPeedDamping.Delta     = 0;
	DataVSPeedDamping.Dir       = DATA_APPR_DIR_INC;
  //Vspeed_Seg_Disp[0] = 0;
  //Vspeed_Seg_Disp[1] = 0;
  //Vspeed_Seg_Disp[2] = 0;
  //Vspeed_Seg_Disp[3] = 0;
  //Vspeed_Seg_Disp[4] = 0;
	//水温
	DataCoolantTemp                  = 0;
	DataCollantTempValid             = 0;
	DataHiCollantTempWarning         = 0;
	DataCoolantTempSegDisp           = 0;
	DataCoolantTemp                  = 0;
	DataCollantTempValid             = 0;
	DataHiCollantTempWarning         = 0;
	DataCoolantTempCalc.Last         = 0;
	DataCoolantTempCalc.InvalidCnt   = 0;
	DataCoolantTempCalc.DstSeg       = 0;
	DataCoolantTempCalc.State        = DATA_COOLANT_TEMP_STATE_DELAY;
	DataCoolantTempCalc.Wait         = DATA_COOLANT_TEMP_WAIT_SEC * 10;
	DataCoolantTempCalc.Prescaler    = 0;
	DataCoolantTempCalc.FastMode     = 0;
	DataCoolantTempCalc.OutputEnable = 0;
	DataCoolantTempCalc.DispTimer    = 0;

	//AirO
  //DataCoolantAirO                  = 0;
  //DataCollantAirOValid             = 0;
  //DataHiCollantAirOWarning         = 0;
	DataCoolantAirOSegDisp           = 0;
	DataCoolantAirO                  = 0;
	DataCollantAirOValid             = 0;
	DataHiCollantAirOWarning         = 0;
	DataCoolantAirOCalc.Last         = 0;
	DataCoolantAirOCalc.InvalidCnt   = 0;
	DataCoolantAirOCalc.DstSeg       = 0;
	DataCoolantAirOCalc.State        = DATA_COOLANT_AirO_STATE_DELAY;
	DataCoolantAirOCalc.Wait         = DATA_COOLANT_AirO_WAIT_SEC * 10;
	DataCoolantAirOCalc.Prescaler    = 0;
	DataCoolantAirOCalc.FastMode     = 0;
	DataCoolantAirOCalc.OutputEnable = 0;
	DataCoolantAirOCalc.DispTimer    = 0;

	//AirT
  //DataCoolantAirT                  = 0;
  //DataCollantAirTValid             = 0;
  //DataHiCollantAirTWarning         = 0;
	DataCoolantAirTSegDisp           = 0;
	DataCoolantAirT                  = 0;
	DataCollantAirTValid             = 0;
	DataHiCollantAirTWarning         = 0;
	DataCoolantAirTCalc.Last         = 0;
	DataCoolantAirTCalc.InvalidCnt   = 0;
	DataCoolantAirTCalc.DstSeg       = 0;
	DataCoolantAirTCalc.State        = DATA_COOLANT_AirT_STATE_DELAY;
	DataCoolantAirTCalc.Wait         = DATA_COOLANT_AirT_WAIT_SEC * 10;
	DataCoolantAirTCalc.Prescaler    = 0;
	DataCoolantAirTCalc.FastMode     = 0;
	DataCoolantAirTCalc.OutputEnable = 0;
	DataCoolantAirTCalc.DispTimer    = 0;

	//ADBLUE
  //DataCoolantADblue                  = 0;
  //DataCollantADblueValid             = 0;
  //DataHiCollantADblueWarning         = 0;
	DataCoolantADblueSegDisp           = 0;
	DataCoolantADblue                  = 0;
	DataCollantADblueValid             = 0;
	DataHiCollantADblueWarning         = 0;
	DataCoolantADblueCalc.Last         = 0;
	DataCoolantADblueCalc.InvalidCnt   = 0;
	DataCoolantADblueCalc.DstSeg       = 0;
	DataCoolantADblueCalc.State        = DATA_COOLANT_ADBLUE_STATE_DELAY;
	DataCoolantADblueCalc.Wait         = DATA_COOLANT_ADBLUE_WAIT_SEC * 10;
	DataCoolantADblueCalc.Prescaler    = 0;
	DataCoolantADblueCalc.FastMode     = 0;
	DataCoolantADblueCalc.OutputEnable = 0;
	DataCoolantADblueCalc.DispTimer    = 0;	

	//机油压力
	DataCoolantOilSegDisp           = 0;
	DataCoolantOil                  = 0;
	DataCollantOilValid             = 1;
	DataHiCollantOilWarning         = 0;
	DataCoolantOilCalc.Last         = 0;
	//DataCoolantADblueCalc.InvalidCnt = 0;
	//DataCoolantADblueCalc.DstSeg     = 0;
	DataCoolantOilCalc.State        = DATA_COOLANT_OIL_STATE_DELAY;
	DataCoolantOilCalc.Wait         = DATA_COOLANT_OIL_WAIT_SEC * 10;
	DataCoolantOilCalc.Prescaler    = 0;
	DataCoolantOilCalc.OutputEnable = 0;
	DataCoolantOilCalc.DispTimer    = 0; 
	
	//断电计时
	DataIGNOffTimerSec        = 0;
	DataIGNOffTimer.IGNStatus = 0;
	DataIGNOffTimer.RoCBackup = 0;

	//室外温度
  //	if (NVM_CONFIG_AMBIENT_TEMP_EN)
  //		DataAmbientTempDispMode = GUI_DISP_MODE_INVALID;
  //	else
  //		DataAmbientTempDispMode = GUI_DISP_MODE_BLANK;
  //	DataAmbientTempUnit       = NVM_USER_SETTINGS_TEMP_UNIT;

	//燃油温度
	DataoilTempDispMode = GUI_DISP_MODE_INVALID;
	DataoilTempUnit     = NVM_USER_SETTINGS_TEMP_UNIT;

	//里程滚动计数器
	DataMileageRollingCounter    = 0;
	DataMileage.mmRollingCounter = 0;
	DataMileage.mmRoCBackup      = 0;

	//总计里程
	DataODOValid = !NVM_EEPROM_FAULT;
	DataODOCalc.UpdateDisable = 0;
	DataODOCalc.RoCBackup = 0;
	DataODOCalc.LastSaved = NVM_ODO_VALUE;

	//小计里程
	DataTrip      = 0;
	DataTripUnit  = NVM_USER_SETTINGS_DIST_UNIT;
	DataTripValid = 1;
	DataTripCalc.MileageA100m = 0;
	DataTripCalc.MileageB100m = 0;
	DataTripCalc.RoCBackup   = 0;

	//TPMS
	DataTpmsUpdateTimer = 30;

	DataTPMSPrFL        = 0xFF;
	DataTPMSPrFR        = 0xFF;
	DataTPMSPrRL        = 0xFF;
	DataTPMSPrRR        = 0xFF;

	DataTPMSTempFL      = 0xFF;
	DataTPMSTempFR      = 0xFF;
	DataTPMSTempRL      = 0xFF;
	DataTPMSTempRR      = 0xFF;
}

void Data_IGN_On_Init(void)
{
	//转速,考虑移动到ACC_On_Init
	DataESpeedDisp          = 0;
	DataESPeedDamping.Speed = 0;
	DataESPeedDamping.Delta = 0;
	DataESPeedDamping.Dir   = DATA_APPR_DIR_INC;
	DataESpeedIdle.Timer    = 0;
	Fuel_Seg = 0;//燃油段数初始化
  //Espeed_Seg_Disp[0] = 0;
  //Espeed_Seg_Disp[1] = 0;
  //Espeed_Seg_Disp[2] = 0;
  //Espeed_Seg_Disp[3] = 0;
  //Espeed_Seg_Disp[4] = 0;
	//车速,考虑移动到ACC_On_Init
	DataVSpeedDisp              = 0;
	DataVSpeedHysteresis        = 0;
	DataOverSpeed               = 0;
	DataVSPeedDamping.Speed     = 0;
	DataVSPeedDamping.Delta     = 0;
	DataVSPeedDamping.Dir       = DATA_APPR_DIR_INC;
  //Vspeed_Seg_Disp[0] = 0;
  //Vspeed_Seg_Disp[1] = 0;
  //Vspeed_Seg_Disp[2] = 0;
  //Vspeed_Seg_Disp[3] = 0;
  //Vspeed_Seg_Disp[4] = 0;
	//水温
	DataCoolantTempSegDisp           = 0;
	DataCoolantTemp                  = 0;
	DataCollantTempValid             = 1;
	DataHiCollantTempWarning         = 0;
	DataCoolantTempCalc.Last         = 0;
	DataCoolantTempCalc.InvalidCnt   = 0;
	DataCoolantTempCalc.DstSeg       = 0;
	DataCoolantTempCalc.State        = DATA_COOLANT_TEMP_STATE_DELAY;
	DataCoolantTempCalc.Wait         = DATA_COOLANT_TEMP_WAIT_SEC * 10;
	DataCoolantTempCalc.Prescaler    = 0;
	DataCoolantTempCalc.OutputEnable = 0;
	DataCoolantTempCalc.DispTimer    = 0;  

	//AirO
	DataCoolantAirOSegDisp           = 0;
	DataCoolantAirO                  = 0;
	DataCollantAirOValid             = 1;
	DataHiCollantAirOWarning         = 0;
	DataCoolantAirOCalc.Last         = 0;
	DataCoolantAirOCalc.InvalidCnt   = 0;
	DataCoolantAirOCalc.DstSeg       = 0;
	DataCoolantAirOCalc.State        = DATA_COOLANT_AirO_STATE_DELAY;
	DataCoolantAirOCalc.Wait         = DATA_COOLANT_AirO_WAIT_SEC * 10;
	DataCoolantAirOCalc.Prescaler    = 0;
	DataCoolantAirOCalc.OutputEnable = 0;
	DataCoolantAirOCalc.DispTimer    = 0;

	//AirT
	DataCoolantAirTSegDisp           = 0;
	DataCoolantAirT                  = 0;
	DataCollantAirTValid             = 1;
	DataHiCollantAirTWarning         = 0;
	DataCoolantAirTCalc.Last         = 0;
	DataCoolantAirTCalc.InvalidCnt   = 0;
	DataCoolantAirTCalc.DstSeg       = 0;
	DataCoolantAirTCalc.State        = DATA_COOLANT_AirT_STATE_DELAY;
	DataCoolantAirTCalc.Wait         = DATA_COOLANT_AirT_WAIT_SEC * 10;
	DataCoolantAirTCalc.Prescaler    = 0;
	DataCoolantAirTCalc.OutputEnable = 0;
	DataCoolantAirTCalc.DispTimer    = 0; 

	//ADBLUE
	DataCoolantADblueSegDisp           = 0;
	DataCoolantADblue                  = 0;
	DataCollantADblueValid             = 1;
	DataHiCollantADblueWarning         = 0;
	DataCoolantADblueCalc.Last         = 0;
	DataCoolantADblueCalc.InvalidCnt   = 0;
	DataCoolantADblueCalc.DstSeg       = 0;
	DataCoolantADblueCalc.State        = DATA_COOLANT_ADBLUE_STATE_DELAY;
	DataCoolantADblueCalc.Wait         = DATA_COOLANT_ADBLUE_WAIT_SEC * 10;
	DataCoolantADblueCalc.Prescaler    = 0;
	DataCoolantADblueCalc.OutputEnable = 0;
	DataCoolantADblueCalc.DispTimer    = 0; 
	
		//机油压力
	DataCoolantOilSegDisp           = 0;
	DataCoolantOil                  = 0;
	DataCollantOilValid             = 1;
	DataHiCollantOilWarning         = 0;
	DataCoolantOilCalc.Last         = 0;
	//DataCoolantADblueCalc.InvalidCnt = 0;
	//DataCoolantADblueCalc.DstSeg     = 0;
	DataCoolantOilCalc.State        = DATA_COOLANT_OIL_STATE_DELAY;
	DataCoolantOilCalc.Wait         = DATA_COOLANT_OIL_WAIT_SEC * 10;
	DataCoolantOilCalc.Prescaler    = 0;
	DataCoolantOilCalc.OutputEnable = 0;
	DataCoolantOilCalc.DispTimer    = 0; 

	//总计里程
	DataODOCalc.UpdateDisable  = 0;    
	
	SEATBELT_Count             = 0;
	Break_nodown_Count         = 0;
	BREAK_FLUID_Count          = 0;
	BREAK_Count                = 0;
	Break_down_count           = 0;
	RR_HOOVES_Count            = 0;
	RF_HOOVES_Count            = 0;
	DoorSts_Count              = 0;
	CAB_LOCK_Count             = 0;
	CollantAir_Count           = 0;
	Drivability_Count          = 0;
	PTO_Count                  = 0;
	BreakLight_Count           = 0;
	FILT_BLOCK_Count           = 0;
	CHARGE_Count               = 0;
	EngineSeriousFailure_Count = 0;
	Coolant_Temp_Count         = 0;
	EngOilPress_Count          = 0;
	DPF_Lamp_Count             = 0;
	Led_DPF_Count              = 0;
	DPF_Forbidden_Count        = 0;
	Stop_Start_System_Count    = 0;
	EPB_Count                  = 0; 
  AEB_Count                  = 0;
  AMT_Count                  = 0;
  OVER_SPEED_Count           = 0;
}

/******************************************************************************
  函数名：Data_Engine_Speed_Processing_Service
  功  能：发动机转速数据处理函数
  参  数：无
  返回值：无
 ******************************************************************************
 注  意：该函数必须每10ms被调用一次
 ******************************************************************************/
void Data_Engine_Speed_Processing_Service(void)
{
	uint8_t   i;
	uint16_t  ESpeed;
	uint16_t  Delta;
	uint16_t  ESpeed_Value;
	

	//第1步：获取实际转速值及转速有效性
	if (SYS_OPR_STAT_IGN_ON)
	{ 
	 	ESpeed_Value = Engine_SpeedH << 8;
    ESpeed_Value = ESpeed_Value | Engine_SpeedL;
		if ((ESpeed_Value >= 0xFAFF) || (EEC1_STATUS & CAN_MSG_LOST)) 
		{
			if (DataESpeedSampler.Timer < 34)  //170
			{
				if (DataESpeedValid)
				{
					DataESpeedSampler.Timer++;
					DataESpeedActual = DataESpeedSampler.Backup;
				}
				else
				{
					DataESpeedSampler.Timer  = 34; //170
					DataESpeedSampler.Backup = 0;
					DataESpeedActual         = 0;
				}
			}
			else
			{
				DataESpeedValid          = 0;
				DataESpeedActual         = 0;
				DataESpeedSampler.Backup = 0;
			}

			DataESpeedSampler.Cnt = 0;
		}
		else
		{
			if (DataESpeedValid == 0)
			{
				DataESpeedValid = 1;      
				ESpeed = ESpeed_Value;
				ESpeed = ESpeed / 8;             //转速系数  0.125            
				if (ESpeed >= 6000)
					ESpeed = 6000; 
				DataESpeedActual = ESpeed;       //如果是转速采样占空比 ESPEED赋值给这个实际值
			}
			else
			{
        DataESpeedSampler.Buffer[DataESpeedSampler.Cnt] = ESpeed_Value;            

				i = DataESpeedSampler.Cnt;
				while ((i > 0) && (DataESpeedSampler.Buffer[i] < DataESpeedSampler.Buffer[i - 1]))
				{
					ESpeed = DataESpeedSampler.Buffer[i];
					DataESpeedSampler.Buffer[i] = DataESpeedSampler.Buffer[i - 1];
					DataESpeedSampler.Buffer[i - 1] = ESpeed;
					i--;
				}

				DataESpeedSampler.Cnt++;
				if (DataESpeedSampler.Cnt >= 5)
				{
					DataESpeedSampler.Cnt = 0;

					ESpeed = DataESpeedSampler.Buffer[3];
					ESpeed = ESpeed / 8;           //转速系数  0.125
					if (ESpeed >= 6000)
						ESpeed = 6000; 
					DataESpeedActual = ESpeed;
				}
			}

			DataESpeedSampler.Timer     = 0;
			//DataESpeedSampler.UseBackup = 0;
			DataESpeedSampler.Backup    = DataESpeedActual;
		}
	}
	else
	{
		DataESpeedValid             = 0;
		DataESpeedActual            = 0;
		DataESpeedSampler.Timer     = 0;
		DataESpeedSampler.Cnt       = 0;
		//DataESpeedSampler.UseBackup = 0;
		DataESpeedSampler.Backup    = 0;
	}

	//第2步：怠速模式
	//if (DataESpeedSampler.UseBackup)
	//  ESpeed = DataESpeedSampler.Backup;
	//else
	ESpeed = DataESpeedActual;

	if ((ESpeed >= 500) && (ESpeed <= 1000)) //20200109
  //if ((ESpeed >= 500) && (ESpeed <= 6000))
	{
		DataESpeedIdle.Timer++;

		if (ESpeed > DataESpeedIdle.ESpeedBackup)
			Delta = ESpeed - DataESpeedIdle.ESpeedBackup;
		else
			Delta = DataESpeedIdle.ESpeedBackup - ESpeed;

		if (DataESpeedIdle.Mode == 0)
		{
			if (Delta < 300)
			{
				if (DataESpeedIdle.Timer >= 200)
				{
					DataESpeedIdle.Mode  = 1;
					DataESpeedIdle.Timer = 0;
				}
			}
			else
				DataESpeedIdle.Timer = 0;

			DataESpeedIdle.ESpeedBackup = ESpeed;
		}
		else
		{
			if (Delta < 300)
			{
				if (DataESpeedIdle.Timer >= 1000)                 //怠速模式下每10秒转速数据更新一次
				{
					DataESpeedIdle.Timer = 0;
					DataESpeedIdle.ESpeedBackup = ESpeed;
				}
				else
					ESpeed = DataESpeedIdle.ESpeedBackup;
			}
			else                                                //转速变化大于等于300立即退出怠速模式
			{
				DataESpeedIdle.Mode  = 0;
				DataESpeedIdle.Timer = 0;
				DataESpeedIdle.ESpeedBackup = ESpeed;
			}
		}
	}
	else
	{
		DataESpeedIdle.Mode  = 0;
		DataESpeedIdle.Timer = 0;
		DataESpeedIdle.ESpeedBackup = ESpeed;
	}
  
	//第3步：转速的阻尼处理
	if (ESpeed > DataESPeedDamping.Speed)                   //实际值比当前显示值大时
	{
		Delta = ESpeed - DataESPeedDamping.Speed;

		if (DataESPeedDamping.Dir == DATA_APPR_DIR_INC)       //显示值正在向实际值增加,则维持当前方向调节增加速度
		{
			if (DataESPeedDamping.Delta < Delta)                //当前增量小于显示值与实际值的差值,则提升增加的速度
			{
				DataESPeedDamping.Delta += DATA_ESPEED_INC_STEP;
				if (DataESPeedDamping.Delta > Delta)
					DataESPeedDamping.Delta = Delta;
			}
			else                                                //当前增量大于等于显示值与实际值的差值,保持增量与当前差值同步,增加的速度即逐步减小
				DataESPeedDamping.Delta = Delta;

			Delta  = DataESPeedDamping.Delta;
			Delta /= DATA_ESPEED_DAMPING_FACTOR;

			if (Delta < DATA_ESPEED_APPR_SPEED_MIN)
				Delta = DATA_ESPEED_APPR_SPEED_MIN;

			DataESPeedDamping.Speed += Delta;
			if (DataESPeedDamping.Speed > ESpeed)
				DataESPeedDamping.Speed = ESpeed;
		}
		else                                                  //显示值正在减小,则尽快减速至速度为最小时更换方向
		{
			if (DataESPeedDamping.Delta > DATA_ESPEED_DEC_STEP)
				DataESPeedDamping.Delta -= DATA_ESPEED_DEC_STEP;
			else
				DataESPeedDamping.Delta = 0;

			Delta  = DataESPeedDamping.Delta;
			Delta /= DATA_ESPEED_DAMPING_FACTOR;

			if (Delta < DATA_ESPEED_APPR_SPEED_MIN)             //已减速至最小速度
				DataESPeedDamping.Dir = DATA_APPR_DIR_INC;        //更换方向
			else
			{
				if (DataESPeedDamping.Speed > Delta)
					DataESPeedDamping.Speed -= Delta;
				else
					DataESPeedDamping.Speed = 0;
			}
		}
	}
	else if (ESpeed < DataESPeedDamping.Speed)              //实际值比当前显示值小时
	{
		Delta = DataESPeedDamping.Speed - ESpeed;

		if (DataESPeedDamping.Dir == DATA_APPR_DIR_INC)       //显示值仍在增加,则尽快减速至速度为最小时更换方向
		{
			if (DataESPeedDamping.Delta > DATA_ESPEED_DEC_STEP)
				DataESPeedDamping.Delta -= DATA_ESPEED_DEC_STEP;
			else
				DataESPeedDamping.Delta = 0;

			Delta  = DataESPeedDamping.Delta;
			Delta /= DATA_ESPEED_DAMPING_FACTOR;

			if (Delta < DATA_ESPEED_APPR_SPEED_MIN)             //已减速至最小速度
				DataESPeedDamping.Dir = DATA_APPR_DIR_DEC;        //更换方向
			else
			{
				DataESPeedDamping.Speed += Delta; 
				if (DataESPeedDamping.Speed > 6000)
					DataESPeedDamping.Speed = 6000;            
			}
		}
		else                                                  //显示值正在向实际值减小,则维持当前方向调节增加速度
		{
			if (DataESPeedDamping.Delta < Delta)                //当前(负)增量小于显示值与实际值的差值,则提升减小的速度
			{
				DataESPeedDamping.Delta += DATA_ESPEED_INC_STEP;
				if (DataESPeedDamping.Delta > Delta)
					DataESPeedDamping.Delta = Delta;
			}
			else                                                //当前(负)增量大于等于显示值与实际值的差值,保持(负)增量与当前差值同步,减小的速度即逐步减小
				DataESPeedDamping.Delta = Delta;

			Delta  = DataESPeedDamping.Delta;
			Delta /= DATA_ESPEED_DAMPING_FACTOR;

			if (Delta < DATA_ESPEED_APPR_SPEED_MIN)
				Delta = DATA_ESPEED_APPR_SPEED_MIN;

			if (DataESPeedDamping.Speed < ESpeed + Delta)
				DataESPeedDamping.Speed  = ESpeed;
			else
				DataESPeedDamping.Speed -= Delta;
		}
	}
	else                                                    //实际值与当前显示值相等时
	{
		Delta  = DataESPeedDamping.Delta;
		Delta /= DATA_ESPEED_DAMPING_FACTOR;

		if (Delta > DATA_ESPEED_APPR_SPEED_MIN)               //当前的速度不是最小,说明数值正在增加/减小中,则继续原过程
		{
			if (DataESPeedDamping.Delta > DATA_ESPEED_DEC_STEP) //显示值越过了实际值,必然要先减速至最小速度,再改变方向返回实际值
				DataESPeedDamping.Delta -= DATA_ESPEED_DEC_STEP;
			else
				DataESPeedDamping.Delta = 0;

			Delta  = DataESPeedDamping.Delta;
			Delta /= DATA_ESPEED_DAMPING_FACTOR;

			if (DataESPeedDamping.Dir == DATA_APPR_DIR_INC)     //显示值当前是增加方向
			{
				if (Delta < DATA_ESPEED_APPR_SPEED_MIN)           //已减速至最小速度
					DataESPeedDamping.Dir = DATA_APPR_DIR_DEC;      //更换方向
				else
				{
					DataESPeedDamping.Speed += Delta;
					if (DataESPeedDamping.Speed > 6000)
						DataESPeedDamping.Speed = 6000; 
				}
			}
			else                                                //显示值当前是减小方向
			{
				if (Delta < DATA_ESPEED_APPR_SPEED_MIN)           //已减速至最小速度
					DataESPeedDamping.Dir = DATA_APPR_DIR_INC;      //更换方向
				else
				{
					if (DataESPeedDamping.Speed > Delta)
						DataESPeedDamping.Speed -= Delta;
					else
						DataESPeedDamping.Speed = 0;
				}
			}
		}
	}
	//第4步 增加回差
  if ((DataESpeedDisp <= 50) || (DataESpeedDisp >= 5950))
  	DataESpeedDisp = DataESPeedDamping.Speed;
  else
  {
  	if (DataESpeedDisp > DataESPeedDamping.Speed)
  		Delta = DataESpeedDisp - DataESPeedDamping.Speed;
  	else
  		Delta = DataESPeedDamping.Speed - DataESpeedDisp;

  	if (Delta >= DATA_ESPEED_HYSTERESIS)
  		DataESpeedDisp = DataESPeedDamping.Speed; 
  }
  Gauges_ESpeed_LCD_Status(); 
}

/******************************************************************************
  函数名：Data_Vehicle_Speed_Processing_Service
  功  能：车速数据处理函数
  参  数：无
  返回值：无
 ******************************************************************************
 注  意：该函数必须每20ms被调用一次
 ******************************************************************************/
void Data_Vehicle_Speed_Processing_Service(void)
{
	uint8_t   i;
	uint16_t  Delta;
	uint16_t  VSpeed;
	uint32_t  VSpeedCal;
	uint32_t  VSpeed_32; 
	
	uint16_t  VSpeed_Value;
	
	VSpeed_Value = (uint16_t)((FA_SpeedH << 8) | (FA_SpeedL));
     
	//第1步：获取实际车速值及车速有效性
	if (SYS_OPR_STAT_IGN_ON)
	{     
		if ((VSpeed_Value >= 0xFAFF) || (EBC2_STATUS & CAN_MSG_LOST))           
		{
			if (DataVSpeedSampler.Timer < 15)  //85
			{
				if (DataVSpeedValid)
				{
					DataVSpeedSampler.Timer++;
					DataVSpeedActual = DataVSpeedSampler.Backup;
				}
				else
				{
					DataVSpeedSampler.Timer  = 15; //85
					DataVSpeedActual         = 0;
					DataVSpeedSampler.Backup = 0;
				}
			}
			else
			{
				DataVSpeedValid          = 0;
				DataVSpeedActual         = 0;
				DataVSpeedSampler.Backup = 0;
			}

			DataVSpeedSampler.Cnt = 0;
		}
		else
		{
			if (DataVSpeedValid == 0)
			{
				DataVSpeedValid = 1;

				VSpeed_32 = (uint32_t)VSpeed_Value;    
				VSpeed    = (uint16_t)(VSpeed_32 * 10 / 256); //系数 1/256  放大10倍    
			  
			  if(VSpeed >= 1600)
			    VSpeed = 1600;
			  
				DataVSpeedActual = VSpeed;
			}
			else
			{
				DataVSpeedSampler.Buffer[DataVSpeedSampler.Cnt] = VSpeed_Value;

				i = DataVSpeedSampler.Cnt;
				while ((i > 0) && (DataVSpeedSampler.Buffer[i] < DataVSpeedSampler.Buffer[i - 1]))
				{
					VSpeed = DataVSpeedSampler.Buffer[i];
					DataVSpeedSampler.Buffer[i] = DataVSpeedSampler.Buffer[i - 1];
					DataVSpeedSampler.Buffer[i - 1] = VSpeed;
					i--;
				}

				DataVSpeedSampler.Cnt++;
				if (DataVSpeedSampler.Cnt >= 3)
				{
					DataVSpeedSampler.Cnt = 0;
		
					VSpeed_32 = (uint32_t)DataVSpeedSampler.Buffer[1];;    
  				VSpeed    = (uint16_t)(VSpeed_32 * 10 / 256); //系数 1/256  放大10倍    
			  
			    if(VSpeed >= 1600)
			      VSpeed = 1600;
			  
					DataVSpeedActual = VSpeed;
				}
			}

			DataVSpeedSampler.Timer     = 0;
			//DataVSpeedSampler.UseBackup = 0;
			DataVSpeedSampler.Backup    = DataVSpeedActual;
		}
	}
	else
	{
		DataVSpeedValid  = 0;
		DataVSpeedActual = 0;
		DataVSpeedSampler.Timer     = 0;
		DataVSpeedSampler.Cnt       = 0;
		//DataVSpeedSampler.UseBackup = 0;
		DataVSpeedSampler.Backup    = 0;
	}

	  //第2步：车速的阻尼处理
  //if (DataVSpeedSampler.UseBackup)
  //  VSpeed = DataVSpeedSampler.Backup;
  //else
  
  VSpeed = DataVSpeedActual;

  if (VSpeed > DataVSPeedDamping.Speed)                   //实际值比当前显示值大时
  {
    Delta = VSpeed - DataVSPeedDamping.Speed;

    if (DataVSPeedDamping.Dir == DATA_APPR_DIR_INC)       //显示值正在向实际值增加,则维持当前方向调节增加速度
    {
      if (DataVSPeedDamping.Delta < Delta)                //当前增量小于显示值与实际值的差值,则提升增加的速度
      {
        DataVSPeedDamping.Delta += DATA_VSPEED_INC_STEP;
        if (DataVSPeedDamping.Delta > Delta)
          DataVSPeedDamping.Delta = Delta;
      }
      else                                                //当前增量大于等于显示值与实际值的差值,保持增量与当前差值同步,增加的速度即逐步减小
        DataVSPeedDamping.Delta = Delta;

      Delta  = DataVSPeedDamping.Delta;
      Delta /= DATA_VSPEED_DAMPING_FACTOR;

      if (Delta < DATA_VSPEED_APPR_SPEED_MIN)
        Delta = DATA_VSPEED_APPR_SPEED_MIN;

      DataVSPeedDamping.Speed += Delta;
      if (DataVSPeedDamping.Speed > VSpeed)
        DataVSPeedDamping.Speed = VSpeed;
    }
    else                                                 //显示值正在减小,则尽快减速至速度为最小时更换方向
    {
      if (DataVSPeedDamping.Delta > DATA_VSPEED_DEC_STEP)
        DataVSPeedDamping.Delta -= DATA_VSPEED_DEC_STEP;
      else
        DataVSPeedDamping.Delta = 0;

      Delta  = DataVSPeedDamping.Delta;
      Delta /= DATA_VSPEED_DAMPING_FACTOR;

      if (Delta < DATA_VSPEED_APPR_SPEED_MIN)            //已减速至最小速度
        DataVSPeedDamping.Dir = DATA_APPR_DIR_INC;       //更换方向
      else
      {
        if (DataVSPeedDamping.Speed > Delta)
          DataVSPeedDamping.Speed -= Delta;
        else
          DataVSPeedDamping.Speed = 0;
      }
    }
  }
  else if (VSpeed < DataVSPeedDamping.Speed)             //实际值比当前显示值小时
  {
    Delta = DataVSPeedDamping.Speed - VSpeed;

    if (DataVSPeedDamping.Dir == DATA_APPR_DIR_INC)       //显示值仍在增加,则尽快减速至速度为最小时更换方向
    {
      if (DataVSPeedDamping.Delta > DATA_VSPEED_DEC_STEP)
        DataVSPeedDamping.Delta -= DATA_VSPEED_DEC_STEP;
      else
        DataVSPeedDamping.Delta = 0;

      Delta  = DataVSPeedDamping.Delta;
      Delta /= DATA_VSPEED_DAMPING_FACTOR;

      if (Delta < DATA_VSPEED_APPR_SPEED_MIN)             //已减速至最小速度
        DataVSPeedDamping.Dir = DATA_APPR_DIR_DEC;        //更换方向
      else
      {
        DataVSPeedDamping.Speed += Delta;
        if (DataVSPeedDamping.Speed > 3000)
          DataVSPeedDamping.Speed = 3000;
      }
    }
    else                                                  //显示值正在向实际值减小,则维持当前方向调节增加速度
    {
      if (DataVSPeedDamping.Delta < Delta)                //当前(负)增量小于显示值与实际值的差值,则提升减小的速度
      {
        DataVSPeedDamping.Delta += DATA_VSPEED_INC_STEP;
        if (DataVSPeedDamping.Delta > Delta)
          DataVSPeedDamping.Delta = Delta;
      }
      else                                                //当前(负)增量大于等于显示值与实际值的差值,保持(负)增量与当前差值同步,减小的速度即逐步减小
        DataVSPeedDamping.Delta = Delta;

      Delta  = DataVSPeedDamping.Delta;
      Delta /= DATA_VSPEED_DAMPING_FACTOR;

      if (Delta < DATA_VSPEED_APPR_SPEED_MIN)
        Delta = DATA_VSPEED_APPR_SPEED_MIN;

      if (DataVSPeedDamping.Speed < VSpeed + Delta)
        DataVSPeedDamping.Speed  = VSpeed;
      else
        DataVSPeedDamping.Speed -= Delta;
    }
  }
  else                                                    //实际值与当前显示值相等时
  {
    Delta  = DataVSPeedDamping.Delta;
    Delta /= DATA_VSPEED_DAMPING_FACTOR;

    if (Delta > DATA_VSPEED_APPR_SPEED_MIN)               //当前的速度不是最小,说明数值正在增加/减小中,则继续原过程
    {
      if (DataVSPeedDamping.Delta > DATA_VSPEED_DEC_STEP) //显示值越过了实际值,必然要先减速至最小速度,再改变方向返回实际值
        DataVSPeedDamping.Delta -= DATA_VSPEED_DEC_STEP;
      else
        DataVSPeedDamping.Delta = 0;

      Delta  = DataVSPeedDamping.Delta;
      Delta /= DATA_VSPEED_DAMPING_FACTOR;

      if (DataVSPeedDamping.Dir == DATA_APPR_DIR_INC)     //显示值当前是增加方向
      {
        if (Delta < DATA_VSPEED_APPR_SPEED_MIN)           //已减速至最小速度
          DataVSPeedDamping.Dir = DATA_APPR_DIR_DEC;      //更换方向
        else
        {
          DataVSPeedDamping.Speed += Delta;
          if (DataVSPeedDamping.Speed > 3000)
            DataVSPeedDamping.Speed = 3000;
        }
      }
      else                                                //显示值当前是减小方向
      {
        if (Delta < DATA_VSPEED_APPR_SPEED_MIN)           //已减速至最小速度
          DataVSPeedDamping.Dir = DATA_APPR_DIR_INC;      //更换方向
        else
        {
          if (DataVSPeedDamping.Speed > Delta)
            DataVSPeedDamping.Speed -= Delta;
          else
            DataVSPeedDamping.Speed = 0;
        }
      }
    }
  }   
  DataVSPeedDamping.Speed  = DataVSpeedActual;
	//第3步：生成显示车速
	if ((DataVSPeedDamping.Speed >= DataVSpeedHysteresis) || (DataVSPeedDamping.Speed < 10))
		DataVSpeedHysteresis = DataVSPeedDamping.Speed;
	else
	{
		if (DataVSpeedHysteresis - DataVSPeedDamping.Speed >= DATA_VSPEED_HYSTERESIS)  //20201208解决定速巡航车速不稳问题
			DataVSpeedHysteresis = DataVSPeedDamping.Speed;
	}

	VSpeedCal  = (uint32_t)DataVSpeedHysteresis;
	VSpeedCal *= 103;
	VSpeedCal /= 100;
	if (VSpeedCal >= 100)
		VSpeedCal += 10;
	else
		VSpeedCal += VSpeedCal / 10;
	
	DataVSpeedDisp = (uint16_t)VSpeedCal;
	if (DataVSpeedDisp >= 5)
		DataVSpeedDisp += 5;
	

	//第4步：超速报警判断
	if (DataOverSpeed)
	{
		if (DataVSpeedDisp <= 1009)
			DataOverSpeed = 0;
	}
	else
	{
		if (DataVSpeedDisp > 1009)
			DataOverSpeed = 1;
	}
	Gauges_VSpeed_LCD_Status();
}
/**************************************气压1******************************************************************************************/
/******************************************************************************
  函数名：Data_AirO_Level_Processing_Service
  功  能：
  参  数：无
  返回值：无
 *******************************************************************************
 注  意：该函数必须每50ms被调用一次
 ******************************************************************************/
void Data_AirO_Level_Processing_Service(void)
{
	uint16_t  Temp;
	uint8_t   Step;
  uint16_t  Gas1_Voleage = 0;	 
  uint32_t  Gas1_temp = 0;
  
  Gas1_Voleage = ANALOG_GAS1_VOLTAGE;  	
	
	if ((Gas1_Voleage < 500) || (Gas1_Voleage > 4500))
	{
	  if (DataCoolantAirOCalc.LostTimer < 200)        
		{
			if (DataCollantAirOValid)
			{
				DataCoolantAirOCalc.LostTimer++;
				DataCoolantAirO = DataCoolantAirOCalc.Backup;
			}
			else
			{
				DataCoolantAirOCalc.LostTimer = 200;         
				DataCoolantAirOCalc.Backup    = 0;
				DataCoolantAirO               = 0;
			}  
		}
		else
		{
			DataCoolantAirOCalc.Backup = 0;
			DataCollantAirOValid       = 0;
			DataCoolantAirO            = 0;
		}
  }
	else 
	{  
    Temp = (uint16_t)Gas1_Voleage;         

  	DataCoolantAirO               = Temp;    
  	DataCollantAirOValid          = 1;
  	DataCoolantAirOCalc.LostTimer = 0;
	}
		
	DataCoolantAirOCalc.Prescaler++;
	if (DataCoolantAirOCalc.Prescaler >= 5)
	{
		DataCoolantAirOCalc.Prescaler = 0;

		switch (DataCoolantAirOCalc.State)
		{
			case DATA_COOLANT_AirO_STATE_DELAY    : 
				if (DataCoolantAirOCalc.Wait)
					DataCoolantAirOCalc.Wait--;
				else
					DataCoolantAirOCalc.State = DATA_COOLANT_AirO_STATE_INIT;
				break;

			case DATA_COOLANT_AirO_STATE_INIT     : 
				if (DataCollantAirOValid)
				{
					DataCoolantAirOCalc.OutputEnable = 1;
					DataCoolantAirOCalc.FastMode     = 1;
					DataCoolantAirOCalc.State        = DATA_COOLANT_AirO_STATE_FAST;
				}
				else
				{
					DataCoolantAirOCalc.OutputEnable = 1;
					DataCoolantAirOCalc.FastMode     = 1;
					DataCoolantAirOCalc.Last         = 0;
					DataCoolantAirOCalc.Backup       = 0;

					DataCoolantAirOCalc.State        = DATA_COOLANT_AirO_STATE_FAULT;
				}

				break;

			case DATA_COOLANT_AirO_STATE_FAST     : 
				if (DataCollantAirOValid)
				{
					if (DataCoolantAirOCalc.FastMode == 0)
						DataCoolantAirOCalc.State = DATA_COOLANT_AirO_STATE_NORMAL;
				}
				else
				{
					DataCoolantAirOCalc.OutputEnable = 1;
					DataCoolantAirOCalc.FastMode     = 1;
					DataCoolantAirOCalc.Last         = 0;
					DataCoolantAirOCalc.Backup       = 0;

					DataCoolantAirOCalc.State        = DATA_COOLANT_AirO_STATE_FAULT;
				}

				break;                                                

			case DATA_COOLANT_AirO_STATE_NORMAL   : 
				if (DataCollantAirOValid == 0)
				{
					DataCoolantAirOCalc.OutputEnable = 1;
					DataCoolantAirOCalc.FastMode     = 1;
					DataCoolantAirOCalc.Last         = 0;
					DataCoolantAirOCalc.Backup       = 0;

					DataCoolantAirOCalc.State        = DATA_COOLANT_AirO_STATE_FAULT;
				}

				break;

			case DATA_COOLANT_AirO_STATE_FAULT    : 
				if (DataCollantAirOValid)
					DataCoolantAirOCalc.State = DATA_COOLANT_AirO_STATE_FAST;                                            
				break;

			default                               : 
				DataCoolantAirOSegDisp           = 0;

				DataCoolantAirO                  = 0;
				DataCollantAirOValid             = 0;
				DataCoolantAirOCalc.OutputEnable = 1;
				DataCoolantAirOCalc.FastMode     = 1;
				DataCoolantAirOCalc.Last         = 0;
				DataCoolantAirOCalc.Backup       = 0;

				DataCoolantAirOCalc.State        = DATA_COOLANT_AirO_STATE_FAULT;

				break;
		}
	}

	//第3步：显示输出
	if (DataCoolantAirOCalc.OutputEnable)
	{
		if ( (DataCoolantAirO <= 1960) && (DataCoolantAirO >= 1920) )
			DataCoolantAirO = 1960 ; 

		if ( DataCoolantAirOSegDisp < DataCoolantAirO )
		{
			if (DataCoolantAirOCalc.FastMode) 
			{
				DataCoolantAirOSegDisp =  DataCoolantAirO; 
      } 
			else 
			{
			  if ((DataCoolantAirOSegDisp + 100) < DataCoolantAirO )
			  { 
  				Step = 5;
  				DataCoolantAirOCalc.DispTimer++;

  				if (DataCoolantAirOCalc.DispTimer >= Step)
  				{
  					DataCoolantAirOCalc.DispTimer = 0;
  					DataCoolantAirOSegDisp += 20;  
  				} 
			  }
			  else 
			  {
			    Step = 10;
  				DataCoolantAirOCalc.DispTimer++;

  				if (DataCoolantAirOCalc.DispTimer >= Step)
  				{
  					DataCoolantAirOCalc.DispTimer = 0;
  					DataCoolantAirOSegDisp++;  
  				}
			  }
			}

			if ( DataCoolantAirOSegDisp == DataCoolantAirO )
				DataCoolantAirOCalc.FastMode = 0; 
    }
		else if ( DataCoolantAirOSegDisp > DataCoolantAirO )
		{
			if (DataCoolantAirOCalc.FastMode) 
			{
				DataCoolantAirOSegDisp = DataCoolantAirO; 

				if ( (DataCoolantAirO <= 1960) && (DataCoolantAirO >= 1920) )
					DataCoolantAirOSegDisp = 1960; 
			} 
			else 
			{
			  if ((DataCoolantAirOSegDisp - 100) > DataCoolantAirO)
			  {
  				Step = 5;
  				DataCoolantAirOCalc.DispTimer++;
  				if (DataCoolantAirOCalc.DispTimer >= Step)
  				{
  					DataCoolantAirOCalc.DispTimer = 0;

  					if ( DataCoolantAirOSegDisp > 0)
  						DataCoolantAirOSegDisp -= 20; 
  					else
  						DataCoolantAirOSegDisp = 0; 
  				}
			  }
			  else 
			  {
			   	Step = 10;
  				DataCoolantAirOCalc.DispTimer++;
  				if (DataCoolantAirOCalc.DispTimer >= Step)
  				{
  					DataCoolantAirOCalc.DispTimer = 0;

  					if ( DataCoolantAirOSegDisp > 0)
  						DataCoolantAirOSegDisp--; 
  					else
  						DataCoolantAirOSegDisp = 0; 
  				}

			  }
				if ( DataCoolantAirOSegDisp == DataCoolantAirO)
					DataCoolantAirOCalc.FastMode = 0; 

				if ((DataCoolantAirO <= 1960 ) && (DataCoolantAirO >= 1920))
					DataCoolantAirOSegDisp = 1960;   
			}
		}
		else
		{
			DataCoolantAirOCalc.DispTimer = 0;
		}
	}
  Gauges_GAS1_LCD_Status();
	//第4步：报警判断
	if ((DataCoolantAirOSegDisp <= 1860) || (DataCoolantAirOSegDisp >= 3765))
		DataHiCollantAirOWarning = 1;
	else  
		DataHiCollantAirOWarning = 0;  

	DataCoolantAirOCalc.Backup = DataCoolantAirO;
	if (DataCoolantAirO >= 500)
  {
	  Gas1_temp = DataCoolantAirO - 500;
	  Gas1_temp = Gas1_temp * 147 / 400;
	}
	else
	  Gas1_temp = 0;
	
	FrontPress = Gas1_temp / 8;
}
/**************************************气压2******************************************************************************************/
/******************************************************************************
  函数名：Data_AirT_Level_Processing_Service
  功  能：
  参  数：无
  返回值：无
 *******************************************************************************
 注  意：该函数必须每20ms被调用一次
 ******************************************************************************/
void Data_AirT_Level_Processing_Service(void)
{
  uint16_t  Temp;
	uint8_t   Step;
	uint16_t  Gas2_Voleage = 0;	 
  uint32_t  Gas2_temp = 0;
  
  Gas2_Voleage = ANALOG_GAS2_VOLTAGE;
  
	if ((Gas2_Voleage < 500) || (Gas2_Voleage > 4500))
	{
	  if (DataCoolantAirTCalc.LostTimer < 200)        
		{
			if (DataCollantAirTValid)
			{
				DataCoolantAirTCalc.LostTimer++;
				DataCoolantAirT = DataCoolantAirTCalc.Backup;
			}
			else
			{
				DataCoolantAirTCalc.LostTimer = 200;        
				DataCoolantAirTCalc.Backup    = 0;
				DataCoolantAirT               = 0;
			}  
		}
		else
		{
			DataCoolantAirTCalc.Backup = 0;
			DataCollantAirTValid       = 0;
			DataCoolantAirT            = 0;
		}
	}
	else 
	{  
    Temp = (uint16_t)Gas2_Voleage;         

  	DataCoolantAirT               = Temp;    
  	DataCollantAirTValid          = 1;
  	DataCoolantAirTCalc.LostTimer = 0;
	}
	
	DataCoolantAirTCalc.Prescaler++;
	if (DataCoolantAirTCalc.Prescaler >= 5)
	{
		DataCoolantAirTCalc.Prescaler = 0;

		switch (DataCoolantAirTCalc.State)
		{
			case DATA_COOLANT_AirT_STATE_DELAY    : 
				if (DataCoolantAirTCalc.Wait)
					DataCoolantAirTCalc.Wait--;
				else
					DataCoolantAirTCalc.State = DATA_COOLANT_AirT_STATE_INIT;
				break;

			case DATA_COOLANT_AirT_STATE_INIT     : 
				if (DataCollantAirTValid)
				{
					DataCoolantAirTCalc.OutputEnable = 1;
					DataCoolantAirTCalc.FastMode     = 1;
					DataCoolantAirTCalc.State        = DATA_COOLANT_AirT_STATE_FAST;
				}
				else
				{
					DataCoolantAirTCalc.OutputEnable = 1;
					DataCoolantAirTCalc.FastMode     = 1;
					DataCoolantAirTCalc.Last         = 0;
					DataCoolantAirTCalc.Backup       = 0;

					DataCoolantAirTCalc.State        = DATA_COOLANT_AirT_STATE_FAULT;
				}

				break;

			case DATA_COOLANT_AirT_STATE_FAST     : 
				if (DataCollantAirTValid)
				{
					if (DataCoolantAirTCalc.FastMode == 0)
						DataCoolantAirTCalc.State = DATA_COOLANT_AirT_STATE_NORMAL;
				}
				else
				{
					DataCoolantAirTCalc.OutputEnable = 1;
					DataCoolantAirTCalc.FastMode     = 1;
					DataCoolantAirTCalc.Last         = 0;
					DataCoolantAirTCalc.Backup       = 0;

					DataCoolantAirTCalc.State        = DATA_COOLANT_AirT_STATE_FAULT;
				}

				break;                                                

			case DATA_COOLANT_AirT_STATE_NORMAL   : 
				if (DataCollantAirTValid == 0)
				{
					DataCoolantAirTCalc.OutputEnable = 1;
					DataCoolantAirTCalc.FastMode     = 1;
					DataCoolantAirTCalc.Last         = 0;
					DataCoolantAirTCalc.Backup       = 0;

					DataCoolantAirTCalc.State        = DATA_COOLANT_AirT_STATE_FAULT;
				}

				break;

			case DATA_COOLANT_AirT_STATE_FAULT    : 
				if (DataCollantAirTValid)
					DataCoolantAirTCalc.State = DATA_COOLANT_AirT_STATE_FAST;                                            
				break;

			default                               : 
				DataCoolantAirTSegDisp           = 0;

				DataCoolantAirT                  = 0;
				DataCollantAirTValid             = 0;
				DataCoolantAirTCalc.OutputEnable = 1;
				DataCoolantAirTCalc.FastMode     = 1;
				DataCoolantAirTCalc.Last         = 0;
				DataCoolantAirTCalc.Backup       = 0;

				DataCoolantAirTCalc.State        = DATA_COOLANT_AirT_STATE_FAULT;

				break;
		}
	}

	//第3步：显示输出
	if (DataCoolantAirTCalc.OutputEnable)
	{
		if ( (DataCoolantAirT <= 1960) && (DataCoolantAirT >= 1920) )
			DataCoolantAirT = 1960; 

		if ( DataCoolantAirTSegDisp < DataCoolantAirT )
		{
			if (DataCoolantAirTCalc.FastMode) 
			{
				DataCoolantAirTSegDisp = DataCoolantAirT; 
			} 
			else 
			{
			  if ((DataCoolantAirTSegDisp + 100) < DataCoolantAirT)
			  {
			    Step = 5;
  				DataCoolantAirTCalc.DispTimer++;

  				if (DataCoolantAirTCalc.DispTimer >= Step)
  				{
  					DataCoolantAirTCalc.DispTimer = 0;
  					DataCoolantAirTSegDisp += 20;  
  				}  
			  }
			  else 
			  {  
  				Step = 10;
  				DataCoolantAirTCalc.DispTimer++;

  				if (DataCoolantAirTCalc.DispTimer >= Step)
  				{
  					DataCoolantAirTCalc.DispTimer = 0;
  					DataCoolantAirTSegDisp++;  
   				} 
			  }
			}

			if ( DataCoolantAirTSegDisp == DataCoolantAirT )
				DataCoolantAirTCalc.FastMode = 0; 

		}
		else if ( DataCoolantAirTSegDisp > DataCoolantAirT )
		{
			if (DataCoolantAirTCalc.FastMode) 
			{
				DataCoolantAirTSegDisp = DataCoolantAirT ; 

				if ( (DataCoolantAirT <= 1960) && (DataCoolantAirT >= 1920) )
					DataCoolantAirTSegDisp = 1960; 
			} 
			else 
			{
			  if ((DataCoolantAirTSegDisp - 100) > DataCoolantAirT)
			  {
			   	Step = 5;
  				DataCoolantAirTCalc.DispTimer++;
  				if (DataCoolantAirTCalc.DispTimer >= Step)
  				{
  					DataCoolantAirTCalc.DispTimer = 0;

  					if (DataCoolantAirTSegDisp > 0)
  						DataCoolantAirTSegDisp -= 20; 
  					else
  						DataCoolantAirTSegDisp  = 0; 
  				} 
			  }
			  else 
			  {  
  				Step = 10;
  				DataCoolantAirTCalc.DispTimer++;
  				if (DataCoolantAirTCalc.DispTimer >= Step)
  				{
  					DataCoolantAirTCalc.DispTimer = 0;

  					if (DataCoolantAirTSegDisp > 0)
  						DataCoolantAirTSegDisp--; 
  					else
  						DataCoolantAirTSegDisp = 0; 
  				}
			  }
				if (DataCoolantAirTSegDisp == DataCoolantAirT)
					DataCoolantAirTCalc.FastMode = 0 ; 

				if ((DataCoolantAirT <= 1960) && (DataCoolantAirT >= 1920))
					DataCoolantAirTSegDisp = 1960;   
			}
		}
		else
		{
			DataCoolantAirTCalc.DispTimer = 0;
		}
	}
  Gauges_GAS2_LCD_Status();
	//第4步：报警判断
	if ((DataCoolantAirTSegDisp <= 1860) || (DataCoolantAirTSegDisp >= 3765))     //20190721
		DataHiCollantAirTWarning = 1;
	else 
		DataHiCollantAirTWarning = 0;  

	DataCoolantAirTCalc.Backup = DataCoolantAirT; 

	if (DataCoolantAirT >= 500)
  {
	  Gas2_temp = DataCoolantAirT - 500;
	  Gas2_temp = Gas2_temp * 147 / 400;
	}
	else
	  Gas2_temp = 0;
	
	RearPress = Gas2_temp / 8;
}
/**************************************水温******************************************************************************************/
/******************************************************************************
  函数名：Data_Coolant_Temp_Processing_Service
  功  能：冷却液温度数据处理函数
  参  数：无
  返回值：无
 *******************************************************************************
 注  意：该函数必须每20ms被调用一次
 ******************************************************************************/
void Data_Coolant_Temp_Processing_Service(void)
{
	uint16_t Temp = 0;
	uint8_t  Step;
	
  if ((Engine_Coolant_Temp >= 0xFF) || (ET1_STATUS & CAN_MSG_LOST))    
  {
    if (DataCoolantTempCalc.LostTimer < 17)        //250
    {
      if (DataCollantTempValid)
      {
        DataCoolantTempCalc.LostTimer++;
        DataCoolantTemp = DataCoolantTempCalc.Backup;
      }
      else
      {
        DataCoolantTempCalc.LostTimer = 17;        //250
        DataCoolantTempCalc.Backup    = 0;
        DataCoolantTemp               = 0;
      }  
    }
    else
    {
      DataCoolantTempCalc.Backup = 0;
      DataCollantTempValid       = 0;
      DataCoolantTemp            = 0;
    }
  }
  else
  {
		Temp = Engine_Coolant_Temp; 
		
		if (Temp >= 40)
			Temp -= 40;
		else
			Temp = 40 - Temp;
		
		if (Temp > 210)
			Temp = 210;    
    
    DataCoolantTemp               = Temp;    
    DataCollantTempValid          = 1;
    DataCoolantTempCalc.LostTimer = 0;

  }
  DataCoolantTempCalc.Prescaler++;
  if (DataCoolantTempCalc.Prescaler >= 5)
  {
    DataCoolantTempCalc.Prescaler = 0;
    
    switch (DataCoolantTempCalc.State)
    {
      case DATA_COOLANT_TEMP_STATE_DELAY    : if (DataCoolantTempCalc.Wait)
                                                DataCoolantTempCalc.Wait--;
                                              else
                                                DataCoolantTempCalc.State = DATA_COOLANT_TEMP_STATE_INIT;

                                              break;
                                              
      case DATA_COOLANT_TEMP_STATE_INIT     : if (DataCollantTempValid)
                                              {
                                                DataCoolantTempCalc.OutputEnable = 1;
                                                DataCoolantTempCalc.FastMode     = 1;
                                                DataCoolantTempCalc.State        = DATA_COOLANT_TEMP_STATE_FAST;
                                           
                                              }
                                              else
                                              {
                                                DataCoolantTempCalc.OutputEnable = 1;
                                                DataCoolantTempCalc.FastMode     = 1;
                                                DataCoolantTempCalc.Last         = 0;
                                                DataCoolantTempCalc.Backup       = 0;
                                                
                                                DataCoolantTempCalc.State        = DATA_COOLANT_TEMP_STATE_FAULT;
                                              }
                                              
                                              break;
                                                  
      case DATA_COOLANT_TEMP_STATE_FAST     : if (DataCollantTempValid)
                                              {
                                                if (DataCoolantTempCalc.FastMode == 0)
                                                  DataCoolantTempCalc.State = DATA_COOLANT_TEMP_STATE_NORMAL;
                                              }
                                              else
                                              {
                                                DataCoolantTempCalc.OutputEnable = 1;
                                                DataCoolantTempCalc.FastMode     = 1;
                                                DataCoolantTempCalc.Last         = 0;
                                                DataCoolantTempCalc.Backup       = 0;
                                                
                                                DataCoolantTempCalc.State        = DATA_COOLANT_TEMP_STATE_FAULT;
                                              }
                                              
                                              break;                                                
                                                
      case DATA_COOLANT_TEMP_STATE_NORMAL   : if (DataCollantTempValid == 0)
                                              {
                                                DataCoolantTempCalc.OutputEnable = 1;
                                                DataCoolantTempCalc.FastMode     = 1;
                                                DataCoolantTempCalc.Last         = 0;
                                                DataCoolantTempCalc.Backup       = 0;
                                                
                                                DataCoolantTempCalc.State        = DATA_COOLANT_TEMP_STATE_FAULT;
                                              }
                                              
                                              break;
      
      case DATA_COOLANT_TEMP_STATE_FAULT    : if (DataCollantTempValid)
                                                DataCoolantTempCalc.State = DATA_COOLANT_TEMP_STATE_FAST;                                            
                                              break;
                                              
      default                               : DataCoolantTempSegDisp           = 300;
      
                                              DataCoolantTemp                  = 0;
                                              DataCollantTempValid             = 0;
                                              DataCoolantTempCalc.OutputEnable = 1;
                                              DataCoolantTempCalc.FastMode     = 1;
                                              DataCoolantTempCalc.Last         = 0;
                                              DataCoolantTempCalc.Backup       = 0;
                                              
                                              DataCoolantTempCalc.State        = DATA_COOLANT_TEMP_STATE_FAULT;
                                              
                                              break;
    }
  }

  //第3步：显示输出
  if (DataCoolantTempCalc.OutputEnable)
  {
    if ( (DataCoolantTemp < 106) && (DataCoolantTemp > 104) )
   	  DataCoolantTemp = 105; 

    if ( DataCoolantTempSegDisp < DataCoolantTemp )
    {
      if (DataCoolantTempCalc.FastMode) 
      {
        DataCoolantTempSegDisp = DataCoolantTemp; 
      } 
      else 
      {
        Step = 5;
        DataCoolantTempCalc.DispTimer++;
        
        if (DataCoolantTempCalc.DispTimer >= Step)
        {
          DataCoolantTempCalc.DispTimer = 0;
          DataCoolantTempSegDisp++;  
        } 
      }
       
      if ( DataCoolantTempSegDisp == DataCoolantTemp )
        DataCoolantTempCalc.FastMode = 0; 
    }
    else if ( DataCoolantTempSegDisp > DataCoolantTemp )
    {
      if (DataCoolantTempCalc.FastMode) 
      {
        DataCoolantTempSegDisp = DataCoolantTemp; 
          
        if ( (DataCoolantTemp < 106) && (DataCoolantTemp > 104) )
          DataCoolantTempSegDisp = 105; 
      } 
      else 
      {
        Step = 5;
        DataCoolantTempCalc.DispTimer++;
        if (DataCoolantTempCalc.DispTimer >= Step)
        {
          DataCoolantTempCalc.DispTimer = 0;
    
          if (DataCoolantTempSegDisp <= 120)
            DataCoolantTempSegDisp--; 
          else
            DataCoolantTempSegDisp = 120; 
        }
        
        if (DataCoolantTempSegDisp == DataCoolantTemp)
          DataCoolantTempCalc.FastMode = 0; 
        
        if ( (DataCoolantTemp < 106) && (DataCoolantTemp > 104) )
          DataCoolantTempSegDisp = 105;   
      }
    }
    else
    {
      DataCoolantTempCalc.DispTimer = 0;
    }
  }
 
  //第4步：水温高报警判断
  if (DataCoolantTempSegDisp > 104) 
    DataHiCollantTempWarning = 1;
  else if (DataCoolantTempSegDisp < 106)
    DataHiCollantTempWarning = 0;  
  
  DataCoolantTempCalc.Backup = DataCoolantTemp;
}
/**************************************机油******************************************************************************************/
/******************************************************************************
  函数名：Data_Coolant_Oil_Processing_Service
  功  能：机油压力数据处理函数
  参  数：无
  返回值：无
 *******************************************************************************
 注  意：该函数必须每20ms被调用一次
 ******************************************************************************/
void Data_Coolant_Oil_Processing_Service(void)
{
//#if ModVersion != Version_KANG

	uint16_t Temp = 0;
	uint8_t  Step;
	
  if (1) //NVM_CONFIG_KANG == 0)
  {	
    if ( (EngOilPress >= 0xFF) || (EFLP1_STATUS & CAN_MSG_LOST))    
    {
      if (DataCoolantOilCalc.LostTimer < 17)        //250
      {
        if (DataCollantOilValid)
        {
          DataCoolantOilCalc.LostTimer++;
          DataCoolantOil = DataCoolantOilCalc.Backup;
        }
        else
        {
          DataCoolantOilCalc.LostTimer = 17;        //250
          DataCoolantOilCalc.Backup    = 0;
          DataCoolantOil               = 0;
        }  
      }
      else
      {
        DataCoolantOilCalc.Backup = 0;
        DataCollantOilValid       = 0;
        DataCoolantOil            = 0;
      }
    }
    else
    {
  		Temp = EngOilPress; 
  		Temp = Temp * 4;  //精度4
  		
  		if (Temp >= 1000)
  		  Temp = 1000;   
      
      DataCoolantOil               = Temp;    
      DataCollantOilValid          = 1;
      DataCoolantOilCalc.LostTimer = 0;
    }
    
    DataCoolantOilCalc.Prescaler++;
    if (DataCoolantOilCalc.Prescaler >= 5)
    {
      DataCoolantOilCalc.Prescaler = 0;
      
      switch (DataCoolantOilCalc.State)
      {
        case DATA_COOLANT_OIL_STATE_DELAY    :  if (DataCoolantOilCalc.Wait)
                                                  DataCoolantOilCalc.Wait--;
                                                else
                                                  DataCoolantOilCalc.State = DATA_COOLANT_OIL_STATE_INIT;

                                                break;
                                                
        case DATA_COOLANT_OIL_STATE_INIT     :  if (DataCollantOilValid)
                                                {
                                                  DataCoolantOilCalc.OutputEnable = 1;
                                                  DataCoolantOilCalc.FastMode     = 1;
                                                  DataCoolantOilCalc.State        = DATA_COOLANT_OIL_STATE_FAST;
                                                }
                                                else
                                                {
                                                  DataCoolantOilCalc.OutputEnable = 1;
                                                  DataCoolantOilCalc.FastMode     = 1;
                                                  DataCoolantOilCalc.Last         = 0;
                                                  DataCoolantOilCalc.Backup       = 0;
                                                  
                                                  DataCoolantOilCalc.State        = DATA_COOLANT_OIL_STATE_FAULT;
                                                }
                                              
                                                break;
                                                    
        case DATA_COOLANT_OIL_STATE_FAST     :  if (DataCollantOilValid)
                                                {
                                                  if (DataCoolantOilCalc.FastMode == 0)
                                                    DataCoolantOilCalc.State = DATA_COOLANT_OIL_STATE_NORMAL;
                                                }
                                                else
                                                {
                                                  DataCoolantOilCalc.OutputEnable = 1;
                                                  DataCoolantOilCalc.FastMode     = 1;
                                                  DataCoolantOilCalc.Last         = 0;
                                                  DataCoolantOilCalc.Backup       = 0;
                                                  
                                                  DataCoolantOilCalc.State        = DATA_COOLANT_OIL_STATE_FAULT;
                                                }
                                                
                                                break;                                                
                                                  
        case DATA_COOLANT_OIL_STATE_NORMAL   :  if (DataCollantOilValid == 0)
                                                {
                                                  DataCoolantOilCalc.OutputEnable = 1;
                                                  DataCoolantOilCalc.FastMode     = 1;
                                                  DataCoolantOilCalc.Last         = 0;
                                                  DataCoolantOilCalc.Backup       = 0;
                                                  
                                                  DataCoolantOilCalc.State        = DATA_COOLANT_OIL_STATE_FAULT;
                                                }
                                                
                                                break;
        
        case DATA_COOLANT_OIL_STATE_FAULT    :  if (DataCollantOilValid)
                                                  DataCoolantOilCalc.State = DATA_COOLANT_OIL_STATE_FAST;                                            
                                                break;
                                                
        default                              :  DataCoolantOilSegDisp           = 300;
        
                                                DataCoolantOil                  = 0;
                                                DataCollantOilValid             = 0;
                                                DataCoolantOilCalc.OutputEnable = 1;
                                                DataCoolantOilCalc.FastMode     = 1;
                                                DataCoolantOilCalc.Last         = 0;
                                                DataCoolantOilCalc.Backup       = 0;
                                                
                                                DataCoolantOilCalc.State        = DATA_COOLANT_OIL_STATE_FAULT;
                                                
                                                break;
      }
    }

    //第3步：显示输出
    if (DataCoolantOilCalc.OutputEnable)
    {
      if ( (DataCoolantOil < 101) && (DataCoolantOil > 99) )
     	  DataCoolantOil = 100; 

      if ( DataCoolantOilSegDisp < DataCoolantOil )
      {
        if (DataCoolantOilCalc.FastMode) 
        {
          DataCoolantOilSegDisp = DataCoolantOil; 
        } 
        else 
        {
          Step = 5;
          DataCoolantOilCalc.DispTimer++;
          
          if (DataCoolantOilCalc.DispTimer >= Step)
          {
            DataCoolantOilCalc.DispTimer = 0;
            DataCoolantOilSegDisp++;  
          } 
        }
         
        if ( DataCoolantOilSegDisp == DataCoolantOil )
          DataCoolantOilCalc.FastMode = 0 ; 
        
      }
      else if ( DataCoolantOilSegDisp > DataCoolantOil )
      {
        if (DataCoolantOilCalc.FastMode) 
        {
          DataCoolantOilSegDisp = DataCoolantOil; 
          
          if ( (DataCoolantOil < 101) && (DataCoolantOil > 99) )
            DataCoolantOilSegDisp = 100; 
        } 
        else 
        {
          Step = 5;
          DataCoolantOilCalc.DispTimer++;
          if (DataCoolantOilCalc.DispTimer >= Step)
          {
            DataCoolantOilCalc.DispTimer = 0;
      
            if (DataCoolantOilSegDisp <= 1000)
              DataCoolantOilSegDisp--; 
            else
              DataCoolantOilSegDisp = 1000; 
          }
          
          if (DataCoolantOilSegDisp == DataCoolantOil)
            DataCoolantOilCalc.FastMode = 0; 
          
          if ( (DataCoolantOil < 101) && (DataCoolantOil > 99) )
            DataCoolantOilSegDisp = 100;   
        }
      }
      else
      {
        DataCoolantOilCalc.DispTimer = 0;
      }
    }
 
    //第4步：
    if (DataCoolantOilSegDisp <= 100) 
      DataHiCollantOilWarning = 1;
    else if (DataCoolantOilSegDisp > 102)
      DataHiCollantOilWarning = 0;  
    
    DataCoolantOilCalc.Backup = DataCoolantOil;
  }
  else
  {
    if (EngOilPress == 0)              //20200907
      DataCoolantOilSegDisp = 0;
    else if (EngOilPress == 0x4B)
      DataCoolantOilSegDisp = 500;
  }
}
/**************************************ADBLUE******************************************************************************************/
/******************************************************************************
  函数名：Data_Coolant_ADblue_Processing_Service
  功  能：天蓝液数据处理函数
  参  数：无
  返回值：无
 *******************************************************************************
 注  意：该函数必须每20ms被调用一次
 ******************************************************************************/
void Data_Coolant_ADblue_Processing_Service(void)
{
	uint16_t Temp = 0;
	uint8_t  Step;
  
  Temp = EMS_CylinderPressure;
  if ((Temp > 64255) || (EMS_51C_STATUS & CAN_MSG_LOST) || (IO_DISP_TEST_OFF_TIME <= 20))    
  {
    if (DataCoolantADblueCalc.LostTimer < 17)        //250
    {
      if (DataCollantADblueValid)
      {
        DataCoolantADblueCalc.LostTimer++;
        DataCoolantADblue = DataCoolantADblueCalc.Backup;
      }
      else
      {
        DataCoolantADblueCalc.LostTimer = 17;        //250
        DataCoolantADblueCalc.Backup    = 0;
        DataCoolantADblue               = 0;
      }  
    }
    else
    {
      DataCoolantADblueCalc.Backup = 0;
      DataCollantADblueValid       = 0;
      DataCoolantADblue            = 0;
    }
  }
  else
  {
		if (Temp <= 2000)
		{
		  Temp = 0;
		} 
		else if (Temp <= 3500)
		{
		  Temp = (Temp - 2000) / 125;
		}
		else if (Temp <= 7100)
		{
		  Temp = 12 + (Temp - 3500) / 300;
		} 
		else if (Temp < 7500)
		{
		  Temp = 24;
		}
		else if (Temp < 8000)
		{
		  Temp = 25;
		} 
		else if (Temp <= 11220)
	  {
	    Temp = 26 + (Temp - 8000) / 140;
	  }
	  else if (Temp < 11500)
		{
		  Temp = 49;
		}
		else if (Temp < 12000)
		{
		  Temp = 50;
		}
		else if (Temp <= 15220)
	  {
	    Temp = 51 + (Temp - 12000) / 140;
	  }
	  else if (Temp < 15500)
		{
		  Temp = 74;
		}
		else if (Temp < 16000)
		{
		  Temp = 76;
		}
		else if (Temp <= 18760)
	  {
	    Temp = 76 + (Temp - 16000) / 120;
	  }
	  else if (Temp < 19000)
		{
		  Temp = 99;
		} 
		else
	  {
	    Temp = 100 ;   
	  }
    
    DataCoolantADblue               = Temp;    
    DataCollantADblueValid          = 1;
    DataCoolantADblueCalc.LostTimer = 0;
  }
  
  DataCoolantADblueCalc.Prescaler++;
  
  if (DataCoolantADblueCalc.Prescaler >= 5)
  {
    DataCoolantADblueCalc.Prescaler = 0;
    
    switch (DataCoolantADblueCalc.State)
    {
      case DATA_COOLANT_ADBLUE_STATE_DELAY    : if (DataCoolantADblueCalc.Wait)
                                                  DataCoolantADblueCalc.Wait--;
                                                else
                                                  DataCoolantADblueCalc.State = DATA_COOLANT_ADBLUE_STATE_INIT;

                                                break;
                                              
      case DATA_COOLANT_ADBLUE_STATE_INIT     : if (DataCollantADblueValid)
                                                {
                                                  DataCoolantADblueCalc.OutputEnable = 1;
                                                  DataCoolantADblueCalc.FastMode     = 1;
                                                  DataCoolantADblueCalc.State        = DATA_COOLANT_ADBLUE_STATE_FAST;
                                                }
                                                else
                                                {
                                                  DataCoolantADblueCalc.OutputEnable = 1;
                                                  DataCoolantADblueCalc.FastMode     = 1;
                                                  DataCoolantADblueCalc.Last         = 0;
                                                  DataCoolantADblueCalc.Backup       = 0;
                                                  
                                                  DataCoolantADblueCalc.State        = DATA_COOLANT_ADBLUE_STATE_FAULT;
                                                }
                                                
                                                break;
                                                  
      case DATA_COOLANT_ADBLUE_STATE_FAST     : if (DataCollantADblueValid)
                                                {
                                                  if (DataCoolantADblueCalc.FastMode == 0)
                                                    DataCoolantADblueCalc.State = DATA_COOLANT_ADBLUE_STATE_NORMAL;
                                                }
                                                else
                                                {
                                                  DataCoolantADblueCalc.OutputEnable = 1;
                                                  DataCoolantADblueCalc.FastMode     = 1;
                                                  DataCoolantADblueCalc.Last         = 0;
                                                  DataCoolantADblueCalc.Backup       = 0;
                                                  
                                                  DataCoolantADblueCalc.State        = DATA_COOLANT_ADBLUE_STATE_FAULT;
                                                }
                                                
                                                break;                                                
                                                
      case DATA_COOLANT_ADBLUE_STATE_NORMAL   : if (DataCollantADblueValid == 0)
                                                {
                                                  DataCoolantADblueCalc.OutputEnable = 1;
                                                  DataCoolantADblueCalc.FastMode     = 1;
                                                  DataCoolantADblueCalc.Last         = 0;
                                                  DataCoolantADblueCalc.Backup       = 0;
                                                  
                                                  DataCoolantADblueCalc.State        = DATA_COOLANT_ADBLUE_STATE_FAULT;
                                                }
                                                
                                                break;
      
      case DATA_COOLANT_ADBLUE_STATE_FAULT    : if (DataCollantADblueValid)
                                                  DataCoolantADblueCalc.State = DATA_COOLANT_ADBLUE_STATE_FAST;                                            
                                                
                                                break;
                                              
      default                                 : DataCoolantADblueSegDisp           = 300;
      
                                                DataCoolantADblue                  = 0;
                                                DataCollantADblueValid             = 0;
                                                DataCoolantADblueCalc.OutputEnable = 1;
                                                DataCoolantADblueCalc.FastMode     = 1;
                                                DataCoolantADblueCalc.Last         = 0;
                                                DataCoolantADblueCalc.Backup       = 0;
                                                
                                                DataCoolantADblueCalc.State        = DATA_COOLANT_ADBLUE_STATE_FAULT;
                                                
                                                break;
    }
  }

  //第3步：显示输出
  if (DataCoolantADblueCalc.OutputEnable)
  {
    //if ( (DataCoolantADblue < 21) && (DataCoolantADblue > 19) )
   	//  DataCoolantADblue = 20; 

    if ( DataCoolantADblueSegDisp < DataCoolantADblue )
    {
      if (DataCoolantADblueCalc.FastMode) 
      {
        DataCoolantADblueSegDisp = DataCoolantADblue; 
      } 
      else 
      {
        Step = 5;
        DataCoolantADblueCalc.DispTimer++;
        
        if (DataCoolantADblueCalc.DispTimer >= Step)
        {
          DataCoolantADblueCalc.DispTimer = 0;
          DataCoolantADblueSegDisp++;  
        } 
      }
       
      if ( DataCoolantADblueSegDisp == DataCoolantADblue )
        DataCoolantADblueCalc.FastMode = 0; 
    }
    else if ( DataCoolantADblueSegDisp > DataCoolantADblue )
    {
      if (DataCoolantADblueCalc.FastMode) 
      {
        DataCoolantADblueSegDisp = DataCoolantADblue; 
          
        //if ( (DataCoolantADblue < 21) && (DataCoolantADblue > 19) )
        //  DataCoolantADblueSegDisp = 20; 
      } 
      else 
      {
        Step = 5;
        DataCoolantADblueCalc.DispTimer++;
        if (DataCoolantADblueCalc.DispTimer >= Step)
        {
          DataCoolantADblueCalc.DispTimer = 0;
    
          if ( DataCoolantADblueSegDisp <= 100)
            DataCoolantADblueSegDisp--; 
          else
            DataCoolantADblueSegDisp = 100; 
        }
        
        if ( DataCoolantADblueSegDisp == DataCoolantADblue)
          DataCoolantADblueCalc.FastMode = 0; 
        
        //if ( (DataCoolantADblue < 21) && (DataCoolantADblue > 19) )
        //  DataCoolantADblueSegDisp = 20;   
      }
    }
    else
    {
      DataCoolantADblueCalc.DispTimer = 0;
    }
  }
 
  //第4步：天蓝液报警判断
  //if (DataCoolantADblueSegDisp <= 20) 
  //  DataHiCollantADblueWarning = 1;
  //else if (DataCoolantADblueSegDisp > 21)
  //  DataHiCollantADblueWarning = 0;  
  
  DataCoolantADblueCalc.Backup = DataCoolantADblue;
}
 
void Data_Drive_Info_Group1_Processing_Service(void)
{
	//Data_oil_Temperature_Processing();
	Data_Trip_Processing();
	Data_ODO_Processing(); 
	Data_TPMS_Value_Processing();
}

void Data_Drive_Info_Group2_Processing_Service(void)
{
	Data_Fuel_Consumption_Processing();
	Data_DTE_Processing();
}

/******************************************************************************
  函数名：Data_IGN_Off_Timing_Service
  功  能：断电时间计时服务,用于计量断电时间,该函数在IGN ON / OFF 状态下都需要被周
  期性调用
  参  数：无
  返回值：无
*******************************************************************************
 注  意：该服务函数必须每100ms被调用一次
******************************************************************************/
void Data_IGN_Off_Timing_Service(void)
{
	uint16_t SecInc;
	uint16_t RollingCounter;

	if (SYS_OPR_STAT_IGN_ON)
	{
		DataIGNOffTimer.IGNStatus = 5;          //防止点火时电源抖动误清断电计时

		if ((IO_DISP_TEST_OFF_TIME < 250) && (!SYS_SELF_TEST_DISP_MODE)) //自检熄灭时间 
			IO_DISP_TEST_OFF_TIME++;   

		if ((DataVSpeedDisp > 0) && (VEH_TIME <= 700))
			VEH_TIME++;
		else if (DataVSpeedDisp == 0)
			VEH_TIME = 0;
	}                                                      
	else
	{  
		IO_DISP_TEST_OFF_TIME = 0;
		VEH_TIME = 0;
		if (DataIGNOffTimer.IGNStatus)
		{
			DataIGNOffTimer.IGNStatus--;
			if (DataIGNOffTimer.IGNStatus == 0)
			{
				DataIGNOffTimerSec = 0;
				DataIGNOffTimer.RoCBackup = RTC_ROLLING_COUNTER;
			}
		}
		else
		{
			RollingCounter = RTC_ROLLING_COUNTER;

			if (RollingCounter - DataIGNOffTimer.RoCBackup >= 10)
			{
				SecInc = (RollingCounter - DataIGNOffTimer.RoCBackup) / 10;
				DataIGNOffTimer.RoCBackup += SecInc * 10;

				if (DataIGNOffTimerSec <= 65535 - SecInc)
					DataIGNOffTimerSec += SecInc;
				else
					DataIGNOffTimerSec = 65535;
			}
		}
	}
}

/******************************************************************************
  函数名：Data_Ambient_Temperature_Processing
  功  能: 室外温度数据处理
  参  数: 无
  返回值：无
******************************************************************************/
#if NVM_FUNC_DISABLE
void Data_Ambient_Temperature_Processing(void)
{
	uint16_t  TempValue;
	uint16_t  Temp10F;
	
	TempValue = (Outside_Temperature / 2);

	if (DataAmbientTempDispMode == GUI_DISP_MODE_INVALID)
	{
		if (AC_0x530_STATUS & CAN_UPDATE == 0)
			return;
	}

	if ((AC_0x530_STATUS & CAN_MSG_LOST) || (Outside_TemperatureFailSts == 1))
		DataAmbientTempDispMode = GUI_DISP_MODE_INVALID;
	else
	{
		if (TempValue < 0xD7)
		{
			if (TempValue < 40)
			{
				DataAmbientTempDispMode = GUI_DISP_MODE_NEGATIVE;
				DataAmbientTemp = 40 - TempValue;
			}
			else
			{
				DataAmbientTempDispMode = GUI_DISP_MODE_NORMAL;
				DataAmbientTemp = TempValue - 40;
			}
		}
		else
			DataAmbientTempDispMode = GUI_DISP_MODE_INVALID;
	}
}
#endif

/******************************************************************************
  函数名：Data_ODO_Processing
  功  能: 总计里程数据处理
  参  数: 无
  返回值：无
******************************************************************************/
void Data_ODO_Processing(void)
{
	uint16_t RollingCounter;
	uint16_t Inc;
  uint8_t  i;
	
	if (NVM_EEPROM_FAULT)
		DataODOValid = 0;
	else
	{
		RollingCounter = DATA_MILEAGE_ROLLING_COUNTER;

		if (DataODOCalc.UpdateDisable)
		{
			if((DataVSpeedDisp >= 1600 ) && (DataESpeedDisp >= 4480))
			{
				DataODOCalc.RoCBackup = RollingCounter;
				return;
			}
			else
				DataODOCalc.UpdateDisable = 0;
		}

		if (DataODOValid == 0)
		{
			DataODOCalc.RoCBackup = RollingCounter;
			DataODOValid = 1;
		}

		if (RollingCounter - DataODOCalc.RoCBackup >= 100)
		{
			Inc = (RollingCounter - DataODOCalc.RoCBackup) / 100;
			DataODOCalc.RoCBackup += Inc * 100;

			NVM_ODO_VALUE += Inc;
			if (NVM_ODO_VALUE - DataODOCalc.LastSaved >= 10)
			{
				NVM_Data_Update(NVM_ODO_DATA);
				DataODOCalc.LastSaved = NVM_ODO_VALUE;
			}
		}
				 
	  for (i=0; i<50; i++)
	  {
 		  if ((NVM_ODO_VALUE >= 25000) && (NVM_ODO_VALUE <= 30000)) //20200911
      {
        Maintain_alarm = 1;
        break;
      }   		  
		  else if ((NVM_ODO_VALUE >= (95000 + 100000 * i)) && (NVM_ODO_VALUE <= (100000 + 100000 * i))) //20190806
      {
        Maintain_alarm = 1;
        break;
      }
 		  else
		  {
		    Maintain_alarm = 0;
		  }
	  }
	}	   
}

/******************************************************************************
  函数名：Data_Trip_Processing
  功  能: 小计里程数据处理
  参  数: 无
  返回值：无
******************************************************************************/
uint16_t DataTripA;
uint16_t DataTripB;
//uint16_t DataTripAFuelAve;
uint16_t DataTripASeatbelt;

void Data_Trip_Processing(void)
{
	uint16_t RollingCounter;
	uint16_t Inc;

	if (DATA_VEHICLE_SPEED_VALID)
	{
		RollingCounter = DATA_MILEAGE_ROLLING_COUNTER;

		if (DataODOCalc.UpdateDisable)
		{
			if ((DataVSpeedDisp >= 1600 ) && (DataESpeedDisp >= 4480))
			{
				DataTripCalc.RoCBackup = RollingCounter;
				return;
			}
			else
				DataODOCalc.UpdateDisable = 0;
		}

		if (DataTripValid == 0)
		{
			DataTripCalc.RoCBackup = RollingCounter;
			DataTripValid = 1;
		}

		if (NVM_USER_SETTINGS_DIST_UNIT != DataTripUnit)
		{
			if (DataTripUnit == NVM_DIST_UNIT_MILE) //原里程单位为 mile 现切换为 km
			{
				if (DataTripCalc.MileageA100m > 9999)
					DataTripCalc.MileageA100m -= 10000;
			    //if (DataTripCalc.MileageB100m > 9999)
			    //	DataTripCalc.MileageB100m -= 10000;
			}

			DataTripUnit = NVM_USER_SETTINGS_DIST_UNIT;
		}

		if (RollingCounter - DataTripCalc.RoCBackup >= 100)
		{
			Inc = (RollingCounter - DataTripCalc.RoCBackup) / 100;
			DataTripCalc.RoCBackup += Inc * 100;
		  //	if (TrapPOS == 0)
				DataTripCalc.MileageA100m += Inc;
		  //	else  if (TrapPOS == 1)
		  //		DataTripCalc.MileageB100m += Inc;
			//DataTripAFuelAve += Inc;
			//DataTripASeatbelt += Inc;
		}
		if (DataTripCalc.MileageA100m > 9999)
			DataTripCalc.MileageA100m -= 10000;
	    //	if (DataTripCalc.MileageB100m > 9999)
	    //		DataTripCalc.MileageB100m -= 10000;
		DataTripA = DataTripCalc.MileageA100m;
	  //	DataTripB = DataTripCalc.MileageB100m;   
	}
	else
	{
		DataTripValid = 0;
		DataTripUnit = NVM_USER_SETTINGS_DIST_UNIT;
	}
}

/******************************************************************************
  函数名：Data_Clear_Trip
  功  能: 小计里程清零
  参  数: 无
  返回值：无
******************************************************************************/

void Data_Clear_TripA(void)
{
	DataTripA = 0;
	DataTripCalc.MileageA100m = 0;
	DataTripCalc.RoCBackup    = DATA_MILEAGE_ROLLING_COUNTER;
}
void Data_Clear_TripB(void)
{
	DataTripB = 0;
	DataTripCalc.MileageB100m = 0;
	DataTripCalc.RoCBackup    = DATA_MILEAGE_ROLLING_COUNTER;
}

/******************************************************************************
  函数名：Data_Fuel_Consumption_Processing
  功  能: (平均/瞬时)油耗数据处理
  参  数: 无
  返回值：无
******************************************************************************/
void Data_Fuel_Consumption_Processing(void)
{
  uint16_t Value;
  
  Value = FuelEconomyH << 8;
  Value = Value | FuelEconomyL;
  Value = Value / 512;
  if (Value > 0)
    Value = 1000 / Value;
  else
    Value = 0;
  //if (Value > 299)
  //  Value = 299;
  FuelConsumptionRate = Value;
}

/******************************************************************************
  函数名：Data_Get_Average_Fuel_Consumption
  功  能: 获取当前平均油耗
  参  数: 无
  返回值：无
******************************************************************************/
uint8_t Data_Get_Average_Fuel_Consumption(void)
{
   return 0;
}

/******************************************************************************
  函数名：Data_Average_Fuel_Consumption_Reset
  功  能: 平均油耗清零
  参  数: 无
  返回值：无
******************************************************************************/
void Data_Average_Fuel_Consumption_Reset(void)
{}

/******************************************************************************
  函数名：Data_DTE_Processing
  功  能: 续航里程数据处理
  参  数: 无
  返回值：无
******************************************************************************/

void Data_DTE_Processing(void)
{}

/******************************************************************************
  函数名：Data_DTE_Processing
  功  能: 续航里程数据初始化
  参  数: 无
  返回值：无
******************************************************************************/

void Data_DTE_Init(void)
{}

/******************************************************************************
  函数名：Data_TPMS_Value_Processing
  功  能: TPMS数值(胎压/胎温)处理
  参  数: 无
  返回值：无
******************************************************************************/

void Data_Tpms_Proceser(void)
{
}

/******************************************************************************
  函数名：Data_TPMS_Value_Processing
  功  能: TPMS数值(胎压/胎温)处理
  参  数: 无
  返回值：无
******************************************************************************/
void Data_TPMS_Value_Processing(void)
{
  uint16_t TireTEMP;
  uint16_t TirePLR;
  
  TireTEMP = 0;
  TirePLR  = 0;
  
  if (!(BCM_TPMS_STATUS & CAN_MSG_LOST))
  {
    TirePLR = TirePressure;
    TirePLR = TirePLR * 11;     //
    TirePLR = TirePLR / 20;     //20190922 
    TireTEMP = TireTempH << 8;
    TireTEMP = TireTEMP + TireTempL;
    TireTEMP = TireTEMP >> 5;   //0.03125      
    
    if (TireLocation == 0)
    {
      TirePL    = TirePLR;
      TireTEMPL = TireTEMP;
    }
    if (TireLocation == 1)
    {
      TirePR    = TirePLR;      //20190922
      TireTEMPR = TireTEMP;
    }
  }
  else
  {
    TirePL    = 0xFF;
    TireTEMPL = 0xFF;
    TirePR    = 0xFF;           //20190922
    TireTEMPR = 0xFF;
  }
}

void Data_Mileage_Rolling_Counter_Update_ISR(void)
{
	uint16_t Mileage;

	if (SYS_OPR_STAT_IGN_ON)
	{
		if (DATA_VEHICLE_SPEED_VALID)
		{
			if (DATA_VEHICLE_SPEED_ACTUAL <= 2000)
				Mileage = (DATA_VEHICLE_SPEED_ACTUAL * 25) / 9;
			else
				Mileage = (DATA_VEHICLE_SPEED_ACTUAL / 9) * 25;

			DataMileage.mmRollingCounter += Mileage;

			//将原始的mm单位的Rolling Counter变换为以m为单位
			if (DataMileage.mmRollingCounter - DataMileage.mmRoCBackup >= 1000)
			{
				Mileage = (DataMileage.mmRollingCounter - DataMileage.mmRoCBackup) / 1000;
				DataMileage.mmRoCBackup += Mileage * 1000;

				DataMileageRollingCounter += Mileage;
			}
		}
	}
}
/******************************************************************************
  函数名：Data_ODO_Update_Disable
  功  能: 禁止总计里程数据更新
  参  数: 无
  返回值：无                                  
 ******************************************************************************/
void Data_ODO_Update_Disable(void)
{
	DataODOCalc.UpdateDisable = 1;
}
