Init
This commit is contained in:
parent
6c359a9c7a
commit
29202b55f4
114
APP/main.c
114
APP/main.c
|
|
@ -1,6 +1,95 @@
|
|||
#include <stdio.h>
|
||||
#include "ADC_Temp.h"
|
||||
|
||||
// Функция для сохранения таблицы в файл
|
||||
void save_table_to_file(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, "Всего записей: %d\n", TABLE_SIZE_LOOKUP);
|
||||
fprintf(file, "%-8s %-12s %-15s\n", "ADC", "Temp (°C)", "Resistance (Ω)");
|
||||
fprintf(file, "----------------------------------------\n");
|
||||
|
||||
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' сохранена в файл: %s\n", table_name, filename);
|
||||
}
|
||||
|
||||
// Функция для сохранения таблицы в CSV формате
|
||||
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, "ADC,Temperature_C,Resistance_Ohm\n");
|
||||
|
||||
for (int i = 0; i < TABLE_SIZE_LOOKUP; i++) {
|
||||
fprintf(file, "%u,%.1f,%.2f\n",
|
||||
table[i].adc_value,
|
||||
table[i].temp_c / 10.0f,
|
||||
table[i].resistance_ohm);
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
printf("Таблица '%s' сохранена в CSV файл: %s\n", table_name, filename);
|
||||
}
|
||||
|
||||
// Функция для сохранения обеих таблиц
|
||||
void save_both_tables(void) {
|
||||
const fast_lookup_tables_t* tables = get_fast_tables();
|
||||
|
||||
// Сохраняем в текстовом формате
|
||||
save_table_to_file("kst45_table.txt", tables->kst45, "KST45");
|
||||
save_table_to_file("incar_table.txt", tables->incar, "INCAR");
|
||||
|
||||
// Сохраняем в CSV формате (удобно для Excel)
|
||||
save_table_to_csv("kst45_table.csv", tables->kst45, "KST45");
|
||||
save_table_to_csv("incar_table.csv", tables->incar, "INCAR");
|
||||
}
|
||||
|
||||
// Функция для сохранения только рабочего диапазона (без зон насыщения)
|
||||
void save_working_range_to_file(const char* filename, const adc_temp_lookup* table,
|
||||
const char* table_name, uint16_t min_adc, uint16_t max_adc) {
|
||||
FILE* file = fopen(filename, "w");
|
||||
if (file == NULL) {
|
||||
printf("Ошибка: не удалось создать файл %s\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(file, "=== Рабочий диапазон таблицы: %s ===\n", table_name);
|
||||
fprintf(file, "Диапазон ADC: %u - %u\n", min_adc, max_adc);
|
||||
fprintf(file, "%-8s %-12s %-15s\n", "ADC", "Temp (°C)", "Resistance (Ω)");
|
||||
fprintf(file, "----------------------------------------\n");
|
||||
|
||||
int count = 0;
|
||||
for (int i = 0; i < TABLE_SIZE_LOOKUP; i++) {
|
||||
if (table[i].adc_value >= min_adc && table[i].adc_value <= max_adc) {
|
||||
fprintf(file, "%-8u %-12.1f %-15.2f\n",
|
||||
table[i].adc_value,
|
||||
table[i].temp_c / 10.0f,
|
||||
table[i].resistance_ohm);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(file, "\nВсего записей в рабочем диапазоне: %d\n", count);
|
||||
fclose(file);
|
||||
printf("Рабочий диапазон таблицы '%s' сохранен в файл: %s\n", table_name, filename);
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Инициализируем обе таблицы одновременно с разными значениями R1
|
||||
init_both_tables(3300.0f, // R1 для KST45
|
||||
|
|
@ -34,39 +123,46 @@ int main() {
|
|||
const fast_lookup_tables_t* tables = get_fast_tables();
|
||||
|
||||
printf("\n=== Пример данных из таблиц быстрого поиска ===\n");
|
||||
printf("KST45 таблица (первые 3 записи):\n");
|
||||
for(int i = 0; i < 3; i++) {
|
||||
printf("KST45 таблица (первые 15 записи):\n");
|
||||
for(int i = 0; i < 15; i++) {
|
||||
printf(" ADC: %u, Temp: %.1f °C, R: %.2f Ω\n",
|
||||
tables->kst45[i].adc_value,
|
||||
tables->kst45[i].temp_c / 10.0f,
|
||||
tables->kst45[i].resistance_ohm);
|
||||
}
|
||||
|
||||
printf("\nINCAR таблица (первые 3 записи):\n");
|
||||
for(int i = 0; i < 3; i++) {
|
||||
printf("\nINCAR таблица (первые 15 записи):\n");
|
||||
for(int i = 0; i < 15; i++) {
|
||||
printf(" ADC: %u, Temp: %.1f °C, R: %.2f Ω\n",
|
||||
tables->incar[i].adc_value,
|
||||
tables->incar[i].temp_c / 10.0f,
|
||||
tables->incar[i].resistance_ohm);
|
||||
}
|
||||
|
||||
|
||||
printf("\nKST45 таблица (последние 3 записи):\n");
|
||||
for(int i = TABLE_SIZE_LOOKUP - 1; i > TABLE_SIZE_LOOKUP - 4; i--) {
|
||||
printf("\nKST45 таблица (последние 15 записи):\n");
|
||||
for(int i = TABLE_SIZE_LOOKUP - 1; i > TABLE_SIZE_LOOKUP - 16; i--) {
|
||||
printf(" ADC: %u, Temp: %.1f °C, R: %.2f Ω\n",
|
||||
tables->kst45[i].adc_value,
|
||||
tables->kst45[i].temp_c / 10.0f,
|
||||
tables->kst45[i].resistance_ohm);
|
||||
}
|
||||
|
||||
printf("\nINCAR таблица (последние 3 записи):\n");
|
||||
for(int i = TABLE_SIZE_LOOKUP - 1; i > TABLE_SIZE_LOOKUP - 4; i--) {
|
||||
printf("\nINCAR таблица (последние 15 записи):\n");
|
||||
for(int i = TABLE_SIZE_LOOKUP - 1; i > TABLE_SIZE_LOOKUP - 16; i--) {
|
||||
printf(" ADC: %u, Temp: %.1f °C, R: %.2f Ω\n",
|
||||
tables->incar[i].adc_value,
|
||||
tables->incar[i].temp_c / 10.0f,
|
||||
tables->incar[i].resistance_ohm);
|
||||
}
|
||||
|
||||
// Сохраняем таблицы в файлы
|
||||
printf("\n=== Сохранение таблиц в файлы ===\n");
|
||||
save_both_tables();
|
||||
|
||||
// Сохраняем только рабочие диапазоны (без зон насыщения)
|
||||
// Для KST45 рабочий диапазон примерно от 58 до 3418
|
||||
save_working_range_to_file("kst45_working_range.txt", tables->kst45, "KST45", 58, 3418);
|
||||
save_working_range_to_file("incar_working_range.txt", tables->incar, "INCAR", 58, 3418);
|
||||
|
||||
// Пример обратного преобразования (температура -> сопротивление)
|
||||
printf("\n=== Обратное преобразование ===\n");
|
||||
|
|
|
|||
|
|
@ -319,48 +319,91 @@ void init_fast_lookup_table(eNtcTable table_type, float r1, eAlg use_alg) {
|
|||
uint16_t min_valid_adc = 0;
|
||||
uint16_t max_valid_adc = 0;
|
||||
|
||||
// Ищем минимальное АЦП, при котором температура >= start_temp
|
||||
// Значения для граничных точек
|
||||
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
|
||||
// Ищем максимальное АЦП, при котором температура <= 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;
|
||||
}
|
||||
}
|
||||
|
||||
// Если не нашли корректные значения, используем весь диапазон
|
||||
if (min_valid_adc == 0) min_valid_adc = 1;
|
||||
if (max_valid_adc == 0) max_valid_adc = (uint16_t)(ADC_MAX - 1);
|
||||
// Заполняем таблицу для всего диапазона 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;
|
||||
|
||||
// Заполняем таблицу
|
||||
for (uint16_t i = 0; i < TABLE_SIZE_LOOKUP; i++) {
|
||||
float ratio = (float)i / (TABLE_SIZE_LOOKUP - 1);
|
||||
uint16_t adc = min_valid_adc + (uint16_t)(ratio * (max_valid_adc - min_valid_adc));
|
||||
uint16_t adc;
|
||||
|
||||
float resistance = calculate_resistance(adc, r1);
|
||||
float temp = get_temperature_from_adc_with_table(adc, use_alg, table_type, r1);
|
||||
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 (temp < start_temp) temp = (float)start_temp;
|
||||
if (temp > end_temp) temp = (float)end_temp;
|
||||
// Убеждаемся, что значения монотонно возрастают и нет дубликатов
|
||||
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;
|
||||
}
|
||||
|
||||
// Устанавливаем флаг инициализации
|
||||
|
|
@ -397,11 +440,6 @@ const fast_lookup_tables_t* get_fast_tables(void) {
|
|||
return &g_fast_tables;
|
||||
}
|
||||
|
||||
// Быстрые функции с использованием активной таблицы
|
||||
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_log_fast_for_table(uint16_t adc_value, eNtcTable table_type) {
|
||||
if (!is_table_initialized(table_type)) {
|
||||
|
|
@ -413,33 +451,14 @@ 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);
|
||||
|
||||
// Защита от выхода за границы
|
||||
if (adc_value >= fast_table[TABLE_SIZE_LOOKUP - 1].adc_value) {
|
||||
return fast_table[TABLE_SIZE_LOOKUP - 1].temp_c;
|
||||
}
|
||||
if (adc_value <= fast_table[0].adc_value) {
|
||||
return fast_table[0].temp_c;
|
||||
}
|
||||
|
||||
// Бинарный поиск интервала
|
||||
int left = 0;
|
||||
int right = TABLE_SIZE_LOOKUP - 1;
|
||||
|
||||
while (left <= right) {
|
||||
int mid = left + (right - left) / 2;
|
||||
|
||||
if (fast_table[mid].adc_value <= adc_value &&
|
||||
(mid == TABLE_SIZE_LOOKUP - 1 || adc_value < fast_table[mid + 1].adc_value)) {
|
||||
// Нашли интервал
|
||||
if (mid == TABLE_SIZE_LOOKUP - 1) {
|
||||
return fast_table[mid].temp_c;
|
||||
}
|
||||
|
||||
// Простой линейный поиск (так как таблица небольшая - 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[mid].adc_value;
|
||||
uint16_t adc2 = fast_table[mid + 1].adc_value;
|
||||
int16_t temp1 = fast_table[mid].temp_c;
|
||||
int16_t temp2 = fast_table[mid + 1].temp_c;
|
||||
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;
|
||||
|
|
@ -447,15 +466,19 @@ int16_t get_temperature_log_fast_for_table(uint16_t adc_value, eNtcTable table_t
|
|||
|
||||
return temp1 + ((int32_t)(temp2 - temp1) * (adc_value - adc1)) / (adc2 - adc1);
|
||||
}
|
||||
|
||||
if (adc_value < fast_table[mid].adc_value) {
|
||||
right = mid - 1;
|
||||
} else {
|
||||
left = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Если не нашли, возвращаем ближайшее значение
|
||||
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);
|
||||
}
|
||||
|
||||
// Альтернативная простая версия
|
||||
|
|
@ -463,11 +486,6 @@ 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(int16_t temperature_c10) {
|
||||
return get_resistance_log_fast_for_table(temperature_c10, active_config.table_type);
|
||||
}
|
||||
|
||||
// Функция для получения сопротивления из температуры для конкретной таблицы
|
||||
float get_resistance_log_fast_for_table(int16_t temperature_c10, eNtcTable table_type) {
|
||||
if (!is_table_initialized(table_type)) {
|
||||
|
|
@ -522,6 +540,11 @@ float get_resistance_log_fast_for_table(int16_t temperature_c10, eNtcTable table
|
|||
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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue