Simulatore software

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:

Uno schema del simulatore è riportato in figura 1.11.

Figure: Schema a blocchi del simulatore di alimentatore switching
\begin{figure}\centerline{\hbox{\vbox{
\psfig{figure=fig/schema_simulatore.eps,width=90mm,angle=-90} } } }~
\end{figure}

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 $\neq$ 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 ), $\backslash$
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 ),$\backslash$
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) ,$\backslash$
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:

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