diff --git a/ADC_Temp.c b/ADC_Temp.c index 461a25b..3961b53 100644 --- a/ADC_Temp.c +++ b/ADC_Temp.c @@ -1,14 +1,49 @@ // // Created by cfif on 02.12.2025. // -#include "stdint.h" #include "ADC_Temp.h" #include +#include +#include -adc_temp_lookup fast_lookup[TABLE_SIZE_LOOKUP]; // Таблица на TABLE_SIZE_LOOKUP значений +// Структура для хранения табличных данных +typedef struct { + int temp_c; // Температура (°C) + float r_nom; // Номинальное сопротивление (Ω) +} ntc_table_entry; -// Таблица из документа InCar -static const ntc_table_entry ntc_table[] = { +// Таблица из документа KST45 +static const ntc_table_entry ntc_table_kst45[] = { + {-40, 100950.0f}, + {-35, 72777.0f}, + {-30, 53100.0f}, + {-25, 39111.0f}, + {-20, 29121.0f}, + {-15, 21879.0f}, + {-10, 16599.0f}, + {-5, 12695.0f}, + {0, 9795.0f}, + {5, 7616.0f}, + {10, 5970.0f}, + {15, 4712.0f}, + {20, 3747.0f}, + {25, 3000.0f}, + {30, 2417.0f}, + {35, 1959.0f}, + {40, 1598.0f}, + {45, 1311.0f}, + {50, 1081.0f}, + {55, 895.9f}, + {60, 746.4f}, + {65, 624.9f}, + {70, 525.6f}, + {75, 444.4f}, + {80, 377.4f}, + {85, 321.7f} +}; + +// Таблица из документа Incar +static const ntc_table_entry ntc_table_incar[] = { {-40, 101000.0f}, {-35, 72600.0f}, {-30, 52720.0f}, @@ -16,12 +51,12 @@ static const ntc_table_entry ntc_table[] = { {-20, 28620.0f}, {-15, 21390.0f}, {-10, 16120.0f}, - {-5, 12260.0f}, + {-5, 12260.0f}, {-4, 11620.0f}, {-3, 11010.0f}, {-2, 10440.0f}, {-1, 9907.0f}, - {0, 9399.0f}, + {0, 9399.0f}, {1, 8924.0f}, {2, 8473.0f}, {3, 8048.0f}, @@ -31,7 +66,7 @@ static const ntc_table_entry ntc_table[] = { {7, 6570.0f}, {8, 6250.0f}, {9, 5947.0f}, - {10, 5661.0f}, + {10, 5661.0f}, {15, 4441.0f}, {20, 3512.0f}, {25, 2795.0f}, @@ -49,40 +84,104 @@ static const ntc_table_entry ntc_table[] = { {85, 283.0f} }; +// Глобальная структура для хранения таблиц быстрого доступа +fast_lookup_tables_t g_fast_tables = { + .kst45_initialized = false, + .incar_initialized = false, + .kst45_r1 = 3300.0f, + .incar_r1 = 3300.0f +}; + +// Активная конфигурация +static ntc_config_t active_config = { + .table_type = TABLE_KST45, + .r1 = 3300.0f, + .start_temp = -40, + .end_temp = 85, + .table_size = TABLE_SIZE_KST45 +}; + +// Вспомогательная функция для получения таблицы по типу +static const ntc_table_entry* get_table_by_type(eNtcTable table_type, uint16_t* size, int16_t* start_temp, int16_t* end_temp) { + const ntc_table_entry* table = NULL; + *size = 0; + + switch(table_type) { + case TABLE_KST45: + table = ntc_table_kst45; + *size = TABLE_SIZE_KST45; + *start_temp = -40; + *end_temp = 85; + break; + case TABLE_INCAR: + table = ntc_table_incar; + *size = TABLE_SIZE_INCAR; + *start_temp = -40; + *end_temp = 85; + break; + default: + table = ntc_table_kst45; + *size = TABLE_SIZE_KST45; + *start_temp = -40; + *end_temp = 85; + break; + } + return table; +} + +// Функция для получения указателя на таблицу быстрого доступа по типу +static adc_temp_lookup* get_fast_table_by_type(eNtcTable table_type) { + switch(table_type) { + case TABLE_KST45: + return g_fast_tables.kst45; + case TABLE_INCAR: + return g_fast_tables.incar; + default: + return g_fast_tables.kst45; + } +} + +// Функция для получения статуса инициализации таблицы +static bool is_table_initialized(eNtcTable table_type) { + switch(table_type) { + case TABLE_KST45: + return g_fast_tables.kst45_initialized; + case TABLE_INCAR: + return g_fast_tables.incar_initialized; + default: + return false; + } +} + // Функция расчёта сопротивления NTC из значения АЦП -static float calculate_resistance(uint16_t adc_value) { +static float calculate_resistance(uint16_t adc_value, float r1) { if (adc_value == 0 || adc_value >= (uint16_t) ADC_MAX) { return 0.0f; } - // Формула делителя напряжения: R_ntc = R1 * (ADC_MAX / adc_value - 1) - // float R_ntc = R1 * (ADC_MAX / (float)adc_value - 1.0f); - - float R_ntc = R1 * (float) adc_value / (ADC_MAX - (float) adc_value); - + float R_ntc = r1 * (float) adc_value / (ADC_MAX - (float) adc_value); return R_ntc; } - // Бинарный поиск в таблице -static int find_interval_index(float resistance) { +static int find_interval_index(float resistance, const ntc_table_entry* table, uint16_t table_size) { int left = 0; - int right = TABLE_SIZE - 1; + int right = table_size - 1; // Проверка границ - if (resistance >= ntc_table[0].r_nom) return 0; - if (resistance <= ntc_table[right].r_nom) return right - 1; + if (resistance >= table[0].r_nom) return 0; + if (resistance <= table[right].r_nom) return right - 1; // Бинарный поиск while (left <= right) { int mid = left + (right - left) / 2; - if (mid < TABLE_SIZE - 1 && - resistance <= ntc_table[mid].r_nom && - resistance >= ntc_table[mid + 1].r_nom) { + if (mid < table_size - 1 && + resistance <= table[mid].r_nom && + resistance >= table[mid + 1].r_nom) { return mid; } - if (resistance > ntc_table[mid].r_nom) { + if (resistance > table[mid].r_nom) { right = mid - 1; } else { left = mid + 1; @@ -93,12 +192,12 @@ static int find_interval_index(float resistance) { } // Интерполяция с использованием уравнения Стейнхарта-Харта между точками -static float interpolate_steinhart(float resistance, int index) { +static float interpolate_steinhart(float resistance, int index, const ntc_table_entry* table) { // Берем две соседние точки из таблицы - float t1 = (float) ntc_table[index].temp_c + 273.15f; // в Кельвинах - float t2 = (float) ntc_table[index + 1].temp_c + 273.15f; - float r1 = ntc_table[index].r_nom; - float r2 = ntc_table[index + 1].r_nom; + float t1 = (float) table[index].temp_c + 273.15f; // в Кельвинах + float t2 = (float) table[index + 1].temp_c + 273.15f; + float r1 = table[index].r_nom; + float r2 = table[index + 1].r_nom; // Вычисляем коэффициент B для интервала float B = logf(r1 / r2) / (1.0f / t1 - 1.0f / t2); @@ -111,11 +210,11 @@ static float interpolate_steinhart(float resistance, int index) { } // Линейная интерполяция в логарифмическом масштабе -static float interpolate_log_linear(float resistance, int index) { - float t1 = (float) ntc_table[index].temp_c; - float t2 = (float) ntc_table[index + 1].temp_c; - float r1 = ntc_table[index].r_nom; - float r2 = ntc_table[index + 1].r_nom; +static float interpolate_log_linear(float resistance, int index, const ntc_table_entry* table) { + float t1 = (float) table[index].temp_c; + float t2 = (float) table[index + 1].temp_c; + float r1 = table[index].r_nom; + float r2 = table[index + 1].r_nom; float log_r1 = logf(r1); float log_r2 = logf(r2); @@ -125,7 +224,7 @@ static float interpolate_log_linear(float resistance, int index) { } // Более надежная версия с проверкой параметров -static float interpolate_steinhart_full(float resistance, int index) { +static float interpolate_steinhart_full(float resistance, int index, const ntc_table_entry* table) { // Проверка корректности входных данных if (resistance <= 0.0f) { return -273.15f; // Абсолютный ноль при некорректном сопротивлении @@ -143,7 +242,7 @@ static float interpolate_steinhart_full(float resistance, int index) { // Проверка на физическую реализуемость (температура должна быть положительной в Кельвинах) if (inv_T <= 0.0f || inv_T > 1.0f) { // 1/T не может быть <= 0 (T < 0K) или слишком большим // В случае ошибки возвращаем температуру из таблицы по индексу - return (float)ntc_table[index].temp_c; + return (float) table[index].temp_c; } double temp_K = 1.0f / inv_T; @@ -151,61 +250,302 @@ static float interpolate_steinhart_full(float resistance, int index) { // Дополнительная проверка диапазона (например, для NTC обычно -50...+150°C) if (temp_K < 223.15f || temp_K > 423.15f) { // -50°C...150°C в Кельвинах // Возвращаем значение из таблицы как запасной вариант - return (float)ntc_table[index].temp_c; + return (float) table[index].temp_c; } - return (float)(temp_K - 273.15f); + return (float) (temp_K - 273.15f); } -// Основная функция для получения температуры -float get_temperature_from_adc(uint16_t adc_value, eAlg use_alg) { - float resistance = calculate_resistance(adc_value); +// Основная функция для получения температуры с указанием таблицы и R1 +float get_temperature_from_adc_with_table(uint16_t adc_value, eAlg alg, eNtcTable table_type, float r1) { + float resistance = calculate_resistance(adc_value, r1); if (resistance <= 0.0f) { return -273.15f; // Ошибка } - int index = find_interval_index(resistance); + uint16_t table_size; + int16_t start_temp, end_temp; + const ntc_table_entry* table = get_table_by_type(table_type, &table_size, &start_temp, &end_temp); - if (index < 0 || index >= TABLE_SIZE - 1) { + int index = find_interval_index(resistance, table, table_size); + + if (index < 0 || index >= table_size - 1) { // Вне диапазона таблицы - if (resistance >= ntc_table[0].r_nom) return TABLE_START_TEMP; - if (resistance <= ntc_table[TABLE_SIZE - 1].r_nom) return TABLE_END_TEMP; + if (resistance >= table[0].r_nom) return (float) start_temp; + if (resistance <= table[table_size - 1].r_nom) return (float) end_temp; return -273.15f; // Ошибка } - if (use_alg == ALG_STEINHART) { - return interpolate_steinhart(resistance, index); - } else if (use_alg == ALG_STEINHART_FULL) { - return interpolate_steinhart_full(resistance, index); + if (alg == ALG_STEINHART) { + return interpolate_steinhart(resistance, index, table); + } else if (alg == ALG_STEINHART_FULL) { + return interpolate_steinhart_full(resistance, index, table); } else { - return interpolate_log_linear(resistance, index); + return interpolate_log_linear(resistance, index, table); } } +// Функция для получения температуры с активной конфигурацией +float get_temperature_from_adc(uint16_t adc_value, eAlg alg) { + return get_temperature_from_adc_with_table(adc_value, alg, active_config.table_type, active_config.r1); +} -adc_temp_lookup fast_lookup[TABLE_SIZE_LOOKUP]; // Таблица на TABLE_SIZE_LOOKUP значений +// Функция для получения сопротивления из значения АЦП с указанием таблицы +float get_resistance_from_adc_with_table(uint16_t adc_value, eNtcTable table_type, float r1) { + return calculate_resistance(adc_value, r1); +} + +// Функция для получения сопротивления с активной конфигурацией +float get_resistance_from_adc(uint16_t adc_value) { + return calculate_resistance(adc_value, active_config.r1); +} + +// Инициализация таблицы быстрого поиска для конкретной таблицы +void init_fast_lookup_table(eNtcTable table_type, float r1, eAlg use_alg) { + uint16_t table_size; + int16_t start_temp, end_temp; + const ntc_table_entry* table = get_table_by_type(table_type, &table_size, &start_temp, &end_temp); + adc_temp_lookup* fast_table = get_fast_table_by_type(table_type); + + // Сохраняем значение R1 для этой таблицы + if (table_type == TABLE_KST45) { + g_fast_tables.kst45_r1 = r1; + } else { + g_fast_tables.incar_r1 = r1; + } + + // Находим рабочий диапазон АЦП + uint16_t min_valid_adc = 0; + uint16_t max_valid_adc = 0; + + // Значения для граничных точек + float temp_at_min_adc = 0.0f; + float temp_at_max_adc = 0.0f; + float res_at_min_adc = 0.0f; + float res_at_max_adc = 0.0f; + + // Ищем минимальное АЦП, при котором температура >= start_temp (максимальная температура) + for (uint16_t adc = 1; adc < ADC_MAX; adc++) { + float resistance = calculate_resistance(adc, r1); + float temp = get_temperature_from_adc_with_table(adc, use_alg, table_type, r1); + + if (temp >= start_temp && temp <= end_temp) { + min_valid_adc = adc; + temp_at_min_adc = temp; + res_at_min_adc = resistance; + break; + } + } + + // Ищем максимальное АЦП, при котором температура <= end_temp (минимальная температура) + for (uint16_t adc = (uint16_t)(ADC_MAX - 1); adc > 0; adc--) { + float resistance = calculate_resistance(adc, r1); + float temp = get_temperature_from_adc_with_table(adc, use_alg, table_type, r1); + + if (temp >= start_temp && temp <= end_temp) { + max_valid_adc = adc; + temp_at_max_adc = temp; + res_at_max_adc = resistance; + break; + } + } + + // Заполняем таблицу для всего диапазона ADC от 0 до 4095 + uint32_t adc_step = ((uint32_t)(ADC_MAX - 1) * 1000) / (TABLE_SIZE_LOOKUP - 1); + uint32_t current_adc = 0; + uint16_t prev_adc = 0; -void init_fast_lookup_table(eAlg use_alg) { - // Создаем таблицу для быстрого преобразования АЦП->температура for (uint16_t i = 0; i < TABLE_SIZE_LOOKUP; i++) { - uint16_t adc = i * (uint8_t)roundf(ADC_MAX / (TABLE_SIZE_LOOKUP - 1)); // Для 12-битного АЦП (0-4095) - float temp = get_temperature_from_adc(adc, use_alg); - fast_lookup[i].adc_value = adc; - fast_lookup[i].temp_c = (int16_t) (temp * 10.0f); // Храним с точностью 0.1°C + uint16_t adc; + + if (i == 0) { + adc = 0; + current_adc = 0; + prev_adc = 0; + } else if (i == TABLE_SIZE_LOOKUP - 1) { + adc = (uint16_t)(ADC_MAX - 1); + } else { + current_adc += adc_step; + adc = (uint16_t)(current_adc / 1000); + + // Убеждаемся, что значения монотонно возрастают и нет дубликатов + if (adc <= prev_adc) { + adc = prev_adc + 1; + } + + // Убеждаемся, что не выходим за пределы + if (adc >= (uint16_t)(ADC_MAX - 1)) { + adc = (uint16_t)(ADC_MAX - 2); + } + } + + float resistance; + float temp; + + // Определяем, находится ли ADC в рабочем диапазоне + if (adc <= min_valid_adc) { + // Зона низких ADC (высокая температура) - используем граничное значение + resistance = res_at_min_adc; + temp = temp_at_min_adc; + } else if (adc >= max_valid_adc) { + // Зона высоких ADC (низкая температура) - используем граничное значение + resistance = res_at_max_adc; + temp = temp_at_max_adc; + } else { + // В рабочем диапазоне - вычисляем нормально + resistance = calculate_resistance(adc, r1); + temp = get_temperature_from_adc_with_table(adc, use_alg, table_type, r1); + } + + fast_table[i].adc_value = adc; + fast_table[i].temp_c = (int16_t)(temp * 10.0f); + fast_table[i].resistance_ohm = resistance; + fast_table[i].table_type = table_type; + + prev_adc = adc; + } + + // Устанавливаем флаг инициализации + if (table_type == TABLE_KST45) { + g_fast_tables.kst45_initialized = true; + } else { + g_fast_tables.incar_initialized = true; } } -int16_t get_temperature_fast(uint16_t adc_value) { - // Простой поиск в таблице с линейной интерполяцией - uint16_t index = adc_value / (uint8_t)roundf(ADC_MAX / (TABLE_SIZE_LOOKUP - 1)); // Делим на 16 для TABLE_SIZE_LOOKUP = 256 - if (index >= (TABLE_SIZE_LOOKUP - 1)) return fast_lookup[TABLE_SIZE_LOOKUP - 1].temp_c; +// Инициализация обеих таблиц +void init_both_tables(float r1_kst45, float r1_incar, eAlg use_alg) { + init_fast_lookup_table(TABLE_KST45, r1_kst45, use_alg); + init_fast_lookup_table(TABLE_INCAR, r1_incar, use_alg); +} - uint16_t adc1 = fast_lookup[index].adc_value; - uint16_t adc2 = fast_lookup[index + 1].adc_value; - int16_t temp1 = fast_lookup[index].temp_c; - int16_t temp2 = fast_lookup[index + 1].temp_c; +// Установка активной конфигурации +void set_active_config(eNtcTable table_type, float r1) { + active_config.table_type = table_type; + active_config.r1 = r1; - // Линейная интерполяция - return temp1 + ((temp2 - temp1) * (adc_value - adc1)) / (adc2 - adc1); + uint16_t table_size; + get_table_by_type(table_type, &table_size, &active_config.start_temp, &active_config.end_temp); + active_config.table_size = table_size; +} + +// Получение активной конфигурации +const ntc_config_t* get_active_config(void) { + return &active_config; +} + +// Получение таблиц быстрого доступа +const fast_lookup_tables_t* get_fast_tables(void) { + return &g_fast_tables; +} + +// Быстрая функция для конкретной таблицы +int16_t get_temperature_log_fast_for_table(uint16_t adc_value, eNtcTable table_type) { + if (!is_table_initialized(table_type)) { + // Если таблица не инициализирована, используем обычный расчет + float temp = get_temperature_from_adc_with_table(adc_value, ALG_STEINHART, table_type, + (table_type == TABLE_KST45) ? g_fast_tables.kst45_r1 : g_fast_tables.incar_r1); + return (int16_t)(temp * 10.0f); + } + + adc_temp_lookup* fast_table = get_fast_table_by_type(table_type); + + // Простой линейный поиск (так как таблица небольшая - 4096 элементов) + for (uint16_t i = 0; i < TABLE_SIZE_LOOKUP - 1; i++) { + if (adc_value >= fast_table[i].adc_value && adc_value <= fast_table[i + 1].adc_value) { + // Линейная интерполяция + uint16_t adc1 = fast_table[i].adc_value; + uint16_t adc2 = fast_table[i + 1].adc_value; + int16_t temp1 = fast_table[i].temp_c; + int16_t temp2 = fast_table[i + 1].temp_c; + + if (adc2 == adc1) { + return temp1; + } + + return temp1 + ((int32_t)(temp2 - temp1) * (adc_value - adc1)) / (adc2 - adc1); + } + } + + // Если не нашли, возвращаем ближайшее значение + if (adc_value <= fast_table[0].adc_value) { + return fast_table[0].temp_c; + } else { + return fast_table[TABLE_SIZE_LOOKUP - 1].temp_c; + } +} + +// Быстрые функции с использованием активной таблицы +int16_t get_temperature_log_fast(uint16_t adc_value) { + return get_temperature_log_fast_for_table(adc_value, active_config.table_type); +} + +// Альтернативная простая версия +int16_t get_temperature_linear_fast(uint16_t adc_value) { + return get_temperature_log_fast_for_table(adc_value, active_config.table_type); +} + +// Функция для получения сопротивления из температуры для конкретной таблицы +float get_resistance_log_fast_for_table(int16_t temperature_c10, eNtcTable table_type) { + if (!is_table_initialized(table_type)) { + return 0.0f; + } + + adc_temp_lookup* fast_table = get_fast_table_by_type(table_type); + + // Защита от выхода за границы + if (temperature_c10 >= fast_table[0].temp_c) { + return fast_table[0].resistance_ohm; + } + if (temperature_c10 <= fast_table[TABLE_SIZE_LOOKUP - 1].temp_c) { + return fast_table[TABLE_SIZE_LOOKUP - 1].resistance_ohm; + } + + // Бинарный поиск интервала по температуре + int left = 0; + int right = TABLE_SIZE_LOOKUP - 1; + + while (left <= right) { + int mid = left + (right - left) / 2; + + if (temperature_c10 <= fast_table[mid].temp_c && + temperature_c10 >= fast_table[mid + 1].temp_c) { + // Нашли интервал + int16_t temp_high = fast_table[mid].temp_c; + int16_t temp_low = fast_table[mid + 1].temp_c; + float res_high = fast_table[mid].resistance_ohm; + float res_low = fast_table[mid + 1].resistance_ohm; + + if (temp_high == temp_low) { + return res_high; + } + + // Интерполяция в логарифмическом масштабе + float log_res_high = logf(res_high); + float log_res_low = logf(res_low); + float log_res = log_res_high + (log_res_low - log_res_high) * + (float)(temp_high - temperature_c10) / (float)(temp_high - temp_low); + + return expf(log_res); + } + + if (temperature_c10 > fast_table[mid].temp_c) { + right = mid - 1; + } else { + left = mid + 1; + } + } + + return fast_table[TABLE_SIZE_LOOKUP - 1].resistance_ohm; +} + +// Функция для получения сопротивления из температуры (обратное преобразование) +float get_resistance_log_fast(int16_t temperature_c10) { + return get_resistance_log_fast_for_table(temperature_c10, active_config.table_type); +} + +// Упрощенная версия с линейным поиском +float get_resistance_fast_simple(int16_t temperature_c10) { + return get_resistance_log_fast_for_table(temperature_c10, active_config.table_type); } \ No newline at end of file diff --git a/ADC_Temp.h b/ADC_Temp.h index 7a46720..9b9b93f 100644 --- a/ADC_Temp.h +++ b/ADC_Temp.h @@ -6,41 +6,83 @@ #define MDF_ADC_TEMP_KST45_14_2_H #include +#include "stdbool.h" -// Константы -#define ADC_MAX 4095.0f // 12-битный АЦП -#define R1 3400.0f // Сопротивление делителя напряжения -#define TABLE_START_TEMP (-40) -#define TABLE_END_TEMP 85 -#define TABLE_SIZE 38 - -// Параметры Steinhart-Hart для термистора -#define koef_A 0.001741624168166423 -#define koef_B 0.00017003940268680147 -#define koef_C 0.0000004890545443703666 - -#define TABLE_SIZE_LOOKUP 1024 - -// Структура для хранения табличных данных -typedef struct { - int temp_c; // Температура (°C) - float r_nom; // Номинальное сопротивление (Ω) -} ntc_table_entry; +// Типы таблиц NTC +typedef enum { + TABLE_KST45 = 0, // Таблица из документа KST45 + TABLE_INCAR = 1 // Таблица из документа Incar +} eNtcTable; +// Алгоритмы расчёта температуры typedef enum { ALG_STEINHART = 0, ALG_STEINHART_FULL = 1, ALG_LINEAR = 2 } eAlg; -// Предварительно вычисленная таблица для быстрого доступа +// Константы +#define ADC_MAX 4095.0f // 12-битный АЦП + +// Параметры Steinhart-Hart для термистора (общие для всех таблиц) +#define koef_A 0.001741624168166423 +#define koef_B 0.00017003940268680147 +#define koef_C 0.0000004890545443703666 + +// Размеры таблиц +#define TABLE_SIZE_KST45 26 +#define TABLE_SIZE_INCAR 38 +#define TABLE_SIZE_LOOKUP 256 + +// Предварительно вычисленная таблица для быстрого доступа для каждой таблицы typedef struct { - uint16_t adc_value; // Значение АЦП - int16_t temp_c; // Температура в °C * 10 (для фиксированной точки) + uint16_t adc_value; // Значение АЦП + int16_t temp_c; // Температура в °C * 10 (для фиксированной точки) + float resistance_ohm; // Сопротивление в Ом, соответствующее значению АЦП + eNtcTable table_type; // Тип таблицы, для которой вычислены данные } adc_temp_lookup; -void init_fast_lookup_table(eAlg use_alg); -float get_temperature_from_adc(uint16_t adc_value, eAlg alg); -int16_t get_temperature_fast(uint16_t adc_value); +// Структура конфигурации для NTC +typedef struct { + eNtcTable table_type; // Тип используемой таблицы + float r1; // Сопротивление делителя напряжения (Ом) + int16_t start_temp; // Начальная температура таблицы (°C) + int16_t end_temp; // Конечная температура таблицы (°C) + uint16_t table_size; // Размер таблицы +} ntc_config_t; -#endif //MDF_ADC_TEMP_KST45_14_2_H +// Структура для хранения таблиц быстрого доступа для каждой конфигурации +typedef struct { + adc_temp_lookup kst45[TABLE_SIZE_LOOKUP]; + adc_temp_lookup incar[TABLE_SIZE_LOOKUP]; + bool kst45_initialized; + bool incar_initialized; + float kst45_r1; + float incar_r1; +} fast_lookup_tables_t; + +// Глобальная структура для доступа к таблицам +extern fast_lookup_tables_t g_fast_tables; + +// Функции инициализации и конфигурации +void init_fast_lookup_table(eNtcTable table_type, float r1, eAlg use_alg); +void init_both_tables(float r1_kst45, float r1_incar, eAlg use_alg); +void set_active_config(eNtcTable table_type, float r1); +const ntc_config_t* get_active_config(void); +const fast_lookup_tables_t* get_fast_tables(void); + +// Основные функции получения температуры +float get_temperature_from_adc(uint16_t adc_value, eAlg alg); +float get_temperature_from_adc_with_table(uint16_t adc_value, eAlg alg, eNtcTable table_type, float r1); +float get_resistance_from_adc(uint16_t adc_value); +float get_resistance_from_adc_with_table(uint16_t adc_value, eNtcTable table_type, float r1); + +// Быстрые функции с использованием предварительно вычисленной таблицы +int16_t get_temperature_log_fast(uint16_t adc_value); +int16_t get_temperature_log_fast_for_table(uint16_t adc_value, eNtcTable table_type); +int16_t get_temperature_linear_fast(uint16_t adc_value); +float get_resistance_log_fast(int16_t temperature_c10); +float get_resistance_log_fast_for_table(int16_t temperature_c10, eNtcTable table_type); +float get_resistance_fast_simple(int16_t temperature_c10); + +#endif //MDF_ADC_TEMP_KST45_14_2_H \ No newline at end of file diff --git a/ADC_Temp_Table.c b/ADC_Temp_Table.c deleted file mode 100644 index 8a97770..0000000 --- a/ADC_Temp_Table.c +++ /dev/null @@ -1,1037 +0,0 @@ -// -// Created by cfif on 16.12.2025. -// -#include "ADC_Temp.h" - -const adc_temp_lookup fast_lookup_KST45[TABLE_SIZE_LOOKUP] = { - {0,-2731}, - {8,2748}, - {16,2276}, - {24,2035}, - {32,1878}, - {40,1762}, - {48,1672}, - {56,1598}, - {64,1536}, - {72,1483}, - {80,1436}, - {88,1395}, - {96,1358}, - {104,1324}, - {112,1293}, - {120,1265}, - {128,1239}, - {136,1214}, - {144,1192}, - {152,1171}, - {160,1151}, - {168,1132}, - {176,1114}, - {184,1097}, - {192,1081}, - {200,1065}, - {208,1051}, - {216,1037}, - {224,1023}, - {232,1010}, - {240,998}, - {248,986}, - {256,974}, - {264,963}, - {272,952}, - {280,942}, - {288,932}, - {296,922}, - {304,913}, - {312,903}, - {320,894}, - {328,886}, - {336,877}, - {344,869}, - {352,861}, - {360,853}, - {368,845}, - {376,838}, - {384,831}, - {392,824}, - {400,817}, - {408,810}, - {416,803}, - {424,796}, - {432,790}, - {440,784}, - {448,777}, - {456,771}, - {464,765}, - {472,760}, - {480,754}, - {488,748}, - {496,743}, - {504,737}, - {512,732}, - {520,726}, - {528,721}, - {536,716}, - {544,711}, - {552,706}, - {560,701}, - {568,696}, - {576,692}, - {584,687}, - {592,682}, - {600,678}, - {608,673}, - {616,669}, - {624,664}, - {632,660}, - {640,656}, - {648,652}, - {656,647}, - {664,643}, - {672,639}, - {680,635}, - {688,631}, - {696,627}, - {704,623}, - {712,620}, - {720,616}, - {728,612}, - {736,608}, - {744,605}, - {752,601}, - {760,597}, - {768,594}, - {776,590}, - {784,587}, - {792,583}, - {800,580}, - {808,577}, - {816,573}, - {824,570}, - {832,567}, - {840,563}, - {848,560}, - {856,557}, - {864,554}, - {872,550}, - {880,547}, - {888,544}, - {896,541}, - {904,538}, - {912,535}, - {920,532}, - {928,529}, - {936,526}, - {944,523}, - {952,520}, - {960,517}, - {968,514}, - {976,512}, - {984,509}, - {992,506}, - {1000,503}, - {1008,500}, - {1016,498}, - {1024,495}, - {1032,492}, - {1040,489}, - {1048,487}, - {1056,484}, - {1064,481}, - {1072,479}, - {1080,476}, - {1088,474}, - {1096,471}, - {1104,468}, - {1112,466}, - {1120,463}, - {1128,461}, - {1136,458}, - {1144,456}, - {1152,453}, - {1160,451}, - {1168,448}, - {1176,446}, - {1184,443}, - {1192,441}, - {1200,439}, - {1208,436}, - {1216,434}, - {1224,431}, - {1232,429}, - {1240,427}, - {1248,424}, - {1256,422}, - {1264,420}, - {1272,418}, - {1280,415}, - {1288,413}, - {1296,411}, - {1304,408}, - {1312,406}, - {1320,404}, - {1328,402}, - {1336,400}, - {1344,397}, - {1352,395}, - {1360,393}, - {1368,391}, - {1376,389}, - {1384,386}, - {1392,384}, - {1400,382}, - {1408,380}, - {1416,378}, - {1424,376}, - {1432,374}, - {1440,371}, - {1448,369}, - {1456,367}, - {1464,365}, - {1472,363}, - {1480,361}, - {1488,359}, - {1496,357}, - {1504,355}, - {1512,353}, - {1520,351}, - {1528,349}, - {1536,347}, - {1544,345}, - {1552,343}, - {1560,341}, - {1568,339}, - {1576,337}, - {1584,335}, - {1592,333}, - {1600,331}, - {1608,329}, - {1616,327}, - {1624,325}, - {1632,323}, - {1640,321}, - {1648,319}, - {1656,317}, - {1664,315}, - {1672,314}, - {1680,312}, - {1688,310}, - {1696,308}, - {1704,306}, - {1712,304}, - {1720,302}, - {1728,300}, - {1736,298}, - {1744,297}, - {1752,295}, - {1760,293}, - {1768,291}, - {1776,289}, - {1784,287}, - {1792,285}, - {1800,283}, - {1808,282}, - {1816,280}, - {1824,278}, - {1832,276}, - {1840,274}, - {1848,272}, - {1856,271}, - {1864,269}, - {1872,267}, - {1880,265}, - {1888,263}, - {1896,262}, - {1904,260}, - {1912,258}, - {1920,256}, - {1928,254}, - {1936,253}, - {1944,251}, - {1952,249}, - {1960,247}, - {1968,245}, - {1976,244}, - {1984,242}, - {1992,240}, - {2000,238}, - {2008,237}, - {2016,235}, - {2024,233}, - {2032,231}, - {2040,230}, - {2048,228}, - {2056,226}, - {2064,224}, - {2072,222}, - {2080,221}, - {2088,219}, - {2096,217}, - {2104,215}, - {2112,214}, - {2120,212}, - {2128,210}, - {2136,208}, - {2144,207}, - {2152,205}, - {2160,203}, - {2168,202}, - {2176,200}, - {2184,198}, - {2192,196}, - {2200,195}, - {2208,193}, - {2216,191}, - {2224,189}, - {2232,188}, - {2240,186}, - {2248,184}, - {2256,182}, - {2264,181}, - {2272,179}, - {2280,177}, - {2288,176}, - {2296,174}, - {2304,172}, - {2312,170}, - {2320,169}, - {2328,167}, - {2336,165}, - {2344,163}, - {2352,162}, - {2360,160}, - {2368,158}, - {2376,156}, - {2384,155}, - {2392,153}, - {2400,151}, - {2408,150}, - {2416,148}, - {2424,146}, - {2432,144}, - {2440,143}, - {2448,141}, - {2456,139}, - {2464,137}, - {2472,136}, - {2480,134}, - {2488,132}, - {2496,130}, - {2504,129}, - {2512,127}, - {2520,125}, - {2528,123}, - {2536,122}, - {2544,120}, - {2552,118}, - {2560,116}, - {2568,115}, - {2576,113}, - {2584,111}, - {2592,109}, - {2600,108}, - {2608,106}, - {2616,104}, - {2624,102}, - {2632,101}, - {2640,99}, - {2648,97}, - {2656,95}, - {2664,94}, - {2672,92}, - {2680,90}, - {2688,88}, - {2696,86}, - {2704,85}, - {2712,83}, - {2720,81}, - {2728,79}, - {2736,77}, - {2744,76}, - {2752,74}, - {2760,72}, - {2768,70}, - {2776,68}, - {2784,66}, - {2792,65}, - {2800,63}, - {2808,61}, - {2816,59}, - {2824,57}, - {2832,55}, - {2840,53}, - {2848,52}, - {2856,50}, - {2864,48}, - {2872,46}, - {2880,44}, - {2888,42}, - {2896,40}, - {2904,38}, - {2912,37}, - {2920,35}, - {2928,33}, - {2936,31}, - {2944,29}, - {2952,27}, - {2960,25}, - {2968,23}, - {2976,21}, - {2984,19}, - {2992,17}, - {3000,15}, - {3008,13}, - {3016,11}, - {3024,9}, - {3032,7}, - {3040,5}, - {3048,3}, - {3056,1}, - {3064,0}, - {3072,-2}, - {3080,-4}, - {3088,-6}, - {3096,-8}, - {3104,-10}, - {3112,-12}, - {3120,-14}, - {3128,-16}, - {3136,-18}, - {3144,-21}, - {3152,-23}, - {3160,-25}, - {3168,-27}, - {3176,-29}, - {3184,-31}, - {3192,-33}, - {3200,-36}, - {3208,-38}, - {3216,-40}, - {3224,-42}, - {3232,-44}, - {3240,-47}, - {3248,-49}, - {3256,-51}, - {3264,-53}, - {3272,-56}, - {3280,-58}, - {3288,-60}, - {3296,-63}, - {3304,-65}, - {3312,-67}, - {3320,-70}, - {3328,-72}, - {3336,-75}, - {3344,-77}, - {3352,-79}, - {3360,-82}, - {3368,-84}, - {3376,-87}, - {3384,-89}, - {3392,-92}, - {3400,-94}, - {3408,-97}, - {3416,-100}, - {3424,-102}, - {3432,-105}, - {3440,-107}, - {3448,-110}, - {3456,-113}, - {3464,-116}, - {3472,-118}, - {3480,-121}, - {3488,-124}, - {3496,-127}, - {3504,-129}, - {3512,-132}, - {3520,-135}, - {3528,-138}, - {3536,-141}, - {3544,-144}, - {3552,-147}, - {3560,-150}, - {3568,-153}, - {3576,-156}, - {3584,-159}, - {3592,-163}, - {3600,-166}, - {3608,-169}, - {3616,-172}, - {3624,-176}, - {3632,-179}, - {3640,-183}, - {3648,-186}, - {3656,-190}, - {3664,-193}, - {3672,-197}, - {3680,-200}, - {3688,-204}, - {3696,-208}, - {3704,-212}, - {3712,-216}, - {3720,-220}, - {3728,-224}, - {3736,-228}, - {3744,-232}, - {3752,-236}, - {3760,-240}, - {3768,-245}, - {3776,-249}, - {3784,-254}, - {3792,-259}, - {3800,-263}, - {3808,-268}, - {3816,-273}, - {3824,-278}, - {3832,-283}, - {3840,-289}, - {3848,-294}, - {3856,-300}, - {3864,-306}, - {3872,-312}, - {3880,-318}, - {3888,-324}, - {3896,-331}, - {3904,-338}, - {3912,-345}, - {3920,-352}, - {3928,-360}, - {3936,-367}, - {3944,-376}, - {3952,-384}, - {3960,-393}, - {3968,-403}, - {3976,-413}, - {3984,-423}, - {3992,-434}, - {4000,-446}, - {4008,-459}, - {4016,-473}, - {4024,-488}, - {4032,-505}, - {4040,-524}, - {4048,-545}, - {4056,-569}, - {4064,-599}, - {4072,-636}, - {4080,-686}, - {4088,-770} -}; // Таблица на TABLE_SIZE_LOOKUP значений - -const adc_temp_lookup fast_lookup_Incar[TABLE_SIZE_LOOKUP] = { - - {0,-2731}, - {8,2605}, - {16,2164}, - {24,1937}, - {32,1789}, - {40,1680}, - {48,1594}, - {56,1524}, - {64,1466}, - {72,1415}, - {80,1371}, - {88,1331}, - {96,1296}, - {104,1264}, - {112,1234}, - {120,1207}, - {128,1182}, - {136,1159}, - {144,1138}, - {152,1117}, - {160,1098}, - {168,1080}, - {176,1063}, - {184,1047}, - {192,1032}, - {200,1017}, - {208,1003}, - {216,989}, - {224,976}, - {232,964}, - {240,952}, - {248,941}, - {256,930}, - {264,919}, - {272,909}, - {280,899}, - {288,889}, - {296,880}, - {304,871}, - {312,862}, - {320,853}, - {328,845}, - {336,837}, - {344,829}, - {352,821}, - {360,813}, - {368,806}, - {376,799}, - {384,792}, - {392,785}, - {400,778}, - {408,772}, - {416,766}, - {424,759}, - {432,753}, - {440,747}, - {448,741}, - {456,735}, - {464,730}, - {472,724}, - {480,718}, - {488,713}, - {496,708}, - {504,702}, - {512,697}, - {520,692}, - {528,687}, - {536,682}, - {544,678}, - {552,673}, - {560,668}, - {568,664}, - {576,659}, - {584,655}, - {592,650}, - {600,646}, - {608,641}, - {616,637}, - {624,633}, - {632,629}, - {640,625}, - {648,621}, - {656,617}, - {664,613}, - {672,609}, - {680,605}, - {688,601}, - {696,597}, - {704,594}, - {712,590}, - {720,586}, - {728,583}, - {736,579}, - {744,576}, - {752,572}, - {760,569}, - {768,565}, - {776,562}, - {784,559}, - {792,555}, - {800,552}, - {808,549}, - {816,546}, - {824,542}, - {832,539}, - {840,536}, - {848,533}, - {856,530}, - {864,527}, - {872,524}, - {880,521}, - {888,518}, - {896,515}, - {904,512}, - {912,509}, - {920,506}, - {928,503}, - {936,500}, - {944,497}, - {952,494}, - {960,492}, - {968,489}, - {976,486}, - {984,483}, - {992,481}, - {1000,478}, - {1008,475}, - {1016,473}, - {1024,470}, - {1032,468}, - {1040,465}, - {1048,462}, - {1056,460}, - {1064,457}, - {1072,455}, - {1080,452}, - {1088,450}, - {1096,447}, - {1104,445}, - {1112,442}, - {1120,440}, - {1128,437}, - {1136,435}, - {1144,433}, - {1152,430}, - {1160,428}, - {1168,425}, - {1176,423}, - {1184,421}, - {1192,418}, - {1200,416}, - {1208,414}, - {1216,411}, - {1224,409}, - {1232,407}, - {1240,405}, - {1248,402}, - {1256,400}, - {1264,398}, - {1272,396}, - {1280,394}, - {1288,391}, - {1296,389}, - {1304,387}, - {1312,385}, - {1320,383}, - {1328,381}, - {1336,378}, - {1344,376}, - {1352,374}, - {1360,372}, - {1368,370}, - {1376,368}, - {1384,366}, - {1392,364}, - {1400,362}, - {1408,360}, - {1416,358}, - {1424,356}, - {1432,354}, - {1440,352}, - {1448,350}, - {1456,348}, - {1464,346}, - {1472,344}, - {1480,342}, - {1488,340}, - {1496,338}, - {1504,336}, - {1512,334}, - {1520,332}, - {1528,330}, - {1536,328}, - {1544,326}, - {1552,324}, - {1560,322}, - {1568,320}, - {1576,318}, - {1584,316}, - {1592,314}, - {1600,312}, - {1608,311}, - {1616,309}, - {1624,307}, - {1632,305}, - {1640,303}, - {1648,301}, - {1656,299}, - {1664,297}, - {1672,296}, - {1680,294}, - {1688,292}, - {1696,290}, - {1704,288}, - {1712,286}, - {1720,285}, - {1728,283}, - {1736,281}, - {1744,279}, - {1752,277}, - {1760,276}, - {1768,274}, - {1776,272}, - {1784,270}, - {1792,268}, - {1800,267}, - {1808,265}, - {1816,263}, - {1824,261}, - {1832,260}, - {1840,258}, - {1848,256}, - {1856,254}, - {1864,253}, - {1872,251}, - {1880,249}, - {1888,247}, - {1896,246}, - {1904,244}, - {1912,242}, - {1920,240}, - {1928,239}, - {1936,237}, - {1944,235}, - {1952,233}, - {1960,232}, - {1968,230}, - {1976,228}, - {1984,227}, - {1992,225}, - {2000,223}, - {2008,221}, - {2016,220}, - {2024,218}, - {2032,216}, - {2040,215}, - {2048,213}, - {2056,211}, - {2064,209}, - {2072,208}, - {2080,206}, - {2088,204}, - {2096,203}, - {2104,201}, - {2112,199}, - {2120,198}, - {2128,196}, - {2136,194}, - {2144,193}, - {2152,191}, - {2160,189}, - {2168,188}, - {2176,186}, - {2184,184}, - {2192,182}, - {2200,181}, - {2208,179}, - {2216,177}, - {2224,176}, - {2232,174}, - {2240,172}, - {2248,171}, - {2256,169}, - {2264,167}, - {2272,166}, - {2280,164}, - {2288,162}, - {2296,161}, - {2304,159}, - {2312,157}, - {2320,156}, - {2328,154}, - {2336,152}, - {2344,151}, - {2352,149}, - {2360,147}, - {2368,146}, - {2376,144}, - {2384,142}, - {2392,141}, - {2400,139}, - {2408,137}, - {2416,136}, - {2424,134}, - {2432,132}, - {2440,130}, - {2448,129}, - {2456,127}, - {2464,125}, - {2472,124}, - {2480,122}, - {2488,120}, - {2496,119}, - {2504,117}, - {2512,115}, - {2520,114}, - {2528,112}, - {2536,110}, - {2544,109}, - {2552,107}, - {2560,105}, - {2568,104}, - {2576,102}, - {2584,100}, - {2592,98}, - {2600,97}, - {2608,95}, - {2616,93}, - {2624,92}, - {2632,90}, - {2640,88}, - {2648,86}, - {2656,85}, - {2664,83}, - {2672,81}, - {2680,79}, - {2688,78}, - {2696,76}, - {2704,74}, - {2712,73}, - {2720,71}, - {2728,69}, - {2736,67}, - {2744,66}, - {2752,64}, - {2760,62}, - {2768,60}, - {2776,58}, - {2784,57}, - {2792,55}, - {2800,53}, - {2808,51}, - {2816,50}, - {2824,48}, - {2832,46}, - {2840,44}, - {2848,42}, - {2856,41}, - {2864,39}, - {2872,37}, - {2880,35}, - {2888,33}, - {2896,31}, - {2904,30}, - {2912,28}, - {2920,26}, - {2928,24}, - {2936,22}, - {2944,20}, - {2952,18}, - {2960,16}, - {2968,15}, - {2976,13}, - {2984,11}, - {2992,9}, - {3000,7}, - {3008,5}, - {3016,3}, - {3024,1}, - {3032,0}, - {3040,-2}, - {3048,-4}, - {3056,-6}, - {3064,-8}, - {3072,-10}, - {3080,-12}, - {3088,-14}, - {3096,-16}, - {3104,-18}, - {3112,-20}, - {3120,-22}, - {3128,-24}, - {3136,-26}, - {3144,-28}, - {3152,-30}, - {3160,-32}, - {3168,-34}, - {3176,-36}, - {3184,-38}, - {3192,-40}, - {3200,-42}, - {3208,-44}, - {3216,-47}, - {3224,-49}, - {3232,-51}, - {3240,-53}, - {3248,-55}, - {3256,-58}, - {3264,-60}, - {3272,-62}, - {3280,-64}, - {3288,-67}, - {3296,-69}, - {3304,-71}, - {3312,-73}, - {3320,-76}, - {3328,-78}, - {3336,-80}, - {3344,-83}, - {3352,-85}, - {3360,-88}, - {3368,-90}, - {3376,-92}, - {3384,-95}, - {3392,-97}, - {3400,-100}, - {3408,-102}, - {3416,-105}, - {3424,-107}, - {3432,-110}, - {3440,-112}, - {3448,-115}, - {3456,-118}, - {3464,-120}, - {3472,-123}, - {3480,-126}, - {3488,-128}, - {3496,-131}, - {3504,-134}, - {3512,-137}, - {3520,-140}, - {3528,-142}, - {3536,-145}, - {3544,-148}, - {3552,-151}, - {3560,-154}, - {3568,-157}, - {3576,-160}, - {3584,-163}, - {3592,-166}, - {3600,-170}, - {3608,-173}, - {3616,-176}, - {3624,-179}, - {3632,-182}, - {3640,-186}, - {3648,-189}, - {3656,-193}, - {3664,-196}, - {3672,-200}, - {3680,-203}, - {3688,-207}, - {3696,-211}, - {3704,-214}, - {3712,-218}, - {3720,-222}, - {3728,-226}, - {3736,-230}, - {3744,-234}, - {3752,-238}, - {3760,-242}, - {3768,-247}, - {3776,-251}, - {3784,-256}, - {3792,-260}, - {3800,-265}, - {3808,-270}, - {3816,-275}, - {3824,-280}, - {3832,-285}, - {3840,-290}, - {3848,-296}, - {3856,-301}, - {3864,-307}, - {3872,-313}, - {3880,-319}, - {3888,-325}, - {3896,-332}, - {3904,-338}, - {3912,-345}, - {3920,-352}, - {3928,-360}, - {3936,-368}, - {3944,-376}, - {3952,-384}, - {3960,-393}, - {3968,-403}, - {3976,-412}, - {3984,-423}, - {3992,-434}, - {4000,-446}, - {4008,-459}, - {4016,-472}, - {4024,-487}, - {4032,-504}, - {4040,-522}, - {4048,-543}, - {4056,-568}, - {4064,-597}, - {4072,-634}, - {4080,-684}, - {4088,-768} - - -}; // Таблица на TABLE_SIZE_LOOKUP значений \ No newline at end of file diff --git a/ADC_Temp_Table.h b/ADC_Temp_Table.h deleted file mode 100644 index a9526a0..0000000 --- a/ADC_Temp_Table.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// Created by cfif on 16.12.2025. -// - -#ifndef HVAC_M7_ADC_TEMP_TABLE_H -#define HVAC_M7_ADC_TEMP_TABLE_H - -#include "ADC_Temp.h" - -extern const adc_temp_lookup fast_lookup_Incar[TABLE_SIZE_LOOKUP]; -extern const adc_temp_lookup fast_lookup_KST45[TABLE_SIZE_LOOKUP]; - -#endif //HVAC_M7_ADC_TEMP_TABLE_H