779 lines
30 KiB
C
779 lines
30 KiB
C
|
||
|
||
#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
|