Approcciarsi utilizzando il C inizialmente può però sembrare difficile, ad esempio un compito semplice come "alzare un pin" può essere svolto in più modi:
- Utilizzando direttamente i registri del microcontrollore
- Utilizzando il framework ASF
- API GPIO
- API IOPORT
Il framework ASF permette un livello di astrazione maggiore, internamente manipola i registri del microcontrollore che sono la strada maestra per la sua programmazione ma richiedono spesso un'approfondita conoscenza del datasheet.
I "nuovi" spesso cercando in internet rimangono confusi dalla molteplicità di istruzioni che trovano per svolgere la solita azione, in questo caso possono trovare ben tre "set" di istruzioni diverse, alcune addirittura con diverse varianti.
Tralasciando le API GPIO che sono deprecate vediamo un esempio con entrambi gli approcci.
Supponiamo di voler impostare come uscita, alzare ed abbassare il pin 1 della PORT A
Utilizzando i registri:
PORTA.DIRSET = PIN1_bm; // set pin to outputPORTA.OUTSET = PIN1_bm; // set to highPORTA.OUTCLR = PIN1_bm; // set to low
Utilizzando ASF (API IOPORT):
#define PORTA1 IOPORT_CREATE_PIN(PORTA,1) // create a pin name aliasioport_init(); // initialize IOPORTioport_set_pin_dir(PORTA1, IOPORT_DIR_OUTPUT); // set pin to outputioport_set_pin_level(PORTA1, HIGH); // set to highioport_set_pin_level(PORTA1, LOW); // set to low
Entrambi gli approcci hanno vantaggi e svantaggi tipici della programmazione a basso livello contro una programmazione di livello maggiore.
La sintassi tramite i registri è molto diversa rispetto alla famiglia ATMega dove erano presenti ad esempio i registri DDRx e PORTx, è però meglio organizzata tramite delle strutture accessibili tramite una sintassi PORTx.REGISTER dove REGISTER è il registro della porta che si vuole impostare e può essere per esempio sull’ATXMega32A4U uno dei seguenti valori (tratto dal file header iox32a4u.h)
Un ulteriore vantaggio di questa sintassi è senza ombra di dubbio l’intellisense dell’ambiente Atmel Studio che alla pressione del punto ci proporrà visualmente uno dei possibili registri
Per chi si trovasse male con la sintassi col punto può optare per utilizzare l’underscore al suo posto, ad esempio potrà scrivere in maniera equivalente
PORTA_DIRSET = PIN1_bm;PORTA_OUTSET = PIN1_bm;PORTA_OUTCLR = PIN1_bm;
ricordando però che non potrà utilizzare un #define per impostare la sola porta come ad esempio è possibile con la sintassi con le strutture:
#define MYPORT PORTAMYPORT.DIRSET = PIN1_bm;
Il prezzo da pagare per questa ulteriore flessibilità (utilizza del punto o dell’underscore) è un’ulteriore confusione per i novizi che troveranno quindi molti modi per gestire i pin. Una volta consci delle molteplici possibilità non si avranno però problemi.
Aggiungo come nota al codice ASF che quasi tutte le API hanno una funzione nomeAPI_init() che deve essere chiamata prima dell'utilizzo delle restanti funzioni.
Per chi volesse valutare o iniziare a programmare gli XMega personalmente consiglio di partire dalla libreria ASF che ha buona parte delle API corredate da una documentazione minimale ma con un'ottima sezione Quick Start che permette di fare i primi passi in tempi molto brevi, per IOPORT il link è http://asf.atmel.com/docs/latest/xmegaau/html/ioport_quickstart.html, accessibile anche da ASF Explorer direttamente dall'interno di Atmel Studio
Nessun commento:
Posta un commento