/** ****************************************************************************** * @file balancer.c * @author ECS, Falko Jahn * @version V1.0.0 * @date 03.02.2021 * @brief BALANCER Modul * Beschreibung in Header ****************************************************************************** */ // --- INCLUDES ---------------------------------------------------------------- #include #include "balancer.h" #include "main.h" #include "sysdata.h" #include "tim.h" #include "dac.h" #include "comp.h" #include "led.h" //--- GGF. EXTERNE VARIABLEN --------------------------------------------------- //--- LOKALE DEFINES - bitte hier dokumentieren -------------------------------- //Imax = 20A //Verstrkung = 100 //Shunt = 0,001 Ohm //U dac = Imax * Rshunt * Verstrkung --> 20 A * 0,001 Ohm * 100 = 2.0V //Dac Value = Udac / (Uref / 4096) //#define MAX_DAC_VALUE 3276 //Zur Zeit reduzieren wir den max. Wert weil der Strommessverstrker langsam ist und zu spt den max Wert ausgibt //Daher zur Zeit nur 1,7V statt 2.0V #define MAX_DAC_VALUE 1500 //2300 //MAX Timer Value um nicht mehr laufenden DC DC Wandler zu erkennen //gemessen 1500 Periode bei 5V/12 und Sysclock 64Mhz //um Faktor 10 vergrert #define MAX_TIMER_VALUE 500 #define MIN_OUTPUT_VOLTAGE 10000 //mV #define MAX_OUTPUT_VOLTAGE 68000 //mv //Messgenauikeit ca. +- 2-3V #define MAX_ERROR 100 // #define RESTART_TIMEOUT 100 //ms #define BALANCER_REGULATION_TIME 10 //Alle 10mS ein Schritt #define CONVERTER_MIN_POWER 300 //300 von 3000 = 10% //--- LOKALE TYPE DEFS - bitte hier dokumentieren------------------------------- //--- DEFINATIONEN GLOBALER VARIABLEN - Bitte in Header dokumentieren ---------- //--- LOKALE VARIABLEN - bitte hier dokumentieren ------------------------------ uint32_t restartCounter; uint32_t startImpulsCounter; uint32_t balancer_running; uint32_t secondCounter; uint32_t balancerRegulationCounter= BALANCER_REGULATION_TIME; //--- LOKALE FUNKTIONS PROTOTYPEN ---------------------------------------------- void BALANCER_SetStartImpulse(void); //--- LOKALE FUNKTIONEN - bitte hier dokumentieren ----------------------------- //--- GLOBALE FUNKTIONEN - bitte in Header dokumentieren------------------------ void BALANCER_Init(void) { // Starte timer zur Messung der Charge Time und der Charge Transfer Time // Charge Time bedeutet die Zeit zum Aufbau des Magnedfeldes. Also vom Einschalten // des Mosfets bis zum erreichen der Maximal Stroms. //HAL_TIM_Base_Start_IT(&htim16); //HAL_TIM_Base_Start_IT(&htim17); HAL_TIM_IC_Start(&htim1,TIM_CHANNEL_1); HAL_TIM_IC_Start(&htim1,TIM_CHANNEL_2); if (HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0) != HAL_OK) { /* Setting value Error */ printf("HAL_DAC_SetValue ERROR\n"); return; } printf("HAL_DAC_SetValue OK\n"); if (HAL_DAC_Start(&hdac1, DAC_CHANNEL_1) != HAL_OK) { /* Start Error */ printf("HAL_DAC_Start ERROR\n"); return; } printf("HAL_DAC_Start OK\n"); //Comparator fr Strom if(HAL_COMP_Start(&hcomp1) != HAL_OK) { /* Initialization Error */ printf("HAL_COMP1_Start ERROR\n"); return; } printf("HAL_COMP1_Start OK\n"); //Comparator fr Charge Transfer if(HAL_COMP_Start(&hcomp2) != HAL_OK) { /* Initialization Error */ printf("HAL_COMP2_Start ERROR\n"); return; } printf("HAL_COMP2_Start OK\n"); printf("BALANCER_Init OK\n"); } uint32_t counterValue; void BALANCER_Exec() { uint32_t val1 = HAL_TIM_ReadCapturedValue(&htim1,TIM_CHANNEL_1); uint32_t val2 = HAL_TIM_ReadCapturedValue(&htim1,TIM_CHANNEL_2); //Val1 representiert die gesamte Periode von Ipeak Abschaltung zu Ipeak Abschaltung (falling edge comparator 1) //Val2 Periode von Ipeak Abschaltung (falling edge comparator 1) bis zu ende charge transfer (comparartor 2 rising edge ) uint32_t periodeTime = val1; uint32_t chargeTransferTime = val2; uint32_t chargeTime = periodeTime - chargeTransferTime; uint32_t trafo = 2;// n2 / n1; uint32_t usek = ((float)chargeTime / (float)chargeTransferTime) * trafo * sysData.s.cellVoltage; sysData.s.chargeTime = chargeTime; sysData.s.chargeTransferTime = chargeTransferTime; sysData.s.sekVoltage = usek / 10; //Wenn Balancer eingeschaltet if (sysData.s.balancerPower > 0) { // ----- Prfe ob Flyback converter luft ----- counterValue = __HAL_TIM_GET_COUNTER(&htim1); if (( counterValue > MAX_TIMER_VALUE) && (sysData.s.converterError == CONVERTER_ERROR_NONE) ) { restartCounter++; balancer_running=0; } else { if (restartCounter>0) restartCounter--; } if (restartCounter >= RESTART_TIMEOUT) { BALANCER_SetStartImpulse(); restartCounter = 0; balancer_running=1; startImpulsCounter++; } else { } if (startImpulsCounter > 10) { sysData.s.balancerPower=0; HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0); sysData.s.converterError = CONVERTER_ERROR_STARTUP_ERROR; printf("CONVERTER ERROR: CONVERTER_STARTUP ERROR!\n"); startImpulsCounter = 0; } secondCounter++; if (secondCounter > 999) { if (startImpulsCounter > 0) startImpulsCounter--; secondCounter = 0; } // ----- Prfe ob Flyback converter Ausgangsspannung zu hoch ----- if ((usek > MAX_OUTPUT_VOLTAGE) && (balancer_running == 1)) { sysData.s.SekHvErrorCounter++; } else { if (sysData.s.SekHvErrorCounter>0) sysData.s.SekHvErrorCounter--; } if (sysData.s.SekHvErrorCounter > MAX_ERROR) { sysData.s.balancerPower=0; HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0); sysData.s.converterError = CONVERTER_ERROR_OUTPUT_VOLT_TOO_HIGH; printf("CONVERTER ERROR: CONVERTER_ERROR_OUTPUT_VOLT_TOO_HIGH\n"); sysData.s.SekHvErrorCounter=0; } // ----- Prfe ob Flyback converter Ausgangsspannung zu niedrig ----- if ((usek < MIN_OUTPUT_VOLTAGE) && (balancer_running == 1)) { sysData.s.SekLvErrorCounter++; } else { if (sysData.s.SekLvErrorCounter>0) sysData.s.SekLvErrorCounter--; } if (sysData.s.SekLvErrorCounter > MAX_ERROR) { sysData.s.balancerPower=0; HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0); sysData.s.converterError = CONVERTER_ERROR_OUTPUT_VOLT_TOO_LOW; printf("CONVERTER ERROR: CONVERTER_ERROR_OUTPUT_VOLT_TOO_LOW\n"); sysData.s.SekLvErrorCounter=0; } } else { //Balancer ist ausgeschaltet sysData.s.sekVoltage=0; } if (balancerRegulationCounter > 0) balancerRegulationCounter--; if ((sysData.s.mode == 0) && (balancerRegulationCounter == 0)) //AUTO MODE { balancerRegulationCounter = BALANCER_REGULATION_TIME; if (sysData.s.cellVoltageUnfiltered > sysData.s.balancerVoltage) { if ((sysData.s.balancerPower < MAX_DAC_VALUE) && (sysData.s.converterError == CONVERTER_ERROR_NONE )) { sysData.s.balancerPower++; if (sysData.s.balancerPower < CONVERTER_MIN_POWER ) { sysData.s.balancerPower = CONVERTER_MIN_POWER; startImpulsCounter = 0; } HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, sysData.s.balancerPower); } } if (sysData.s.cellVoltageUnfiltered < sysData.s.balancerVoltage) { if (sysData.s.balancerPower > 0) { sysData.s.balancerPower--; if( sysData.s.balancerPower < CONVERTER_MIN_POWER) sysData.s.balancerPower = 0; HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, sysData.s.balancerPower); } } } if (sysData.s.mode == 1) { if ((sysData.s.balancerPower < MAX_DAC_VALUE) && (sysData.s.converterError == CONVERTER_ERROR_NONE )) { HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, sysData.s.balancerPower); } } if (sysData.s.balancerPower > 0) { LED_FunctionSetTimes(900,100); } else { LED_FunctionSetTimes(100,900); } } void BALANCER_SetStartImpulse() { //Balancer arbeitet nicht. Schalte Ausgang von Comparator um auf normalen GPIO, //setze ausgang auf 0, und schalte dann wieder auf Comparator, dadurch wird ein neuer Setz Impuls auf das Flip Flop gegeben. printf("DC DC Wandler not running, start impuls\n"); GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = COMP2_OUT_DISCHARGE_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(COMP2_OUT_DISCHARGE_GPIO_Port, &GPIO_InitStruct); HAL_GPIO_WritePin(COMP2_OUT_DISCHARGE_GPIO_Port, COMP2_OUT_DISCHARGE_Pin, GPIO_PIN_RESET); //Ausgang zurck auf Comparator GPIO_InitStruct.Pin = COMP2_OUT_DISCHARGE_Pin; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF7_COMP2; HAL_GPIO_Init(COMP2_OUT_DISCHARGE_GPIO_Port, &GPIO_InitStruct); }