• Non ci sono risultati.

N/A
N/A
Protected

Academic year: 2021

Condividi ""

Copied!
16
0
0

Testo completo

(1)

I

L FIRMWARE

In questo capitolo verrà presentato il software che permette il corretto funzionamento del regolatore. Sarà, in un primo momento, discussa la sua struttura, ed in seguito si passerà alla descrizione delle funzioni che lo realizzano. Finita la presentazione del firmware, verranno mostrati alcuni dei segnali che caratterizzano il funzionamento del sistema.

Riferimenti bibliografici: [21], [22], [24], [25], [26], [27], [28], [29], [31], [35], [36], [17], [18].

S

TRUTTURA DEL FIRMWARE

Il programma che gestisce l’ATxmega128a1 è stato scritto in linguaggio C, e compilato e caricato nella memoria del processore attraverso AVR Studio 4, una GUI (Graphical User Interface) messa a disposizione dalla ATMEL stessa; il suo funzionamento è basato sul meccanismo delle interruzioni, ed è rappresento dalla macchina a stati finiti di figura 6.1.

(2)

Figura 6.1 – Rappresentazione della macchina a stati realizzata dal firmware.

Dopo un’iniziale fase di setup durante la quale vengono settate tutte le periferiche ed inizializzate le variabili necessarie al processo, il microcontrollore si porta nello stato ASPETTAINTERRUZIONE0 nel quale si mette in attesa dell’interrupt esterno porth_int0, che indica l’inizio della semionda positiva di Vmo;

questa richiesta viene soddisfatta eseguendo le dovute funzioni e il sistema si porta nel nuovo stato interno ASPETTAINTERRUZIONE1 nel quale, dualmente al caso precedente, aspetta l’IRQ generata dallo zero crossing del semiperiodo negativo porth_int1 e conclude il ciclo operativo riportandosi nello stato ASPETTAINTERRUZIONE0. In entrambi i due stati possono arrivare richieste di interruzione anche da parte del timer con l’IRQ, quando avviene il compare match, che determina la chiusura degli interruttori. Le richieste generate da parte dell’ADC sono abilitate solo in ASPETTAINTERRUZIONE0, perché come già visto in precedenza i campionamenti della tensione sul carico vengono effettuati solamente durante il semiperiodo positivo di Vmo.

Le tre possibili richieste di interruzione o IRQ (Interrupt Request), quella generata dal timer, quella generata dall’ADC e quelle generate dalla Porta H, hanno tre differenti livelli di priorità: qualora ne arrivassero due contemporaneamente, verrà eseguita prima la routine appartenente alla richiesta con priorità più alta; se dovesse

(3)

arrivare una richiesta di interrupt con priorità maggiore durante l’esecuzione della

routine di una istanza di livello inferiore, quest’ultima sarà sospesa a vantaggio

dell’istanza più importante, per essere ripresa e portata a termine successivamente. La tabella 6.1 riporta la scala delle priorità assegnate alle possibili richieste di interruzione.

Richiesta di interruzione Livello di priorità

tcd0_cca alta

adca_ch0 media

porth_int0, porth_int1 bassa

Tabella 6.1 – Scala delle priorità assegnate alle possibili richieste di interrup.

La scelta di una tale distribuzione di importanza è così giustificata: le richieste generate dalla Porta H si hanno in concomitanza con l’attraversamento dello zero da parte di Vmo; le routine a loro attribuite (PORTH_INT0_vect e

PORTH_INT1_vect) richiedono tempi di elaborazione piuttosto lunghi, e durante la loro esecuzione potrebbe arrivare la richiesta tcd0_cca. Questa richiesta è generata dal timer nel momento in cui vanno chiusi gli interruttori: è estremamente importante che la sua routine (TCD0_CCA_vect), tra l’altro molto breve, venga eseguita immediatamente. L’ADC viene attivato durante l’esecuzione di TCD0_CCA_vect e genera la sua richiesta alla fine di ogni conversione; la sua routine (ADCA_CH0_vect) ne elabora il risultato e da il via ad una nuova conversione. Così come per quello generato dal timer, anche l’interrupt dell’ADC potrebbe arrivare durante l’esecuzione di PORTH_INT0_vect: se non avesse una priorità maggiore, ADCA_CH0_vect sarebbe eseguita in ritardo con il risultato di una compromissione della lettura di Vload. I tempi di esecuzione della richiesta associata a questa periferica

sono molto ridotti, per cui, una IRQ generata dalla Porta H, non rimarrà pendente a lungo.

(4)

S

TRATEGIE PER AUMENTARE LE PRESTAZIONI

Per ridurre il più possibile i tempi di esecuzioni delle varie funzioni, sono stati ideati dei semplici stratagemmi che, grazie ad una manipolazione delle equazioni da risolvere, hanno portato a dei notevoli risultati in quanto ad aumento della velocità di elaborazione.

Primo fra tutti, come già annunciato in precedenza, è il meccanismo di confronto tra Vload-RMS e V*RMS. Il normale calcolo del valore efficace di una tensione

(3.2) richiede, l’esecuzione di una radice quadrata, ma questa operazione comporta lunghi tempi di elaborazione: si è quindi pensato di effettuare il confronto tra i quadrati di queste due grandezze, cosa che, si è constato in fase di ottimizzazione dell’algoritmo di controllo, non solo ha l’effetto di aumentare la velocità di elaborazione, ma rende anche più rapido e stabile il controllore stesso. La riga di comando all’interno del programma che definisce V*RMS è la seguente:

Un tale valore di Vrif è stato ottenuto attraverso la (6.1) dove LSB (Least Significant

Bit) è un parametro di conversione dell’ADC dato dal rapporto tra la massima

tensione convertibile e il numero di livelli di quantizzazione, e dove con Pload si è

indicato il fattore di partizione nella rete di adattamento per la Vload.

(6.1) 2 * RMS rif load

V

V

LSB P

 

.

Poiché per risalire dal risultato di una conversione al valore della tensione che l’ha generato bisogna applicare la (6.2), dove v è la tensione analogica inviata ad un ADC una risoluzione pari a LSB attraverso una partizione P e V è il risultato della

(5)

conversione: la scelta optata per la definizione di Vrif consente di evitare al microcontrollore l’esecuzione di 2 moltiplicazioni ad ogni confronto.

(6.2)

v V P LSB

.

Sempre per calcolo del valore efficace di Vload, è stata realizzata questa

procedura:

Tsample è il numero dei cicli che un clock da 16 MHz compie tra due

conversioni dell’ADC; sommatoria non è altro che la somma dei quadrati dei risultati delle conversioni di Vload. Le conversioni non vengono memorizzate per poi essere

elaborate in una seconda fase, sono elaborate nella stessa routine dell’IRQ del convertitore, con un notevole risparmio di risorse. Veff è l’equivalente del valore efficace di Vload per la strategia di calcolo adottata, semiperiodo è una stima della

durata del semiperiodo di Vmo, ottenuta attraverso un timer con un clock di 16 MHz.

Altri accorgimenti particolari sono stati usati nel trattare le relazioni (5.8), (510), (5.12) e (5.13). Queste sono tutte nel formato

(6.3)

y

     

a x x

b x

c

.

Una tale equazione ha bisogno dell’esecuzione di 3 moltiplicazioni e 2 addizioni, ma scrivendole seconda la (6.4), si riesce a ridurre di 1 il numero di moltiplicazioni necessarie.

#define Tsample 61 …

sommatoria += (unsigned int)ADCA_CH0_RESL*(unsigned int)ADCA_CH0_RESL;

(6)

(6.4)

y

  

c

x b

(

 

a c

)

.

Un ulteriore accorgimento per ottimizzare la velocità del sistema è stato quello di utilizzare il più possibile variabili di tipo intero ed intero lungo, che richiedono minori tempi di elaborazione.

D

ESCRIZIONE DELLE FUNZIONI

Per una miglior leggibilità del codice e per un più facile intervento durante la fase debugging del sistema, il firmware è stato scritto suddiviso nel maggior numero possibile di funzioni.

All’accensione del regolatore il microcontrollore entra nella fase di setup chiamando in sequenza le funzioni:

AttivaClock32M()

l’ATxmega128a1 offre la possibilità di utilizzare un clock interno a 32 MHz; questa periferica va selezionata ed abilitata ad ogni accensione del microcontrollore che, di default, si avvia con il clock a 2 MHz;

SettaAC(), SettaTimer(), SettaADC()

configurano rispettivamente il comparatore analogico, il timer ed il convertitore analogico digitale, conformandoli alle specifiche del sistema; SettaInterruzioniEsterne()

imposta i parametri della Porta H per il corretto funzionamento delle interruzioni esterne;

SettaDriver()

predispone la Porta J ad inviare i segnali di On e Off agli interruttori; AttivaAC(), AccendiTimer()

(7)

AbilitaInterruzioni()

abilita le interruzione a livello generale, andando a configurare il registro predisposto all’interno della processore.

Quando, nello stato interno ASPETTAINTERRUZIONE0, il processore riceve l’IRQ INT0 dalla Porta H ed esegue la Interrupt Service Routine ISR(PORTH_INT0_vect). Dato il sistema e la struttura del programma, sarà praticamente impossibile che il processore riceva un richiesta di interruzione porth_int1 quando si trova in questo stato interno; lo switch (STATO) {...} è un’ulteriore protezione contro l’eventualità che venga eseguita ISR(PORTH_INT0_vect) nella semionda di Vmo sbagliata. Di seguito è spiegata

ogni riga di comando di questa ISR:

PORTQ_OUT |= (1<<PIN0_bp);

Questo comando permette di controllare quando avviene l’esecuzione di questa routine, è molto utile in fase di debug.

switch (STATO) {

case ASPETTAINTERRUZIONE0: { PORTJ_OUT &= ~(ON_DOWN_gc);

Invia gli impulsi di off_down; l’interrupt INT0 indica che è finita la semionda negativa ed cominciata quella positiva.

STATO = ASPETTAINTERRUZIONE1; Cambia lo stato interno.

ResettaTimer();

Questa funzione memorizza nella variabile semiperiodo il valore del registro del contatore, corrispondente alla durata del semiperiodo di Vmo, e fa

(8)

TCD0_CCA = (semiperiodo-conduzione);

Con questo comando si scrive all’interno del registro CCA del timer D0 il valore del conteggio equivalente all’istante di chiusura degli interruttori. if (RegolazionePassiva) {

Qui esegue un controllo sulla condizione di RegolazionePassiva; questa variabile è un flag che l’algoritmo del controllore mette ad 1 quando non è attuabile una regolazione attiva.

PORTJ_OUT |= ON_UP_gc;

Durante la fase di regolazione passiva, vengono subito mandati agli interruttori gli impulsi di On_up (si ricorda che Vmo è nella semionda

positiva). AccendiADC();

Poiché è iniziata la fase di conduzione, viene acceso l’ADC per il calcolo di Vload-RMS.

TCD0_CCA = MAXIMUM; }

Il timer invia la sua IRQ quando c’è la necessità di inviare gli impulsi di on, ma questi impulsi sono stati generati due istruzioni fa, per cui non c’è bisogno di far generare nessuna richiesta al timer: ecco perché in CCA viene scritto un valore irraggiungibile: 65535.

Veff = (sommatoria/semiperiodo)*Tsample;

Qui viene effettuato il calcolo della tensione efficace sul carico. RiferimentoConduzione();

Kbase();

Queste due funzioni determinano i valori delle variabili che nel precedente capitolo sono state indicate con T100on(T) e K100(T) attraverso la (5.10) e la

(9)

sommatoria = 0;

Dopo aver effettuato il calcolo del valore efficace, la sommatoria viene azzerata per poter essere riutilizzata correttamente nella successiva elaborazione.

break;}

default:{break;} }

PORTQ_OUT &= ~(1<<PIN0_bp); Indica la fine dell’esecuzione della ISR.

Durante la regolazione attiva, la normale successione delle richieste di interruzione prevede a questo punto quella generata dal timer. Il corpo di ISR(TCD0_CCA_vect) è il seguente:

PORTQ_OUT |= (1<<PIN2_bp);

Segnala l’inizio dell’esecuzione della routine. switch (STATO) {

case ASPETTAINTERRUZIONE1: { PORTJ_OUT |= ON_UP_gc;

AccendiADC();

Durante la semionda positiva di Vmo, invia gli impulsi di On_up ed accende il

convertitore analogico digitale.

break; }

case ASPETTAINTERRUZIONE0: { PORTJ_OUT |= ON_DOWN_gc;

Durante la semionda negativa invia soltanto gli impulsi di On_down: durante questa fase di conduzione non è prevista la misurazione di Vload.RMS.

break; }

(10)

PORTQ_OUT &=~(1<<PIN2_bp);

Segnale che indica la fine dell’esecuzione della routine.

Poco dopo averlo azionato, il convertitore analogico-digitale invierà una sua richiesta di interrupt; verrà eseguita una ISR(ADCA_CH0_vect) cosi fatta:

PORTQ_OUT |= (1<<PIN3_bp); Segnale di inizio esecuzione della ISR. switch (STATO) {

Ulteriore controllo per evitare le conversioni durante la conduzione negativa. case ASPETTAINTERRUZIONE1: {

RiavviaADC();

Da il via ad una nuova conversione.

Sommatoria += (unsigned int)ADCA_CH0_RESL*(unsigned

int)ADCA_CH0_RESL;

Esegue il quadrato della conversione appena effettuta.

break; }

default: {break;}}

PORTQ_OUT &= ~(1<<PIN3_bp); Comando di fine esecuzione della ISR.

Al sopraggiungere della semionda negativa di Vmo, viene generata dalla Porta H una IRQ che darà il via all’esecuzione di ISR(PORTH_INT1_vect):

PORTQ_OUT |= (1<<PIN1_bp); Controllo esecuzione routine. switch (STATO) {

Ulteriore protezione contro una errata esecuzione della ISR. case ASPETTAINTERRUZIONE1: {

(11)

PORTJ_OUT &= ~(ON_UP_gc);

Generazione degli impulsi di off_up: la semionda positiva è appena finita. STATO = ASPETTAINTERRUZIONE0;

Cambio di stato interno.

if (RegolazionePassiva) {

Controllo sulla condizione di RegolazionePassiva. PORTJ_OUT |= ON_DOWN_gc; }

Generazione degli impulsi di on_down. ResettaTimer();

DisattivaADC();

Spegne il convertitore analogico digitale. StimaCarico();

Effettua il calcolo di Rload attraverso la (5.8) e la (5.9).

CalcoloK();

Determina K*p attraverso la (5.11). controllore();

Questa funzione realizza il controllore dimensionato nel capitolo V. break; }

default: {break; }}

PORTQ_OUT &= ~(1<<PIN1_bp);

(12)

L’ultima funzione in esame è controllore(); essa è così fatta: RegolazionePassiva = 0;

Come prima cosa il controllore resetta il flag della regolazione passiva; qualora fosse necessario rimanere nelle fase di conduzione continua, ripristinerà il valore di questa variabile più avanti.

if (Veff>Vrif) {

Questo controllo è indispensabile in quant oil fattore di correzione è stato dichiarato come unsigned, ovvero può assumere solo valori positivi.

correzione = (unsigned int)(Kp*(Veff-Vrif));

Effettua il calcolo della correzione da apportare all’intervallo di conduzione per ridurre la differenza Veff-Vrif.

PORTD_OUT = 0b11110011;

Accende i LED per il controllo visivo sulla condizione di Veff. if ((conduzione-correzione)<Tguardia)

{conduzione = Tguardia;}

Tguardia equivale ad un tempo di 6,25 µs; poiché dalle simulazioni effettuate

risulta Tonmin = 37,4 µs, un intervallo di conduzione inferiore a Tguardia non

dovrebbe essere mai possibile. La protezione offerta da questo controllo è invece utile quando l’intervallo di conduzione è lungo circa quanto il semiperiodo di Vmo: in una tale situazione, un repentino cambio della frequenza del generatore potrebbe determinare un intervallo di conduzione maggiore del semiperiodo stesso.

else{conduzione=(unsigned int)(conduzione-correzione);}} Determinazione del nuovo intervallo di conduzione.

else {correzione = (unsigned int)(Kp*(Vrif-Veff));

Effettua il calcolo della correzione da apportare all’intervallo di conduzione per ridurre la differenza Vrif-Veff.

PORTD_OUT = 0b11111100;

(13)

if((conduzione+correzione)>(semiperiodo-Tguardia)) Controllo sulla protezione Tguardia.

{RegolazionePassiva = 1;}

Se la differenza tra il semiperiodo di Vmo e l’intervallo di conduzione è

inferiore a Tguradia, si instaura nuovamente il regime di regolazione passiva.

else{conduzione=(unsigned int)(conduzione+correzione);}} Determinazione del nuovo valore di conduzione.

I

L REGOLATORE IN FUNZIONE

Di seguito sono riportati i segnali che descrivono il funzionamento del regolatore ottenuti con l’ausilio dell’oscilloscopio.

Figura 6.2 – Segnale di esecuzione di ISR(PORTH_INT0_vect) (curva rossa) e andamento

(14)

Figura 6.3 – Segnale di esecuzione di ISR(PORTH_INT0_vect) (curva rossa) e andamento

di Vmo (curva verde).

Figura 6.4 – Segnale che indica l’esecuzione di della routine associata ad INT1 generata

(15)

Figura 6.5 – Segnale di esecuzione di ISR(ADCA_CH0_vect) (curva rossa) e andamento di

Vload (curva verde).

Figura 6.6 – Segnale di esecuzione di ISR(ADCA_CH0_vect) (curva rossa) e andamento di

(16)

Figura 6.7 – Prove di laboratorio. Confronto tra la tensione prodotta dal generatore (canale

1) e l’effetto della parzializzazione sul carico (canale 2).

Figura 6.8 – Prove di laboratorio. È possibile vedere il regolatore in funzione: lampadina

accesa e segnali della regolazione sullo schermo dell’oscilloscopio. È inoltre possibile vedere la scheda dei componenti di potenza mutuata dal progetto analogico.

Figura

Figura 6.1 – Rappresentazione della macchina a stati realizzata dal firmware.
Tabella 6.1 – Scala delle priorità assegnate alle possibili richieste di interrup.
Figura 6.2 – Segnale  di  esecuzione  di ISR(PORTH_INT0_vect) (curva rossa) e andamento
Figura 6.4 – Segnale che indica l’esecuzione di della routine associata ad INT1 generata
+3

Riferimenti

Documenti correlati

Danish National Maritime Museum in Helsingor, Denmark - BIG Bjarke Ingels Group, Focus I ponti abitati | Arketipo Danish National Maritime Museum in Helsingor, Denmark – BIG

delle possibilità che sono del tutto precluse alla coscienza, perché esso dispone di tutti quei contenuti psichici al di sotto del valore-soglia (sub-liminali), di tutto ciò che

As Figure 4.4.2 shows, this activity actually contributed only for about half of the students who answered affirmatively to question 1; these students observed that this

The availability of a new reliable instrument aimed at obtaining a thorough understanding of the epidemiological characteristics, determinants and the workers’ behaviours

Clinical research has been fundamental to enhancing medical treatment progress and patient care but the current COVID-19 pandemic has led to the shift of priority to SARS-CoV-2

In any case, this triumphal entry staked out a new direction for royal celebrations in the Italian territories and became, for example, an obvious model for Charles V’s victory

L’unità di Salerno ha organizzato i Congressi internazionali ‘Donne in movi- mento’ (12-14 maggio 2010, Atti pubblicati: Salerno, Oèdipus, 2011) e ‘Pene- lope e le altre’

It was Euler’s observation that real numbers with an eventually periodic continued fraction expansion satisfy a quadratic equation with integer coefficients, and Lagrange proved