/* * buck_emulator.c * * Created on: 12 May 2025 * Author: Christian Lind Vie Madsen */ #include "buck_emulator.h" static int isStructOk(BuckEmulator_t *inst){ if(inst == NULL)return 0; return 1; } static void buck_emulator_step(BuckEmulator_t *inst, float duty_cycle) { float dIL_on = 0.0f, dIL_off = 0.0f; // ON-phase if (duty_cycle > 0.0f) { float V_L_on = inst->Vin - inst->Vout; dIL_on = (V_L_on / inst->L) * (duty_cycle * inst->dt); } // OFF-phase float V_L_off = 0.0f; if ((inst->IL + dIL_on) > 0.0f) { V_L_off = -inst->Vout; // Diode conducts dIL_off = (V_L_off / inst->L) * ((1.0f - duty_cycle) * inst->dt); } else { dIL_off = 0.0f; } // Total inductor current update inst->IL += dIL_on + dIL_off; if (inst->IL < 0.0f) inst->IL = 0.0f; // Capacitor current float capCurrent = inst->IL - inst->Vout / inst->Rload; // Diode blocking check if (inst->IL == 0.0f && capCurrent < 0.0f) { capCurrent = 0.0f; } // Vout update float dVout = capCurrent / inst->C; inst->Vout += dVout * inst->dt; // Clamp Vout if (inst->Vout < 0.0f) inst->Vout = 0.0f; if (inst->Vout > inst->Vin) inst->Vout = inst->Vin; return; } int buck_emulator_Run(BuckEmulator_t *inst){ if(!isStructOk(inst))return 1; float dutyCycle = 0.0; for(float t = 0.0; t < inst->simTime; t+=inst->dt){ if(inst->regulate_evt != NULL)dutyCycle = inst->regulate_evt(inst->Vout); buck_emulator_step(inst, dutyCycle); if(inst->getResult_evt != NULL)inst->getResult_evt(dutyCycle,inst->Vout,t); } return 0; } int buck_emulator_RegGetResultEvt(BuckEmulator_t *inst, getResult_evt_t getRes_evt){ if(!isStructOk(inst))return 1; if(getRes_evt != NULL){ inst->getResult_evt = getRes_evt; return 0; } return 1; } int buck_emulator_RegRegulationEvt(BuckEmulator_t *inst, regulate_evt_t reg_evt){ if(!isStructOk(inst))return 1; if(reg_evt != NULL){ inst->regulate_evt = reg_evt; return 0; } return 1; } int buck_emulator_init(BuckEmulator_t *inst, float Vin, float L, float C, float Rload, float dt, float sim_time){ if(!isStructOk(inst))return 1; inst->Vin = Vin; inst->L = L; inst->C = C; inst->Rload = Rload; inst->dt = dt; inst->Vout = 0.0; inst->IL = 0.0; inst->simTime = sim_time; return 0; }