Xmega Tutorial – I/O

Auf den folgenden Seiten findet Ihr ein kleines Xmega Tutorial – I/O zu den Microcontrollern der Familie AVR Xmega in der Programmiersprache “C”. Auch bei den Ein- und Ausgangspins (I/O-Pins) der XMEGAs wurden einige Neuerungen im Vergleich zur Atmel Familie gemacht. Die Atmega und Attiny Familien hatten für jeden Port nur drei Register (PORT, DDR, PIN). Im Vergleich dazu haben die Xmega für jeden Port einen Registersatz von 32 Registern, wovon momentan aber nur 21 verwendet werden.

Features

  • Flexible pin configuration
  • Synchronous and/or asynchronous input sensing
  • Asynchronous wake-up signaling
  • Configurable output driver – and pull settings: Totem-pole Wired-AND Wired-OR Pull-up/-down Bus keeper Inverted I/O
  • Slew rate control
  • Configuration of multiple pins in a single operation
  • Virtual set/clear/toggle registers for output and direction registers
  • Mapping of ports into virtual ports in I/O space for faster access

Die bisherigen Register gibt es nach wie vor, jedoch unter den Namen OUT, DIR und IN. Die Funktion hast sich fast nicht verändert. Der einzige Unterschied ist bei den drei Registern des Xmegas, dass man den internen PullUp Widerstand nicht mehr durch das Setzen des OUT-Bits des jeweiligen Ports aktivieren kann. Für diese Funktion steht jetzt jedem Pin ein komplettes Byte (PINxCTRL) zur Verfügung , in dem man neben dem PullUp auch verschiedenen Verhalten bei Ausgang oder Eingang definieren kann (invertieren des Pins beim Ausgang). Die weiteren Register werden dazu verwendet die Funktionen im Zusammenhang mit Interrupts zu definieren. Das wird jedoch in einem anderem Tutorial behandelt.Table 13-4. Output/Pull Configuration (PINxCTRL)

OPC[2:0]
000     001010011100101110111 





Group Configuration
TOTEMBUSKEEPER
PULLDOWN
PULLUP
WIREDOR
WIREDAND
WIREDORPULL
WIREDANDPULL
Output configuration
Totempole
Totempole
Totempole
Totempole
Wired OR
Wired AND
Wired ORWired AND   
Pull configuration
(N/A)
Bus keeper 
Pull-down (on input) 
Pull-up (on input)
(N/A)
(N/A)
Pull-downPull-up

Weiter wurde den Registern OUT und DIR jeweils drei neue Register mit dem Namen OUTSET, OUTCLR und OUTTGL, bzw. DIRSET, DIRCLR und DIRTGL spendiert. Mit diesen Register kann man ohne die bisherigen Read-Modify-Write Operationen die einzelne Bits setzen oder löschen. Dazu schreibt man einfach mit Hilfe einer Bitmaske einen Wert in das jeweilige Register, welcher dem gewünschten Bitmuster entspricht, das man ändern will. Danach setzt, löscht oder toggelt der Controller automatisch die entsprechenden Bits. Vorteil dieses Features ist , dass man damit einiges an Codegröße und Ausführungszeit sparen kann, da die Schritte Read und Write im Hintergrund automatisch ausgeführt werden.

Allgemein werden bei einem Microcontroller die I/O-Pins in I/O-Ports mit jeweiles 8 einzelnen Pins gruppiert. Die verschiedenen I/O-Ports haben den Namen PORTx, wobei x ein Buchstabe, zB. PORTA oder PORTB usw. ist. Die einzelnen Pins an jedem Port haben die Bezeichnung PXn, wobei x der Port-Buchstabe und n die Pin-Nummer, zB. PA0, PA1, … ist.Xmega – I/O Bitmanipulation

//#################################################### Pin als Ausgang
PORTA.DIRSET = PIN3_bm; /* PA3 as output */
PORTA.OUTSET = PIN3_bm; /* PA3 as high */
PORTA.OUTCLR = PIN3_bm; /* PA3 as low */
PORTA.OUTTGL = PIN3_bm; /* PA3 togglw */
 
//#################################################### Pin als Eingang
PORTD.DIRCLR = PIN0_bm; /* Pin 0 as input */
PORTD.PIN0CTRL = PORT_OPC_WIREDANDPULL_gc; /* PIN0 WIRED AND PULLup */
if (bis(PORTD.IN,0)) /* if Pin 0 High --> set Pin3 low*/
 PORTA.OUTSET = PIN3_bm; /* Pin 3 as high */ 

Alternativ zu diesen Befehlen kann man auch über die herkömmliche Weise durch Bitmanipulation mit den folgenden Macros die Register der einzelnen Ports manipulieren. Gern könnt ihr die Macros aus unserem Xmega Tutorial – I/O für eure Anwendung übernehmen.

#define sbi(ADDRESS,BIT) ADDRESS |= (1<<BIT) // set Bit
#define cbi(ADDRESS,BIT) ADDRESS &= ~(1<<BIT) // clear Bit
#define toggle(ADDRESS,BIT) ADDRESS ^= (1<<BIT) // Bit umschalten
 
#define bis(ADDRESS,BIT) ADDRESS & (1<<BIT) // bit is set?
#define bic(ADDRESS,BIT) !(ADDRESS & (1<<BIT)) // bit is clear?

Hinweis:
Das Tutorial wird nach und nach von mir ergänzt. Wenn ihr Fehler in dem Tutorial findet, würde ich mich freuen wenn ihr mir diese mitteilt, damit ich diese korrigieren kann. Wenn jemand eigene Tips, Informationen oder Code-Schnipsel hat kann er mir diese gern zusenden, damit ich sie anschließend in das Tutorial einbinden kann.

Links 
Atmel Appnote
Xmega I/O
AVR1313: Using the XMEGA IO Pins and External Interrupts (pdf)
AVR1313: Using the XMEGA IO Pins and External Interrupts (Software)