From 2d5e7010d2e51efca80ae3821cbce0fc476300f1 Mon Sep 17 00:00:00 2001 From: cfif Date: Wed, 13 May 2026 09:36:15 +0300 Subject: [PATCH] Init --- APP/main.c | 24 +++++++++ APP/src/ADC_Temp.c | 127 ++++++++++++++++++++++++++------------------- 2 files changed, 98 insertions(+), 53 deletions(-) diff --git a/APP/main.c b/APP/main.c index 7dba1a3..865c62c 100644 --- a/APP/main.c +++ b/APP/main.c @@ -8,6 +8,29 @@ typedef struct { float resistance_ohm; // Сопротивление в Ом } adc_temp_lookup_entry_t; +// Функция для сохранения температур в одну строку через пробел (все значения) +void save_temperature_int_one_line(const char* filename, const adc_temp_lookup* table, const char* table_name) { + FILE* file = fopen(filename, "w"); + if (file == NULL) { + printf("Ошибка: не удалось создать файл %s\n", filename); + return; + } + + fprintf(file, "# Температуры для таблицы %s (одна строка, через пробел)\n", table_name); + fprintf(file, "# VCC=%.2fV, VREF=%.2fV\n", VCC_DIVIDER_MV / 1000.0f, VREF_MV / 1000.0f); + fprintf(file, "# Всего значений: %d\n", TABLE_SIZE_LOOKUP); + fprintf(file, "# Температура в °C * 10 (целые числа)\n\n"); + + for (int i = 0; i < TABLE_SIZE_LOOKUP; i++) { + if (i > 0) fprintf(file, " "); + fprintf(file, "%d", table[i].temp_c); + } + + fprintf(file, "\n"); + fclose(file); + printf("Температуры (int one-line) для '%s' сохранены в файл: %s\n", table_name, filename); +} + // Функция для сохранения таблицы в C файл в виде статического массива void save_table_to_c_file(const char* filename, const adc_temp_lookup* table, const char* table_name, const char* array_name) { @@ -186,6 +209,7 @@ void save_all_tables_to_files(void) { save_table_to_c_file("duct_table_array.c", tables->duct, "DUCT", "duct_lookup_table"); save_table_to_csv("duct_table.csv", tables->duct, "DUCT"); save_table_to_txt("duct_table.txt", tables->duct, "DUCT"); +// save_temperature_int_one_line("duct_table.txt", tables->duct, "DUCT"); // Сохраняем INCAR таблицу save_table_to_c_file("incar_table_array.c", tables->incar, "INCAR", "incar_lookup_table"); diff --git a/APP/src/ADC_Temp.c b/APP/src/ADC_Temp.c index c72b050..bf601d5 100644 --- a/APP/src/ADC_Temp.c +++ b/APP/src/ADC_Temp.c @@ -482,91 +482,113 @@ void init_fast_lookup_table(eNtcTable table_type, float r1, eAlg use_alg) { float max_resistance = table[0].r_nom; // Максимальное сопротивление (мин. температура) float min_resistance = table[table_size - 1].r_nom; // Минимальное сопротивление (макс. температура) - // Ищем минимальное ADC, при котором сопротивление <= max_resistance - for (uint16_t adc = 1; adc < ADC_MAX; adc++) { + // Ищем минимальное ADC, при котором сопротивление >= max_resistance (низкая температура) + // При ADC=0 напряжение на NTC минимально, сопротивление минимально, температура максимальна + // При ADC=max напряжение максимально, сопротивление максимально, температура минимальна + min_valid_adc = 0; + for (uint16_t adc = 0; adc < ADC_MAX; adc++) { float resistance = calculate_resistance(adc, r1); - if (resistance <= max_resistance && !isinf(resistance)) { + if (resistance >= max_resistance && !isinf(resistance) && resistance > 0) { min_valid_adc = adc; break; } } - // Ищем максимальное ADC, при котором сопротивление >= min_resistance + // Ищем максимальное ADC, при котором сопротивление <= min_resistance (высокая температура) + max_valid_adc = (uint16_t)(ADC_MAX - 1); for (uint16_t adc = (uint16_t)(ADC_MAX - 1); adc > 0; adc--) { float resistance = calculate_resistance(adc, r1); - if (resistance >= min_resistance && resistance < INFINITY) { + if (resistance <= min_resistance && !isinf(resistance) && resistance > 0) { max_valid_adc = adc; break; } } - printf("DEBUG: %s - min_valid_adc=%u, max_valid_adc=%u\n", + // Корректировка: min_valid_adc - начало диапазона низких температур (высокое сопротивление) + // max_valid_adc - конец диапазона высоких температур (низкое сопротивление) + if (min_valid_adc < max_valid_adc) { + uint16_t temp = min_valid_adc; + min_valid_adc = max_valid_adc; + max_valid_adc = temp; + } + + printf("DEBUG: %s - min_temp_adc=%u (low temp), max_temp_adc=%u (high temp)\n", table_type == TABLE_DUCT ? "DUCT" : (table_type == TABLE_INCAR ? "INCAR" : "AMBIENT"), min_valid_adc, max_valid_adc); - // Заполняем таблицу - uint32_t adc_step = ((uint32_t)(ADC_MAX - 1) * 1000) / (TABLE_SIZE_LOOKUP - 1); - uint32_t current_adc = 0; - uint16_t prev_adc = 0; - + // Заполняем таблицу - теперь ADC растет от 0 до MAX + // При ADC=0: минимальное сопротивление, максимальная температура + // При ADC=MAX: максимальное сопротивление, минимальная температура for (uint16_t i = 0; i < TABLE_SIZE_LOOKUP; i++) { - uint16_t adc; + uint16_t adc = i; // Просто индекс = ADC (0...4095) float resistance; float temp; - // Определяем ADC для текущей записи - if (i == 0) { - 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); - } - // Расчет сопротивления и температуры в зависимости от зоны - if (adc <= min_valid_adc) { - // Зона низких ADC (высокая температура) - насыщение - resistance = min_resistance; - temp = (float)end_temp; // Максимальная температура (+85°C) - } - else if (adc >= max_valid_adc) { - // Зона высоких ADC (низкая температура) - насыщение + if (adc >= min_valid_adc) { + // Зона высоких ADC (низкая температура, высокое сопротивление) - насыщение resistance = max_resistance; + if (resistance > 10000000.0f) resistance = 10000000.0f; temp = (float)start_temp; // Минимальная температура (-40°C) } + else if (adc <= max_valid_adc) { + // Зона низких ADC (высокая температура, низкое сопротивление) - насыщение + resistance = min_resistance; + if (resistance < 1.0f) resistance = 1.0f; + temp = (float)end_temp; // Максимальная температура (85°C или 150°C) + } else { // Рабочая зона - нормальный расчет resistance = calculate_resistance(adc, r1); - if (isinf(resistance) || resistance <= 0.0f) { - temp = (float)start_temp - 10.0f; - } else { - int index = find_interval_index(resistance, table, table_size); + // Дополнительные проверки сопротивления + if (isinf(resistance)) { + resistance = max_resistance; + temp = (float)start_temp; + goto fill_entry; + } - if (index < 0 || index >= table_size - 1) { - if (resistance >= table[0].r_nom) { - temp = (float)start_temp; - } else if (resistance <= table[table_size - 1].r_nom) { - temp = (float)end_temp; - } else { - temp = 25.0f; - } + if (resistance <= 0.0f) { + resistance = min_resistance; + if (resistance < 1.0f) resistance = 1.0f; + temp = (float)end_temp; + goto fill_entry; + } + + // Ограничиваем сопротивления физическими пределами + if (resistance < 1.0f) resistance = 1.0f; + if (resistance > 10000000.0f) resistance = 10000000.0f; + + // Поиск температуры + int index = find_interval_index(resistance, table, table_size); + + if (index < 0 || index >= table_size - 1) { + if (resistance >= table[0].r_nom) { + temp = (float)start_temp; + resistance = max_resistance; + } else if (resistance <= table[table_size - 1].r_nom) { + temp = (float)end_temp; + resistance = min_resistance; } else { - if (use_alg == ALG_STEINHART) { - temp = interpolate_steinhart(resistance, index, table); - } else if (use_alg == ALG_STEINHART_FULL) { - temp = interpolate_steinhart_full(resistance, index, table); - } else { - temp = interpolate_log_linear(resistance, index, table); - } + temp = 25.0f; } + } else { + if (use_alg == ALG_STEINHART) { + temp = interpolate_steinhart(resistance, index, table); + } else if (use_alg == ALG_STEINHART_FULL) { + temp = interpolate_steinhart_full(resistance, index, table); + } else { + temp = interpolate_log_linear(resistance, index, table); + } + + // Проверяем полученную температуру на реалистичность + if (temp < (float)start_temp - 5.0f) temp = (float)start_temp; + if (temp > (float)end_temp + 5.0f) temp = (float)end_temp; } } - // Заполняем запись + fill_entry: + // Заполняем запись - теперь ADC=i fast_table[i].adc_value = adc; fast_table[i].temp_c = (int16_t)(temp * 10.0f); fast_table[i].resistance_ohm = resistance; @@ -574,8 +596,6 @@ void init_fast_lookup_table(eNtcTable table_type, float r1, eAlg use_alg) { fast_table[i].v_ntc_mv = (adc * VREF_MV) / ADC_MAX; fast_table[i].v_r1_mv = VCC_DIVIDER_MV - fast_table[i].v_ntc_mv; fast_table[i].table_type = table_type; - - prev_adc = adc; } // Устанавливаем флаг инициализации @@ -588,6 +608,7 @@ void init_fast_lookup_table(eNtcTable table_type, float r1, eAlg use_alg) { } } + // Инициализация таблицы Duct void init_duct_table(float r1, eAlg use_alg) { init_fast_lookup_table(TABLE_DUCT, r1, use_alg);