#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; }