/** ****************************************************************************** * @file vi.h * @author AMG Energy Solution Team * @version V1.0.0 * @date 07-Feb-2022 * @brief This file provides all the headers of voltage and current functions. ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * *

© COPYRIGHT 2022 AMG

****************************************************************************** */ /** @addtogroup mBMS2 * @{ */ /* Includes ------------------------------------------------------------------*/ #include #include "vi.h" #include "delay.h" #include "adc.h" #include "asutil.h" #include "device_param.h" #include "malloc.h" #include "relay.h" #include "alarm.h" #include "brtc.h" #include "os_cfg_app.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define VI_TASK_TIME 2 // 1ms Delay #define CURR_AVG_BUF_MAX 100 /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ // ADC Buffer uint16_t VIAdData[VI_CH_MAX][VI_BUF_MAX]; int32_t VIRealData[VI_CH_MAX][VI_BUF_MAX]; uint16_t VIAdCh = 0; int32_t VICurrentCalc[VI_BUF_MAX] = {0, }; uint32_t CurrentAvgBuff[CURR_AVG_BUF_MAX]; uint16_t CurrentAvgBuffCh = 0; uint16_t CurrentAvgBuffTime = 0; uint32_t relexation_chg_time = 60 * 1000; uint32_t relexation_dsg_time = 60 * 1000; uint32_t dis_radc[4]; int32_t dis_tadc = 0; /* Private function prototypes -----------------------------------------------*/ void InitVIAD(uint8_t ch); void VI_ADC_Data_Process(void); int32_t GetCurrentAvgValue(void); void CheckCurrentStatus(void); int32_t CalcDischargeCurrent(uint32_t adc); int32_t CalcChargeCurrent(uint32_t adc); /* Private functions ---------------------------------------------------------*/ /* ********************************************************************************************************* * VIAdcInit * * Description : ADC TASK INIT * ********************************************************************************************************* */ void VIAdcInit(void) { // ADC initialization // ADC Clock frequency: 115.200 kHz // ADC Voltage Reference: Vref Pin // ADC High Speed Mode: On ADC_Port_Init(); memset(VIAdData, 0x00, sizeof(VIAdData)); relexation_chg_time = device_param.chg_ctrl.current_thr.Charge_Relax_Time * 1000; relexation_dsg_time = device_param.chg_ctrl.current_thr.Discharge_Relax_Time * 1000; } /* ********************************************************************************************************* * AppTaskVIAdc * * Description : Voltage and current measurement task * ********************************************************************************************************* */ void AppTaskVIAdc(void) { VIAdcInit(); ADC_StartConvert(M4_ADC2); for (;;) { if (GetAdcIrgFlag(1) == true) { VI_ADC_Data_Process(); DmaReloadConfig(1); // PORT_SetBits(PortE, Pin00); ADC_StartConvert(M4_ADC2); } delay_os_ms(VI_TASK_TIME); } } /* ********************************************************************************************************* * VI_ADC_Data_Process * * Description : VI_ADC_Data_Process * ********************************************************************************************************* */ uint32_t bakODC = 0; uint32_t bakODC1 = 0; void VI_ADC_Data_Process(void) { int32_t sum, sum1; for (int i = 0; i < VI_CH_MAX; i++) { sum = AvgAdc2DmaValue(i); VIRealData[i][VIAdCh] = (uint16_t)((sum * (ADC_VBASE * 10)) / 0xFFF); switch (i) { case DSG_CURR_ID: sum1 = (int32_t)CalcDischargeCurrent(sum); VIAdData[i][VIAdCh] = (int32_t)sum1; break; case CHG_CURR_ID: sum1 = (int32_t)CalcChargeCurrent(sum); VIAdData[i][VIAdCh] = (int32_t)sum1; break; } } VICurrentCalc[VIAdCh] = VIRealData[CHG_CURR_ID][VIAdCh] - VIRealData[DSG_CURR_ID][VIAdCh]; VIAdCh++; VIAdCh %= VI_BUF_MAX; // Discharge current sum = 0; for (int i = 0; i < VI_BUF_MAX; i++) { sum += VIAdData[DSG_CURR_ID][i]; } device_value.DCurrent = (int32_t)(sum / VI_BUF_MAX); if (device_value.DCurrent < (device_param.chg_ctrl.term_cfg.Taper_Current / 100)) device_value.DCurrent = 0; // Charge current sum = 0; for (int i = 0; i < VI_BUF_MAX; i++) { sum += VIAdData[CHG_CURR_ID][i]; } device_value.CCurrent = (int32_t)(sum / VI_BUF_MAX); if (device_value.CCurrent < (device_param.chg_ctrl.term_cfg.Taper_Current / 100)) { device_value.CCurrent = 0; } if (device_value.DCurrent > device_value.CCurrent) { device_value.CCurrent = 0; } else { device_value.DCurrent = 0; } device_value.Current = device_value.CCurrent - device_value.DCurrent; CheckCurrentStatus(); } int32_t CalcDischargeCurrent(uint32_t adc) { int32_t result = 0; double tmp, bGain, bOffset; tmp = (double)((adc * ADC_VBASE) / 0xFFF) / 1000; bGain = (float)device_calib_data.cal.current.DC_Gain / 1000; bOffset = (float)device_calib_data.cal.current.DC_Offset / 10000; tmp = (tmp + bOffset) * bGain; result = tmp * 10; return result; } int32_t CalcChargeCurrent(uint32_t adc) { int32_t result = 0; double tmp, bGain, bOffset; tmp = (double)((adc * ADC_VBASE) / 0xFFF) / 1000; bGain = (float)device_calib_data.cal.current.CC1_Gain / 1000; bOffset = (float)device_calib_data.cal.current.CC1_Offset / 10000; tmp = (tmp + bOffset) * bGain; result = tmp * 10; return result; } uint32_t GetRealCurrentAdc(uint8_t id) { uint16_t i; uint32_t result = 0; for (i = 0; i < VI_BUF_MAX; i++) { result += VIRealData[id][i]; } return (result / VI_BUF_MAX); } int32_t GetRealCurrentSum(void) { int32_t i, result = 0; for (i = 0; i < VI_BUF_MAX; i++) { result += VICurrentCalc[i]; } return (result / VI_BUF_MAX); } void dec_relexation_tick(uint32_t tick) { if (relexation_chg_time > 0) { if (relexation_chg_time > tick) { relexation_chg_time -= tick; } else { relexation_chg_time = 0; } } if (relexation_dsg_time > 0) { if (relexation_dsg_time > tick) { relexation_dsg_time -= tick; } else { relexation_dsg_time = 0; } } } void CheckCurrentStatus(void) { PDEVICE_CHG_CTRL_CURRENT_THR_VALUE thr; thr = (PDEVICE_CHG_CTRL_CURRENT_THR_VALUE)mymalloc(sizeof(TDEVICE_CHG_CTRL_CURRENT_THR_VALUE)); if (thr != NULL) { memcpy(thr, &device_param.chg_ctrl.current_thr, sizeof(TDEVICE_CHG_CTRL_CURRENT_THR_VALUE)); if (device_status.battery_status.bit.RXM == false) { // Charge or Discharge Mode if (device_status.battery_status.bit.MD == true) { // Discharge Mode if (device_value.CCurrent > (thr->Charge_Detection_Threshold / 100)) { device_status.battery_status.bit.MD = false; } else if (device_value.DCurrent < (thr->Quit_Current / 100)) { // Relexation time if (relexation_dsg_time == 0) { device_status.battery_status.bit.RXM = true; } } else { // Discharge time relexation_dsg_time = thr->Discharge_Relax_Time * 1000; } } else { // Charge Mode if (device_value.DCurrent > (thr->Discharge_Detection_Threshold / 100)) { device_status.battery_status.bit.MD = true; } else if (device_value.CCurrent < (thr->Quit_Current / 100)) { // Relexation time if (relexation_chg_time == 0) { device_status.battery_status.bit.RXM = true; } } else { // Charge time relexation_chg_time = thr->Charge_Relax_Time * 1000; } } } else { // Relexation True Mode if (device_value.CCurrent > (thr->Charge_Detection_Threshold / 100)) { device_status.battery_status.bit.RXM = false; relexation_chg_time = thr->Charge_Relax_Time * 1000; } else if (device_value.DCurrent > (thr->Discharge_Detection_Threshold / 100)) { device_status.battery_status.bit.RXM = false; relexation_dsg_time = thr->Discharge_Relax_Time * 1000; } } myfree(thr); } } /*************************************** Display **********************************************/ #ifdef CONSOLE_DEBUG void SDisplayCurrentAdcRealValue(uint8_t p) { float aParam; int32_t radc, tadc; static int dCount = 0; if (p || (dCount == 0)) { for (int i = 0; i < VI_CH_MAX; i++) { radc = GetRealCurrentAdc(i); if (p ||(dis_radc[i] != radc)) { aParam = (float)radc / 10000; FloatNormalOutIntXY( 70, 3 + i, aParam, 6, 4); dis_radc[i] = radc; } } tadc = GetRealCurrentSum(); if (dis_tadc != tadc) { aParam = (float)tadc / 10000; FloatNormalOutIntXY( 68, 3 + 3, aParam, 8, 4); dis_tadc = tadc; } dCount = 100; } dCount--; } #endif // #ifdef CONSOLE_DEBUG /*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/