149 lines
4.6 KiB
C
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;
|
|
}
|
|
|
|
|