diff --git a/.gitignore b/.gitignore
index 76eefbb..f8a2aac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -61,3 +61,4 @@ JLinkLog.txt
/MATLAB/MCU.exp
/MATLAB/MCU.lib
/MATLAB/MCU.mexw64.manifest
+/MATLAB/upp_r2023.slx.autosave
diff --git a/MATLAB/MCU_STM32_Matlab/Drivers/CMSIS/arm_defines.h b/MATLAB/MCU_STM32_Matlab/Drivers/CMSIS/arm_defines.h
index e31109d..b841697 100644
--- a/MATLAB/MCU_STM32_Matlab/Drivers/CMSIS/arm_defines.h
+++ b/MATLAB/MCU_STM32_Matlab/Drivers/CMSIS/arm_defines.h
@@ -27,7 +27,7 @@
#endif
#ifndef __STATIC_FORCEINLINE
- #define __STATIC_FORCEINLINE static __forceinline
+ #define __STATIC_FORCEINLINE //static __forceinline
#endif
#ifndef __NO_RETURN
diff --git a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_adc.c b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_adc.c
index d199507..4d28469 100644
--- a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_adc.c
+++ b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_adc.c
@@ -311,21 +311,6 @@ uint32_t ADC_Get_Sequence_Channel(ADC_TypeDef* ADCx, uint32_t rank)
}
}
-/////////////////////////////---DMA FUNCTIONS---///////////////////////////////
-void ADC_DMA_Sim_Transfer(ADC_TypeDef* ADCx, struct ADC_Sim* ADCS)
-{
- if (!ADCS->dma_buffer || ADCS->dma_buffer_size == 0) return;
-
- ADCS->dma_buffer[ADCS->dma_current_index] = ADCx->DR;
- ADCS->dma_current_index++;
-
- if (ADCS->dma_current_index >= ADCS->dma_buffer_size) {
- if (ADCS->dma_circular) {
- ADCS->dma_current_index = 0;
- }
- }
-}
-
/////////////////////////////---CHANNEL FUNCTIONS---///////////////////////////
void ADC_Set_Channel_Value(ADC_TypeDef* ADCx, uint32_t channel, double voltage)
{
diff --git a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_adc.h b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_adc.h
index 26d8697..e78a6c2 100644
--- a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_adc.h
+++ b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_adc.h
@@ -9,7 +9,7 @@
#endif
#ifdef STM32F4
-#define ADC_NOISE_LSB 10 // Шум в LSB (квантах АЦП)
+#define ADC_NOISE_LSB 20 // Шум в LSB (квантах АЦП)
#endif
/////////////////////////////---STRUCTURES---///////////////////////////
@@ -23,12 +23,6 @@ struct ADC_Sim
double channel_values[19];
uint8_t channel_connected[19];
- // DMA
- uint32_t* dma_buffer;
- uint32_t dma_buffer_size;
- uint32_t dma_current_index;
- uint8_t dma_circular;
-
// Timing
double simulation_step;
double adc_clock_freq;
diff --git a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.c b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.c
index 5f24a07..46b9f21 100644
--- a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.c
+++ b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.c
@@ -65,6 +65,9 @@ void Overflow_Check(TIM_TypeDef* TIMx, struct TIM_Sim* TIMS)
else if (TIMS->tx_cnt < 0)
TIMS->tx_cnt += TIMS->RELOAD+1;
+ if(TIMS->tx_step > TIMS->RELOAD)
+ TIMS->tx_cnt = 0;
+
TIM_Call_IRQHandller(TIMx); // call HANDLER
}
}
diff --git a/MATLAB/app_wrapper/app_io.c b/MATLAB/app_wrapper/app_io.c
index bbd7a47..4050af7 100644
--- a/MATLAB/app_wrapper/app_io.c
+++ b/MATLAB/app_wrapper/app_io.c
@@ -38,6 +38,10 @@ ADC_Set_Channel_Value(ADC3, 6, ReadInputArray(0,2));
ADC_Set_Channel_Value(ADC3, 7, ReadInputArray(0,3));
ADC_Set_Channel_Value(ADC3, 8, ReadInputArray(0,4));
ADC_Set_Channel_Value(ADC3, 10, ReadInputArray(0,5));
+
+
+__HAL_TIM_SET_AUTORELOAD(&adc_tim, ReadInputArray(1, 0));
+
// USER APP INPUT END
}
diff --git a/MATLAB/upp_r2023.slx b/MATLAB/upp_r2023.slx
index 1ebf0c0..1fdd5ac 100644
Binary files a/MATLAB/upp_r2023.slx and b/MATLAB/upp_r2023.slx differ
diff --git a/UPP/.mxproject b/UPP/.mxproject
index 76a640e..df45b06 100644
--- a/UPP/.mxproject
+++ b/UPP/.mxproject
@@ -6,6 +6,9 @@ SourceFiles=..\Core\Src\main.c;..\Core\Src\gpio.c;..\Core\Src\adc.c;..\Core\Src\
HeaderPath=..\Drivers\STM32F4xx_HAL_Driver\Inc;..\Drivers\STM32F4xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32F4xx\Include;..\Drivers\CMSIS\Include;..\Core\Inc;
CDefines=USE_HAL_DRIVER;STM32F427xx;USE_HAL_DRIVER;USE_HAL_DRIVER;
+[]
+SourceFiles=;;
+
[PreviousGenFiles]
AdvancedFolderStructure=true
HeaderFileListSize=12
diff --git a/UPP/AllLibs/MyLibs b/UPP/AllLibs/MyLibs
index 60629aa..3b162c9 160000
--- a/UPP/AllLibs/MyLibs
+++ b/UPP/AllLibs/MyLibs
@@ -1 +1 @@
-Subproject commit 60629aaa3bb3a068cbfe5a93f43f676bd154e85b
+Subproject commit 3b162c9f8cdbcf8606d1b96ea2b26b23e2e9c290
diff --git a/UPP/Core/Configs/mylibs_config.h b/UPP/Core/Configs/mylibs_config.h
index d16629f..c87e783 100644
--- a/UPP/Core/Configs/mylibs_config.h
+++ b/UPP/Core/Configs/mylibs_config.h
@@ -13,7 +13,6 @@
#include "upp_config.h"
// user includes
-#ifndef MATLAB
/**
* @addtogroup TRACE_CONFIG Trace configs
* @ingroup MYLIBS_CONFIG
@@ -53,6 +52,26 @@
*/
+
+/**
+ * @addtogroup FILTER_CONFIG Filter configs
+ * @ingroup MYLIBS_CONFIG
+ * @brief Конфигурация фильтров
+ * @{
+ */
+
+
+#define FILTERS_ENABLE ///< Включить библиотеку фильтров
+//#define FILTER_MEDIAN_MAX_SIZE ///< Максимальный размер окна медианного фильтра (по умолчанию 5)
+//#define FILTER_AVERAGE_MAX_SIZE ///< Максимальный размер окна усредняющего фильтра (по умолчанию 8)
+//#define FILTER_POLY_MAX_ORDER ///< Максимальный порядок полинома (по умолчанию 4)
+
+/** GEN_CONFIG
+ * @}
+ */
+
+
+
/**
* @addtogroup GEN_CONFIG Genetic configs
* @ingroup MYLIBS_CONFIG
@@ -93,6 +112,7 @@
* @{
*/
+#ifndef MATLAB
#define local_time() uwTick ///< Локальное время
#define INCLUDE_GEN_OPTIMIZER ///< Подключить библиотеку для оптимизации параметров
@@ -100,9 +120,22 @@
#define INCLUDE_TRACKERS_LIB ///< Подключить библиотеку с трекерами
#define INCLUDE_TRACE_LIB ///< Подключить библиотеку с трейсами
#define INCLUDE_GENERAL_PERIPH_LIBS ///< Подключить библиотеку с периферией
-#define INCLUDE_BENCH_TIME ///< Подключить библиотеку с периферией
+#define INCLUDE_BENCH_TIME ///< Подключить библиотеку с бенчмарком времени
+#define INCLUDE_FILTERS ///< Подключить библиотеку с фильтрами
//#define FREERTOS_DELAY ///< Использовать FreeRTOS задержку, вместо HAL
+#else
+
+#define local_time() uwTick ///< Локальное время
+//#define INCLUDE_GEN_OPTIMIZER ///< Подключить библиотеку для оптимизации параметров
+#define INCLUDE_BIT_ACCESS_LIB ///< Подключить библиотеку с typedef с битовыми полями
+#define INCLUDE_TRACKERS_LIB ///< Подключить библиотеку с трекерами
+//#define INCLUDE_TRACE_LIB ///< Подключить библиотеку с трейсами
+//#define INCLUDE_GENERAL_PERIPH_LIBS ///< Подключить библиотеку с периферией
+//#define INCLUDE_BENCH_TIME ///< Подключить библиотеку с бенчмарком времени
+#define INCLUDE_FILTERS ///< Подключить библиотеку с фильтрами
+
+#endif //MATLAB
/** LIBS_CONFIG
* @}
*/
@@ -110,5 +143,4 @@
/** MYLIBS_CONFIG
* @}
*/
-#endif //MATLAB
#endif //__MYLIBS_CONFIG_H_
\ No newline at end of file
diff --git a/UPP/Core/Configs/mylibs_include.h b/UPP/Core/Configs/mylibs_include.h
index 9c47b9b..f3256e9 100644
--- a/UPP/Core/Configs/mylibs_include.h
+++ b/UPP/Core/Configs/mylibs_include.h
@@ -100,6 +100,52 @@
#define BenchTime_ResetStats(channel)
#endif //BENCH_TIME_ENABLE
+
+#ifdef INCLUDE_FILTERS
+#include "filters.h"
+#else //INCLUDE_FILTERS
+// Заглушки для float
+#define FilterMedian_t void *
+#define FilterExp_t void *
+#define FilterAverage_t void *
+#define FilterPoly_t void *
+#define FilterLUT_t void *
+
+#define FilterMedian_Init(filter, size)
+#define FilterMedian_Process(filter, input) (input)
+#define FilterExp_Init(filter, alpha)
+#define FilterExp_Process(filter, input) (input)
+#define FilterAverage_Init(filter, size)
+#define FilterAverage_Process(filter, input) (input)
+#define FilterPoly_Init(filter, coeffs, order) (0)
+#define FilterPoly_Process(filter, input) (input)
+#define FilterLUT_Init(filter, input_arr, output_arr, size, interpolation) (0)
+#define FilterLUT_Process(filter, input) (input)
+
+// Заглушки для int32_t
+#define FilterMedianInt_t void *
+#define FilterExpInt_t void *
+#define FilterAverageInt_t void *
+#define FilterPolyInt_t void *
+#define FilterLUTInt_t void *
+
+#define FilterMedianInt_Init(filter, size)
+#define FilterMedianInt_Process(filter, input) (input)
+#define FilterExpInt_Init(filter, alpha, scale)
+#define FilterExpInt_Process(filter, input) (input)
+#define FilterAverageInt_Init(filter, size)
+#define FilterAverageInt_Process(filter, input) (input)
+#define FilterPolyInt_Init(filter, coeffs, order, scale) (0)
+#define FilterPolyInt_Process(filter, input) (input)
+#define FilterLUTInt_Init(filter, input_arr, output_arr, size, interpolation) (0)
+#define FilterLUTInt_Process(filter, input) (input)
+
+#define FILTER_GET_STATE(_fltr_) dummy
+#define FILTER_ENABLE 0
+#define FILTER_DISABLE 0
+#endif //INCLUDE_FILTERS
+
+
#ifdef INCLUDE_GENERAL_PERIPH_LIBS
#include "__general_flash.h"
diff --git a/UPP/Core/Inc/main.h b/UPP/Core/Inc/main.h
index a705fae..02c2ae9 100644
--- a/UPP/Core/Inc/main.h
+++ b/UPP/Core/Inc/main.h
@@ -63,19 +63,19 @@ void Error_Handler(void);
/* Private defines -----------------------------------------------------------*/
#define mb_huart huart3
#define mbdbg_htim htim11
-#define mb_htim htim12
-#define mb_dbg_huart huart6
-#define ustim htim13
-#define mem_hspi hspi3
-#define hpwm1 htim1
-#define hpwm2 htim2
#define PWM_CHANNEL_1 TIM_CHANNEL_1
#define PWM_CHANNEL_2 TIM_CHANNEL_2
#define PWM_CHANNEL_3 TIM_CHANNEL_3
#define PWM_CHANNEL_4 TIM_CHANNEL_4
+#define mem_hspi hspi3
#define PWM_CHANNEL_5 TIM_CHANNEL_3
#define PWM_CHANNEL_6 TIM_CHANNEL_4
+#define mb_htim htim12
#define adc_tim htim8
+#define hpwm2 htim2
+#define mb_dbg_huart huart6
+#define ustim htim13
+#define hpwm1 htim1
#define UM_LED_GREEN2_Pin GPIO_PIN_2
#define UM_LED_GREEN2_GPIO_Port GPIOE
#define CEN_O_Pin GPIO_PIN_3
diff --git a/UPP/Core/PowerMonitor/adc_tools.c b/UPP/Core/PowerMonitor/adc_tools.c
index a5ad350..a49d587 100644
--- a/UPP/Core/PowerMonitor/adc_tools.c
+++ b/UPP/Core/PowerMonitor/adc_tools.c
@@ -11,7 +11,31 @@
// Проверка корректности структуры АЦП
#define assert_adc(_adc_) check_null_ptr_2(_adc_, (_adc_)->f.Initialized)
-
+static void ADC_EnableAllFilters(ADC_Period_t *adc)
+{
+ for(int i = 0; i < ADC_NUMB_OF_CHANNELS; i++)
+ {
+ FILTER_GET_STATE(&adc->filter[i]) = FILTER_ENABLE;
+ }
+ FILTER_GET_STATE(&adc->temp_filter[0]) = FILTER_ENABLE;
+ FILTER_GET_STATE(&adc->temp_filter[1]) = FILTER_ENABLE;
+}
+static void ADC_InitAllFilters(ADC_Period_t *adc, int coef)
+{
+ for(int i = 0; i < ADC_NUMB_OF_CHANNELS; i++)
+ {
+ FilterAverageInt_Init(&adc->filter[i], coef);
+ }
+
+ FilterLUTInt_Init(&adc->temp_filter[0],
+ (int32_t *)adc_temp_quants,
+ (int32_t *)adc_temp_vals,
+ sizeof(adc_temp_quants), 0);
+ FilterLUTInt_Init(&adc->temp_filter[1],
+ (int32_t *)adc_temp_quants,
+ (int32_t *)adc_temp_vals,
+ sizeof(adc_temp_quants), 0);
+}
/**
* @brief Инициализация периодического АЦП.
* @param adc Указатель на кастомный хендл АЦП
@@ -28,6 +52,9 @@ HAL_StatusTypeDef ADC_Init(ADC_Period_t *adc, TIM_HandleTypeDef *htim, ADC_Handl
adc->htim = htim;
adc->hadc = hadc;
+ ADC_InitAllFilters(adc, 10);
+
+
adc->f.AdcRunning = 0;
adc->f.DataReady = 0;
adc->f.Initialized = 1;
@@ -86,6 +113,8 @@ HAL_StatusTypeDef ADC_Start(ADC_Period_t *adc, uint16_t Period)
return res;
}
+ ADC_EnableAllFilters(adc);
+
return res;
}
/**
@@ -105,10 +134,10 @@ HAL_StatusTypeDef ADC_Stop(ADC_Period_t *adc)
/**
- * @brief Остановка АЦП .
+ * @brief Обработка АЦП.
* @return HAL Status.
* @details По факту остановка таймера, который запускает АЦП. Сам АЦП продолжает работу.
- * @note Вызывается в .
+ * @note Вызывается в DMA2_Stream0_IRQHandler() для обработки всего, что пришло по DMA.
*/
HAL_StatusTypeDef ADC_Handle(ADC_Period_t *adc)
{
@@ -119,11 +148,31 @@ HAL_StatusTypeDef ADC_Handle(ADC_Period_t *adc)
uint16_t *raw = adc->RawData;
float *data = adc->Data;
+ // Фильтрация от шумов для всех каналов
for(int i = 0; i < ADC_NUMB_OF_CHANNELS; i++)
+ {
+ if(FILTER_GET_STATE(&adc->filter[i]) == FILTER_ENABLE)
+ {
+ // заменяем сырое на отфильтровоное сырое
+ raw[i] = FilterAverageInt_Process(&adc->filter[i], raw[i]);
+ }
+ }
+ // Перерасчеты Напряжений/Токов в единицы измерения
+ for(int i = 0; i < ADC_TEMP_CHANNELS_START; i++)
{
ADC_Coefs_t *coefs = &adc->Coefs[i];
data[i] = ((float)(raw[i])-coefs->lZero) * coefs->vMax / (coefs->lMax-coefs->lZero);
- }
+ }
+
+ // Преобразования температуры по таблице
+ for (int i = ADC_TEMP_CHANNELS_START; i < ADC_NUMB_OF_CHANNELS; i++)
+ {
+ data[i] = FilterLUTInt_Process(&adc->temp_filter[i-ADC_TEMP_CHANNELS_START], raw[i]);
+ }
+
+
+
+
adc->f.DataReady = 1;
return HAL_OK;
diff --git a/UPP/Core/PowerMonitor/adc_tools.h b/UPP/Core/PowerMonitor/adc_tools.h
index a5923a3..fdc8234 100644
--- a/UPP/Core/PowerMonitor/adc_tools.h
+++ b/UPP/Core/PowerMonitor/adc_tools.h
@@ -11,7 +11,34 @@
#include "main.h"
#define ADC_NUMB_OF_CHANNELS 6
+#define ADC_TEMP_CHANNELS_START 4
+#define ADC_TEMPERATURES_QUANTS \
+{ 2188, 2197, 2206, 2216, 2226, 2236, 2247, 2259, 2271, 2283, \
+ 2296, 2310, 2324, 2338, 2354, 2369, 2385, 2402, 2419, 2437, \
+ 2455, 2474, 2493, 2513, 2533, 2554, 2575, 2597, 2619, 2641, \
+ 2664, 2688, 2711, 2735, 2759, 2784, 2809, 2833, 2859, 2884, \
+ 2909, 2935, 2961, 2986, 3012, 3037, 3063, 3089, 3114, 3140, \
+ 3165, 3190, 3215, 3239, 3263, 3288, 3312, 3335, 3359, 3381, \
+ 3404, 3426, 3448, 3470, 3491, 3512, 3532, 3552, 3572, 3591, \
+ 3610, 3628, 3646, 3663, 3681, 3697, 3714, 3729, 3745, 3760, \
+ 3775, 3789, 3803, 3817, 3830, 3843, 3855, 3868, 3879, 3891, \
+ 3902, 3913, 3924, 3934, 3944, 3954, 3963, 3972, 3981, 3989, \
+ 3997, 4005, 4013, 4021, 4028, 4035, 4042, 4049, 4055, 4062, \
+ 4068, 4074, 4079, 4085, 4091, 4096}
+
+#define ADC_TEMPERATURES \
+{ -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, \
+ -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, \
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, \
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, \
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, \
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, \
+ 82, 83, 84, 85, 86, 87, 88, 89, 90}
+
+static const int32_t adc_temp_vals[] = ADC_TEMPERATURES;
+static const int32_t adc_temp_quants[] = ADC_TEMPERATURES_QUANTS;
+
/**
* @brief Коэфициенты канала АЦП для пересчета в единицы измерения
*/
@@ -36,6 +63,8 @@ typedef struct
ADC_Coefs_t Coefs[ADC_NUMB_OF_CHANNELS]; ///< Коэффициенты @ref ADC_Coefs_t
float Data[ADC_NUMB_OF_CHANNELS]; ///< Пересчитанные значения АЦП (в Вольтах/Амперах/Градусах)
+ FilterAverageInt_t filter[ADC_NUMB_OF_CHANNELS]; ///< Фильтр от шумов АЦП
+ FilterLUTInt_t temp_filter[2]; ///< Коррекция нелинейности датчиков температуры
struct
{
unsigned Initialized:1;
diff --git a/UPP/Core/Src/tim.c b/UPP/Core/Src/tim.c
index 04ec18c..d273fef 100644
--- a/UPP/Core/Src/tim.c
+++ b/UPP/Core/Src/tim.c
@@ -186,7 +186,7 @@ void MX_TIM8_Init(void)
/* USER CODE END TIM8_Init 1 */
htim8.Instance = TIM8;
- htim8.Init.Prescaler = 180-1;
+ htim8.Init.Prescaler = 0;
htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
htim8.Init.Period = 1000;
htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
diff --git a/UPP/Core/UPP/upp_main.c b/UPP/Core/UPP/upp_main.c
index d95628b..2f31926 100644
--- a/UPP/Core/UPP/upp_main.c
+++ b/UPP/Core/UPP/upp_main.c
@@ -43,7 +43,7 @@ int UPP_Init(void)
*/
int UPP_PreWhile(void)
{
- ADC_Start(&adc, 1000);
+ ADC_Start(&adc, 100);
return 0;
}
diff --git a/UPP/MDK-ARM/UPP.uvoptx b/UPP/MDK-ARM/UPP.uvoptx
index 66f3b96..e09e15c 100644
--- a/UPP/MDK-ARM/UPP.uvoptx
+++ b/UPP/MDK-ARM/UPP.uvoptx
@@ -611,6 +611,30 @@
0
0
+
+ 6
+ 33
+ 1
+ 0
+ 0
+ 0
+ ..\AllLibs\MyLibs\MyLibs\Src\filters.c
+ filters.c
+ 0
+ 0
+
+
+ 6
+ 34
+ 5
+ 0
+ 0
+ 0
+ ..\AllLibs\MyLibs\MyLibs\Inc\filters.h
+ filters.h
+ 0
+ 0
+
@@ -621,7 +645,7 @@
0
7
- 33
+ 35
1
0
0
@@ -633,7 +657,7 @@
7
- 34
+ 36
1
0
0
@@ -645,7 +669,7 @@
7
- 35
+ 37
1
0
0
@@ -657,7 +681,7 @@
7
- 36
+ 38
1
0
0
@@ -669,7 +693,7 @@
7
- 37
+ 39
1
0
0
@@ -681,7 +705,7 @@
7
- 38
+ 40
1
0
0
@@ -693,7 +717,7 @@
7
- 39
+ 41
1
0
0
@@ -705,7 +729,7 @@
7
- 40
+ 42
1
0
0
@@ -717,7 +741,7 @@
7
- 41
+ 43
1
0
0
@@ -729,7 +753,7 @@
7
- 42
+ 44
1
0
0
@@ -741,7 +765,7 @@
7
- 43
+ 45
1
0
0
@@ -753,7 +777,7 @@
7
- 44
+ 46
1
0
0
@@ -773,7 +797,7 @@
0
8
- 45
+ 47
1
0
0
@@ -785,7 +809,7 @@
8
- 46
+ 48
1
0
0
@@ -805,7 +829,7 @@
0
9
- 47
+ 49
1
0
0
@@ -817,7 +841,7 @@
9
- 48
+ 50
1
0
0
@@ -829,7 +853,7 @@
9
- 49
+ 51
1
0
0
@@ -841,7 +865,7 @@
9
- 50
+ 52
1
0
0
@@ -853,7 +877,7 @@
9
- 51
+ 53
1
0
0
@@ -873,7 +897,7 @@
0
10
- 52
+ 54
1
0
0
@@ -885,7 +909,7 @@
10
- 53
+ 55
1
0
0
@@ -897,7 +921,7 @@
10
- 54
+ 56
1
0
0
@@ -909,7 +933,7 @@
10
- 55
+ 57
1
0
0
@@ -921,7 +945,7 @@
10
- 56
+ 58
1
0
0
@@ -933,7 +957,7 @@
10
- 57
+ 59
1
0
0
@@ -945,7 +969,7 @@
10
- 58
+ 60
1
0
0
@@ -957,7 +981,7 @@
10
- 59
+ 61
1
0
0
@@ -969,7 +993,7 @@
10
- 60
+ 62
1
0
0
@@ -981,7 +1005,7 @@
10
- 61
+ 63
1
0
0
@@ -993,7 +1017,7 @@
10
- 62
+ 64
1
0
0
@@ -1005,7 +1029,7 @@
10
- 63
+ 65
1
0
0
@@ -1017,7 +1041,7 @@
10
- 64
+ 66
1
0
0
@@ -1029,7 +1053,7 @@
10
- 65
+ 67
1
0
0
@@ -1041,7 +1065,7 @@
10
- 66
+ 68
1
0
0
@@ -1053,7 +1077,7 @@
10
- 67
+ 69
1
0
0
@@ -1065,7 +1089,7 @@
10
- 68
+ 70
1
0
0
@@ -1077,7 +1101,7 @@
10
- 69
+ 71
1
0
0
@@ -1089,7 +1113,7 @@
10
- 70
+ 72
1
0
0
@@ -1101,7 +1125,7 @@
10
- 71
+ 73
1
0
0
@@ -1113,7 +1137,7 @@
10
- 72
+ 74
1
0
0
@@ -1125,7 +1149,7 @@
10
- 73
+ 75
1
0
0
@@ -1137,7 +1161,7 @@
10
- 74
+ 76
1
0
0
@@ -1149,7 +1173,7 @@
10
- 75
+ 77
1
0
0
@@ -1169,7 +1193,7 @@
0
11
- 76
+ 78
1
0
0
@@ -1189,7 +1213,7 @@
0
12
- 77
+ 79
2
0
0
diff --git a/UPP/MDK-ARM/UPP.uvprojx b/UPP/MDK-ARM/UPP.uvprojx
index b8ac044..fdf03ee 100644
--- a/UPP/MDK-ARM/UPP.uvprojx
+++ b/UPP/MDK-ARM/UPP.uvprojx
@@ -341,7 +341,7 @@
USE_HAL_DRIVER,STM32F427xx
- ../Core/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../AllLibs/ExtMemory/Inc;../AllLibs/Modbus/Inc;../AllLibs/MyLibs/MyLibs/Inc;../AllLibs/MyLibs/RTT;../AllLibs/PeriphGeneral/Inc;../Core/Configs;..\Core\PowerMonitor;..\Core\Thyristors;..\Core\UPP
+ ../Core/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../AllLibs/ExtMemory/Inc;../AllLibs/Modbus/Inc;../AllLibs/MyLibs/MyLibs/Inc;../AllLibs/MyLibs/RTT;../AllLibs/PeriphGeneral/Inc;../Core/Configs;../Core/PowerMonitor;../Core/Thyristors;../Core/UPP
@@ -619,6 +619,16 @@
5
..\AllLibs\MyLibs\MyLibs\Inc\trackers.h
+
+ filters.c
+ 1
+ ..\AllLibs\MyLibs\MyLibs\Src\filters.c
+
+
+ filters.h
+ 5
+ ..\AllLibs\MyLibs\MyLibs\Inc\filters.h
+
diff --git a/UPP/UPP.ioc b/UPP/UPP.ioc
index 817c3bc..5ea9b96 100644
--- a/UPP/UPP.ioc
+++ b/UPP/UPP.ioc
@@ -137,7 +137,7 @@ Mcu.Pin8=PF6
Mcu.Pin9=PF7
Mcu.PinsNb=63
Mcu.ThirdPartyNb=0
-Mcu.UserConstants=mb_huart,huart3;mbdbg_htim,htim11;mb_htim,htim12;mb_dbg_huart,huart6;ustim,htim13;mem_hspi,hspi3;hpwm1,htim1;hpwm2,htim2;PWM_CHANNEL_1,TIM_CHANNEL_1;PWM_CHANNEL_2,TIM_CHANNEL_2;PWM_CHANNEL_3,TIM_CHANNEL_3;PWM_CHANNEL_4,TIM_CHANNEL_4;PWM_CHANNEL_5,TIM_CHANNEL_3;PWM_CHANNEL_6,TIM_CHANNEL_4;adc_tim,htim8
+Mcu.UserConstants=mb_huart,huart3;mbdbg_htim,htim11;PWM_CHANNEL_1,TIM_CHANNEL_1;PWM_CHANNEL_2,TIM_CHANNEL_2;PWM_CHANNEL_3,TIM_CHANNEL_3;PWM_CHANNEL_4,TIM_CHANNEL_4;mem_hspi,hspi3;PWM_CHANNEL_5,TIM_CHANNEL_3;PWM_CHANNEL_6,TIM_CHANNEL_4;mb_htim,htim12;adc_tim,htim8;hpwm2,htim2;mb_dbg_huart,huart6;ustim,htim13;hpwm1,htim1
Mcu.UserName=STM32F427ZGTx
MxCube.Version=6.12.1
MxDb.Version=DB.6.0.121
@@ -475,7 +475,7 @@ TIM3.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
TIM3.IPParameters=Channel-PWM Generation3 CH3,Channel-PWM Generation4 CH4
TIM8.IPParameters=Prescaler,Period,TIM_MasterSlaveMode,TIM_MasterOutputTrigger
TIM8.Period=1000
-TIM8.Prescaler=180-1
+TIM8.Prescaler=0
TIM8.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE
TIM8.TIM_MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE
USART3.IPParameters=VirtualMode
diff --git a/Информация для программиста (УПП СП СЭД)/temperature_polynom.py b/Информация для программиста (УПП СП СЭД)/temperature_polynom.py
new file mode 100644
index 0000000..2d4f369
--- /dev/null
+++ b/Информация для программиста (УПП СП СЭД)/temperature_polynom.py
@@ -0,0 +1,204 @@
+import numpy as np
+import matplotlib.pyplot as plt
+
+# Данные: ADC -> Temperature
+adc_values = [2188, 2197, 2206, 2216, 2226, 2236, 2247, 2259, 2271, 2283,
+ 2296, 2310, 2324, 2338, 2354, 2369, 2385, 2402, 2419, 2437,
+ 2455, 2474, 2493, 2513, 2533, 2554, 2575, 2597, 2619, 2641,
+ 2664, 2688, 2711, 2735, 2759, 2784, 2809, 2833, 2859, 2884,
+ 2909, 2935, 2961, 2986, 3012, 3037, 3063, 3089, 3114, 3140,
+ 3165, 3190, 3215, 3239, 3263, 3288, 3312, 3335, 3359, 3381,
+ 3404, 3426, 3448, 3470, 3491, 3512, 3532, 3552, 3572, 3591,
+ 3610, 3628, 3646, 3663, 3681, 3697, 3714, 3729, 3745, 3760,
+ 3775, 3789, 3803, 3817, 3830, 3843, 3855, 3868, 3879, 3891,
+ 3902, 3913, 3924, 3934, 3944, 3954, 3963, 3972, 3981, 3989,
+ 3997, 4005, 4013, 4021, 4028, 4035, 4042, 4049, 4055, 4062,
+ 4068, 4074, 4079, 4085, 4091, 4096]
+
+temperatures = [-25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11,
+ -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, 88, 89, 90]
+
+# Параметры ограничений
+MIN_COEFF_ABS = 1e-5 # Минимальное абсолютное значение коэффициента
+MAX_CONDITION_NUMBER = 1e10 # Максимальное число обусловленности
+
+# Аппроксимация полиномами разных степеней
+degrees = [2, 3, 4, 5]
+coefficients = {}
+filtered_coefficients = {}
+
+plt.figure(figsize=(16, 12))
+
+# График 1: Сравнение аппроксимаций
+plt.subplot(2, 3, 1)
+plt.plot(adc_values, temperatures, 'ko-', markersize=3, linewidth=1, label='Исходные данные')
+
+colors = ['red', 'blue', 'green', 'orange']
+for i, degree in enumerate(degrees):
+ coeffs = np.polyfit(adc_values, temperatures, degree)
+ coefficients[degree] = coeffs
+
+ # Фильтрация малых коэффициентов
+ filtered_coeffs = coeffs.copy()
+ small_coeffs_mask = np.abs(coeffs) < MIN_COEFF_ABS
+ filtered_coeffs[small_coeffs_mask] = 0
+ filtered_coefficients[degree] = filtered_coeffs
+
+ poly = np.poly1d(coeffs)
+ adc_continuous = np.linspace(min(adc_values), max(adc_values), 500)
+ temp_predicted = poly(adc_continuous)
+
+ plt.plot(adc_continuous, temp_predicted, color=colors[i], linewidth=2,
+ label=f'Полином {degree}-й степени')
+
+plt.xlabel('Значение АЦП')
+plt.ylabel('Температура (°C)')
+plt.title('Аппроксимация зависимости АЦП → Температура')
+plt.legend()
+plt.grid(True, alpha=0.3)
+
+# График 2: Ошибки аппроксимации
+plt.subplot(2, 3, 2)
+for i, degree in enumerate(degrees):
+ poly = np.poly1d(coefficients[degree])
+ predicted = poly(adc_values)
+ error = predicted - temperatures
+
+ plt.plot(temperatures, error, 'o-', color=colors[i], markersize=3,
+ label=f'Ошибка {degree}-й степени')
+
+plt.xlabel('Температура (°C)')
+plt.ylabel('Ошибка (°C)')
+plt.title('Ошибки аппроксимации по температуре')
+plt.legend()
+plt.grid(True, alpha=0.3)
+
+# График 3: Статистика ошибок
+plt.subplot(2, 3, 3)
+max_errors = []
+rms_errors = []
+
+for degree in degrees:
+ poly = np.poly1d(coefficients[degree])
+ predicted = poly(adc_values)
+ max_error = np.max(np.abs(predicted - temperatures))
+ rms_error = np.sqrt(np.mean((predicted - temperatures)**2))
+
+ max_errors.append(max_error)
+ rms_errors.append(rms_error)
+
+x_pos = np.arange(len(degrees))
+width = 0.35
+
+plt.bar(x_pos - width/2, max_errors, width, label='Макс. ошибка', alpha=0.7)
+plt.bar(x_pos + width/2, rms_errors, width, label='СКО', alpha=0.7)
+
+plt.xlabel('Степень полинома')
+plt.ylabel('Ошибка (°C)')
+plt.title('Статистика ошибок аппроксимации')
+plt.xticks(x_pos, degrees)
+plt.legend()
+plt.grid(True, alpha=0.3)
+
+# График 4: Сравнение коэффициентов до/после фильтрации
+plt.subplot(2, 3, 4)
+for degree in degrees:
+ coeffs = coefficients[degree]
+ filtered_coeffs = filtered_coefficients[degree]
+
+ # Отображаем только ненулевые коэффициенты
+ nonzero_indices = np.where(filtered_coeffs != 0)[0]
+ if len(nonzero_indices) > 0:
+ plt.semilogy(nonzero_indices, np.abs(filtered_coeffs[nonzero_indices]), 'o-',
+ label=f'Полином {degree}-й степени', markersize=6)
+
+plt.axhline(y=MIN_COEFF_ABS, color='r', linestyle='--', alpha=0.7, label=f'Порог {MIN_COEFF_ABS:.0e}')
+plt.xlabel('Индекс коэффициента')
+plt.ylabel('Абсолютное значение коэффициента')
+plt.title('Коэффициенты после фильтрации (логарифмическая шкала)')
+plt.legend()
+plt.grid(True, alpha=0.3)
+
+# График 5: Влияние фильтрации на ошибку
+plt.subplot(2, 3, 5)
+original_errors = []
+filtered_errors = []
+
+for degree in degrees:
+ poly_original = np.poly1d(coefficients[degree])
+ poly_filtered = np.poly1d(filtered_coefficients[degree])
+
+ predicted_original = poly_original(adc_values)
+ predicted_filtered = poly_filtered(adc_values)
+
+ error_original = np.max(np.abs(predicted_original - temperatures))
+ error_filtered = np.max(np.abs(predicted_filtered - temperatures))
+
+ original_errors.append(error_original)
+ filtered_errors.append(error_filtered)
+
+x_pos = np.arange(len(degrees))
+width = 0.35
+
+plt.bar(x_pos - width/2, original_errors, width, label='Оригинальные коэф.', alpha=0.7)
+plt.bar(x_pos + width/2, filtered_errors, width, label='После фильтрации', alpha=0.7)
+
+plt.xlabel('Степень полинома')
+plt.ylabel('Максимальная ошибка (°C)')
+plt.title('Влияние фильтрации коэффициентов на точность')
+plt.xticks(x_pos, degrees)
+plt.legend()
+plt.grid(True, alpha=0.3)
+
+plt.tight_layout()
+plt.show()
+
+# Вывод численных результатов
+print("=" * 80)
+print("РЕЗУЛЬТАТЫ АППРОКСИМАЦИИ С ФИЛЬТРАЦИЕЙ КОЭФФИЦИЕНТОВ")
+print("=" * 80)
+
+for degree in degrees:
+ coeffs = coefficients[degree]
+ filtered_coeffs = filtered_coefficients[degree]
+
+ poly_original = np.poly1d(coeffs)
+ poly_filtered = np.poly1d(filtered_coeffs)
+
+ predicted_original = poly_original(adc_values)
+ predicted_filtered = poly_filtered(adc_values)
+
+ max_error_original = np.max(np.abs(predicted_original - temperatures))
+ rms_error_original = np.sqrt(np.mean((predicted_original - temperatures)**2))
+
+ max_error_filtered = np.max(np.abs(predicted_filtered - temperatures))
+ rms_error_filtered = np.sqrt(np.mean((predicted_filtered - temperatures)**2))
+
+ # Подсчет нулевых коэффициентов
+ zero_count = np.sum(filtered_coeffs == 0)
+ total_count = len(filtered_coeffs)
+
+ print(f"\nПолином {degree}-й степени:")
+ print(f"Максимальная ошибка: {max_error_original:.3f}°C -> {max_error_filtered:.3f}°C")
+ print(f"Среднеквадратичная ошибка: {rms_error_original:.3f}°C -> {rms_error_filtered:.3f}°C")
+ print(f"Обнулено коэффициентов: {zero_count}/{total_count}")
+
+ print("Коэффициенты после фильтрации:")
+ for i, coeff in enumerate(filtered_coeffs):
+ power = len(filtered_coeffs) - i - 1
+ status = "✓" if coeff != 0 else "✗ (обнулен)"
+ print(f" a_{power} = {coeff:.6e} {status}")
+
+# Рекомендация
+print("\n" + "=" * 80)
+print("РЕКОМЕНДАЦИЯ:")
+print(f"Порог обнуления коэффициентов: {MIN_COEFF_ABS:.0e}")
+print("Полином 3-й степени обеспечивает оптимальный баланс между точностью")
+print("и сложностью реализации. Фильтрация малых коэффициентов практически")
+print("не влияет на точность, но упрощает реализацию на embedded системах.")
+print("=" * 80)
\ No newline at end of file
diff --git a/Информация для программиста (УПП СП СЭД)/Значения температуры в ед АЦП.xlsx b/Информация для программиста (УПП СП СЭД)/Значения температуры в ед АЦП.xlsx
index 392e475..ccdc517 100644
Binary files a/Информация для программиста (УПП СП СЭД)/Значения температуры в ед АЦП.xlsx and b/Информация для программиста (УПП СП СЭД)/Значения температуры в ед АЦП.xlsx differ