From 8ac9d543b3c754c92ddb80866a6f220002933c7e Mon Sep 17 00:00:00 2001 From: cfif Date: Wed, 13 May 2026 15:50:47 +0300 Subject: [PATCH] Init --- APP/inc/ADC_Temp.h | 5 +++- APP/main.c | 61 +++++++++------------------------------------- APP/src/ADC_Temp.c | 51 ++++++++++++++++++++------------------ 3 files changed, 43 insertions(+), 74 deletions(-) diff --git a/APP/inc/ADC_Temp.h b/APP/inc/ADC_Temp.h index 02d13fa..00b8968 100644 --- a/APP/inc/ADC_Temp.h +++ b/APP/inc/ADC_Temp.h @@ -44,7 +44,10 @@ typedef enum { #define TABLE_SIZE_DUCT 26 #define TABLE_SIZE_INCAR 38 #define TABLE_SIZE_AMBIENT 39 -#define TABLE_SIZE_LOOKUP 4096 + +#define TABLE_SIZE_LOOKUP 1024 // Размер таблицы для быстрого доступа +#define ADC_STEP (ADC_MAX / TABLE_SIZE_LOOKUP) // Шаг между значениями АЦП (4095/1024 ≈ 4) + // Предварительно вычисленная таблица для быстрого доступа для каждой таблицы typedef struct { diff --git a/APP/main.c b/APP/main.c index 1a9d2d4..f1eaf80 100644 --- a/APP/main.c +++ b/APP/main.c @@ -31,7 +31,7 @@ void save_temperature_int_one_line(const char* filename, const adc_temp_lookup* printf("Температуры (int one-line) для '%s' сохранены в файл: %s\n", table_name, filename); } -// Функция для сохранения таблицы в C файл в виде статического массива +// Функция для сохранения таблицы в C файл с информацией о равномерном распределении void save_table_to_c_file(const char* filename, const adc_temp_lookup* table, const char* table_name, const char* array_name) { FILE* file = fopen(filename, "w"); @@ -49,9 +49,15 @@ void save_table_to_c_file(const char* filename, const adc_temp_lookup* table, (table_name[0] == 'D' && table_name[1] == 'U') ? g_fast_tables.duct_r1 : (table_name[0] == 'I') ? g_fast_tables.incar_r1 : g_fast_tables.ambient_r1); fprintf(file, "// Всего записей: %d\n", TABLE_SIZE_LOOKUP); + fprintf(file, "// Шаг между ADC значениями: %.2f (ADC_MAX/%d)\n", ADC_STEP, TABLE_SIZE_LOOKUP); fprintf(file, "//\n\n"); - fprintf(file, "#include \n\n"); + fprintf(file, "#include \n"); + fprintf(file, "#include \n\n"); + + // Константы для быстрого доступа + fprintf(file, "#define TABLE_SIZE_%s %d\n", table_name, TABLE_SIZE_LOOKUP); + fprintf(file, "#define ADC_STEP_%s %.2f\n\n", table_name, ADC_STEP); // Структура для элемента таблицы fprintf(file, "// Структура для хранения записи таблицы\n"); @@ -92,57 +98,14 @@ void save_table_to_c_file(const char* filename, const adc_temp_lookup* table, } fprintf(file, "};\n\n"); - // Добавляем функцию для быстрого доступа по ADC + // Функция для быстрого доступа (прямая индексация) fprintf(file, "// Быстрый поиск температуры по ADC (прямая индексация)\n"); fprintf(file, "static inline int16_t %s_get_temp(uint16_t adc_value) {\n", array_name); - fprintf(file, " if (adc_value >= %d) return %s[%d].temp_c;\n", - TABLE_SIZE_LOOKUP, array_name, TABLE_SIZE_LOOKUP - 1); - fprintf(file, " return %s[adc_value].temp_c;\n", array_name); + fprintf(file, " uint16_t index = adc_value / ADC_STEP_%s;\n", table_name); + fprintf(file, " if (index >= TABLE_SIZE_%s) index = TABLE_SIZE_%s - 1;\n", table_name, table_name); + fprintf(file, " return %s[index].temp_c;\n", array_name); fprintf(file, "}\n\n"); - fprintf(file, "// Быстрый поиск сопротивления по ADC (прямая индексация)\n"); - fprintf(file, "static inline float %s_get_resistance(uint16_t adc_value) {\n", array_name); - fprintf(file, " if (adc_value >= %d) return %s[%d].resistance_ohm;\n", - TABLE_SIZE_LOOKUP, array_name, TABLE_SIZE_LOOKUP - 1); - fprintf(file, " return %s[adc_value].resistance_ohm;\n", array_name); - fprintf(file, "}\n\n"); - - // Добавляем функцию для обратного поиска (температура -> сопротивление) - fprintf(file, "// Поиск сопротивления по температуре (бинарный поиск)\n"); - fprintf(file, "static inline float %s_get_resistance_by_temp(int16_t temp_c10) {\n", array_name); - fprintf(file, " if (temp_c10 >= %s[0].temp_c) return %s[0].resistance_ohm;\n", array_name, array_name); - fprintf(file, " if (temp_c10 <= %s[%d].temp_c) return %s[%d].resistance_ohm;\n", - array_name, TABLE_SIZE_LOOKUP - 1, array_name, TABLE_SIZE_LOOKUP - 1); - fprintf(file, " \n"); - fprintf(file, " // Бинарный поиск\n"); - fprintf(file, " int left = 0, right = %d;\n", TABLE_SIZE_LOOKUP - 1); - fprintf(file, " while (left <= right) {\n"); - fprintf(file, " int mid = left + (right - left) / 2;\n"); - fprintf(file, " if (temp_c10 >= %s[mid].temp_c && temp_c10 <= %s[mid + 1].temp_c) {\n", array_name, array_name); - fprintf(file, " // Нашли интервал, интерполируем в логарифмическом масштабе\n"); - fprintf(file, " int16_t t_high = %s[mid].temp_c;\n", array_name); - fprintf(file, " int16_t t_low = %s[mid + 1].temp_c;\n", array_name); - fprintf(file, " float r_high = %s[mid].resistance_ohm;\n", array_name); - fprintf(file, " float r_low = %s[mid + 1].resistance_ohm;\n", array_name); - fprintf(file, " \n"); - fprintf(file, " if (t_high == t_low) return r_high;\n"); - fprintf(file, " \n"); - fprintf(file, " float log_r_high = logf(r_high);\n"); - fprintf(file, " float log_r_low = logf(r_low);\n"); - fprintf(file, " float log_r = log_r_high + (log_r_low - log_r_high) * \n"); - fprintf(file, " (float)(t_high - temp_c10) / (float)(t_high - t_low);\n"); - fprintf(file, " return expf(log_r);\n"); - fprintf(file, " }\n"); - fprintf(file, " \n"); - fprintf(file, " if (temp_c10 > %s[mid].temp_c) {\n", array_name); - fprintf(file, " right = mid - 1;\n"); - fprintf(file, " } else {\n"); - fprintf(file, " left = mid + 1;\n"); - fprintf(file, " }\n"); - fprintf(file, " }\n"); - fprintf(file, " return %s[%d].resistance_ohm;\n", array_name, TABLE_SIZE_LOOKUP - 1); - fprintf(file, "}\n"); - fclose(file); printf("Таблица '%s' сохранена в файл: %s\n", table_name, filename); } diff --git a/APP/src/ADC_Temp.c b/APP/src/ADC_Temp.c index 6b7b25f..cf4b35f 100644 --- a/APP/src/ADC_Temp.c +++ b/APP/src/ADC_Temp.c @@ -464,11 +464,17 @@ void init_fast_lookup_table(eNtcTable table_type, float r1, eAlg use_alg) { max_valid_adc = temp; } - // Заполняем таблицу - теперь ADC растет от 0 до MAX - // При ADC=0: минимальное сопротивление, максимальная температура - // При ADC=MAX: максимальное сопротивление, минимальная температура + // Заполняем таблицу с равномерным шагом + // Теперь ADC значения распределены равномерно с шагом ADC_STEP for (uint16_t i = 0; i < TABLE_SIZE_LOOKUP; i++) { - uint16_t adc = i; // Просто индекс = ADC (0...4095) + // Рассчитываем ADC с равномерным шагом + uint16_t adc = (uint16_t)((float)i * ADC_STEP); + + // Убеждаемся, что ADC не выходит за пределы + if (adc > (uint16_t)(ADC_MAX - 1)) { + adc = (uint16_t)(ADC_MAX - 1); + } + float resistance; float temp; @@ -534,7 +540,7 @@ void init_fast_lookup_table(eNtcTable table_type, float r1, eAlg use_alg) { } 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; @@ -599,7 +605,7 @@ bool is_vcc_equal_to_vref(void) { return (VCC_DIVIDER_MV_INT == VREF_MV_INT); } -// Быстрая функция для конкретной таблицы +// Быстрая функция для конкретной таблицы (оптимизирована для равномерного шага) int16_t get_temperature_log_fast_for_table(uint16_t adc_value, eNtcTable table_type) { if (!is_table_initialized(table_type)) { // Если таблица не инициализирована, используем обычный расчет @@ -611,31 +617,28 @@ int16_t get_temperature_log_fast_for_table(uint16_t adc_value, eNtcTable table_t 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; + // Для равномерного распределения можно вычислить индекс напрямую + uint16_t index = adc_value / ADC_STEP; - if (adc2 == adc1) { - return temp1; - } + // Проверяем границы + if (index >= TABLE_SIZE_LOOKUP) { + index = TABLE_SIZE_LOOKUP - 1; + } + // Если нужно более точное значение - интерполируем с соседними точками + if (adc_value > fast_table[index].adc_value && index < TABLE_SIZE_LOOKUP - 1) { + uint16_t adc1 = fast_table[index].adc_value; + uint16_t adc2 = fast_table[index + 1].adc_value; + int16_t temp1 = fast_table[index].temp_c; + int16_t temp2 = fast_table[index + 1].temp_c; + + if (adc2 > adc1) { 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; - } + return fast_table[index].temp_c; } - // Быстрые функции с использованием активной таблицы int16_t get_temperature_log_fast(uint16_t adc_value) { return get_temperature_log_fast_for_table(adc_value, TABLE_DUCT);