Il simulatore software realizzato si basa sulla valutazione delle 1.49 e 1.50 (che si riducono alle 1.51 e 1.52
nello stato di IDLE). Per questo assume in ingresso un valore di duty cycle e mantenendo memoria degli stati del
circuito produce i nuovi stati e le uscite.
Durante un intero ciclo di switching si possono presentare uno o più dei tre stati di funzionamento (
ON, OFF e IDLE). Esiste quindi una parte del codice che si può definire parte di controllo1.3 che si
occupa della corretta invocazione della routine di valutazione degli stati dell'alimentatore in base al duty cycle
e agli stati del circuito. In particolare deve:
- distinguere la presenza dello stato di IDLE (verificando il valore di
al termine dello stato
di OFF)
- iniziare con lo stato di OFF (o addirittura di IDLE) se il duty cycle è zero.
- controllare il limite in corrente
dell'induttore: se esso viene superato lo switch viene immediatamente
aperto (valido solo per il buck). Questa è una scelta opinabile in quanto implica delle protezioni all'interno dell'alimentatore.
Se questa protezione non è richiesta può venire disabilitata.
Uno schema del simulatore è riportato in figura 1.11.
Figure:
Schema a blocchi del simulatore di alimentatore switching
 |
Si analizzano ora le varie componenti di questo schema.
La parte di calcolo delle matrici A, B, C e D è l'unica dipendente dalla
topologia e risiede in un'unica funzione chiamata Matrix:
indentation
int Matrix()
{
A[0][0][ON] = -1L(Rl+Ron+(RRc)(R+Rc));
A[1][0][ON] = 1C(R(R+Rc));
A[0][1][ON] = -1L(R(R+Rc));
A[1][1][ON] = -1C(1(R+Rc));
B[0][ON] = VsL+(1L)Io(RRc)(R+Rc);
B[1][ON] = -(1C)IoR(R+Rc);
C1[0][0][ON] = 1.0;
C1[1][0][ON] = RRc(R+Rc);
C1[0][1][ON] = 0.0;
C1[1][1][ON] = R(R+Rc);
D1[0][ON] = 0.0;
D1[1][ON] = -Io(RRc)(R+Rc);
A[0][0][OFF] = -1L(Rl+Rd+(RRc)(R+Rc));
A[1][0][OFF] = 1C(R(R+Rc));
A[0][1][OFF] = -1L(R(R+Rc));
A[1][1][OFF] = -1C(1(R+Rc));
B[0][OFF] = -vdL+(1L)Io(RRc)(R+Rc);
B[1][OFF] = -(1C)IoR(R+Rc);
C1[0][0][OFF] = 0.0;
C1[1][0][OFF] = RRc(R+Rc);
C1[0][1][OFF] = 0.0;
C1[1][1][OFF] = R(R+Rc);
D1[0][OFF] = 0.0;
D1[1][OFF] = -Io(RRc)(R+Rc);
A[0][0][IDLE] = 0.0;
A[1][0][IDLE] = 0.0;
A[0][1][IDLE] = 0.0;
A[1][1][IDLE] = -1C(1(R+Rc));
B[0][IDLE] = 0.0;
B[1][IDLE] = -(1C)IoR(R+Rc);
C1[0][0][IDLE] = 0.0;
C1[1][0][IDLE] = 0.0;
C1[0][1][IDLE] = 0.0;
C1[1][1][IDLE] = R(R+Rc);
D1[0][IDLE] = 0.0;
D1[1][IDLE] = -Io(RRc)(R+Rc);
return(OK);
}
Questa è la funzione Matrix per il buck (sono le matrici di pagina
) ma una analoga
è stata scritta per il boost utilizzando le matrici di pagina
.
La parte di valutazione delle equazioni di stato risiede in una funzione Calc_State che ha la forma seguente:
indentation
int Calc_State(double time, double bound_cond, double state, double out, mode_of_func modo)
{
double det, tr, a;
cplx alpha, beta, gamma, sigma, tau, csi, p1, p2,v,i,tmpe1,tmpe2;
i = c_complex(bound_cond[0]);
v = c_complex(bound_cond[1]);
det = A[0][0][modo] A[1][1][modo] - A[0][1][modo] A[1][0][modo];
tr = A[0][0][modo] + A[1][1][modo];
a = trtr;
if (modo
IDLE)
{
cplx tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7;
tmp2= c_sqrt(c_complex(a-4.0det));
tmp3= c_complex(2.0);
p1 = c_div( c_sub( c_complex(tr), tmp2 ), tmp3 );
p2 = c_div( c_sum( c_complex(tr), tmp2 ), tmp3 );
tmp1=c_mul(p1,p2);
tmp4=c_sum( c_complex(B[1][modo]), c_mul(p1,v) );
tmp5=c_sum(c_complex(B[0][modo]), c_mul(p1,i) );
tmp6=c_sum(c_complex(B[1][modo]) ,c_mul(p2 ,v ) );
tmp7=c_sum(c_complex(B[0][modo]),c_mul(p2,i));
alpha = c_div( c_complex( (A[0][1][modo]B[1][modo])-(A[1][1][modo]B[0][modo]) ), tmp1 );
sigma = c_div( c_complex( (A[1][0][modo]B[0][modo])-(A[0][0][modo]B[1][modo]) ), tmp1 );
beta = c_div( c_sub(c_mul(c_complex(A[0][1][modo]),tmp4 ),
c_mul( c_sub(c_complex(A[1][1][modo]),p1) ,tmp5 ) ), c_mul(p1,c_sub(p1,p2)) );
tau = c_div( c_sub( c_mul( c_sub(c_complex(A[0][0][modo]),p1), tmp4 ),
c_mul(c_complex(A[1][0][modo]),tmp5 )),c_mul(p1,c_sub(p2,p1)) );
gamma = c_div(c_sub(c_mul(c_complex(A[0][1][modo]),tmp6) ,
c_mul(c_sub(c_complex(A[1][1][modo]),p2) ,tmp7) ), c_mul(p2,c_sub(p2,p1)));
csi = c_div(c_sub(c_mul(c_sub(c_complex(A[0][0][modo]),p2 ) ,tmp6 ) ,
c_mul(c_complex(A[1][0][modo]) ,tmp7 ) ) ,c_mul(p2 ,c_sub(p1,p2)) );
}
else / modo
IDLE /
{
double tmpi1;
p1 = c_complex(0.0);
p2 = c_complex(A[1][1][modo]);
tmpi1= B[1][modo]A[1][1][modo];
alpha = c_complex(0.0);
sigma = c_complex( -tmpi1);
beta = c_complex(0.0);
tau = c_complex(0.0);
gamma = c_complex(0.0);
csi = c_sum(c_complex(tmpi1) ,v );
}
tmpe1=c_exp( c_mul(p1, c_complex(time) ) );
tmpe2=c_exp( c_mul(p2, c_complex(time) ) );
state[0] = c_real(c_sum(alpha , c_sum(c_mul(beta ,tmpe1 ) ,c_mul(gamma ,tmpe2 ) ) ) );
state[1] = c_real(c_sum(sigma , c_sum(c_mul(tau ,tmpe1 ) ,c_mul(csi ,tmpe2 ) ) ) );
out[0]= state[0]C1[0][0][modo]+state[1]C1[0][1][modo]+D1[0][modo];
out[1] = state[0]C1[1][0][modo]+state[1]C1[1][1][modo]+D1[1][modo];
return(OK);
}
Questa funzione assume in ingresso gli stati iniziali, il tempo di durata del ciclo (ON, OFF o IDLE) e
lo stato di funzionamento in cui si trova l'alimentatore. Restituisce gli stati e le uscite al termine del tempo
richiesto. Le funzioni c_sum, c_mul ecc. eseguono le operazioni nell'insieme dei numeri complessi.
La parte di ``controllo'' accetta in ingresso un valore di duty cycle (proveniente dal controllo esterno) e procede
nel seguente modo:
- se il duty cycle è zero è possibile avere stato di OFF (
) o stato di IDLE (
dai passi
precedenti).
- se il duty cycle è uno, ci si trova nello stato di ON per tutto il periodo di switching.
- se si ha
si parte dallo stato di ON, dopo il tempo
si passa allo stato
di OFF e si calcolano le variabili di stato fino alla fine del periodo di switching. Se, a questo punto,
ho , è necessario scoprire il punto in cui si passa da OFF a IDLE. Il metodo scelto consiste
nel ricalcolare le variabili di stato in condizione OFF variando il tempo fino a quando la
si
approssima a zero entro una certa tolleranza. Il tempo viene ricalcolato secondo la seguente formula:
, avendo definito come
il valore che assume la corrente nell'induttanza all'inizio del ciclo di OFF.
Al termine di ogni stato di funzionamento dell'alimentatore viene scritta su un file una linea contenente il tempo,
gli stati e le uscite in una forma facilmente comprensibile da un qualunque programma per tracciare grafici.
La parte di controllo deve anche, ad ogni passo di switching, variare i parametri dell'alimentatore per simulare
le variazioni di carico o di ingresso richieste dall'utente. I sorgenti completi sono riportati in appendice.
Bofh
2004-02-09