123 lines
2.2 KiB
C
123 lines
2.2 KiB
C
/*
|
|
* 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;
|
|
|
|
}
|