diff --git a/APP/inc/ADC_Temp.h b/APP/inc/ADC_Temp.h index 7033dcc..1fce8a9 100644 --- a/APP/inc/ADC_Temp.h +++ b/APP/inc/ADC_Temp.h @@ -41,4 +41,5 @@ int16_t get_temperature_linear_fast(uint16_t adc_value); float get_resistance_from_adc(uint16_t adc_value); // Новая функция для получения сопротивления float get_resistance_log_fast(int16_t temperature_c10); +float get_resistance_fast_simple(int16_t temperature_c10); #endif //MDF_ADC_TEMP_KST45_14_2_H \ No newline at end of file diff --git a/APP/main.c b/APP/main.c index a7e7046..8b7c49d 100644 --- a/APP/main.c +++ b/APP/main.c @@ -18,8 +18,8 @@ int main() { printf("T_FAST = %.1f °C\n", T_FAST / 10.0f); printf("Resistance = %.2f Ω\n", resistance); -// float R = get_resistance_log_fast(250); -// printf("Resistance FAST = %.2f Ω\n", R); + float R = get_resistance_log_fast(227); + printf("Resistance FAST = %.2f Ω\n", R); // Пример доступа к таблице diff --git a/APP/src/ADC_Temp.c b/APP/src/ADC_Temp.c index 67b0376..728495b 100644 --- a/APP/src/ADC_Temp.c +++ b/APP/src/ADC_Temp.c @@ -347,15 +347,17 @@ int16_t get_temperature_linear_fast(uint16_t adc_value) { } +// Функция для получения сопротивления из температуры (обратное преобразование) // Функция для получения сопротивления из температуры (обратное преобразование) float get_resistance_log_fast(int16_t temperature_c10) { // temperature_c10 - температура в °C * 10 (например, 250 = 25.0°C) + // Таблица отсортирована по убыванию температуры (от max к min) // Защита от выхода за границы - if (temperature_c10 <= fast_lookup[0].temp_c) { + if (temperature_c10 >= fast_lookup[0].temp_c) { // >= максимальной температуры return fast_lookup[0].resistance_ohm; } - if (temperature_c10 >= fast_lookup[TABLE_SIZE_LOOKUP - 1].temp_c) { + if (temperature_c10 <= fast_lookup[TABLE_SIZE_LOOKUP - 1].temp_c) { // <= минимальной температуры return fast_lookup[TABLE_SIZE_LOOKUP - 1].resistance_ohm; } @@ -366,40 +368,75 @@ float get_resistance_log_fast(int16_t temperature_c10) { while (left <= right) { int mid = left + (right - left) / 2; - if (fast_lookup[mid].temp_c <= temperature_c10 && - (mid == TABLE_SIZE_LOOKUP - 1 || temperature_c10 < fast_lookup[mid + 1].temp_c)) { + // Таблица отсортирована по убыванию температуры + if (temperature_c10 <= fast_lookup[mid].temp_c && + temperature_c10 >= fast_lookup[mid + 1].temp_c) { // Нашли интервал - if (mid == TABLE_SIZE_LOOKUP - 1) { - return fast_lookup[mid].resistance_ohm; - } + // mid - точка с большей температурой + // mid+1 - точка с меньшей температурой - // Линейная интерполяция по температуре - int16_t temp1 = fast_lookup[mid].temp_c; - int16_t temp2 = fast_lookup[mid + 1].temp_c; - float res1 = fast_lookup[mid].resistance_ohm; - float res2 = fast_lookup[mid + 1].resistance_ohm; + int16_t temp_high = fast_lookup[mid].temp_c; // большая температура + int16_t temp_low = fast_lookup[mid + 1].temp_c; // меньшая температура + float res_high = fast_lookup[mid].resistance_ohm; // сопротивление при большей температуре + float res_low = fast_lookup[mid + 1].resistance_ohm; // сопротивление при меньшей температуре // Избегаем деления на ноль - if (temp2 == temp1) { - return res1; + if (temp_high == temp_low) { + return res_high; } - // Интерполяция в логарифмическом масштабе для сопротивления - // (так как сопротивление изменяется экспоненциально) - float log_res1 = logf(res1); - float log_res2 = logf(res2); - float log_res = log_res1 + (log_res2 - log_res1) * - (float)(temperature_c10 - temp1) / (float)(temp2 - temp1); + // Интерполяция в логарифмическом масштабе + float log_res_high = logf(res_high); + float log_res_low = logf(res_low); + float log_res = log_res_high + (log_res_low - log_res_high) * + (float)(temp_high - temperature_c10) / (float)(temp_high - temp_low); return expf(log_res); } - if (temperature_c10 < fast_lookup[mid].temp_c) { - right = mid - 1; + if (temperature_c10 > fast_lookup[mid].temp_c) { + right = mid - 1; // ищем в сторону больших температур } else { - left = mid + 1; + left = mid + 1; // ищем в сторону меньших температур } } - return fast_lookup[0].resistance_ohm; // Если не нашли, возвращаем первое значение + return fast_lookup[TABLE_SIZE_LOOKUP - 1].resistance_ohm; +} + +// Упрощенная версия с линейным поиском +float get_resistance_fast_simple(int16_t temperature_c10) { + // Защита от выхода за границы + if (temperature_c10 >= fast_lookup[0].temp_c) { + return fast_lookup[0].resistance_ohm; + } + if (temperature_c10 <= fast_lookup[TABLE_SIZE_LOOKUP - 1].temp_c) { + return fast_lookup[TABLE_SIZE_LOOKUP - 1].resistance_ohm; + } + + // Линейный поиск интервала + for (uint16_t i = 0; i < TABLE_SIZE_LOOKUP - 1; i++) { + if (temperature_c10 <= fast_lookup[i].temp_c && + temperature_c10 >= fast_lookup[i + 1].temp_c) { + + int16_t temp_high = fast_lookup[i].temp_c; + int16_t temp_low = fast_lookup[i + 1].temp_c; + float res_high = fast_lookup[i].resistance_ohm; + float res_low = fast_lookup[i + 1].resistance_ohm; + + if (temp_high == temp_low) { + return res_high; + } + + // Логарифмическая интерполяция + float log_res_high = logf(res_high); + float log_res_low = logf(res_low); + float log_res = log_res_high + (log_res_low - log_res_high) * + (float)(temp_high - temperature_c10) / (float)(temp_high - temp_low); + + return expf(log_res); + } + } + + return fast_lookup[TABLE_SIZE_LOOKUP - 1].resistance_ohm; } \ No newline at end of file