ZNY_Pakistan/Anjiehui7_ZNY/User/adc_calculate.c

843 lines
22 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
*********************************************************************************************************
* IAR Development Kits
* on the
*
* Nano130
*
* Filename : adc_calculate.c
* Version : V1.00
* Programmer(s) : Qian Xianghong
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#include "includes.h"
// 介质介电常数
const float e_Src[] =
{
1.62, // LNG
1.48, // O2
1.44, // N2
1.52, // AR
1.60, // CO2
1.23, // H2介电常数暂未知
1.10, // CNG介电常数暂未知
1.41, // He介电常数暂未知
1.60, // C2H4介电常数暂未知
1.75, // LPG介电常数暂未知
2.5, // NH3介电常数暂未知
1.5, // PENT戊烷介电常数暂未知
1.5, // POPO聚醚多元醇介电常数暂未知
};
// 传感器规格参数
const Sensor_Model Adc_Sensor_Tables[1] =
{
// 真空电容常数, 非线性段长度, 底座厚度(忽略), 底部非线性段长度
// {0.0802607, 45, 0, 45}, // 圆管电容,k = 2π*e0 / ln(8 / 4), (e0 = 0.008854187817)
{0.0667859, 45, 0, 45}, // 圆管电容, 内管外部涂氟0.2mm
};
// 储罐理论参数
Bottle_Data Theoretical_Param;
// 余弦函数,只处理[0, PI/2]区间
#define my_cos(angle) cos(angle)
// 反余弦函数,只处理[0, 1]区间
#define my_acos(c) acos(c)
// 正弦函数,只处理[0, PI/2]区间
#define my_sin(angle) sin(angle)
// 反正弦函数,只处理[0, 1]区间
#define my_asin(c) asin(c)
// 计算椭球体容积
u32 Calculate_Ellipsoid_Space(u16 d)
{
float r = ((float) d) / 100 / 2; // 半径, 单位mm->dm
return (u32) (2 * PI * r * r * r / 3); // 单位L
}
// 计算圆柱体积
u32 Calculate_Cylinder_Space(u16 d, u16 L)
{
float r = (float) d / 200; // 转换成分米
float l = (float) L / 100;
return (u32)(PI * r * r * l); // 单位L
}
// 计算球体积
u32 Calculate_Spherical_Space(u16 d)
{
float r = (float) d / 200; // 转换成分米
return (u32)(4 * PI * r * r * r / 3); // 单位L
}
// 根据圆柱体内液位高度与半径之比计算体积比
float Calculate_Cylinder_Rate0(float hr)
{
float b;
float vr;
u8 reverse = 0;
if(hr > 1) // 超过中线,计算顶部容积,再用总容积来减
{
hr = 2 - hr;
reverse = 1;
}
b = my_acos(1 - hr);
vr = (b - my_cos(PI / 2 - b) * (1 - hr)) / PI;
if(!reverse)
{
return vr;
}
return 1 - vr;
}
// 根据圆柱体内液位高度计算体积比
float Calculate_Cylinder_Rate(u16 d, float h)
{
float hr = ((float) h) / d * 2; // 高度与半径之比
return Calculate_Cylinder_Rate0(hr);
}
// 根据椭球体内液位高度计算体积比
float Calculate_Ellipsoid_Rate(u16 d, float h)
{
float hr;
float vr;
u8 reverse = 0;
hr = ((float) h) / d * 2; // 高度与半径之比
if(hr > 1) // 超过中线,计算顶部容积,再用总容积来减
{
hr = 2 - hr;
reverse = 1;
}
vr = hr * hr * (3 - hr) / 4;
if(!reverse)
{
return vr;
}
return 1 - vr;
}
// 根据液位高度与直径,计算空间(无扣除)
// 卧罐
u32 Calculate_Space(u16 d, float h, u32 v)
{
u32 ve = Calculate_Ellipsoid_Space(d);
u32 vc = v - ve;
float re = Calculate_Ellipsoid_Rate(d, h);
float rc = Calculate_Cylinder_Rate(d, h);
return (u32) (ve * re + vc * rc);
}
// 根据液位高度与直径之比,计算剩余液量(有扣除)
// v0: 留底液量
// 卧罐
u32 Calculate_Volume(u16 d, float h, u32 v, u16 v0)
{
// 计算空间容积
u32 space = Calculate_Space(d, h, v);
// 留底
if(space < v0)
{
return 0;
}
return space - v0;
}
// 根据液位高度,计算空间(无扣除)
// 立罐
u32 Calculate_Space_Stand(u16 d, u16 L, float H)
{
float r = (float) d / 200; // 转为dm体积单位为L
float l = (float) L / 100;
float h = (float) H / 100;
if(h <= r / 2)
{
// 只有底下椭球部分
return 2 * PI * r * h * h - 4 * PI * h * h * h / 3;
}
if(h <= r / 2 + l)
{
// 底下椭球+圆柱部分
h -= r/2;
return PI * r * r * r / 3 + PI * r * r * h;
}
if(h <= r / 2 + l + r / 2)
{
// 上下椭球+中间圆柱部分
h -= r / 2 + l;
return PI * r * r * r / 3 + PI * r * r * l + PI * r * r * h - 4 * PI * h * h * h / 3;
}
// 高度超过有效范围
return 2 * PI * r * r * r / 3 + PI * r * r * l;
}
// 根据液位高度,计算剩余液量(有扣除)
// v0: 留底液量
// 立罐
u32 Calculate_Volume_Stand(u16 d, u16 L, float H, u16 v0)
{
// 计算空间容积
u32 space = Calculate_Space_Stand(d, L, H);
// 留底
if(space < v0)
{
return 0;
}
return space - v0;
}
// 根据液位高度,计算空间(无扣除)
// 球罐
u32 Calculate_Space_Spherical(u16 d, float H)
{
float r = (float) d / 200; // 转为dm体积单位为L
float h = (float) H / 100;
if(h <= r)
{
// 高度未超过一半
return PI * r * h * h - PI * h * h * h / 3;
}
if(h <= r + r)
{
// 高度超过一半
h = r + r - h;
return 4 * PI * r * r * r / 3 - PI * r * h * h + PI * h * h * h / 3;
}
// 高度超过有效范围
return 4 * PI * r * r * r / 3;
}
// 根据液位高度,计算剩余液量(有扣除)
// v0: 留底液量
// 球罐
u32 Calculate_Volume_Spherical(u16 d, float H, u16 v0)
{
// 计算空间容积
u32 space = Calculate_Space_Spherical(d, H);
// 留底
if(space < v0)
{
return 0;
}
return space - v0;
}
// 计算底部不可测部分高度
s16 Calculate_Base_Height(s16 d, s16 base_d, s16 base_len)
{
float r = ((float) d) / 2 ;
float base_r = ((float) base_d) / 2;
float b = my_asin(base_r / r);
b = my_cos(b);
return (s16) (r * (1 - b)) + base_len;
}
// 计算理论参数
u8 Calculate_Theoretical_Params()
{
u16 d = dcBuff.configBottle.diameter;
u16 L = dcBuff.configBottle.len + dcBuff.configBottle.lenExtra * 2;
u8 type = dcBuff.configBottle.type;
u8 vresv_percent = 0;// 留底百分比固定为0
u16 h0, h1, zero_h;
u16 zero_v, v0;
Theoretical_Param.LSrc_k = 1000 / 9.8 / Config_GetDensity(dcBuff.configBottle.source);
if(type == BOTTLE_TYPE_SPHERICAL)
Theoretical_Param.v = Calculate_Spherical_Space(d);
else
Theoretical_Param.v = Calculate_Ellipsoid_Space(d) + Calculate_Cylinder_Space(d, L);
// 计算底部不可测高度
Theoretical_Param.nl_len = Calculate_Base_Height(dcBuff.configBottle.diameter, Adc_Sensor_Tables[0].base_d, Adc_Sensor_Tables[0].base_len);
// 计算留底液量及高度, 最多留一半
if(vresv_percent == 0)
{
Theoretical_Param.zero_height = 0;
Theoretical_Param.v0 = 0;
}
else
{
h0 = 0;
if(type == BOTTLE_TYPE_STAND)
{
h1 = d / 4 + L / 2; // 立罐
}
else
{
h1 = d / 2; // 卧罐、球罐
}
v0 = (u16) (Theoretical_Param.v * (vresv_percent * 0.01)); // 目标留底液量
while(1)
{
zero_h = (h0 + h1) / 2;
if(type == BOTTLE_TYPE_LYING)
{
zero_v = Calculate_Volume(d, zero_h, Theoretical_Param.v, 0);
}
else if(type == BOTTLE_TYPE_STAND)
{
zero_v = Calculate_Volume_Stand(d, L, zero_h, 0);
}
else
{
zero_v = Calculate_Volume_Spherical(d, zero_h, 0);
}
if(zero_v == v0)
{
break;
}
else if(zero_v > v0)
{
if(zero_h == h0)
{
break;
}
h1 = zero_h - 1;
}
else
{
if(zero_h == h1)
{
break;
}
h0 = zero_h + 1;
}
}
Theoretical_Param.zero_height = zero_h;
Theoretical_Param.v0 = zero_v;
}
// 有效容积
Theoretical_Param.ve = Theoretical_Param.v * dcBuff.configBottle.chargePct / 100 - Theoretical_Param.v0;
return 1;
}
// 判断采集数据范围是否合法
// 输入:采集值、校零值、校满值
// 返回:传感器状态字节
u8 ADC_Validate(u32 adc, u32 zero, u32 full)
{
u32 temp;
// 如果是降序交换最小最大ADC值
if(zero > full)
{
temp = zero;
zero = full;
full = temp;
}
// 低于校准点的1/3或低于量程范围的1/3未连接
if(adc < zero / 3 || adc + (full - zero) / 3 < zero)
return SENSOR_STATUS_NOCONNECT;
// 低于校准点的1/2或低于量程范围的1/4下溢出
if(adc < zero / 2 || adc + (full - zero) / 4 < zero)
return SENSOR_STATUS_UNDERFLOW;
// 高于量程范围的1/4上溢出
if(adc > full + (full - zero) / 4)
return SENSOR_STATUS_OVERFLOW;
return SENSOR_STATUS_NORMAL;
}
// 计算采集数据
// 输入adc校准值量程
// 输出:经计算得到的值
float ADC_Calculate(u32 adc, u32 zero, u32 full, s32 low, s32 high)
{
if(zero > full)
{
if(adc <= full)
return high; // 量程最大值
if(adc >= zero)
return low; // 量程最小值
return low + ((float) (zero - adc)) / (zero - full) * (high - low);
}
if(adc <= zero)
return low; // 量程最小值
if(adc >= full)
return high; // 量程最大值
return low + ((float) (adc - zero)) / (full - zero) * (high - low);
}
// 冒泡排序,用于数量较少的排序法
void sort(u32 numbs[], s8 cnt)
{
s8 i, j, k;
u32 temp;
for(i = 0; i < cnt - 1; i++)
{
// 查找最小值
k = i;
temp = numbs[k];
for(j = i + 1; j < cnt; j++)
{
if(numbs[j] < temp)
{
k = j;
temp = numbs[k];
}
}
// 交换
if(k != i)
{
numbs[k] = numbs[i];
numbs[i] = temp;
}
}
}
// KPa转换成mmH2O
float KPa2mmH2O(float KPa)
{
return KPa * 101.9716213;
}
// 差压转换为液位高度
float Diff2Level(float dp) // 单位KPa、mm
{
float h = Theoretical_Param.LSrc_k * dp;
u16 max_h;
// 不能超过罐子高度
if(dcBuff.configBottle.type == BOTTLE_TYPE_STAND)
{
// 立罐最大高度
max_h = dcBuff.configBottle.len + dcBuff.configBottle.lenExtra * 2 + dcBuff.configBottle.diameter / 2;
if(h > max_h)
h = max_h;
}
else
{
// 卧罐、球罐最大高度
if(h > dcBuff.configBottle.diameter)
h = dcBuff.configBottle.diameter;
}
return h;
}
// 高度转换为体积
u32 Level2Vol(float h) // 单位mm、L
{
u32 v;
if(dcBuff.configBottle.type == BOTTLE_TYPE_LYING)
{
// 卧罐
v = Calculate_Volume(dcBuff.configBottle.diameter, h, Theoretical_Param.v, Theoretical_Param.v0);
}
else if(dcBuff.configBottle.type == BOTTLE_TYPE_STAND)
{
// 立罐
v = Calculate_Volume_Stand(dcBuff.configBottle.diameter, dcBuff.configBottle.len + dcBuff.configBottle.lenExtra * 2, h, Theoretical_Param.v0);
}
else
{
// 球罐
v = Calculate_Volume_Spherical(dcBuff.configBottle.diameter, h, Theoretical_Param.v0);
}
if(v > Theoretical_Param.ve)
v = Theoretical_Param.ve;
return v;
}
// 体积转换为质量
u32 Vol2Quantity(float v) // 单位L、kg
{
return Config_GetDensity(dcBuff.configBottle.source) * v;
}
// 质量转换为体积
u32 Quantity2Vol(float quantity) // 单位kg、L
{
u32 v = quantity / Config_GetDensity(dcBuff.configBottle.source);
if(v > Theoretical_Param.ve)
v = Theoretical_Param.ve;
return v;
}
// ***********************************************
// 电容计算
// ***********************************************
// 将ADC转化为电容值
float adc_k_convert(s16 adc, s16 c1ADC, s16 c2ADC, s16 c1, s16 c2)
{
float k, b;
float val;
if(adc == -1)
return -1;
if(c2ADC <= c1ADC)
return 0;
k = (float) (c2 - c1) / (c2ADC - c1ADC);
b = (float) (c1 * c2ADC - c2 * c1ADC) / (c2ADC - c1ADC);
val = k * adc + b;
if(val < 0)
return 0;
return val;
}
// 根据电容自计算液位高度
float Cap_Calculate(float cap, s16 base, s16 ref)
{
u16 L;
float h;
// 计算传感器长度=罐子高度
if(dcBuff.configBottle.type == BOTTLE_TYPE_STAND)
{
// 立罐高度
L = dcBuff.configBottle.len + dcBuff.configBottle.lenExtra * 2 + dcBuff.configBottle.diameter / 2;
}
else
{
// 卧罐、球罐高度
L = dcBuff.configBottle.diameter;
}
// 计算传感器可测部分的有效长度
L -= Adc_Sensor_Tables[0].nl_len;
// 将电容转换成液位高度(可测部分)
h = (cap - base) / ref * L;
if(h <= 0)
return 0;
if(h > L)
h = L;
// 高度加上底部不可测部分
return h + Theoretical_Param.nl_len;
}
// PT100铂电阻温度阻值表
const float PT100_Resis[281] =
{
18.52, // -200℃
18.95, 19.38, 19.82, 20.25, 20.68, 21.11, 21.54, 21.97, 22.40, 22.83, // -190℃
23.25, 23.68, 24.11, 24.54, 24.97, 25.39, 25.82, 26.24, 26.67, 27.10, // -180℃
27.52, 27.95, 28.37, 28.80, 29.22, 29.64, 30.07, 30.49, 30.91, 31.34, // -170℃
31.76, 32.18, 32.60, 33.02, 33.44, 33.86, 34.28, 34.70, 35.12, 35.54, // -160℃
35.96, 36.38, 36.80, 37.22, 37.64, 38.05, 38.47, 38.89, 39.31, 39.72, // -150℃
40.14, 40.56, 40.97, 41.39, 41.80, 42.22, 42.63, 43.05, 43.46, 43.88, // -140℃
44.29, 44.70, 45.12, 45.53, 45.94, 46.36, 46.77, 47.18, 47.59, 48.00, // -130℃
48.42, 48.83, 49.24, 49.65, 50.06, 50.47, 50.88, 51.29, 51.77, 52.11, // -120℃
52.50, 52.93, 53.34, 53.75, 54.15, 54.56, 54.97, 55.38, 55.79, 56.19, // -110℃
56.60, 57.01, 57.41, 57.82, 58.23, 58.63, 59.04, 59.41, 59.85, 60.25, // -100℃
60.66, 61.07, 61.47, 61.88, 62.28, 62.68, 63.09, 63.49, 63.90, 64.30, // -90℃
64.70, 65.11, 65.51, 65.91, 66.31, 66.72, 67.12, 67.52, 67.92, 68.33, // -80℃
68.73, 69.13, 69.53, 69.93, 70.33, 70.73, 71.13, 91.53, 71.93, 72.33, // -70℃
72.73, 73.13, 73.53, 73.93, 74.33, 74.73, 75.13, 75.53, 75.93, 76.33, // -60℃
76.73, 77.12, 77.52, 77.92, 78.32, 78.72, 79.11, 79.51, 79.91, 80.31, // -50℃
80.70, 81.10, 81.50, 81.89, 82.29, 82.69, 83.08, 83.48, 83.87, 84.27, // -40℃
84.67, 85.06, 85.46, 85.85, 86.25, 86.64, 87.04, 87.43, 87.83, 88.22, // -30℃
88.62, 89.01, 89.40, 89.80, 90.19, 90.59, 90.98, 91.37, 91.77, 92.16, // -20℃
92.55, 92.95, 93.34, 93.73, 94.12, 94.52, 94.91, 95.30, 95.69, 96.09, // -10℃
96.48, 96.87, 97.26, 97.65, 98.04, 98.44, 98.83, 99.22, 99.61, 100.00, // 0℃
100.39, 100.78, 101.17, 101.56, 101.95, 102.34, 102.73, 103.12, 103.51, // 9℃
103.90, 104.29, 104.68, 105.07, 105.46, 105.85, 106.24, 106.63, 107.02, 107.40, // 19℃
107.79, 108.18, 108.57, 108.96, 109.35, 109.73, 110.12, 110.51, 110.90, 111.01, // 29 ℃
111.67, 112.06, 112.45, 112.83, 113.22, 113.61, 114.00, 114.38, 114.77, 115.15, // 39℃
115.54, 115.93, 116.31, 116.70, 117.08, 117.47, 117.86, 118.24, 118.63, 119.01, // 49℃
119.40, 119.78, 120.07, 120.55, 120.94, 121.32, 121.71, 122.09, 122.47, 122.86, // 59℃
123.24, 123.63, 124.01, 124.39, 124.78, 125.16, 125.54, 125.93, 126.31, 126.69, // 69℃
127.08, 127.46, 127.84, 128.22, 128.61, 128.99, 129.37, 129.75, 130.13, 130.52, // 79℃
130.90 // 80℃
};
// 查表计算:电阻-》温度
float PT100_Resit2Tempr(float r)
{
s16 count = sizeof(PT100_Resis) / sizeof(float);
s16 i;
if(r <= PT100_Resis[0] * dcBuff.configDisplay.op_PT100_MULTI)
return -200;
if(r >= PT100_Resis[count - 1] * dcBuff.configDisplay.op_PT100_MULTI)
return (count - 1) - 200;
for(i = count - 2; i >= 0; i--)
{
if(r >= PT100_Resis[i] * dcBuff.configDisplay.op_PT100_MULTI)
return (i - 200) + (r - PT100_Resis[i] * dcBuff.configDisplay.op_PT100_MULTI) / (PT100_Resis[i + 1] * dcBuff.configDisplay.op_PT100_MULTI - PT100_Resis[i] * dcBuff.configDisplay.op_PT100_MULTI);
}
}
// 查表计算:温度-》电阻
float PT100_Tempr2Resit(float t)
{
s16 count = sizeof(PT100_Resis) / sizeof(float);
s16 idx = floor(t) + 200;
if(t <= -200)
return PT100_Resis[0] * dcBuff.configDisplay.op_PT100_MULTI;
if(t >= (count - 1) - 200)
return PT100_Resis[count - 1] * dcBuff.configDisplay.op_PT100_MULTI;
return PT100_Resis[idx] * dcBuff.configDisplay.op_PT100_MULTI + (t - (idx - 200)) * (PT100_Resis[idx + 1] * dcBuff.configDisplay.op_PT100_MULTI - PT100_Resis[idx] * dcBuff.configDisplay.op_PT100_MULTI);
}
// 差分测量原理:
//
// V=3v
// |
// | |----R--V1--r--Rx---|
// |-----| |---r--R0-----
// |----R--V2--r-------| |
// GND
//
// 说明I1 = (V - V1) / R, I2 = (V - V2) / R, I = I1 + I2
// I1 * (r + Rx) + I * (r + R0) = V1
// I2 * (r) + I * (r + R0) = V2
// (根据电流降压原理)
// 根据所测电压Vx计算待测电阻Rx
float RDiff_Volt2Resit(double V1, double V2)
{
double V = 3, R = 1000, R0 = 0;
double I1, I2, I, FM, Rx, r;
if(V - V1 >= -0.025 && V - V1 <= 0.025)
return 0;
if(V1 >= -0.025 && V1 <= 0.025) // 短路,返回一个大电阻
return 200 * dcBuff.configDisplay.op_PT100_MULTI;
I1 = (V - V1) / R;
I2 = (V - V2) / R;
I = I1 + I2;
r = (V2 - I * R0) / (I2 + I);
#if 1
FM = I1 * (I + I2);
Rx = ((V1 - I * R0) * (I + I2) - (V2 - I * R0) * (I + I1)) / FM;
#else
Rx = (V1 - V2) * R / (V - V1);
if(r > 0)
Rx += (V1 - V2) * r / (V - V1);
#endif
// printf("\nV1 = %f, V2 = %f, Rx = %f, r = %f\n", V1, V2, Rx, r);
return Rx;
}
// 电桥测量原理:
//
// V=5v
// |
// |------------| 5V
// | | |
// R=5000Ω R=5000Ω |\|
// | | | \
// |--------------------------- + --| \ 12位AD(Vref=3v
// | | | a |------------------- Vx2.863~0.572v------------------>(3909~781)
// | |-------------- - --| /
// | | | /|
// | r0=4500Ω |/||
// | | ||
// r=5000Ω Rx(105.295~675.68Ω) GND Vb=1.25v, a=15.7
// | |
// |------------|
// |
// GND
//
// r r0 + Rx
// Vx = (--------- - ----------------) * V * a + Vb
// r + R r0 + Rx + R
//
// 据此可倒推出Rx与Vx的关系
// 根据所测电压Vx计算待测电阻Rx
float RBridge_Volt2Resit(float Vx)
{
float a = 15.7; // 放大倍数
float R = 1000 * dcBuff.configDisplay.op_PT100_MULTI; // 分压电阻
float r = 1000 * dcBuff.configDisplay.op_PT100_MULTI; // 固定电阻
float r0 = 900 * dcBuff.configDisplay.op_PT100_MULTI; // 串联电阻
float V = 5; // 电桥电压
float Vb = 1.25; // 基准电压
// 中间值
float b = r / (r + R) - (Vx - Vb) / V / a;
return b * R / (1 - b) - r0;
}
int16_t PT100_CalTempr(s32 adc1, s32 adc2, s16 cTx10, s16 cRx10)
{
float calibrateT, calibrateR, calibrateR100, calibrateRLine;
double V1, V2;
float Rx, Vx;
float deltaR, r100, t, RLine, r;
if(!dcBuff.configDisplay.op_PT100_3LINE)
{
// 参数:校准温度
calibrateT = (float) cTx10 / 10;
// 参数:校准温度下的总电阻
calibrateR = (float) cRx10 / 10;
// 参数在校准温度下的PT100电阻
calibrateR100 = PT100_Tempr2Resit(calibrateT);
// 参数:在校准温度下的线电阻
calibrateRLine = (calibrateR <= calibrateR100 ? 0 : calibrateR - calibrateR100);
if(dcBuff.configDisplay.op_DIFF_RESIST)
{
// 将adc值转换为电压VREF为3V
V1 = (double) adc1 / 4096 * 3.0;
V2 = (double) adc2 / 4096 * 3.0;
// 将电压值转换成实测电阻值
Rx = RDiff_Volt2Resit(V1, V2);
}
else
{
// 将adc值转换为电压VREF为3V
Vx = (float) adc1 / 4096 * 3.0;
// 将电压值转换成实测电阻值
Rx = RBridge_Volt2Resit(Vx);
}
// 计算总的电阻变化
deltaR = Rx - calibrateR;
// 粗略计算将电阻变化假设全部为PT100引起的忽略导线在不同温度下的电阻变化
r100 = calibrateR100 + deltaR;
// 粗略计算PT100的温度
t = PT100_Resit2Tempr(r100);
// 计算在粗略温度下的线电阻变化(粗略温度和实际温度之间差距不大,线电阻本身也较小,故忽略)
// 温度每下降1℃电阻下降1.3‰
RLine = calibrateRLine * (1 - (calibrateT - t) * 0.0013);
// 用实测电阻减去修正过后的线电阻
r = Rx - RLine;
// 返回修正过后的温度
return PT100_Resit2Tempr(r);
}
// 3线制
if(dcBuff.configDisplay.op_DIFF_RESIST)
{
// 将adc值转换为电压VREF为3V
V1 = (double) adc1 / 4096 * 3.0;
V2 = (double) adc2 / 4096 * 3.0;
// 将电压值转换成实测电阻值
Rx = RDiff_Volt2Resit(V1, V2);
// 参数:校准温度
calibrateT = (float) cTx10 / 10;
// 参数:校准温度下的总电阻
calibrateR = (float) cRx10 / 10;
// 参数在校准温度下的PT100电阻
calibrateR100 = PT100_Tempr2Resit(calibrateT);
Rx += (calibrateR100 - calibrateR);
}
else
{
// 将adc值转换为电压VREF为3V
Vx = (float) adc1 / 4096 * 3.0;
// 将电压值转换成实测电阻值
Rx = RBridge_Volt2Resit(Vx);
}
// 返回对应的温度
return PT100_Resit2Tempr(Rx);
}
// 计算实测电阻
float PT100_CalResit(s32 adc1, s32 adc2)
{
if(dcBuff.configDisplay.op_DIFF_RESIST)
return RDiff_Volt2Resit((double) adc1 / 4096 * 3, (double) adc2 / 4096 * 3) ;
return RBridge_Volt2Resit((float) adc1 / 4096 * 3.0) ;
}
// 根据标定值计算最小、最大量程的测量值
void PT100_Calculate_Theoretical_Params(int16_t lowRange, int16_t highRange)
{
float a = 15.7; // 放大倍数
float R = 1000 * dcBuff.configDisplay.op_PT100_MULTI; // 分压电阻
float r = 1000 * dcBuff.configDisplay.op_PT100_MULTI; // 固定电阻
float r0 = 900 * dcBuff.configDisplay.op_PT100_MULTI; // 串联电阻
float V = 5; // 电桥电压
float Vb = 1.25; // 基准电压
// 中间值
float b = r / (r + R) * V;
// 参数:校准温度
float calibrateT = (float) dcBuff.configSensor.sensorPTempr[0].calibrateT / 10;
// 参数:校准温度下的总电阻
float calibrateR = (float) dcBuff.configSensor.sensorPTempr[0].calibrateR / 10;
// 参数在校准温度下的PT100电阻
float calibrateR100 = PT100_Tempr2Resit(calibrateT);
// 参数:在校准温度下的线电阻
float calibrateRLine = (calibrateR <= calibrateR100 ? 0 : calibrateR - calibrateR100);
// 计算在最低温度(-200℃下的线电阻
float RLine = calibrateRLine * (1 - (calibrateT - lowRange) * 0.0013);
float r100 = PT100_Tempr2Resit(lowRange);
float Rx = RLine + r100;
float Vx = (b - (r0 + Rx) / (r0 + Rx + R) * V) * a + Vb;
dcBuff.configSensor.sensorPTempr[0].zeroValue = Vx / 3 * 4096;
// printf("\ncalibrateT: %.1f, calibrateR: %.2f, calibrateR100: %.2f, calibrateRLine: %.2f\n", calibrateT, calibrateR, calibrateR100, calibrateRLine);
// printf("\nLow-RLine: %.2f, r100: %.2f, RX: %.2f, Vx: %.3f\n", RLine, r100, Rx, Vx);
// printf("\ndcBuff.configSensor.sensorPTempr[0].zeroValue = %d\n", dcBuff.configSensor.sensorPTempr[0].zeroValue);
// 计算在最高温度80℃下的线电阻
RLine = calibrateRLine * (1 - (calibrateT - highRange) * 0.0013);
r100 = PT100_Tempr2Resit(highRange);
Rx = RLine + r100;
Vx = (b - (r0 + Rx) / (r0 + Rx + R) * V) * a + Vb;
dcBuff.configSensor.sensorPTempr[0].fullValue = Vx / 3 * 4096;
// printf("\nHigh-RLine: %.2f, r100: %.2f, RX: %.2f, Vx: %.3f\n", RLine, r100, Rx, Vx);
// printf("\ndcBuff.configSensor.sensorPTempr[0].fullValue = %d\n", dcBuff.configSensor.sensorPTempr[0].fullValue);
}