#include #include "ADC_Temp.h" // Упрощенная структура для хранения записи таблицы typedef struct { uint16_t adc_value; // Значение АЦП int16_t temp_c; // Температура в °C * 10 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) { FILE* file = fopen(filename, "w"); if (file == NULL) { printf("Ошибка: не удалось создать файл %s\n", filename); return; } // Заголовок файла fprintf(file, "//\n"); fprintf(file, "// Автоматически сгенерированный файл таблицы быстрого поиска: %s\n", table_name); fprintf(file, "// VCC делителя = %.2f V\n", VCC_DIVIDER_MV / 1000.0f); fprintf(file, "// VREF АЦП = %.2f V\n", VREF_MV / 1000.0f); fprintf(file, "// Сопротивление R1 = %.0f Ом\n", (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"); 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"); fprintf(file, "typedef struct {\n"); fprintf(file, " uint16_t adc_value; // Значение АЦП\n"); fprintf(file, " int16_t temp_c; // Температура в °C * 10\n"); fprintf(file, " float resistance_ohm; // Сопротивление в Ом\n"); fprintf(file, "} adc_temp_lookup_entry_t;\n\n"); // Объявление массива fprintf(file, "static const adc_temp_lookup_entry_t %s[%d] = {\n", array_name, TABLE_SIZE_LOOKUP); // Вывод данных - по 4 элемента в строке для компактности for (int i = 0; i < TABLE_SIZE_LOOKUP; i++) { if (i % 4 == 0) { fprintf(file, " "); } // Округляем сопротивление до 2 знаков после запятой fprintf(file, "{%u, %d, %.2ff}", table[i].adc_value, table[i].temp_c, table[i].resistance_ohm); if (i < TABLE_SIZE_LOOKUP - 1) { fprintf(file, ", "); } if ((i + 1) % 4 == 0) { fprintf(file, "\n"); } } // Завершаем массив if (TABLE_SIZE_LOOKUP % 4 != 0) { fprintf(file, "\n"); } fprintf(file, "};\n\n"); // Функция для быстрого доступа (прямая индексация) fprintf(file, "// Быстрый поиск температуры по ADC (прямая индексация)\n"); fprintf(file, "static inline int16_t %s_get_temp(uint16_t adc_value) {\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"); fclose(file); printf("Таблица '%s' сохранена в файл: %s\n", table_name, filename); } // Функция для сохранения таблицы в CSV формате (для Excel) void save_table_to_csv(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_DIVIDER = %.2f V, VREF = %.2f V\n", VCC_DIVIDER_MV / 1000.0f, VREF_MV / 1000.0f); fprintf(file, "ADC,Temperature_C,Temperature_x10,Resistance_Ohm\n"); for (int i = 0; i < TABLE_SIZE_LOOKUP; i++) { fprintf(file, "%u,%.1f,%d,%.2f\n", table[i].adc_value, table[i].temp_c / 10.0f, table[i].temp_c, table[i].resistance_ohm); } fclose(file); printf("Таблица '%s' сохранена в CSV файл: %s\n", table_name, filename); } // Функция для сохранения таблицы в TXT формате (для просмотра) void save_table_to_txt(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 делителя = %.2f V\n", VCC_DIVIDER_MV / 1000.0f); fprintf(file, "VREF АЦП = %.2f V\n", VREF_MV / 1000.0f); fprintf(file, "Всего записей: %d\n", TABLE_SIZE_LOOKUP); fprintf(file, "%-8s %-12s %-15s\n", "ADC", "Temp (°C)", "Resistance (Ω)"); fprintf(file, "---------------------------------------------\n"); // Выводим каждые 100 записей для компактности for (int i = 0; i < TABLE_SIZE_LOOKUP; i++) { fprintf(file, "%-8u %-12.1f %-15.2f\n", table[i].adc_value, table[i].temp_c / 10.0f, table[i].resistance_ohm); } fclose(file); printf("Таблица '%s' сохранена в TXT файл: %s\n", table_name, filename); } // Функция для сохранения всех таблиц во всех форматах void save_all_tables_to_files(void) { const fast_lookup_tables_t* tables = get_fast_tables(); printf("\n=== Сохранение таблиц в файлы ===\n"); // Сохраняем DUCT таблицу 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_temperatures.txt", tables->duct, "DUCT"); // Сохраняем INCAR таблицу save_table_to_c_file("incar_table_array.c", tables->incar, "INCAR", "incar_lookup_table"); save_table_to_csv("incar_table.csv", tables->incar, "INCAR"); save_table_to_txt("incar_table.txt", tables->incar, "INCAR"); save_temperature_int_one_line("incar_temperatures.txt", tables->incar, "INCAR"); // Сохраняем AMBIENT таблицу save_table_to_c_file("ambient_table_array.c", tables->ambient, "AMBIENT", "ambient_lookup_table"); save_table_to_csv("ambient_table.csv", tables->ambient, "AMBIENT"); save_table_to_txt("ambient_table.txt", tables->ambient, "AMBIENT"); save_temperature_int_one_line("ambient_temperatures.txt", tables->ambient, "AMBIENT"); printf("\nВсе таблицы успешно сохранены!\n"); } int main() { printf("=== Генерация таблиц быстрого поиска для NTC термисторов ===\n"); printf("Конфигурация:\n"); printf(" VCC делителя = %.2f V\n", VCC_DIVIDER_MV / 1000.0f); printf(" VREF АЦП = %.2f V\n", VREF_MV / 1000.0f); printf(" ADC_MAX = %.0f\n", ADC_MAX); // Инициализируем все три таблицы printf("\n=== Инициализация таблиц ===\n"); init_all_tables(3000.0f, // R1 для DUCT (KST45) - 3kΩ 20000.0f, // R1 для INCAR - 20kΩ 20000.0f, // R1 для AMBIENT (NTC 10k) - 20kΩ ALG_STEINHART); printf("Таблицы успешно инициализированы\n"); // Сохраняем таблицы в файлы save_all_tables_to_files(); printf("\n=== Готово ===\n"); printf("Сгенерированы файлы:\n"); printf(" - duct_table_array.c, incar_table_array.c, ambient_table_array.c (статический массив)\n"); printf(" - duct_table.csv, incar_table.csv, ambient_table.csv (для Excel)\n"); printf(" - duct_table.txt, incar_table.txt, ambient_table.txt (для просмотра)\n"); printf(" - duct_temperatures.txt, incar_temperatures.txt, ambient_temperatures.txt (температуры в одну строку)\n"); return 0; }