• Non ci sono risultati.

F IRMWARE PER L ’AT XMEGA 128 A 1

N/A
N/A
Protected

Academic year: 2021

Condividi "F IRMWARE PER L ’AT XMEGA 128 A 1"

Copied!
11
0
0

Testo completo

(1)

F

IRMWARE PER L

’AT

XMEGA

128

A

1

Per una miglior leggibilità del codice ed un più veloce intervento in fase di

debug, il programma è stato diviso in diversi settori, che tengono conto delle

caratteristiche delle funzioni descritte all’interno di essi. Ad ognuno di questi settori è stato attribuito un simbolo grafico (per esempio alle funzioni di routine è stato assegnato il carattere ‘=’) che, riportato appena prima della dichiarazione della funzione, permette di individuare velocemente le finalità della funzione in esame.

#include <avr/io.h> #include <avr/interrupt.h> #include <math.h> #define Tguardia 100 #define ON_UP_gc(PIN0_bm|PIN1_bm)

#define ON_DOWN_gc (PIN2_bm|PIN3_bm)

#define Vrif 4895 //(Vrif/(LSB*PartitoreVload)^2 #define ADCA_CH0_RESL _SFR_MEM8(0x0224)

//riferimento diretto agli 8 bit meno significativi del

//registro dei risultati dell'ADC, non presente di default nei header //file

#define Tsample 61

//Tsample=(tempo_di_campionamento)/(prescaler_timer) #define MAXIMUM 65535

// --- // dichiarazione variabili globali // ---

typedef enum {ASPETTAINTERRUZIONE0, ASPETTAINTERRUZIONE1} INTERNO;

INTERNO STATO;

unsigned int semiperiodo; unsigned int conduzione;

(2)

unsigned int conduzione100; unsigned int correzione; unsigned long int Veff;

unsigned long int sommatoria; unsigned int ADCres;

unsigned int delta; float Rload;

float K100; float Kp;

char RegolazionePassiva;

//flag per la regolazione passiva

// ############################ // funzioni di inizializzazione // ############################ // ########## // processore void AttivaClock32M(void) { OSC_CTRL |= OSC_RC32MEN_bm;

char controllo = (OSC_STATUS & OSC_RC32MRDY_bm); while (!controllo)

{

controllo = (OSC_STATUS & OSC_RC32MRDY_bm); //aspetta che il clock a 32 MHz si pronto

}

CCP = CCP_IOREG_gc;

//abilita la modifica del registro protetto CLK_CTRL CLK_CTRL = CLK_SCLKSEL_RC32M_gc;

//abilita il clock a 32 MHz

OSC_CTRL &= ~OSC_RC2MEN_bm; } void AbilitaInterruzioni(void) { PMIC_CTRL |= (PMIC_LOLVLEN_bm|PMIC_MEDLVLEN_bm|PMIC_HILVLEN_bm); sei(); }

(3)

// ## // AC void SettaAC(void) { ACB_AC0MUXCTRL |= (AC_MUXPOS_PIN2_gc|AC_MUXNEG_PIN3_gc); // Vmo-a --> PB2; Vmo-rif --> PB3 ACB_AC0CTRL |= (AC_HSMODE_bm|AC_HYSMODE_SMALL_gc);

//abilita il funzionamento in alta velocità e l'isteresi a 50 //mV

ACB_CTRLA |= AC_AC0OUT_bm;

//manda l'uscita del comparatore su PB7 } // #################### // Interruzioni esterne void SettaInterruzioniEsterne(void) { PORTH_INTCTRL |= PORT_INT1LVL_LO_gc; PORTH_INTCTRL |= PORT_INT0LVL_LO_gc; PORTH_PIN0CTRL |= PORT_ISC_RISING_gc;

//PH0 invia una IRQ durante la transizione 0->1 PORTH_PIN1CTRL |= PORT_ISC_FALLING_gc;

//PH1 invia una IRQ durante la transizione 1->0 PORTH_INT0MASK |= PIN0_bm; //PH0 genera INT0 PORTH_INT1MASK |= PIN1_bm; //PH1 genera INT1 } // ##### // timer void SettaTimer(void) { TCD0_INTCTRLB |= TC_CCAINTLVL_HI_gc; //alta priorità per la IRQ del timer

TCD0_CTRLB |= TC0_CCAEN_bm; //abilita il compare match TCD0_CNT = 0;

(4)

// ###### // driver void SettaDriver(void) { PORTJ_DIR |= 0x0F; PORTJ_PIN1CTRL |= PORT_INVEN_bm; //abilita l'inverter del pin PORTJ_PIN3CTRL |= PORT_INVEN_bm; //abilita l'inverter del pin

PORTJ_OUT &= ~(ON_UP_gc|ON_DOWN_gc); //genera i segnali di off_on e off_down } // ### // ADC void SettaADC(void) { ADCA_CTRLB |= ADC_RESOLUTION_8BIT_gc; //Risoluzione a 8 bit ADCA_REFCTRL |= ADC_REFSEL_AREFA_gc; //Riferimento esterno su AREFA

ADCA_PRESCALER |= ADC_PRESCALER_DIV16_gc; //Fclock = 2 MHz ADCA_CH0_CTRL |= ADC_CH_INPUTMODE_SINGLEENDED_gc; ADCA_CH0_MUXCTRL |= (ADC_CH_MUXPOS_PIN3_gc); //ingresso su PA3 ADCA_CH0_INTCTRL |= ADC_CH_INTLVL_MED_gc; //media priorità per la IRQ

} // =================== // funzioni di routine // =================== // == // AC void AttivaAC(void) { ACB_AC0CTRL |= AC_ENABLE_bm; }

(5)

// ===== // timer

void AccendiTimer(void) {

TCD0_CTRLA |= TC_CLKSEL_DIV2_gc; //fclock=16 MHz }

void ResettaTimer(void) {

semiperiodo = (unsigned int)TCD0_CNT; TCD0_CNT = 0; } // === // ADC void AccendiADC(void) { ADCA_CTRLA |= (ADC_ENABLE_bm|ADC_CH0START_bm); } void RiavviaADC(void) { ADCA_CH0_CTRL |= ADC_CH_START_bm; } void DisattivaADC(void) {

ADCA_CTRLA &= ~ADC_ENABLE_bm; } // ============= // calcolo Rload void RiferimentoConduzione(void) { conduzione100 = 829.1+semiperiodo*((4.338e-5)* semiperiodo-0.1493); } void StimaCarico(void) {

(6)

Rload = 100000/ ((float)(763+delta*(5.883+0.002217*delta))); } // ================= // fattore controllo void Kbase(void) { K100 = (float)(semiperiodo*(semiperiodo* (2.13e-8)+(2.43e-5))-.01044); } void CalcoloK(void) { Kp = K100/(0.445+Rload*((12.6e-3)-(7.157e-5)*Rload)); } // =========== // controllore void controllore(void) { RegolazionePassiva = 0; if (Veff>Vrif) {

correzione = (unsigned int)(Kp*(Veff-Vrif)); PORTD_OUT = 0b11110011; if ((conduzione-correzione)<Tguardia) { conduzione = Tguardia; } else {

conduzione = (unsigned int)(conduzione-correzione);

} }

else {

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

if ((conduzione+correzione)>(semiperiodo-Tguardia)) {

(7)

RegolazionePassiva = 1; }

else {

conduzione = (unsigned int)(conduzione+ correzione); } } } ////////// // MAIN // ////////// int main (void)

{

//cambio clock AttivaClock32M();

//inizializzazione led per controllo visivo PORTD_DIR |= 0xFF;

PORTD_OUT |= 0xFF;

//inizializzazione porta Q per il controllo delle //interruzioni

PORTQ_DIR |= (PIN0_bm|PIN1_bm|PIN2_bm|PIN3_bm);

//inizializzazione porte e periferiche PORTB_DIR |= PIN7_bm;

//PB7 è l'uscita del comparatore ACB0 SettaAC(); SettaInterruzioniEsterne(); SettaDriver(); SettaTimer(); SettaADC(); //inizializzazione variabili Veff = 0;

(8)

RegolazionePassiva = 0; sommatoria = 0; semiperiodo = MAXIMUM; TCD0_CCA = MAXIMUM; Kp = 0.19; K100 = 0.19; conduzione100 = Tguardia; Rload = 100; //attivazione perififeriche AttivaAC(); AccendiTimer();

//cambio di stato interno e attivazioni interruzioni a //livello globale STATO = ASPETTAINTERRUZIONE0; AbilitaInterruzioni(); while (1) { //ciclo infinito } } /////////////// // FINE MAIN // /////////////// // ++++++++++++++++++++++++++ // vettori delle interruzioni // ++++++++++++++++++++++++++

// ++++++++++++++++++++ // interruzioni esterne ISR(PORTH_INT0_vect){

PORTQ_OUT |= (1<<PIN0_bp); //controllo esecuzione switch (STATO) {

case ASPETTAINTERRUZIONE0: {

(9)

//impulsi di off_down

STATO = ASPETTAINTERRUZIONE1; ResettaTimer();

TCD0_CCA = (semiperiodo-conduzione); //memorizzazione del nuovo istante di //chiusura degli interruttori

if (RegolazionePassiva) {

PORTJ_OUT |= ON_UP_gc; AccendiADC();

TCD0_CCA = MAXIMUM; //evita la //generazione di una inutile IRQ da //parte del timer

}

Veff = (sommatoria/semiperiodo)*Tsample; //calcolo del valore efficace di Vload RiferimentoConduzione(); Kbase(); sommatoria = 0; break; } default: { break; } }

PORTQ_OUT &= ~(1<<PIN0_bp); //controllo esecuzione }

ISR(PORTH_INT1_vect) {

PORTQ_OUT |= (1<<PIN1_bp); //controllo esecuzione switch (STATO)

{

case ASPETTAINTERRUZIONE1: {

PORTJ_OUT &= ~(ON_UP_gc); STATO = ASPETTAINTERRUZIONE0; if (RegolazionePassiva)

{

(10)

} ResettaTimer(); DisattivaADC(); StimaCarico(); CalcoloK(); controllore(); break; } default: { break; } }

PORTQ_OUT &= ~(1<<PIN1_bp); //controllo esecuzione }

// +++++ // timer

ISR(TCD0_CCA_vect) {

PORTQ_OUT |= (1<<PIN2_bp); //controllo esecuzione switch (STATO) { case ASPETTAINTERRUZIONE1: { PORTJ_OUT |= ON_UP_gc; AccendiADC(); break; } case ASPETTAINTERRUZIONE0: { PORTJ_OUT |= ON_DOWN_gc; break; } default: { break; } }

PORTQ_OUT &=~(1<<PIN2_bp); //controllo esecuzione }

(11)

// ++++++++++++ // campionatore ISR(ADCA_CH0_vect)

{

PORTQ_OUT |= (1<<PIN3_bp); //controllo esecuzione switch (STATO)

{

case ASPETTAINTERRUZIONE1: {

RiavviaADC();

Sommatoria += (unsigned int)ADCA_CH0_RESL* (unsigned int)ADCA_CH0_RESL; break; } default: { break; } }

PORTQ_OUT &= ~(1<<PIN3_bp); //controllo esecuzione }

Riferimenti

Documenti correlati

per le Politiche di incentivazione della produttività delle aree funzionali AMMONTARE COMPLESSIVO DEI PREMI STANZIATI E EFFETTIVAMENTE DISTRIBUITI..

A seguito dell’incontro bilaterale attivato dalla Commissione Europea (nei giorni del 4 e 5 luglio 2019) con i rappresentanti della Direzione Generale Environment e della

[r]

Se consideriamo il grafico di una funzione: f: R → R si può osservare che f è iniettiva se ogni retta orizzontale incontra il grafico al più una

Foglio esercizi MB Corso di Laurea

[r]

[r]

28   Possiamo  a  giusto  titolo  parlare  di  due  paradigmi  epistemologici  differenziati,  poiché  profondamente  diverse  sono  le  premesse  causali  che