- в матлаб проверена отрабокта всех защит - добавлены быстрые защиты на КЗ, которые проверяются в прерывании АЦП - определены и проверены более менее приоритеты ошибок - в мтлаб добавлена симуляция MOE расширенных таймеров
231 lines
6.1 KiB
C
231 lines
6.1 KiB
C
/**
|
||
******************************************************************************
|
||
* @file power_protect.c
|
||
* @brief Модуль реализующий защиты по Напряжению/Токам/Температуре
|
||
******************************************************************************
|
||
* @details
|
||
******************************************************************************/
|
||
#include "power_protect.h"
|
||
|
||
|
||
/**
|
||
* @brief Проверяет защиты по напряжению.
|
||
* @note Заполняет флаги prvt ошибок (приватные).
|
||
* Потом в @ref UPP_ErrorsHandle исходя из них заполняются ошибки для ПУИ
|
||
* @return 1 - напряжение есть, 0 - напряжения нет
|
||
*/
|
||
int Protect_Voltages(PowerMonitor_Measured_t *measure, UPP_PUI_Params_t *params, UPP_ParamsNominal_t *nominal)
|
||
{
|
||
/* Переводим уставки ПУИ в удобный вид */
|
||
float lUmin = u2f(params->Umin, 100)/**u2f(nominal->U, 10)*/;
|
||
float lUmax = u2f(params->Umax, 100)/**u2f(nominal->U, 10)*/;
|
||
UPP_PhaseSequence_t nomPhaseSequence = nominal->PhaseSequence;
|
||
|
||
/* Общее напряжение */
|
||
if(measure->final.Uamp > lUmax)
|
||
{
|
||
ERR_PRIVATE->uamp_max = 1;
|
||
}
|
||
else if (measure->final.Uamp < lUmin)
|
||
{
|
||
ERR_PRIVATE->uamp_min = 1;
|
||
}
|
||
else
|
||
{
|
||
ERR_PRIVATE->uamp_max = 0;
|
||
ERR_PRIVATE->uamp_min = 0;
|
||
}
|
||
|
||
/* Последовательность фаз */
|
||
if(measure->final.PhaseSequence != nomPhaseSequence)
|
||
{
|
||
ERR_PRIVATE->interlance = 1;
|
||
}
|
||
else
|
||
{
|
||
ERR_PRIVATE->interlance = 0;
|
||
}
|
||
|
||
return (ERR_PRIVATE->uamp_min == 0);
|
||
}
|
||
|
||
/**
|
||
* @brief Проверяет защиты по току.
|
||
* @note Заполняет флаги prvt ошибок (приватные).
|
||
* Потом в @ref UPP_ErrorsHandle исходя из них заполняются ошибки для ПУИ
|
||
*/
|
||
int Protect_Currents(PowerMonitor_Measured_t *measure, UPP_PUI_Params_t *params, UPP_ParamsNominal_t *nominal)
|
||
{
|
||
/* Переводим уставки ПУИ в удобный вид */
|
||
float lIref = u2f(params->Iref, 100)/**u2f(nominal->I, 10)*/;
|
||
float lImin = u2f(params->Imin, 100)/**u2f(nominal->I, 10)*/;
|
||
float lImax = u2f(params->Imax, 100) * 50 / u2f(nominal->I, 10); // Imax процентов от 50 А, в о.е. от номинального
|
||
|
||
/* Общий ток */
|
||
if(measure->final.Iamp > lImax)
|
||
{
|
||
ERR_PRIVATE->iamp_max = 1;
|
||
}
|
||
else if (measure->final.Iamp < lImin)
|
||
{
|
||
ERR_PRIVATE->iamp_min = 1;
|
||
}
|
||
else
|
||
{
|
||
// ERR_PRIVATE->iamp_max = 0;
|
||
// ERR_PRIVATE->iamp_min = 0;
|
||
}
|
||
|
||
/* Ток по фазам */
|
||
if(measure->final.I[I_A] > lImax)
|
||
{
|
||
ERR_PRIVATE->ia_max = 1;
|
||
}
|
||
else if (measure->final.I[I_A] < lImin)
|
||
{
|
||
ERR_PRIVATE->ia_min = 1;
|
||
}
|
||
else
|
||
{
|
||
// ERR_PRIVATE->ia_max = 0;
|
||
// ERR_PRIVATE->ia_min = 0;
|
||
}
|
||
|
||
if(measure->final.I[I_B] > lImax)
|
||
{
|
||
ERR_PRIVATE->ib_max = 1;
|
||
}
|
||
else if (measure->final.I[I_B] < lImin)
|
||
{
|
||
ERR_PRIVATE->ib_min = 1;
|
||
}
|
||
else
|
||
{
|
||
// ERR_PRIVATE->ib_max = 0;
|
||
// ERR_PRIVATE->ib_min = 0;
|
||
}
|
||
|
||
if(measure->final.I[I_C] > lImax)
|
||
{
|
||
ERR_PRIVATE->ic_max = 1;
|
||
}
|
||
else if (measure->final.I[I_C] < lImin)
|
||
{
|
||
ERR_PRIVATE->ic_min = 1;
|
||
}
|
||
else
|
||
{
|
||
// ERR_PRIVATE->ic_max = 0;
|
||
// ERR_PRIVATE->ic_min = 0;
|
||
}
|
||
|
||
return (ERR_PRIVATE->iamp_min == 0);
|
||
}
|
||
|
||
|
||
/**
|
||
* @brief Проверяет быстрые защиты.
|
||
* @note Заполняет флаги prvt ошибок (приватные).
|
||
* Потом в @ref UPP_ErrorsHandle исходя из них заполняются ошибки для ПУИ
|
||
*/
|
||
void Protect_Fast(PowerMonitor_Measured_t *measure, float lImaxAmp)
|
||
{
|
||
// /* Переводим уставки ПУИ в удобный вид */
|
||
// float lImaxAmp = u2f(params->Imax, 100) * 50 / u2f(nominal->I, 10) *1.41; // Амплитудное значение Imax
|
||
|
||
|
||
/* Ток по фазам */
|
||
if(measure->fast.I[I_A] > lImaxAmp)
|
||
{
|
||
ERR_PRIVATE->ia_max = 1;
|
||
}
|
||
|
||
if(measure->fast.I[I_B] > lImaxAmp)
|
||
{
|
||
ERR_PRIVATE->ib_max = 1;
|
||
}
|
||
|
||
if(measure->fast.I[I_C] > lImaxAmp)
|
||
{
|
||
ERR_PRIVATE->ic_max = 1;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* @brief Проверяет всякие другие защиты (частота, температура).
|
||
* @note Заполняет флаги prvt ошибок (приватные).
|
||
* Потом в @ref UPP_ErrorsHandle исходя из них заполняются ошибки для ПУИ
|
||
*/
|
||
void Protect_Misc(PowerMonitor_Measured_t *measure, UPP_PUI_Params_t *params, UPP_ParamsNominal_t *nominal)
|
||
{
|
||
/* Переводим внутренние уставки в удобный вид */
|
||
float lFnom = u2f(nominal->F, 100);
|
||
float lFmin = lFnom - lFnom*u2f(nominal->F_deviation_minus, 10000);
|
||
float lFmax = lFnom + lFnom*u2f(nominal->F_deviation_plus, 10000);
|
||
|
||
float lTwarn = PARAM_INTERNAL->temp.TemperatureWarn;
|
||
float lTerr = PARAM_INTERNAL->temp.TemperatureWarn;
|
||
|
||
|
||
/*=============== ЗАЩИТЫ ПО ЧАСТОТЕ ==================*/
|
||
if(measure->final.F[U_CA] > lFmax)
|
||
{
|
||
ERR_PRIVATE->fac_max = 1;
|
||
}
|
||
else if (measure->final.F[U_CA] < lFmin)
|
||
{
|
||
ERR_PRIVATE->fac_min = 1;
|
||
}
|
||
else
|
||
{
|
||
ERR_PRIVATE->fac_max = 0;
|
||
ERR_PRIVATE->fac_min = 0;
|
||
}
|
||
|
||
if(measure->final.F[U_AB] > lFmax)
|
||
{
|
||
ERR_PRIVATE->fba_max = 1;
|
||
}
|
||
else if (measure->final.F[U_AB] < lFmin)
|
||
{
|
||
ERR_PRIVATE->fba_min = 1;
|
||
}
|
||
else
|
||
{
|
||
ERR_PRIVATE->fba_max = 0;
|
||
ERR_PRIVATE->fba_min = 0;
|
||
}
|
||
|
||
if(measure->final.F[U_BC] > lFmax)
|
||
{
|
||
ERR_PRIVATE->fbc_max = 1;
|
||
}
|
||
else if (measure->final.F[U_BC] < lFmin)
|
||
{
|
||
ERR_PRIVATE->fbc_min = 1;
|
||
}
|
||
else
|
||
{
|
||
ERR_PRIVATE->fbc_max = 0;
|
||
ERR_PRIVATE->fbc_min = 0;
|
||
}
|
||
|
||
|
||
|
||
/*=============== ЗАЩИТЫ ПО ТЕМПЕРАТУРЕ ==================*/
|
||
if(measure->final.T[TEMP_1] > lTerr)
|
||
{
|
||
ERR_PRIVATE->temp_err = 1;
|
||
}
|
||
else if (measure->final.T[TEMP_1] > lTwarn)
|
||
{
|
||
ERR_PRIVATE->temp_warn = 1;
|
||
}
|
||
else
|
||
{
|
||
ERR_PRIVATE->temp_err = 0;
|
||
ERR_PRIVATE->temp_warn = 0;
|
||
}
|
||
}
|