diff --git a/MATLAB/MCU_Wrapper/run_mex.bat b/MATLAB/MCU_Wrapper/run_mex.bat
index c30c29f..add764a 100644
--- a/MATLAB/MCU_Wrapper/run_mex.bat
+++ b/MATLAB/MCU_Wrapper/run_mex.bat
@@ -54,6 +54,33 @@ set code_PERIPH=.\MCU_STM32_Matlab\stm32_matlab_conf.c^
.\MCU_STM32_Matlab\Drivers\STM32_SIMULINK\stm32_matlab_gpio.c^
.\MCU_STM32_Matlab\Drivers\STM32_SIMULINK\stm32_matlab_dma.c^
.\MCU_STM32_Matlab\Drivers\STM32_SIMULINK\stm32_periph_registers.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\BasicMathFunctions\BasicMathFunctions.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\BasicMathFunctions\BasicMathFunctionsF16.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\BayesFunctions\BayesFunctions.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\BayesFunctions\BayesFunctionsF16.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\CommonTables\CommonTables.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\CommonTables\CommonTablesF16.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\ComplexMathFunctions\ComplexMathFunctions.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\ComplexMathFunctions\ComplexMathFunctionsF16.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\ControllerFunctions\ControllerFunctions.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\DistanceFunctions\DistanceFunctionsF16.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\FastMathFunctions\FastMathFunctions.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\FastMathFunctions\FastMathFunctionsF16.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\FilteringFunctions\FilteringFunctions.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\FilteringFunctions\FilteringFunctionsF16.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\InterpolationFunctions\InterpolationFunctions.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\InterpolationFunctions\InterpolationFunctionsF16.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\MatrixFunctions\MatrixFunctions.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\MatrixFunctions\MatrixFunctionsF16.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\QuaternionMathFunctions\QuaternionMathFunctions.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\StatisticsFunctions\StatisticsFunctions.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\StatisticsFunctions\StatisticsFunctionsF16.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\SupportFunctions\SupportFunctions.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\SupportFunctions\SupportFunctionsF16.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\SVMFunctions\SVMFunctions.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\SVMFunctions\SVMFunctionsF16.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\TransformFunctions\TransformFunctions.c^
+ .\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\TransformFunctions\TransformFunctionsF16.c^
.\MCU_STM32_Matlab\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal.c^
.\MCU_STM32_Matlab\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_adc.c^
.\MCU_STM32_Matlab\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_adc_ex.c^
@@ -75,7 +102,24 @@ set includes_PERIPH=-I".\MCU_STM32_Matlab\."^
-I".\MCU_STM32_Matlab\Drivers\CMSIS"^
-I".\MCU_STM32_Matlab\Drivers\CMSIS\Device\STM32F4xx"^
-I".\MCU_STM32_Matlab\Drivers\STM32F4xx_HAL_Driver\Inc"^
- -I".\MCU_STM32_Matlab\Drivers\STM32F4xx_HAL_Driver\Inc\Legacy"
+ -I".\MCU_STM32_Matlab\Drivers\STM32F4xx_HAL_Driver\Inc\Legacy"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Include"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\PrivateInclude"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\BasicMathFunctions"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\BayesFunctions"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\CommonTables"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\ComplexMathFunctions"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\ControllerFunctions"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\DistanceFunctions"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\FastMathFunctions"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\FilteringFunctions"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\InterpolationFunctions"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\MatrixFunctions"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\QuaternionMathFunctions"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\StatisticsFunctions"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\SupportFunctions"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\SVMFunctions"^
+ -I".\MCU_STM32_Matlab\Drivers\CMSIS\DSP\Source\TransformFunctions"
:: PERIPH BAT END
::-------------------------------------------------------------------------
diff --git a/MATLAB/app_wrapper/app_io.c b/MATLAB/app_wrapper/app_io.c
index cd56554..780a0bf 100644
--- a/MATLAB/app_wrapper/app_io.c
+++ b/MATLAB/app_wrapper/app_io.c
@@ -33,7 +33,7 @@ void Write_PowerMonitor(real_T* Buffer, int ind_port)
int nn = 0;
for (int i = 0; i < 3; i++)
{ //0-2
- WriteOutputArray(upp.pm.measured.Ureal[i], ind_port, nn++);
+ WriteOutputArray(upp.pm.measured.U[i], ind_port, nn++);
}
for (int i = 0; i < 3; i++)
{ //3-5
@@ -45,16 +45,19 @@ void Write_PowerMonitor(real_T* Buffer, int ind_port)
}
for (int i = 0; i < 3; i++)
{ //9-11
- WriteOutputArray(upp.pm.measured.Ireal[i], ind_port, nn++);
+ WriteOutputArray(upp.pm.measured.I[i], ind_port, nn++);
}
for (int i = 0; i < 2; i++)
{ //12-13
WriteOutputArray(upp.pm.measured.T[i], ind_port, nn++);
}
- { //14-16
- WriteOutputArray(upp.pm.measured.U_mean, ind_port, nn++);
- WriteOutputArray(upp.pm.measured.I_mean, ind_port, nn++);
- WriteOutputArray(upp.pm.measured.F_mean, ind_port, nn++);
+ { //14-19
+ WriteOutputArray(upp.pm.measured.Uvec, ind_port, nn++);
+ WriteOutputArray(upp.pm.measured.Ivec, ind_port, nn++);
+ WriteOutputArray(upp.pm.measured.Imean[0], ind_port, nn++);
+ WriteOutputArray(upp.pm.measured.Imean[1], ind_port, nn++);
+ WriteOutputArray(upp.pm.measured.Imean[2], ind_port, nn++);
+ WriteOutputArray(upp.pm.measured.Fmean, ind_port, nn++);
}
}
diff --git a/MATLAB/upp_r2023.slx b/MATLAB/upp_r2023.slx
index d0868f1..87e6520 100644
Binary files a/MATLAB/upp_r2023.slx and b/MATLAB/upp_r2023.slx differ
diff --git a/UPP/AllLibs/MyLibs b/UPP/AllLibs/MyLibs
index 9bff9ad..513f56f 160000
--- a/UPP/AllLibs/MyLibs
+++ b/UPP/AllLibs/MyLibs
@@ -1 +1 @@
-Subproject commit 9bff9ad44dd625819ef654e98ca351d5bc5568a9
+Subproject commit 513f56fe7dbf0fa8e6a075c22e138c908a01d33f
diff --git a/UPP/Core/Configs/upp_config.h b/UPP/Core/Configs/upp_config.h
index 8e26bda..709f35b 100644
--- a/UPP/Core/Configs/upp_config.h
+++ b/UPP/Core/Configs/upp_config.h
@@ -66,7 +66,7 @@
/* Параметры определения перехода через ноль */
#define ZERO_CROSS_HYSTERESIS_PERCENT_DEFAULT 2.0
-#define ZERO_CROSS_DEBOUNCE_10US_DEFAULT 2*100 // (2.5 * 100 = 2.5 мс)
+#define ZERO_CROSS_DEBOUNCE_CNT_DEFAULT 2*100 // (2.5 * 100 = 2.5 мс)
/* Параметры ШИМ для тиристоров */
#define PWM_THYR_FREQUENCY_HZ_DEFAULT 20000
@@ -84,9 +84,9 @@
* @{
*/
/* Периоды вызова всякого */
-#define PM_ADC_PERIOD_US 10 ///< Период опроса АЦП в мкс
-#define PM_SLOW_PERIOD_10US 50 ///< Период обновление медленных расчетов в 10мкс
-#define PM_TEMP_PERIOD_10US 5000 ///< Период обновление датчиков температуры в 10мкс
+#define PM_ADC_PERIOD_US 10 ///< Период опроса АЦП в мкс
+#define PM_SLOW_PERIOD_CNT 50 ///< Период обновления медленных расчетов тиках @ref PM_ADC_PERIOD_US
+#define PM_TEMP_SLOW_PERIOD_CNT 200 ///< Период обновления датчиков температуры в тиках @ref PM_SLOW_PERIOD_CNT
/* Частоты таймеров в МГц*/
#define ADC_TIM8_FREQ_MZH 180 ///< Частота тиков таймера АЦП
diff --git a/UPP/Core/PowerMonitor/adc_tools.c b/UPP/Core/PowerMonitor/adc_tools.c
index 3ac7560..3e38f48 100644
--- a/UPP/Core/PowerMonitor/adc_tools.c
+++ b/UPP/Core/PowerMonitor/adc_tools.c
@@ -178,6 +178,7 @@ HAL_StatusTypeDef ADC_Handle(ADC_Periodic_t *adc)
if(Filter_isDataReady(&adc->filter[0]))
adc->f.DataReady = 1;
+
return HAL_OK;
}
@@ -217,7 +218,7 @@ void ADC_UpdateStatistics(ADC_Periodic_t *adc, uint8_t channel, ADC_StatLevel_t
}
// Накопление для Avg/RMS
- stat->Sum += ABS(value);
+ stat->Sum += fabsf(value);
stat->SumSquares += value * value;
stat->SampleCount++;
diff --git a/UPP/Core/PowerMonitor/phases_transform.c b/UPP/Core/PowerMonitor/phases_transform.c
new file mode 100644
index 0000000..cf6ab63
--- /dev/null
+++ b/UPP/Core/PowerMonitor/phases_transform.c
@@ -0,0 +1,49 @@
+/**
+******************************************************************************
+* @file phases_transform.c
+* @brief Функции для преобразования напряжений/токов в многофазных системах
+******************************************************************************
+* @details
+******************************************************************************/
+#include "phases_transform.h"
+#define SQRT3 1.7320508
+
+/**
+ * @brief Рассчитать результирующий вектор трехфазной системы по фазным величинам.
+ * @return Длина вектора (модуль).
+ * @note Вызывается в DMA2_Stream0_IRQHandler() для обработки всего, что пришло по DMA.
+ */
+float vector_abs_phase_calc(float phase1, float phase2)
+{
+ /* Двухвазная система координат x-y */
+ float x = phase1;
+ float y = (-phase1 - 2*phase2)/SQRT3;
+ float V = 0;
+ arm_status res = arm_sqrt_f32(x*x + y*y, &V);
+
+ if(res == ARM_MATH_SUCCESS)
+ return V;
+ else
+ return 0;
+}
+
+/**
+ * @brief Рассчитать результирующий вектор трехфазной системы по линейным величинам.
+ * @return Длина вектора (модуль).
+ * @note Вызывается в DMA2_Stream0_IRQHandler() для обработки всего, что пришло по DMA.
+ */
+float vector_abs_linear_calc(float phase1, float phase2)
+{
+ /* Двухвазная система координат x-y */
+ float x = (phase1 - phase2)/SQRT3;
+ float y = -phase1 - phase2;
+ float V = 0;
+ arm_status res = arm_sqrt_f32(x*x + y*y, &V);
+
+ if(res == ARM_MATH_SUCCESS)
+ return V;
+ else
+ return 0;
+}
+
+
diff --git a/UPP/Core/PowerMonitor/phases_transform.h b/UPP/Core/PowerMonitor/phases_transform.h
new file mode 100644
index 0000000..5d78003
--- /dev/null
+++ b/UPP/Core/PowerMonitor/phases_transform.h
@@ -0,0 +1,16 @@
+/**
+******************************************************************************
+* @file phases_transform.h
+* @brief Функции для преобразования напряжений/токов в многофазных системах
+******************************************************************************
+*****************************************************************************/
+#ifndef _PHASES_TRANSFORM_H_
+#define _PHASES_TRANSFORM_H_
+#include "main.h"
+
+/* Рассчитать результирующий вектор трехфазной системы по фазным величинам. */
+float vector_abs_phase_calc(float phase1, float phase2);
+/* Рассчитать результирующий вектор трехфазной системы по линейным величинам. */
+float vector_abs_linear_calc(float phase1, float phase2);
+
+#endif /* _PHASES_TRANSFORM_H_ */
diff --git a/UPP/Core/PowerMonitor/power_monitor.c b/UPP/Core/PowerMonitor/power_monitor.c
index fa0e51e..aeb06ec 100644
--- a/UPP/Core/PowerMonitor/power_monitor.c
+++ b/UPP/Core/PowerMonitor/power_monitor.c
@@ -6,9 +6,11 @@
* @details
******************************************************************************/
#include "power_monitor.h"
+#include "phases_transform.h"
#include "adc.h"
#include "tim.h"
+static void __SynchAvgFilters(PowerMonitor_t *hpm);
HAL_StatusTypeDef PowerMonitor_Init(PowerMonitor_t *hpm)
{
@@ -59,27 +61,27 @@ HAL_StatusTypeDef PowerMonitor_Init(PowerMonitor_t *hpm)
/* Инициализация экпоненциального фильтра медленного алга */
- for(int i = 0; i < 3; i++)
+ for(int i = 0; i < EXP_ALL; i++)
{
- if(FilterExp_Init(&hpm->measured.exp[i], (float)MB_INTERNAL.param.pm.mean_alpha/65535))
+ if(FilterExp_Init(&hpm->exp[i], (float)MB_INTERNAL.param.pm.mean_alpha/65535))
return HAL_ERROR;
- Filter_Start(&hpm->measured.exp[i]);
+ Filter_Start(&hpm->exp[i]);
}
/* Инициализация среднего фильтра медленного алга */
for(int i = 0; i < ADC_NUMB_OF_REGULAR_CHANNELS; i++)
{
- if(FilterAverage_Init(&hpm->measured.avg[i], PM_SLOW_PERIOD_10US, FILTER_MODE_DEFAULT))
- return HAL_ERROR;
+ if(FilterAverage_Init(&hpm->avg[i], PM_SLOW_PERIOD_CNT, FILTER_MODE_DEFAULT))
+ return HAL_ERROR;
- Filter_Start(&hpm->measured.avg[i]);
+ Filter_Start(&hpm->avg[i]);
}
for(int i = 0; i < ADC_NUMB_OF_T_CHANNELS; i++)
{
- if(FilterAverage_Init(&hpm->measured.avg[ADC_TEMP_CHANNELS_START+i], PM_TEMP_PERIOD_10US, FILTER_MODE_DEFAULT))
+ if(FilterAverage_Init(&hpm->avg[ADC_TEMP_CHANNELS_START+i], PM_TEMP_SLOW_PERIOD_CNT, FILTER_MODE_DEFAULT))
return HAL_ERROR;
- Filter_Start(&hpm->measured.avg[ADC_TEMP_CHANNELS_START+i]);
+ Filter_Start(&hpm->avg[ADC_TEMP_CHANNELS_START+i]);
}
return HAL_OK;
@@ -104,76 +106,87 @@ void PowerMonitor_SlowHandle(PowerMonitor_t *hpm)
return;
if(!hpm->f.runSlow)
return;
- hpm->f.runSlow = 0;
PowerMonitor_Measured_t *meas = &hpm->measured;
+ /* Обработка температур */
+ float t1 = hpm->adc.Data[ADC_CHANNEL_TEMP1];
+ float t2 = hpm->adc.Data[ADC_CHANNEL_TEMP2];
+ meas->T[TEMP_1] = Filter_Process(&hpm->avg[ADC_CHANNEL_TEMP1], t1);
+ meas->T[TEMP_2] = Filter_Process(&hpm->avg[ADC_CHANNEL_TEMP2], t2);
+
+ /* Расчет третьей фазы */
meas->Uslow[U_BC] = -meas->Uslow[U_BA] - meas->Uslow[U_AC];
meas->Islow[I_B] = -meas->Islow[I_A] - meas->Islow[I_C];
-
- float umean = 0;
- float imean = 0;
- float fmean = 0;
+
+ /* Расчет всякого для трех фаз отдельно */
+ float fmean = 0; // средняя частота по трем фазам
+ float iphase_mean = 0; // средний ток каждой фазы
for(int i = 0; i < 3; i++)
{
- umean += ABS(meas->Uslow[i]);
- imean += ABS(meas->Islow[i]);
- fmean += ABS(meas->F[i]);
+ /* Получение частоты фазы */
+ meas->F[i] = ZC_GetFrequency(&hpm->zc, i) / 2;
+ fmean += meas->F[i];
+
+ /* Средний ток фазы */
+ iphase_mean = fabsf(meas->Islow[i]);
+ meas->Imean[i] = Filter_Process(&hpm->exp[EXP_IC+i], iphase_mean);
}
- umean /=3;
- imean /=3;
- fmean /=3;
+ /* Получение средней частоты по трем фазам */
+ fmean /= 3;
+ meas->Fmean = Filter_Process(&hpm->exp[EXP_F], fmean);
- meas->U_mean = Filter_Process(&meas->exp[0], umean);
- meas->I_mean = Filter_Process(&meas->exp[1], imean);
- meas->F_mean = Filter_Process(&meas->exp[2], fmean);
+
+ /* Расчет результирущих векторов трехфазной сети */
+ float uvec = vector_abs_linear_calc(meas->Uslow[U_BA], meas->Uslow[U_AC]);
+ float ivec = vector_abs_phase_calc(meas->Islow[I_A], meas->Islow[I_C]);
+ meas->Uvec = Filter_Process(&hpm->exp[EXP_U], uvec);
+ meas->Ivec = Filter_Process(&hpm->exp[EXP_I], ivec);
+ hpm->f.runSlow = 0;
}
void PowerMonitor_Handle(PowerMonitor_t *hpm)
{
if(hpm == NULL)
return;
- /* Считываем АЦП */
- ADC_Handle(&hpm->adc);
+ /* Считываем АЦП с пересчетами и медианой фильтрацией от выбросов */
+ ADC_Handle(&hpm->adc);
-
- /* Заполняем величины */
+ /* Заполняем величины Напряжений/Токов */
PowerMonitor_Measured_t *meas = &hpm->measured;
- meas->Ureal[U_BA] = hpm->adc.Data[ADC_CHANNEL_UBA];
- meas->Ureal[U_AC] = hpm->adc.Data[ADC_CHANNEL_UAC];
- meas->Ureal[U_BC] = -meas->Ureal[U_BA] - meas->Ureal[U_AC];
- meas->Ireal[I_C] = hpm->adc.Data[ADC_CHANNEL_IC];
- meas->Ireal[I_A] = hpm->adc.Data[ADC_CHANNEL_IA];
- meas->Ireal[I_B] = -meas->Ireal[I_A] - meas->Ireal[I_C];
- meas->T[TEMP_1] = hpm->adc.Data[ADC_CHANNEL_TEMP1];
- meas->T[TEMP_2] = hpm->adc.Data[ADC_CHANNEL_TEMP2];
+ meas->U[U_BA] = hpm->adc.Data[ADC_CHANNEL_UBA];
+ meas->U[U_AC] = hpm->adc.Data[ADC_CHANNEL_UAC];
+ meas->U[U_BC] = -meas->U[U_BA] - meas->U[U_AC];
+ meas->I[I_C] = hpm->adc.Data[ADC_CHANNEL_IC];
+ meas->I[I_A] = hpm->adc.Data[ADC_CHANNEL_IA];
+ meas->I[I_B] = -meas->I[I_A] - meas->I[I_C];
/* Преобразуем в относительные единицы (о.е.) */
for(int i = 0; i < 3; i++)
{
- meas->U[i] = 10*meas->Ureal[i]/MB_INTERNAL.param.nominal.U;
- meas->I[i] = 10*meas->Ireal[i]/MB_INTERNAL.param.nominal.I;
+ meas->Ufast[i] = 10*meas->U[i]/MB_INTERNAL.param.nominal.U;
+ meas->Ifast[i] = 10*meas->I[i]/MB_INTERNAL.param.nominal.I;
}
/* Ищем переход через ноль */
- ZC_ProcessAllChannels(&hpm->zc, meas->U, usTick);
- for(int i = 0; i < 3; i++)
- {
- meas->F[i] = ZC_GetFrequency(&hpm->zc, i) / 2;
- }
+ ZC_ProcessAllChannels(&hpm->zc, meas->Ufast, usTick);
+ /* Вообще фильтры должны рабтоать синхронно, но на всякий синхронизация */
+ __SynchAvgFilters(hpm);
+
/* Накопление Average для медленной фильтрации */
- meas->Uslow[U_BA] = Filter_Process(&meas->avg[0], meas->U[U_BA]);
- meas->Uslow[U_AC] = Filter_Process(&meas->avg[1], meas->U[U_AC]);
- meas->Islow[I_C] = Filter_Process(&meas->avg[2], meas->I[I_C]);
- meas->Islow[I_A] = Filter_Process(&meas->avg[3], meas->I[I_A]);
- meas->T[TEMP_1] = Filter_Process(&meas->avg[4], meas->T[TEMP_1]);
- meas->T[TEMP_2] = Filter_Process(&meas->avg[5], meas->T[TEMP_2]);
+ meas->Uslow[U_BA] = Filter_Process(&hpm->avg[ADC_CHANNEL_UBA], meas->Ufast[U_BA]);
+ meas->Uslow[U_AC] = Filter_Process(&hpm->avg[ADC_CHANNEL_UAC], meas->Ufast[U_AC]);
+ meas->Islow[I_C] = Filter_Process(&hpm->avg[ADC_CHANNEL_IC], meas->Ifast[I_C]);
+ meas->Islow[I_A] = Filter_Process(&hpm->avg[ADC_CHANNEL_IA], meas->Ifast[I_A]);
+
/* Запускаем медленную обработку через slow_period прерываний */
-// if(hpm->isr_cnt == PM_SLOW_PERIOD_10US)
+// if(hpm->isr_cnt == PM_SLOW_PERIOD_CNT)
/* Запускаем медленную когда фильтры среднего зациклились */
- if(Filter_isDataReady(&meas->avg[0]))
+ /* Берем 0 фильтр, просто так, потому что они все должны работать синхронно */
+ if(Filter_isDataReady(&hpm->avg[0]))
{
+
hpm->isr_cnt = 0;
if(!hpm->f.runSlow)
{
@@ -189,4 +202,27 @@ void PowerMonitor_Handle(PowerMonitor_t *hpm)
{
hpm->isr_cnt++;
}
+}
+
+/* Синхронизация фильтров. Но вообще не должна никогда отрабатывать */
+static void __SynchAvgFilters(PowerMonitor_t *hpm)
+{
+ uint8_t counts_equal = 1;
+ uint32_t first_count = hpm->avg[0].count;
+ for (int i = 1; i < ADC_NUMB_OF_REGULAR_CHANNELS; i++)
+ {
+ if (hpm->avg[i].count != first_count)
+ {
+ counts_equal = 0;
+ break;
+ }
+ }
+ if(!counts_equal)
+ {
+ for(int i = 0; i < ADC_NUMB_OF_REGULAR_CHANNELS; i++)
+ {
+ Filter_ReInit(&hpm->avg[i], hpm->avg[i].size, FILTER_MODE_DEFAULT);
+ Filter_Start(&hpm->avg[i]);
+ }
+ }
}
\ No newline at end of file
diff --git a/UPP/Core/PowerMonitor/power_monitor.h b/UPP/Core/PowerMonitor/power_monitor.h
index 3a0d378..6d0d54a 100644
--- a/UPP/Core/PowerMonitor/power_monitor.h
+++ b/UPP/Core/PowerMonitor/power_monitor.h
@@ -10,6 +10,15 @@
#include "adc_tools.h"
#include "zero_cross.h"
+/* Индексы экспоненциальных фильтров */
+#define EXP_ALL 6
+#define EXP_U 0
+#define EXP_I 1
+#define EXP_IC 2
+#define EXP_IA 3
+#define EXP_IB 4
+#define EXP_F 5
+
typedef struct
{
@@ -27,24 +36,27 @@ typedef struct
typedef struct
{
- float U_mean; ///< Среднее Напряжение по трем фазам
- float I_mean; ///< Средний Ток по трем фазам
- float F_mean; ///< Средняя Частота по трем фазам
- float Uslow[3]; ///< Напряжение от АЦП (в о.е.)
- float Islow[3]; ///< Ток от АЦП (в о.е.)
+ /* Усредненные величины (о.е.) */
+ float Uvec; ///< Результирующий вектор Напряжения по трем фазам
+ float Ivec; ///< Результирующий вектор Тока по трем фазам
+ float Imean[3]; ///< Средний Ток по трем фазам
+ float Fmean; ///< Средняя Частота по трем фазам
+
+ /* Быстрые величины (в о.е.) - обновляются в каждом прерывании АЦП */
+ float Ufast[3]; ///< Напряжение
+ float Ifast[3]; ///< Ток
+
+ /* Медленные величины (в о.е.) - обновляются в main в @ref PowerMonitor_SlowHandle */
+ float Uslow[3]; ///< Напряжение
+ float Islow[3]; ///< Ток
+
+ /* Реальные величины - обновляются кто где, и содержат значения в В/А/Цельсиях */
+ float U[3]; ///< Напряжение (обновляется в прерывании АЦП)
+ float I[3]; ///< Ток (обновляется в прерывании АЦП)
+ float F[3]; ///< Частота от Zero Cross (обновляется в main)
+ float T[2]; ///< Температура (обновляется в main)
- float U[3]; ///< Напряжение от АЦП (в о.е.)
- float I[3]; ///< Ток от АЦП (в о.е.)
- float F[3]; ///< Частота от Zero Cross
- float T[2]; ///< Температура от АЦП
-
-
- float Ureal[3]; ///< Напряжение от АЦП
- float Ireal[3]; ///< Ток от АЦП
-
- FilterExp_t exp[3]; ///< Фильтры для mean
- FilterAverage_t avg[6]; ///< Фильтры для avg
}PowerMonitor_Measured_t;
typedef struct
@@ -55,8 +67,12 @@ typedef struct
{
ADC_Periodic_t adc; ///< Хендл периодического АЦП
ZeroCross_Handle_t zc; ///< Хендл перехода через ноль
- PowerMonitor_Filters_t fltr;
+
PowerMonitor_Measured_t measured; ///< Измеренные/рассчитанные величины
+
+ FilterExp_t exp[EXP_ALL]; ///< Фильтры для mean
+ FilterAverage_t avg[ADC_NUMB_OF_CHANNELS]; ///< Фильтры для avg
+
PowerMonitor_Flags_t f; ///< Флаги мониторинга
diff --git a/UPP/Core/PowerMonitor/power_protect.c b/UPP/Core/PowerMonitor/power_protect.c
new file mode 100644
index 0000000..99d8aeb
--- /dev/null
+++ b/UPP/Core/PowerMonitor/power_protect.c
@@ -0,0 +1,8 @@
+/**
+******************************************************************************
+* @file power_protect.c
+* @brief Модуль реализующий защиты по Напряжению/Токам/Температуре
+******************************************************************************
+* @details
+******************************************************************************/
+#include "power_protect.h"
\ No newline at end of file
diff --git a/UPP/Core/PowerMonitor/power_protect.h b/UPP/Core/PowerMonitor/power_protect.h
new file mode 100644
index 0000000..a378e78
--- /dev/null
+++ b/UPP/Core/PowerMonitor/power_protect.h
@@ -0,0 +1,11 @@
+/**
+******************************************************************************
+* @file power_monitor.h
+* @brief Модуль реализующий защиты по Напряжению/Токам/Температуре
+******************************************************************************
+*****************************************************************************/
+#ifndef _POWER_PROTECT_H_
+#define _POWER_PROTECT_H_
+#include "main.h"
+
+#endif /* _POWER_PROTECT_H_ */
diff --git a/UPP/Core/UPP/upp_control.c b/UPP/Core/UPP/upp_control.c
index d0265bd..e949a30 100644
--- a/UPP/Core/UPP/upp_control.c
+++ b/UPP/Core/UPP/upp_control.c
@@ -39,7 +39,7 @@ void UPP_Control_InternalParams(void)
uint16_t pwm_freq = upp.hpwm.Config.Frequency;
uint8_t pwm_pulse_num = upp.hpwm.Config.PulseNumber;
// временная переменная для параметров Мониторинга сети
- float pm_alpha = upp.pm.measured.exp[0].alpha;
+ float pm_alpha = upp.pm.exp[0].alpha;
for(int i = 0; i < ADC_NUMB_OF_REGULAR_CHANNELS; i++)
@@ -87,7 +87,7 @@ void UPP_Control_InternalParams(void)
{
for(int i = 0; i < 3; i++)
{
- Filter_ReInit(&upp.pm.measured.exp[i], pm_alpha);
+ Filter_ReInit(&upp.pm.exp[i], pm_alpha);
}
}
@@ -178,7 +178,7 @@ void UPP_SetDefault(int pui_default, int internal_default)
MB_INTERNAL.param.pwm.PulseNumber = PWM_THYR_PULSE_NUMBER_DEFAULT;
MB_INTERNAL.param.zc.Hysteresis = ZERO_CROSS_HYSTERESIS_PERCENT_DEFAULT*100;
- MB_INTERNAL.param.zc.DebouneCouner = ZERO_CROSS_DEBOUNCE_10US_DEFAULT;
+ MB_INTERNAL.param.zc.DebouneCouner = ZERO_CROSS_DEBOUNCE_CNT_DEFAULT;
//__AngleSetLimit();
}
}
diff --git a/UPP/Core/UPP/upp_control.h b/UPP/Core/UPP/upp_control.h
index 45f5b48..1cbcc53 100644
--- a/UPP/Core/UPP/upp_control.h
+++ b/UPP/Core/UPP/upp_control.h
@@ -15,7 +15,7 @@ typedef struct
unsigned set_default_pui:1; ///< Выставить настройки ПУИ в дефолтные
unsigned set_default_internal:1;///< Выставить внутренние настройки в дефолтные
unsigned go:1; ///< Запустить УПП
- unsigned stop:1; ///< Выставить внутренние настройки в дефолтные
+ unsigned stop:1; ///< Остановка УПП (авария)
unsigned reserved:11;
diff --git a/UPP/MDK-ARM/UPP.uvoptx b/UPP/MDK-ARM/UPP.uvoptx
index a8f9a56..fd4f4c5 100644
--- a/UPP/MDK-ARM/UPP.uvoptx
+++ b/UPP/MDK-ARM/UPP.uvoptx
@@ -128,7 +128,24 @@
-U-O142 -O2190 -S0 -C0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC800 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F427ZGTx$CMSIS\Flash\STM32F4xx_1024.FLM)
-
+
+
+ 0
+ 0
+ 156
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ ..\Core\PowerMonitor\power_monitor.c
+
+
+
+
0
@@ -498,6 +515,30 @@
0
0
0
+ ..\Core\PowerMonitor\zero_cross.c
+ zero_cross.c
+ 0
+ 0
+
+
+ 3
+ 26
+ 5
+ 0
+ 0
+ 0
+ ..\Core\PowerMonitor\zero_cross.h
+ zero_cross.h
+ 0
+ 0
+
+
+ 3
+ 27
+ 1
+ 0
+ 0
+ 0
..\Core\PowerMonitor\adc_tools.c
adc_tools.c
0
@@ -505,7 +546,7 @@
3
- 26
+ 28
5
0
0
@@ -517,25 +558,49 @@
3
- 27
+ 29
1
0
0
0
- ..\Core\PowerMonitor\zero_cross.c
- zero_cross.c
+ ..\Core\PowerMonitor\phases_transform.c
+ phases_transform.c
0
0
3
- 28
+ 30
5
0
0
0
- ..\Core\PowerMonitor\zero_cross.h
- zero_cross.h
+ ..\Core\PowerMonitor\phases_transform.h
+ phases_transform.h
+ 0
+ 0
+
+
+ 3
+ 31
+ 1
+ 0
+ 0
+ 0
+ ..\Core\PowerMonitor\power_protect.c
+ power_protect.c
+ 0
+ 0
+
+
+ 3
+ 32
+ 5
+ 0
+ 0
+ 0
+ ..\Core\PowerMonitor\power_protect.h
+ power_protect.h
0
0
@@ -549,7 +614,7 @@
0
4
- 29
+ 33
1
0
0
@@ -561,7 +626,7 @@
4
- 30
+ 34
1
0
0
@@ -573,7 +638,7 @@
4
- 31
+ 35
1
0
0
@@ -585,7 +650,7 @@
4
- 32
+ 36
1
0
0
@@ -597,7 +662,7 @@
4
- 33
+ 37
1
0
0
@@ -609,7 +674,7 @@
4
- 34
+ 38
1
0
0
@@ -621,7 +686,7 @@
4
- 35
+ 39
1
0
0
@@ -633,7 +698,7 @@
4
- 36
+ 40
1
0
0
@@ -645,7 +710,7 @@
4
- 37
+ 41
1
0
0
@@ -657,7 +722,7 @@
4
- 38
+ 42
1
0
0
@@ -669,7 +734,7 @@
4
- 39
+ 43
1
0
0
@@ -681,7 +746,7 @@
4
- 40
+ 44
1
0
0
@@ -693,7 +758,7 @@
4
- 41
+ 45
1
0
0
@@ -713,7 +778,7 @@
0
5
- 42
+ 46
5
0
0
@@ -725,7 +790,7 @@
5
- 43
+ 47
5
0
0
@@ -737,7 +802,7 @@
5
- 44
+ 48
5
0
0
@@ -749,7 +814,7 @@
5
- 45
+ 49
5
0
0
@@ -761,7 +826,7 @@
5
- 46
+ 50
5
0
0
@@ -773,7 +838,7 @@
5
- 47
+ 51
5
0
0
@@ -785,7 +850,7 @@
5
- 48
+ 52
1
0
0
@@ -797,7 +862,7 @@
5
- 49
+ 53
5
0
0
@@ -817,7 +882,7 @@
0
6
- 50
+ 54
1
0
0
@@ -829,7 +894,7 @@
6
- 51
+ 55
1
0
0
@@ -841,7 +906,7 @@
6
- 52
+ 56
1
0
0
@@ -853,7 +918,7 @@
6
- 53
+ 57
1
0
0
@@ -865,7 +930,7 @@
6
- 54
+ 58
1
0
0
@@ -877,7 +942,7 @@
6
- 55
+ 59
1
0
0
@@ -889,7 +954,7 @@
6
- 56
+ 60
1
0
0
@@ -901,7 +966,7 @@
6
- 57
+ 61
1
0
0
@@ -913,7 +978,7 @@
6
- 58
+ 62
1
0
0
@@ -925,7 +990,7 @@
6
- 59
+ 63
1
0
0
@@ -937,7 +1002,7 @@
6
- 60
+ 64
1
0
0
@@ -949,7 +1014,7 @@
6
- 61
+ 65
1
0
0
@@ -969,7 +1034,7 @@
0
7
- 62
+ 66
1
0
0
@@ -981,7 +1046,7 @@
7
- 63
+ 67
1
0
0
@@ -995,13 +1060,13 @@
PeriphGeneral
- 1
+ 0
0
0
0
8
- 64
+ 68
1
0
0
@@ -1013,7 +1078,7 @@
8
- 65
+ 69
1
0
0
@@ -1025,7 +1090,7 @@
8
- 66
+ 70
1
0
0
@@ -1037,7 +1102,7 @@
8
- 67
+ 71
1
0
0
@@ -1049,7 +1114,7 @@
8
- 68
+ 72
1
0
0
@@ -1069,7 +1134,7 @@
0
9
- 69
+ 73
1
0
0
@@ -1081,7 +1146,7 @@
9
- 70
+ 74
1
0
0
@@ -1093,7 +1158,7 @@
9
- 71
+ 75
1
0
0
@@ -1105,7 +1170,7 @@
9
- 72
+ 76
1
0
0
@@ -1117,7 +1182,7 @@
9
- 73
+ 77
1
0
0
@@ -1129,7 +1194,7 @@
9
- 74
+ 78
1
0
0
@@ -1141,7 +1206,7 @@
9
- 75
+ 79
1
0
0
@@ -1153,7 +1218,7 @@
9
- 76
+ 80
1
0
0
@@ -1165,7 +1230,7 @@
9
- 77
+ 81
1
0
0
@@ -1177,7 +1242,7 @@
9
- 78
+ 82
1
0
0
@@ -1189,7 +1254,7 @@
9
- 79
+ 83
1
0
0
@@ -1201,7 +1266,7 @@
9
- 80
+ 84
1
0
0
@@ -1213,7 +1278,7 @@
9
- 81
+ 85
1
0
0
@@ -1225,7 +1290,7 @@
9
- 82
+ 86
1
0
0
@@ -1237,7 +1302,7 @@
9
- 83
+ 87
1
0
0
@@ -1249,7 +1314,7 @@
9
- 84
+ 88
1
0
0
@@ -1261,7 +1326,7 @@
9
- 85
+ 89
1
0
0
@@ -1273,7 +1338,7 @@
9
- 86
+ 90
1
0
0
@@ -1285,7 +1350,7 @@
9
- 87
+ 91
1
0
0
@@ -1297,7 +1362,7 @@
9
- 88
+ 92
1
0
0
@@ -1309,7 +1374,7 @@
9
- 89
+ 93
1
0
0
@@ -1321,7 +1386,7 @@
9
- 90
+ 94
1
0
0
@@ -1333,7 +1398,7 @@
9
- 91
+ 95
1
0
0
@@ -1345,7 +1410,7 @@
9
- 92
+ 96
1
0
0
@@ -1365,7 +1430,7 @@
0
10
- 93
+ 97
1
0
0
@@ -1385,7 +1450,7 @@
0
11
- 94
+ 98
2
0
0
@@ -1399,7 +1464,7 @@
::CMSIS
- 1
+ 0
0
0
1
diff --git a/UPP/MDK-ARM/UPP.uvprojx b/UPP/MDK-ARM/UPP.uvprojx
index 5045ead..24baab7 100644
--- a/UPP/MDK-ARM/UPP.uvprojx
+++ b/UPP/MDK-ARM/UPP.uvprojx
@@ -17,8 +17,8 @@
STM32F427ZGTx
STMicroelectronics
- Keil.STM32F4xx_DFP.2.16.0
- http://www.keil.com/pack/
+ Keil.STM32F4xx_DFP.2.17.1
+ https://www.keil.com/pack/
IRAM(0x20000000-0x2002FFFF) IRAM2(0x10000000-0x1000FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(25000000) FPU2 CPUTYPE("Cortex-M4") TZ
@@ -515,6 +515,16 @@
5
..\Core\PowerMonitor\power_monitor.h
+
+ zero_cross.c
+ 1
+ ..\Core\PowerMonitor\zero_cross.c
+
+
+ zero_cross.h
+ 5
+ ..\Core\PowerMonitor\zero_cross.h
+
adc_tools.c
1
@@ -526,14 +536,24 @@
..\Core\PowerMonitor\adc_tools.h
- zero_cross.c
+ phases_transform.c
1
- ..\Core\PowerMonitor\zero_cross.c
+ ..\Core\PowerMonitor\phases_transform.c
- zero_cross.h
+ phases_transform.h
5
- ..\Core\PowerMonitor\zero_cross.h
+ ..\Core\PowerMonitor\phases_transform.h
+
+
+ power_protect.c
+ 1
+ ..\Core\PowerMonitor\power_protect.c
+
+
+ power_protect.h
+ 5
+ ..\Core\PowerMonitor\power_protect.h