

#include "UWater_gp22_app.h"
#include "UWater_lcd_app.h"
#include "UWater_frame_app.h"
#include "UWater_TemperatureCalculate_app.h"
#include "UWater_gp22_driver.h"
#include "UWater_rtcc_driver.h"

//0-100℃对应的超声波速度 单位m/s
const float sound_speed_in_water[101]=
{1402.336,
1407.31196 ,1412.173988,1416.924022,1421.563966,1426.095691,
1430.521033,1434.841795,1439.059749,1443.176633,1447.194154,
1451.113987,1454.937777,1458.667135,1462.303645,1465.84886 ,
1469.304301,1472.671463,1475.95181 ,1479.146777,1482.257772,
1485.286175,1488.233337,1491.100583,1493.889211,1496.600493,
1499.235674,1501.795973,1504.282585,1506.69668 ,1509.039401,
1511.311869,1513.515181,1515.65041 ,1517.718606,1519.720794,
1521.657981,1523.531149,1525.341257,1527.089246,1528.776035,
1530.40252 ,1531.969579,1533.478071,1534.928834,1536.322685,
1537.660427,1538.942839,1540.170687,1541.344717,1542.465656,
1543.534218,1544.551096,1545.51697 ,1546.432504,1547.298344,
1548.115124,1548.88346 ,1549.603957,1550.277204,1550.903775,
1551.484234,1552.01913 ,1552.508999,1552.954367,1553.355746,
1553.713636,1554.028529,1554.300904,1554.53123 ,1554.719965,
1554.86756 ,1554.974453,1555.041077,1555.067854,1555.055198,
1555.003516,1554.913207,1554.784663,1554.61827 ,1554.414405,
1554.173443,1553.89575 ,1553.581689,1553.231616,1552.845885,
1552.424843,1551.968835,1551.478204,1550.953285,1550.394416,
1549.801928,1549.176154,1548.517423,1547.826062,1547.102399,
1546.346762,1545.559476,1544.740868,1543.891267,1543.011   ,
};

#if WENDU_FANSUAN_OPEN
/*-----------------------------------------------------------------------------*/
TEMP_IVVERSE_UNION_MSG    temp_inverse_struct_msg;//温度反算对外消息联合体
Temp_Inverse_Data1        Temp_Inverse_Data;//反算温度对于单程时间处理


//单程时间滤波相关参数
u32   gp30_tof_up_down_head =0;//
u32   gp30_tof_up_down_length=0;
u32   gp30_tof_up_data[MAX_TEMP_NUM]; //用于采集up单程时间 2020-12-05
u32   gp30_tof_down_data[MAX_TEMP_NUM]; //用于采集up单程时间 2020-12-05
u32   gp30_tof_up_filter_value =0;//up滤波值
u32   gp30_tof_down_filter_value =0;//down滤波值 

//单程时间校准插值相关参数
u8      gp30_tof_buchang_head =0;
u8      gp30_tof_buchang_length =0;
float   gp30_tof_up_chazhi_filter_value =0;//up滤波值
float   gp30_tof_down_chazhi_filter_value =0;//down滤波值 
float   gp30_tof_up_buchang_data[MAX_TOF_BUCHANG_NUM]={0}; 
float   gp30_tof_down_buchang_data[MAX_TOF_BUCHANG_NUM]={0};

u8      tof_caliberate_state = TOF_BUCHANG_IDLE;//空闲状态不采集数据


//单程时间原始数据存储BUF
static u32 s_g_fhl_tof_up_data[GP22_APP_TEMP_INVERSE_DATA_SIZE_FIVE]={0}; //FHL_TOF_UP采集队列
static u32 s_g_fhl_tof_down_data[GP22_APP_TEMP_INVERSE_DATA_SIZE_FIVE]={0}; //FHL_TOF_DOWN采集队列

u32 tof_down_data[MAX_TEMP_NUM]={0};//记录down的单程时间中与UP单程时间对应位置的数据

//继承变量
extern GP30_SYS_Date gp22_app_data; //gp22当前数据
extern GP30_SYS_Date gp22_test_data; //gp22检定状态下当前数据
extern GP30_APP_SAVE_DATA g_sample_save_data; //当前数据备份
extern u32 s_g_up_am[GP22_APP_TEMP_INVERSE_DATA_SIZE+GP22_APP_TEMP_INVERSE_DATA_SIZE]; //am采集队列 数组中前4个存储第4~第7个波形振幅，后4个存储第8~第11个波形振幅
extern u32 s_g_down_am[GP22_APP_TEMP_INVERSE_DATA_SIZE+GP22_APP_TEMP_INVERSE_DATA_SIZE]; //down采集队列 数组中前4个存储第4~第7个波形振幅，后4个存储第8~第11个波形振幅
extern float temp_calculate_last;
/*-----------------------------------------------------------------------------*/


/*温度反算流程第一步：单程时间与振幅数据采集与处理*/

/****************************************************************
Function:     void Tof_And_AM_Data_Collect(u8 i,u32 s_g_tof_am_pointer)  
Description:  采集GP30给的up和down单程时间、up和down对应的振幅
函数性质： 外部接口函数
 *****************************************************************/
void Tof_And_AM_Data_Collect(u8 i,u32 s_g_tof_am_pointer)
{
    u32 s_g_tof_am_data[GP22_APP_QUEUE_SIZE]={0};
	s_g_tof_am_data[i] = s_g_tof_am_pointer;
	s_g_tof_am_data[i] = (s_g_tof_am_data[i] & 0x000000FFU) << 24 | (s_g_tof_am_data[i] & 0x0000FF00U) << 8 | (s_g_tof_am_data[i] & 0x00FF0000U) >> 8 | (s_g_tof_am_data[i] & 0xFF000000U) >> 24;  //大小端转换				
	//温度反算传上来的TOF值和振幅值处理（详见设计文档里传输的数据内容）
	if((0==i%GP22_APP_TEMP_INVERSE_DATA_SIZE)&&(i!=GP22_APP_QUEUE_SIZE-1))//传输的第1 4 7 10 13个数据为FHL 5-9波的up单程时间
	{
		s_g_fhl_tof_up_data[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]=s_g_tof_am_data[i];//传输的第1 4 7 10 个数据为FHL 5-9波的up单程时间
	}
	else if(1==i%GP22_APP_TEMP_INVERSE_DATA_SIZE)//传输的第2 5 8 11 14 个数据为FHL 5-9波的down单程时间
	{
		s_g_fhl_tof_down_data[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]=s_g_tof_am_data[i];//传输的第2 5 8 11 14 个数据为FHL 5-9波的down单程时间
	}
	else if((2==i%GP22_APP_TEMP_INVERSE_DATA_SIZE)||(i==GP22_APP_QUEUE_SIZE-1))//传输的第3 6 9 12 15 16 个数据为FHL 5-10波的up(左移16位高16)|down(低16位)单程时间
	{
		s_g_up_am[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]=s_g_tof_am_data[i]>>16;//获取UP的振幅
		if(0xF000==(s_g_up_am[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]&0xF000))//如果振幅F开头说明是负的振幅，负振幅处理为0
		{
			s_g_up_am[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]=0;
		}
		s_g_down_am[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]=s_g_tof_am_data[i]&0x0000FFFF;//获取DOWN的振幅
		if(0xF000==(s_g_down_am[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]&0xF000))//如果振幅F开头说明是负的振幅，负振幅处理为0
		{
			s_g_down_am[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]=0;
		}
	}
}

/****************************************************************
Function:     void Tof_Calcuate_Average(u32 *tof_up, u32 *tof_down, u8 data_len)   
Description:  分别对up 和Down 单程时间求取平均值
函数性质：   内部函数
 *****************************************************************/
void Tof_Calcuate_Average(u32 *tof_up, u32 *tof_down, u8 data_len)
{
    u8 i = 0;
    u32 sum_tof_up=0,sum_tof_down=0;
    for(i = 0;i< data_len;i++)
    {               
        sum_tof_up += tof_up[i];//求取UP单程时间均值
        sum_tof_down += tof_down[i];//求取Down单程时间均值
    }
    if((sum_tof_up!=0)&&(sum_tof_down!=0))//无水情况下 单程时间为零
    {
        gp22_test_data.s.TOF_up  =  (sum_tof_up/data_len)-TOF_6_US;//将up的单程时间平均值与6us做差后给到TOF_UP
        gp22_test_data.s.TOF_down = (sum_tof_down/data_len)-TOF_6_US;//将up的单程时间平均值与6us做差后给到TOF_DOWN
    }
    else
    {
        gp22_test_data.s.TOF_up = 0;
        gp22_test_data.s.TOF_down=0;
    }
}
/****************************************************************
Function:     AM_Calcuate_Average(u32 *up_am, u32 *down_am, u8 data_len)
Description:  分别对up 和Down 振幅求取平均值
函数性质：   内部函数
 *****************************************************************/
void AM_Calcuate_Average(u32 *up_am, u32 *down_am, u8 data_len)
{
    u8 i = 0,down_am_cnt=0,up_am_cnt=0;
    u32 sum_am_up=0,sum_am_down=0;
    
    for(i = 0;i< data_len;i++)
    {               
        if((s_g_up_am[i]>0)&&(s_g_up_am[i]<UP_AM_MAX))
        {
            sum_am_up += s_g_up_am[i];
            up_am_cnt++;
        }
         if((s_g_down_am[i]>0)&&(s_g_down_am[i]<DOWN_AM_MAX))
        {
           sum_am_down += s_g_down_am[i];
           down_am_cnt++;
        }       
    }
    
    if(down_am_cnt!=0)
    {
         Temp_Inverse_Data.Temp_Inverse_Data.down_am_average = sum_am_down / down_am_cnt;//求取Up振幅均值
    }
    else 
    {     
        Temp_Inverse_Data.Temp_Inverse_Data.down_am_average = 0;//求取Down振幅均值         
    }
    
    if(up_am_cnt!=0)
    {       
        Temp_Inverse_Data.Temp_Inverse_Data.up_am_average = sum_am_up / up_am_cnt;//求取UP振幅均值
    }
    else 
    {
        Temp_Inverse_Data.Temp_Inverse_Data.up_am_average = 0;//求取UP振幅均值 = 0;
    }    
}
/***************************************************************
函数名称： Gp30_Tof_Save(void)
功    能； 单程时间采集函数----分别将up和down的单程时间存储到相应的BUFFER中
函数性质： 内部函数
 ****************************************************************/
void Gp30_Tof_Save(void)
{ 
    gp30_tof_up_data[gp30_tof_up_down_head] =  gp22_test_data.s.TOF_up; //将单程时间存入到数组中
    gp30_tof_down_data[gp30_tof_up_down_head]= gp22_test_data.s.TOF_down; //将单程时间存入到数组中
    gp30_tof_up_down_head++;
    if(MAX_TEMP_NUM!=gp30_tof_up_down_head)//采样数组满了一次
    {
        if(gp30_tof_up_down_length != MAX_TEMP_NUM)//当BUF中数据已经存满一次了
        {
             gp30_tof_up_down_length = gp30_tof_up_down_head;//   
        }
    }
    else 
    {
       gp30_tof_up_down_length = MAX_TEMP_NUM; 
    }
    gp30_tof_up_down_head %= MAX_TEMP_NUM;	
}
/****************************************************************
Function:  单程时间滤波函数  
Description:*p 指向单程时间数组首地址 len 数据长度 flag 0:tof_up  1:tof_down  
函数性质： 内部函数
 *****************************************************************/
u32 Filter_FOR_TOFDOWN(u32 *p, u8 len)   //
{
	u8 i,cnt=0,max_count=0,min_count=0;//max_count:记录大数单程时间个数 min_count:记录小数单程时间个数
	u32 sum=0,sum_max=0,sum_min=0,tof_max=0,tof_min=0,tof_dif_max=0,tof_dif_min=0,tof_current=0;/*sum:单程时间累加和;sum_max：大数单程时间之间累加和 
                                                                                                  sum_min：大数单程时间之间累加和 tof_max:最大单程时间 
                                                                                                  tof_min:最小单程时间 tof_dif_max：最大单程时间与各个单程时间的差值 
                                                                                                  tof_dif_min:最大单程时间与各个单程时间的差值 tof_current: 本次计算得到的单程时间*/
        
    static u32 tof_down_last=0;//记录up和down的上次数值的单程时间
     
    if(0==tof_down_data[0])
    {      
        tof_current = tof_down_last;
        return tof_current;
    }
    
    for(i=0;i<len;i++)
    {        
        if(0==tof_down_data[i])
        {            
            break;//确定数据长度
        }
    }
    cnt = i;//记录有效数据个数
            
    if(1==cnt)
    {
        tof_current = tof_down_data[0];
        tof_down_last = tof_current; //存储上次的单程时间滤波值 
        return tof_current;  
    }
    
    
    tof_max = tof_down_data[0];
    tof_min = tof_down_data[0];  
    
    //找到最大 最小值   
    for(i=0;i<cnt;i++)
    {        
        if((tof_down_data[i]>=tof_max))
        {
           tof_max = tof_down_data[i];
        }        
        if((tof_down_data[i]<=tof_min))
        {
            tof_min = tof_down_data[i];
        }        
    }
    
    //判定
    for(i=0;i<cnt;i++)
    {
        tof_dif_max = tof_max - tof_down_data[i];  
        if(tof_dif_max <= TOF_MAX_DIF_FOR_HUADONG)//200ns 
        {
            max_count++; 
            sum_max += tof_down_data[i];
        }
        
        tof_dif_min = tof_down_data[i] - tof_min;  
        if(tof_dif_min <= TOF_MAX_DIF_FOR_HUADONG)
        {
            min_count++;
            sum_min +=tof_down_data[i];
        }
    }
            
    //比较最大、最小个数的大小 
    if(max_count==min_count)//
    {
        if((tof_max-tof_min) <= TOF_MAX_DIF_FOR_HUADONG)
		{
			tof_current =  sum_max / max_count;//计算本次单程时间滤波值 
		}
		else
		{
			tof_current =  tof_down_last; //存储上次的单程时间滤波值
		}        
    }
    else if(max_count>min_count)
    {
        len = max_count;
        sum = sum_max ;
        tof_current =  sum / len;//计算本次单程时间滤波值      
    }
    else
    {
       len = min_count;
       sum = sum_min;
       tof_current =  sum / len;//计算本次单程时间滤波值        
    }                       	
   
   //先判断合法性，再进行赋值
    if(tof_current!=0)
    {
        tof_down_last = tof_current; //存储上次的单程时间滤波值
    }
    else 
    {
        tof_current = tof_down_last;
    }             
    return  tof_current;      
}
/****************************************************************
Function:  单程时间滤波函数  
Description:*p 指向单程时间数组首地址 len 数据长度 flag 0:tof_up  1:tof_down  
函数性质： 内部函数
 *****************************************************************/
u32 Filter_FOR_TOFUP(u32 *tof_up, u32 *tof_down, u8 len)   //
{
	u8 i,max_count=0,min_count=0;//max_count:记录大数单程时间个数 min_count:记录小数单程时间个数
	u32 sum=0,sum_max=0,sum_min=0,tof_max=0,tof_min=0,tof_dif_max=0,tof_dif_min=0,tof_current=0;/*sum:单程时间累加和;sum_max：大数单程时间之间累加和 
                                                                                                  sum_min：大数单程时间之间累加和 tof_max:最大单程时间 
                                                                                                  tof_min:最小单程时间 tof_dif_max：最大单程时间与各个单程时间的差值 
                                                                                                  tof_dif_min:最大单程时间与各个单程时间的差值 tof_current: 本次计算得到的单程时间*/
    
    
    static u32 tof_up_last=0;//记录up和down的上次数值的单程时间
    u32 temp_max[MAX_TEMP_NUM]={0},temp_min[MAX_TEMP_NUM]={0};//统计
   
    tof_max = tof_up[0];
    tof_min = tof_up[0];    
    if(len==1)
    {
        tof_current = tof_up[0];
        tof_up_last = tof_current; //存储上次的单程时间滤波值 
        tof_down_data[0] = tof_down[0];//
        return tof_current;  
    }        
    //找到最大 最小值   
    for(i=0;i<len;i++)
    {        
        if((tof_up[i]>=tof_max))
        {
           tof_max = tof_up[i];
        }        
        if((tof_up[i]<=tof_min))
        {
            tof_min = tof_up[i];
        }        
    }
    
    //查看最大和最小值是否同为一个量级
    for(i=0;i<len;i++)
    {
        
        tof_dif_max = tof_max - tof_up[i];           
        if(tof_dif_max <= TOF_MAX_DIF_FOR_HUADONG)//200ns 
        {
            temp_max[max_count]= tof_down[i];
            max_count++; 
            sum_max += tof_up[i];            
        }
        
        tof_dif_min = tof_up[i] - tof_min;  
        if(tof_dif_min <= TOF_MAX_DIF_FOR_HUADONG)
        {
            temp_min[min_count]= tof_down[i];
            min_count++;
            sum_min +=tof_up[i];            
        }
    }         
    //比较最大、最小个数的大小 
    if(max_count==min_count)//
    {
        if(max_count == MAX_TEMP_NUM)
		{
			tof_current =  sum_max / max_count;//计算本次单程时间滤波值
			memcpy(tof_down_data,temp_max,MAX_TEMP_NUM*4);
		}
		else
		{
			tof_current =  tof_up_last; //存储上次的单程时间滤波值
			memset(tof_down_data,0,MAX_TEMP_NUM*4);  	
		}             
    }
    else if(max_count>min_count)
    {
        len = max_count;
        sum = sum_max ;
        tof_current =  sum / len;//计算本次单程时间滤波值 
        memcpy(tof_down_data,temp_max,MAX_TEMP_NUM*4);
    }
    else
    {
       len = min_count;
       sum = sum_min;
       tof_current =  sum / len;//计算本次单程时间滤波值
       memcpy(tof_down_data,temp_min,MAX_TEMP_NUM*4);        
    }                       	
   
   //先判断合法性，再进行赋值
    if(tof_current!=0)
    {
        tof_up_last = tof_current; //存储上次的单程时间滤波值
    }
    else 
    {
        tof_current = tof_up_last;
    }             
    return  tof_current;      
}
/***************************************************************
函数名称： Gp30_TOF_and_DOWN_Data_Collect(void)
功    能； 单程时间采集与处理函数  1、单程时间采集 2、单程时间滤波
函数性质： 外部接口函数
 ****************************************************************/
void Gp30_Tof_Collect_and_Deal()
{
	Tof_Calcuate_Average(s_g_fhl_tof_up_data,s_g_fhl_tof_down_data,5);//对单程时间进行滤波
	Gp30_Tof_Save();//存储滤波后的单程时间           
	gp30_tof_up_filter_value = Filter_FOR_TOFUP(gp30_tof_up_data,gp30_tof_down_data,gp30_tof_up_down_length);//
	gp30_tof_down_filter_value = Filter_FOR_TOFDOWN(tof_down_data,gp30_tof_up_down_length);//	
    AM_Calcuate_Average(s_g_up_am,s_g_down_am,6);//振幅均值计算
}

/*温度反算流程第二步：1、单程时间校准  2、校准后单程时间进行计算温度*/

/***************************************************************
函数名称： 单程时间校准函数
功    能；  time_dof_temp_float 用于计算流速  time_tof_up_float：Up单程时间 time_tof_up_float：Down单程时间
函数性质： 内部函数
 ****************************************************************/
void Water_Meter_Caliberate(u32 time_dof,float time_tof_up_float,float time_tof_down_float)
{
    float time_tof_up_xishu = 0,time_tof_down_xishu = 0;
    float temp_jiaozhun=0;//获取表计校准温度
    float sound_speed_C = 0;//声速
    float calculate_decimal ; //温度的小数部分
    float time_tof_up_float_jiaozhun_value =0;//校准的UP单程时间
    float time_tof_down_float_jiaozhun_value =0;//校准的DOWN单程时间
    u8 calculate_num=0;
    float time_dof_temp_float=0;
			
	if(tof_caliberate_state==TOF_BUCHANG_START_SAMPLE)//表计如果处于采样状态就进行
    {
        temp_jiaozhun  = Get_Temperature_Caliberate();//获取台子下发的温度值---待接收接口函数
        if((temp_jiaozhun < 0) || (temp_jiaozhun > 100))  //异常温度判断，防止数组越界
        {
            sound_speed_C = sound_speed_in_water[20];
        }
        else 
        {
            calculate_num = (u8) (temp_jiaozhun); //查表位置
            calculate_decimal = temp_jiaozhun - calculate_num; //温度的小数部分
            sound_speed_C = sound_speed_in_water[calculate_num] + calculate_decimal * (sound_speed_in_water[calculate_num + 1] - sound_speed_in_water[calculate_num]);
        }
        
		time_dof_temp_float = Gp30DataToFloat(time_dof);  //先把有效时间差转换成浮点数
        time_dof_temp_float = time_dof_temp_float * (float)250;// 将us转换成真实的ns， /4 *1000=ns
		
        float ins_flow_rate_float = sound_speed_C * sound_speed_C * time_dof_temp_float * LEGENTH_SPEED_SOUND_DAOSHU;//C^2*(t2-t1)/2L---求得理论流速  m/s
        
        time_tof_up_float_jiaozhun_value = LEGENTH_SPEED_SOUND / (sound_speed_C+ins_flow_rate_float); //计算出UP单程时间us
        time_tof_down_float_jiaozhun_value = LEGENTH_SPEED_SOUND / (sound_speed_C-ins_flow_rate_float); //计算出DOWN单程时间us
        
        time_tof_up_xishu = time_tof_up_float-time_tof_up_float_jiaozhun_value;//表计实际的Up单程时间与理论单程时间进行做差
        time_tof_down_xishu = time_tof_down_float-time_tof_down_float_jiaozhun_value;//表计实际的Down单程时间与理论单程时间进行做差
         //以后需要添加分别Up和Down的合法性判断！！！     
        //合法性判断
        if(((time_tof_down_xishu - time_tof_up_xishu)>(float)0.5)||((time_tof_down_xishu - time_tof_up_xishu)<(float)-0.5))
        {
            time_tof_up_xishu = 0;
            time_tof_down_xishu = 0;
        }
        gp22_app_data.s.up_tof_dif.gp30_float = time_tof_up_xishu;//读取EE中存储的UP单程时间系数
        gp22_app_data.s.down_tof_dif.gp30_float = time_tof_down_xishu;//读取EE中存储的DOWN单程时间系数
        
        //补偿值进行滑动滤波-----------------------
        gp30_tof_up_buchang_data[gp30_tof_buchang_head] =  gp22_app_data.s.up_tof_dif.gp30_float; //将单程时间存入到数组中
        gp30_tof_down_buchang_data[gp30_tof_buchang_head]= gp22_app_data.s.down_tof_dif.gp30_float; //将单程时间存入到数组中
        gp30_tof_buchang_head++;
        if(MAX_TOF_BUCHANG_NUM!=gp30_tof_buchang_head)//采样数组满了一次
        {
            if(gp30_tof_buchang_length != MAX_TOF_BUCHANG_NUM)//当BUF中数据已经存满一次了
            {
                 gp30_tof_buchang_length = gp30_tof_buchang_head;   
            }
        }
        else 
        {
           gp30_tof_buchang_length = MAX_TOF_BUCHANG_NUM; 
        }
        gp30_tof_buchang_head %= MAX_TOF_BUCHANG_NUM; 
        //-------------防护收不到下发温度系数的情况发生!!!!!!!
//        if(gp30_tof_buchang_length == MAX_TOF_BUCHANG_NUM)
//        {
//			FrameClearMsgApp(MsgCaliberate);//清零单程时间校准标志
//			GP30_tof_buchang_filter(NOT_ALLOW_CALIBREATE);
//        }
     }
}

/***************************************************************
函数名称： 反算温度
功    能； time_dof_temp_float 用于计算流速
函数性质： 外部接口函数
 ****************************************************************/
void  Water_Meter_Temp_calculate(u32 time_dof_temp_float)
{
    float time_tof_temp_float =0,temp_calculate_app=0,temp_buchang_chazhi=0,wendu=0;//time_tof_temp_float：up和Down 的单程时间倒数和变量
    float time_tof_up_float =0,time_tof_down_float =0;//实时的单程时间
    u32 heat_temp = 0;
	float heat_temp_xishu=0;//出口温度浮点数类型
	
    if((gp22_test_data.s.TOF_up==0)||(gp22_test_data.s.TOF_down==0))//单程时间为0----认为是空管状态
	{
		Temp_Inverse_Data.Temp_Inverse_Data.gp30_tof_up_filter_value_test = 0;//空管下UP单程时间清零
		Temp_Inverse_Data.Temp_Inverse_Data.gp30_tof_down_filter_value_test = 0;//空管下DOWN单程时间清零
		GP30_tof_buchang_filter(NOT_ALLOW_CALIBREATE);//这里可以有效预防NB上位机导致表计校准		
		return;
	}
    heat_temp = FrameCheckParaApp(FramePara_Tc0);//获取出口温度补偿系数
    if(heat_temp >= 0x80000000)//判定补偿系数的正负号
    {
        heat_temp &= 0x7FFFFFFF;
        heat_temp_xishu= 0- Gp30DataToFloat(heat_temp);
    }
    else
    {
        heat_temp_xishu = Gp30DataToFloat(heat_temp);
    }
    
    time_tof_up_float = Gp30DataToFloat(gp30_tof_up_filter_value)/(float)4; //UP单程时间---转化为us
    time_tof_down_float = Gp30DataToFloat(gp30_tof_down_filter_value)/(float)4;//Down单程时间---转化为us
    
    Water_Meter_Caliberate(time_dof_temp_float,time_tof_up_float,time_tof_down_float);//判断是否需要校准单程时间
    
    //1、单程时间修正-----
    time_tof_up_float = time_tof_up_float - gp22_app_data.s.up_tof_dif.gp30_float;
    time_tof_down_float = time_tof_down_float - gp22_app_data.s.down_tof_dif.gp30_float;
    
     Temp_Inverse_Data.Temp_Inverse_Data.gp30_tof_up_filter_value_test = FloatToGp30Data(time_tof_up_float)*(float)4;//活塞台子的单程时间---GP30格式
     Temp_Inverse_Data.Temp_Inverse_Data.gp30_tof_down_filter_value_test = FloatToGp30Data(time_tof_down_float)*(float)4;//活塞台子的单程时间---GP30格式
    
    time_tof_temp_float = (float)1/time_tof_up_float+(float)1/time_tof_down_float;//单程时间转换 1/up + 1/down
    
    
    #if ROUND_LLGS_WDFS_DN15_BRASS_40KPA_GP30_32768  || Buxiugang_LLGS_WDFS_DN15_BXG_40KPA_GP30_32768  || Plastic_LLGS_WDFS_DN15_PALSTIC_40KPA_GP30_32768      
    if(time_tof_temp_float <= TOF_UP_DOWN_DAOSHUHE_LOW)  //小于35度
    {
          temp_calculate_app = (float)1164325060.28*time_tof_temp_float*time_tof_temp_float*time_tof_temp_float-(float)117666513.36*time_tof_temp_float*time_tof_temp_float + (float)3974951.33*time_tof_temp_float-(float)44879.30;    
    }
    else if(time_tof_temp_float <= TOF_UP_DOWN_DAOSHUHE_MIDDLE)  //35到45度  
    {
        temp_calculate_app = (float)18099447.719*time_tof_temp_float*time_tof_temp_float - (float)1264215.524*time_tof_temp_float +(float)22102.772; 
    }
    else 
    {
        temp_calculate_app = (float)93075924.43*time_tof_temp_float*time_tof_temp_float -(float)6658976.07*time_tof_temp_float +(float)119144.49;       
    }
	
    #elif  ROUND_LLGS_WDFS_DN20_BRASS_40KPA_GP30_32768 || Buxiugang_LLGS_WDFS_DN20_BXG_40KPA_GP30_32768

    if(time_tof_temp_float <= TOF_UP_DOWN_DAOSHUHE_LOW)  //小于35度
    {
          temp_calculate_app = (float)1523999897.62*time_tof_temp_float*time_tof_temp_float*time_tof_temp_float-(float)147356593.93*time_tof_temp_float*time_tof_temp_float +(float) 4761092.78*time_tof_temp_float -(float)51396.5;//温度差值补偿   
    }
    else if(time_tof_temp_float <= TOF_UP_DOWN_DAOSHUHE_MIDDLE)  //35到45度
    {
          temp_calculate_app = (float)18709611.192*time_tof_temp_float*time_tof_temp_float -(float)1245577.831*time_tof_temp_float +(float)20757.105 ;  
    }
    else 
    {
         temp_calculate_app = (float)147329123.77*time_tof_temp_float*time_tof_temp_float -(float)10079793.85*time_tof_temp_float +(float)172450.97 ; 
    }
    #endif
    temp_calculate_app = temp_calculate_app - temp_buchang_chazhi + heat_temp_xishu;//默认状况下温度系数为0	

    //3、温度合法性判断
    temp_calculate_app = temp_calculate_app - wendu;//算出来温度---暂时不添加任何限制
    if((temp_calculate_app<0)||(temp_calculate_app>60))
    {
		temp_calculate_app = temp_calculate_last;//            
    }
	else
	{
		#if Buxiugang_LLGS_WDFS_DN15_BXG_40KPA_GP30_32768 || Buxiugang_LLGS_WDFS_DN20_BXG_40KPA_GP30_32768
			if(temp_calculate_app<(float)22.8)
			{
				temp_calculate_app=temp_calculate_app+((float)-0.05*temp_calculate_app+(float)1.54);  //不锈钢22.8 - 0度之间需要进行补偿
			}
			else
			{
				temp_calculate_app=temp_calculate_app+((float)-0.1296*temp_calculate_app+(float)3.3556);  //不锈钢22.8 - 60度之间需要进行补偿
			}
		#endif
	}
	temp_calculate_last = temp_calculate_app;
//    else //
//    {                   
//       temp_calculate_last = temp_calculate_app;//记录上次正常的温度数据-----从有水到无水时 用这个数据               
//    }
}


/*******************************************************************************
 * @fun_name:	TempInverseSetMsgApp
 * @brief   :   置起反算消息类型
 * 函数性质 :	外部接口函数
 ******************************************************************************/
void TempInverseSetMsgApp(TempInverse_MsgTypeDef msgType)
{
    if(msgType<TEMP_INVERSE_MSG_TYPE_CNT)
	{
	    temp_inverse_struct_msg.MsgBuf[msgType] = 1;
	}
}
/*******************************************************************************
 * @fun_name:	TempInverseCheckMsgApp
 * @brief   :   查询反算msg接口
 * @param[out]: msg     有消息1  无消息0
 ******************************************************************************/
u8 TempInverseCheckMsgApp(TempInverse_MsgTypeDef msgType)
{
	if(msgType < TEMP_INVERSE_MSG_TYPE_CNT)
	{
	    return temp_inverse_struct_msg.MsgBuf[msgType];
	}
    else
	{
	  return ERROR;
	}
}
/*******************************************************************************
 * @fun_name:  TempInverseClearMsgApp	
 * @brief   :   清除反算msg接口
 * @param[out]: 1成功 0失败
 ******************************************************************************/
u8 TempInverseClearMsgApp(TempInverse_MsgTypeDef msgType)
{
	if(msgType < TEMP_INVERSE_MSG_TYPE_CNT)
	{
        temp_inverse_struct_msg.MsgBuf[msgType] = 0;
		return SUCCESS;
	}
    else
	{
	  return ERROR;
	}
}
/****************************************************************
Function:  单程时间插值补偿系数滤波
Description:*p 指向单程时间补偿系数数组首地址 len 数据长度 ----用于进行单程时间补偿值的滤波
函数性质： 内部函数
 *****************************************************************/
float Filter_FOR_TOF_CHAZHI(float *p, u8 len)   //
{
	u8 i;
	float sum=0,tof_current=0,temp_max=p[0],temp_min=p[0];
    
        if(len>3)
        {
            for(i=0;i<len;i++)
            {         
                if((p[i]>=temp_max))
                {
                   temp_max = p[i];
                }        
                if((p[i]<=temp_min))
                {
                    temp_min = p[i];
                }
                sum += p[i];
            }
            tof_current = (sum-temp_min-temp_max) / (len-2);//计算本次单程时间差值滤波值 
        }
        else //用实时数据
        {
			tof_current = p[len-1];  
        }            
        return  tof_current;      
}

/****************************************
Function:  GP30_tof_buchang_filter 
Description: 开启和关闭单程时间校准补偿
Return:     0 启动单程时间差值校准     1：停止单程时间差值校准  2：空管状态下清零校准   3:反算温度滤波
Others:     外部接口函数
 ****************************************************************/
void GP30_tof_buchang_filter(u8 flag)
{
    u8 i=0;
	switch (flag)
	{
		case START_CALIBREATE:
		{
			gp30_tof_buchang_head = 0;//数值指针头结点
			gp30_tof_buchang_length = 0;//数据长度
			gp30_tof_up_chazhi_filter_value =0;//up滤波值
			gp30_tof_down_chazhi_filter_value =0;//down滤波值
			gp22_app_data.s.up_tof_dif.gp30_float = 0;//清零单程时间差值数据
			gp22_app_data.s.down_tof_dif.gp30_float = 0;//清零单程时间差值数据
			
			for(i=0;i<MAX_TOF_BUCHANG_NUM;i++)
			{
				gp30_tof_up_buchang_data[i] =  0; //
				gp30_tof_down_buchang_data[i]= 0; // 
			}
			tof_caliberate_state = TOF_BUCHANG_START_SAMPLE;//先进行清零单程时间补偿系数值			
			break;
		}
		case STOP_CALIBREATE:
		{
			if(tof_caliberate_state == TOF_BUCHANG_START_SAMPLE)//如果是采样状态下才刷新数据
			{                      
				tof_caliberate_state = TOF_BUCHANG_IDLE;
				TempInverseSetMsgApp(TofCaliberateMsg);
				if(0!=gp30_tof_buchang_length)
				{
					gp30_tof_up_chazhi_filter_value = Filter_FOR_TOF_CHAZHI(&gp30_tof_up_buchang_data[0],gp30_tof_buchang_length);
					gp30_tof_down_chazhi_filter_value = Filter_FOR_TOF_CHAZHI(&gp30_tof_down_buchang_data[0],gp30_tof_buchang_length);
					//计算完毕后需要进行差值补偿合法性判定 介于[-4,4]之间认为合格
					if(((gp30_tof_up_chazhi_filter_value)>TOF_COMPENSATION_COEFFICIENT)||((gp30_tof_down_chazhi_filter_value)>TOF_COMPENSATION_COEFFICIENT)|| \
					((gp30_tof_up_chazhi_filter_value)< -TOF_COMPENSATION_COEFFICIENT)||((gp30_tof_down_chazhi_filter_value)<-TOF_COMPENSATION_COEFFICIENT))
					{
						gp30_tof_up_chazhi_filter_value = 0;
						gp30_tof_down_chazhi_filter_value = 0;
					}                               
					gp22_app_data.s.up_tof_dif.gp30_float = gp30_tof_up_chazhi_filter_value;
					gp22_app_data.s.down_tof_dif.gp30_float = gp30_tof_down_chazhi_filter_value;
				} 
			}
			break;
		}
		case NOT_ALLOW_CALIBREATE:
		{			
			tof_caliberate_state = TOF_BUCHANG_IDLE;//空闲状态			
			gp22_app_data.s.up_tof_dif.gp30_float = g_sample_save_data.s.up_tof_dif.gp30_float;//
			gp22_app_data.s.down_tof_dif.gp30_float = g_sample_save_data.s.down_tof_dif.gp30_float;
			break;
		}
		default:
		{			
			break;
		}
	}		
}
/****************************************************************
Function:     GetTemperatureCalculateParameter
Description:  获取反算参数   包括up单程时间、down单程时间、up振幅均值、down振幅均值
函数性质：    外部接口函数
 *****************************************************************/
u32 GetTemperatureCalculateParameter(u8 flag)
{
    if(flag < TemperatureCalculateParameterTotal)
	{
		return Temp_Inverse_Data.Temp_Inverse[flag];
	}
	else
	{
		return ERROR;
	}	
}
/****************************************************************
Function:     void 
Description:  反算校准超时查询函数
函数性质：    外部接口函数
 *****************************************************************/
void FanSuan_Caliberate_Timeout(void)
{
	if(TRUE == FrameCheckMsgApp(MsgCaliberate))//单程时间校准标志查询
	{											
		if(0==RtccCheckTimer(RTCC_TOF_CALIBERATE_TIME))//90s校准超时时间到
		{
			FrameClearMsgApp(MsgCaliberate);//清零单程时间校准标志
			GP30_tof_buchang_filter(NOT_ALLOW_CALIBREATE);
		}					
	}								
}		 

#endif
