UKSI_TEST/Core/UKSI/uksi_calc_res.c
2025-12-30 09:35:49 +03:00

149 lines
4.6 KiB
C

#include "uksi_calc_res.h"
/**
* @brief Конфигуарция коэфициентов АЦП.
* @param adc Указатель на кастомный хендл АЦП
* @param levelZero Нулевой уровень (в квантах АЦП)
* @param valueMax Максимальный уровень Единиц Измерения (в Вольтах/Амперах/Градусах)
* @param levelMax Максимальный уровень АЦП (в квантах АЦП)
* @return HAL Status.
*/
HAL_StatusTypeDef ADC_ConfigCoef(ADC_t *adc, uint16_t levelZero, float valueMax, uint16_t levelMax, uint16_t lOffset)
{
HAL_StatusTypeDef res;
if(check_null_ptr_1(adc))
return HAL_ERROR;
if((valueMax == 0) || (levelMax == 0))
return HAL_ERROR;
adc->Coefs.lMax = levelMax;
adc->Coefs.vMax = valueMax;
adc->Coefs.lZero = levelZero;
adc->Coefs.lOffset = lOffset;
return HAL_OK;
}
/**
* @brief Конфигуарция фильтров АЦП.
* @param adc Указатель на кастомный хендл АЦП
* @param levelZero Нулевой уровень (в квантах АЦП)
* @param valueMax Максимальный уровень Единиц Измерения (в Вольтах/Амперах/Градусах)
* @param levelMax Максимальный уровень АЦП (в квантах АЦП)
* @return HAL Status.
*/
HAL_StatusTypeDef ADC_ConfigFilter(ADC_t *adc, uint8_t median_size, uint32_t average_size)
{
HAL_StatusTypeDef res;
if(check_null_ptr_1(adc))
return HAL_ERROR;
FilterMedianInt_Init(&adc->mdn, median_size, 0);
FilterAverageInt_Init(&adc->avg, average_size, FILTER_MODE_DEFAULT);
Filter_Start(&adc->mdn);
Filter_Start(&adc->avg);
return HAL_OK;
}
/**
* @brief Расчет напряжения на АЦП.
* @param adc Указатель на кастомный хендл АЦП
* @param rawval Сырое значение АЦП
* @return Напряжение (float).
*/
float ADC_Calc(ADC_t *adc)
{
if(check_null_ptr_1(adc))
return 0;
ADC_Coefs_t *coefs = &adc->Coefs;
int16_t rawval = HAL_ADC_GetValue(adc->hadc);
rawval = Filter_Process(&adc->mdn, rawval);
rawval = Filter_Process(&adc->avg, rawval);
rawval -= coefs->lOffset;
if(rawval < 0)
rawval = 0;
if(rawval >4095)
rawval = 4095;
adc->Raw = rawval;
adc->Voltage = ((float)(rawval)-coefs->lZero) * coefs->vMax / (coefs->lMax-coefs->lZero);
return adc->Voltage;
}
HAL_StatusTypeDef UKSI_Calc_Init(UKSI_Calc_t *calc, ADC_HandleTypeDef *hadc)
{
if(check_null_ptr_2(calc, hadc))
return HAL_ERROR;
calc->adc.hadc = hadc;
// ADC_ConfigCoef(&calc->adc, 0, 1.259, 1639, 14);
ADC_ConfigCoef(&calc->adc, 0, 0.529, 703, 14);
ADC_ConfigFilter(&calc->adc, 10, 50000);
calc->RMeasOhm = 35060;
calc->RLimitOhm = 1.5e6;
calc->DCVoltage = 31.58;//60;
foster_init(&calc->adc.foster, 3000.0f);
foster_set_mse(&calc->adc.foster, 0.001f); /* Подберите под ваши значения напряжения */
HAL_ADCEx_Calibration_Start(hadc, ADC_SINGLE_ENDED);
calc->IsoOhm = 100e6;
calc->IsoMOhm = calc->IsoOhm / 1000000.0f;
return HAL_ADC_Start(hadc);
}
/**
* @brief Расчет изоляции.
* @param calc Указатель на структуру для расчета изоляции
* @return Сопротивление изоляции (float).
*/
float UKSI_Calc_Isolation(UKSI_Calc_t *calc)
{
if(check_null_ptr_1(calc))
return 0;
float voltage = ADC_Calc(&calc->adc);
if(Filter_isDataReady(&calc->adc.avg))
{
/* Расчет тока */
float current = voltage / calc->RMeasOhm;
calc->IsoCurrentuA = current * 1000000.0f;
/* Проверка стабильности напряжения */
foster_add_sample(&calc->adc.foster, voltage);
if(foster_is_ready(&calc->adc.foster)) {
uint8_t stability = foster_check(&calc->adc.foster);
calc->adc.is_stable = stability;
/* Если нестабильно, возвращаем 0 или предыдущее значение */
if(stability == 1) { /* Нестабильно */
return calc->IsoOhm; /* Или calc->IsoOhm для сохранения последнего значения */
}
}
/* Расчет изоляции */
float Rtotal = calc->DCVoltage / current;
float Riso = Rtotal - (calc->RMeasOhm + calc->RLimitOhm);
calc->IsoOhm = Riso;
calc->IsoMOhm = Riso / 1000000.0f;
}
return calc->IsoOhm;
}