Files
UPP/UPP/Core/UPP/upp_errors.c

217 lines
7.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
******************************************************************************
* @file upp_errors.c
* @brief Формирование ошибок в ПУИ
******************************************************************************
* @details
******************************************************************************/
#include "upp_main.h" // УПП
#include "upp_errors.h" // всё остальное по работе с УПП
UPP_Errors_t errors;
static UPP_ErrorType_t UPP_SelectCommonError(void);
static int setError(int condition, int flag, int *timer, int delay);
void UPP_Errors_Program(void);
void UPP_Errors_Power(void);
void UPP_Errors_Ranges(void);
void UPP_Errors_LossPhase(void);
void UPP_Errors_Other(void);
void UPP_Errors_Handle(void)
{
/*====== Программные ошибки ======*/
UPP_Errors_Program();
/*====== Ошибки питания плат ======*/
UPP_Errors_Power();
/*====== Ошибки выхода за допустимые пределы ======*/
UPP_Errors_Ranges();
/*====== Потери фазы ======*/
UPP_Errors_LossPhase();
/*====== Остальные ======*/
UPP_Errors_Other();
errors.common = UPP_SelectCommonError();
}
void UPP_Errors_Program(void)
{
}
void UPP_Errors_Power(void)
{
//read discrete inputs
}
void UPP_Errors_Ranges(void)
{
/* Преобразуем уставки в нормальные тики */
float ticksTiMax = to_float(MB_DATA.HoldRegs.pui_params.TiMax, 1)/PM_SLOW_PERIOD_US;
/* Счетчики для отсчитывания задержки выставления ошибки */
static int IMaxCnt = 0;
static int UMaxCnt = 0;
static int UMinCnt = 0;
static int FMaxCnt = 0;
static int FMinCnt = 0;
static int TMaxCnt = 0;
/* Напряжения */
errors.pui.err.OverVoltage = setError(errors.prvt.f.err.uamp_max,
errors.pui.err.OverVoltage,
&UMaxCnt,
ticksTiMax);
errors.pui.err.UnderVoltage = setError(errors.prvt.f.err.uamp_min,
errors.pui.err.UnderVoltage,
&UMinCnt,
ticksTiMax);
/* Токи */
int i_max = ( errors.prvt.f.err.iamp_max ||
errors.prvt.f.err.ia_max ||
errors.prvt.f.err.ib_max ||
errors.prvt.f.err.ic_max);
errors.pui.err.OverCurrent = setError(i_max,
errors.pui.err.OverCurrent,
&IMaxCnt,
ticksTiMax);
/* Частота */
int f_max = ( errors.prvt.f.err.fac_max ||
errors.prvt.f.err.fba_max ||
errors.prvt.f.err.fbc_max);
int f_min = ( errors.prvt.f.err.fac_max ||
errors.prvt.f.err.fba_max ||
errors.prvt.f.err.fbc_max);
errors.pui.err.OverFrequency = setError(f_max,
errors.pui.err.OverFrequency,
&FMaxCnt,
ERRORS_DELAY_TICKS_DEFAULT);
errors.pui.err.UnderFrequency = setError( f_min,
errors.pui.err.UnderFrequency,
&FMinCnt,
ERRORS_DELAY_TICKS_DEFAULT);
/* Температуры */
errors.pui.err.OverTemperature = setError(errors.prvt.f.err.temp_err,
errors.pui.err.OverTemperature,
&TMaxCnt,
ERRORS_DELAY_TICKS_DEFAULT);
}
void UPP_Errors_LossPhase(void)
{
/* Счетчики для отсчитывания задержки выставления ошибки */
static int LossPhaseAllCnt = 0;
static int LossPhaseACnt = 0;
static int LossPhaseBCnt = 0;
static int LossPhaseCCnt = 0;
int loss_phases_all = ( errors.prvt.f.err.ia_min &&
errors.prvt.f.err.ib_min &&
errors.prvt.f.err.ic_min );
errors.pui.err.LossPhaseAll = setError( loss_phases_all,
errors.pui.err.LossPhaseAll,
&LossPhaseAllCnt,
ERRORS_DELAY_TICKS_DEFAULT);
/* Если хотя бы одна фаза есть проверяем фазы отдельно */
if(!errors.pui.err.LossPhaseAll)
{
errors.pui.err.LossPhaseA = setError( errors.prvt.f.err.ia_min,
errors.pui.err.LossPhaseA,
&LossPhaseACnt,
ERRORS_DELAY_TICKS_DEFAULT);
errors.pui.err.LossPhaseB = setError( errors.prvt.f.err.ib_min,
errors.pui.err.LossPhaseB,
&LossPhaseBCnt,
ERRORS_DELAY_TICKS_DEFAULT);
errors.pui.err.LossPhaseC = setError( errors.prvt.f.err.ic_min,
errors.pui.err.LossPhaseC,
&LossPhaseCCnt,
ERRORS_DELAY_TICKS_DEFAULT);
}
/* Если всех фаз нет, то отдельные не смотрим */
else
{
errors.pui.err.LossPhaseA = 0;
errors.pui.err.LossPhaseB = 0;
errors.pui.err.LossPhaseC = 0;
}
}
void UPP_Errors_Other(void)
{
static int InterlaceCnt = 0;
if(errors.prvt.f.err.longstart)
errors.pui.err.LongStart = 1;
else
errors.pui.err.LongStart = 0;
errors.pui.err.Interlace = setError(errors.prvt.f.err.interlance,
errors.pui.err.Interlace,
&InterlaceCnt,
ERRORS_DELAY_TICKS_DEFAULT);
//Interlance
}
static UPP_ErrorType_t UPP_SelectCommonError(void)
{
// Пока нет ошибки
UPP_ErrorType_t best = Err_None;
// Приоритет отсутствия ошибок
uint8_t best_prio = UPP_ErrorPriority[Err_None];
// Перебираем все возможные ошибки по enum
for (int e = Err_None + 1; e <= Err_UnderFrequency; e++)
{
// Проверяем: установлен ли соответствующий бит в pui.all
// e-1, потому что ошибка №1 = бит 0, ошибка №2 = бит 1 и т.д.
if (errors.pui.all & (1u << (e - 1)))
{
// Получаем приоритет этой ошибки
uint8_t pr = UPP_ErrorPriority[e];
// Если её приоритет лучше (меньше число) — запоминаем
if (pr < best_prio)
{
best_prio = pr;
best = (UPP_ErrorType_t)e;
}
}
}
// Возвращаем самую важную (наивысшего приоритета) ошибку
return best;
}
static int setError(int condition, int flag, int *timer, int delay)
{
if (condition) {
if (*timer < delay)
(*timer)++;
else
flag = 1;
} else {
if (*timer > 0)
(*timer)--;
else
flag = 0;
}
return flag;
}