MODEL_ADC_EX/APP/main.c

219 lines
10 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#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 <stdint.h>\n");
fprintf(file, "#include <math.h>\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;
}