#define TC_K 40.0 //температурный коэффициент для CJ, мкВ/°C
#define T_RES 0.25 //дискретность представления температуры CJ, °C (DS18B20)
#define TC_V_MIN -3 //минимальное напряжение с термопары, мВ
#define TC_V_MAX 54 //максимальное напряжение с термопары, мВ
#define TC_POINTS (TC_V_MAX - TC_V_MIN + 1) //количество точек таблицы
//Таблица линеаризации термопары K-типа. В таблице даны значения
//температуры в десятых долях градуса в зависимости от напряжения.
//Диапазон температур -82.4...+1346.0°C.
//Шаг напряжения - 1 мВ, диапазон -3..+54 мВ
const int __flash Lin[TC_POINTS] =
{
-824, -531, -259, //-3..-1 мВ
0, 250, 495, 736, 976, 1220, 1466, 1715, 1965, 2215, // 0.. 9 мВ
2462, 2707, 2950, 3190, 3430, 3668, 3906, 4143, 4378, 4614, //10..19 мВ
4849, 5083, 5318, 5553, 5787, 6022, 6258, 6494, 6731, 6969, //20..29 мВ
7208, 7449, 7690, 7933, 8177, 8423, 8670, 8919, 9169, 9421, //30..39 мВ
9674, 9929, 10186, 10445, 10706, 10969, 11234, 11501, 11772, //40..48 мВ
12045, 12321, 12600, 12883, 13169, 13460 //49..54 мВ
};
int Convert(int adc_code, int tcj)
{
//вычисляем напряжения термопары в десятках мкВ:
int Vtc = Code2uV(adc_code); //функция зависит от шкалы АЦП
//вычисляем эквивалентного напряжения холодного спая:
//делаем приближение, что в диапазоне рабочих температур
//холодного спая коэффициент термопары постоянен
//tcj имеет дискретность T_RES°C
//TC_K имеет размерность мкВ/°C
//Vcj представлено в десятках мкВ
int Vcj = tcj * (int)TC_K / (int)(10 / T_RES);
//вычисляем напряжение термопары с компенсацией холодного спая:
int Vhj = Vtc + Vcj;
//находим целое число милливольт:
signed char Index = Vhj / 100;
//преобразуем его в индекс таблицы:
Index = Index - TC_V_MIN;
//проверяем выход за диапазон вниз:
if(Index < 1) return(Lin[0] / 10);
//проверяем выход за диапазон вверх:
if(Index > TC_POINTS - 2) return(Lin[TC_POINTS - 1] / 10);
//читаем первую точку таблицы:
//температура представлена в десятых градуса
int p1 = Lin[Index];
//читаем вторую точку таблицы:
if(Vhj < 0) Index--; else Index++;
int p2 = Lin[Index];
//вычисляем дельту на интервале 1 мВ:
int DeltaT = p2 - p1;
if(Vhj < 0) DeltaT = -DeltaT;
//вычисляем дробную часть милливольт:
int DeltaV = Vhj % 100;
//линейная интерполяция по отрезку 1 мВ:
p1 = p1 + DeltaV * DeltaT / 100;
//подготовка к округлению:
if(Vhj < 0) p1 -= 5; else p1 += 5;
//возвращаем температуру в градусах:
return(p1 / 10);
}