mercoledì 19 giugno 2013

XMega I/O

Gli XMega (in realtà il vero nome è ATXMega ma utilizzerò XMega per brevità) sono i microcontrollori fratelli maggiori degli ATMega, familiari anche agli utenti della piattaforma Arduino.



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 output
PORTA.OUTSET = PIN1_bm;   // set to high
PORTA.OUTCLR = PIN1_bm;   // set to low

Utilizzando ASF (API IOPORT):

#define PORTA1 IOPORT_CREATE_PIN(PORTA,1)      // create a pin name alias
ioport_init();                                 // initialize IOPORT
ioport_set_pin_dir(PORTA1, IOPORT_DIR_OUTPUT); // set pin to output
ioport_set_pin_level(PORTA1, HIGH);            // set to high
ioport_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)


port structure


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


intellisense


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 PORTA   
MYPORT.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