I/O

XMega Blockdiagramm

Auch bei den I/O hat sich viel getan und es wurden einige Neuerungen in die I/O Ports gebracht. Ich führe euch mal einige der Funktionen vor.

-> Datenrichtungsregister:

Das Datenrichtungsregister bestimmt ob ein Pin als Ausgang oder als Eingang fungiert.
Eine 1 bedeutet, dass der dazu gehörige Pin als Ausgang beschaltet ist und eine 0 bedeutet, dass er als Eingang arbeitet.
Mit dem Befehl

wird also der komplette PortX als Ausgang gesetzt.
Wenn nun einzelne Pins des Datenrichtungsregisters als Ausgang geschaltet werden sollen, wird dieser Befehl verwendet:

Nun wird vom PortX der Pin0 als Ausgang benutzt und die anderen Pins funktionieren als Eingang.
Chips der XMega Reihe bieten außerdem die Möglichkeit Pins direkt zu togglen.
Dazu gibt es das DIRTLG-Register. Dieses Register beschreibt, welches Bit im Datenrichtungsregister getogglet werden soll.
Als Beispiel:

sagt aus, dass alle Bits im Datenrichtungsregister von PortX getogglet werden sollen. Das heißt, dass jede 1 in eine 0 umgewandelt wird und umgekehrt.
Schreibt man hingegen

wird nur der Pin0 im Datenrichtungsregister von PortX getoggled.

 -> Ausgänge schalten und Eingänge einlesen:

– Ausgänge:

Wenn ein Pin im Datenrichtungsregister als Ausgang deklariert wurde, kann er durch das Beschreiben des Out-Registers auf High gesetzt werden.
Möchte man z.B. den kompletten PortX auf High setzen schreibt man folgendes:

und will man einen einzelnen Pin (z.B. Pin0) auf High setzen schreibt man dementsprechend das hier:

Durch den Befehl

wird das Bit gelöscht und der Pin besitzt wieder einen Low Pegel.
Die Ausgänge können außerdem noch über das OUTTGL-Register getoggelt werden.
Um einen kompletten Port zu togglen schreibt man das hier

und für einen einzelnen Pin lautet der Code so

Nun wird der Pin0 vom PortX getoggled.

– Eingänge:

Wurde ein Pin als Eingang deklariert, kann der Status des Pins über das In-Register ausgelesen werden.
Besitzt der Pin einen High Level, steht an der dementsprechenden Stelle im Register eine 1 und bei einem Low Level eine 0.
Dieser Wert kann anschließend in einer Variable gespeichert werden. Will man z.B. einen Port abfragen und den Wert in einer Variable speichern, schreibt man

Dadurch wird der Wert des In-Registers von PortX in der Variable Port gespeichert.
Wenn ein einzelner Pin nach einem High Pegel abgefragt werden soll, schreibt man dies so

und wenn er nach einem Low Pegel abgefragt werden soll lautet die Zeile so

-> Pin Control Register

– Pull-Up und Pull-Down:

Jeder Pin besitzt ein Pin Control-Register. Mit Hilfe dieses Registers können verschiedene Eigenschaften des Pins eingestellt werden.
Bevor das Register beschrieben wird, empfiehlt sich ein Blick in das XMega A Manual.
Dort wird das Pin Control-Register wie folgt beschrieben:

XMega_IO(1)
Auf Seite 143 dieses Datenblattes gibt es das Bild in der Originalgröße.

Soll nun ein Pin mit einem Pull-Down auf einen Low Pegel gezogen werden, muss entweder eine 010 oder eine 110 für OPC[2:0] in das Pin Control-Register geschrieben werden (siehe Pull configuration in der Tabelle).
Die Output configuration kann (in diesem Fall) vernachlässigt werden. Wer aber trotzdem wissen möchte was das für Funktionen sind, kann dies im XMega A Manual nachlesen.
Wenn nun ein Pin mit einem Pull-Down Widerstand versehen werden soll, kann das ganz einfach durch diese Codezeile erledigt werden:

Wenn aber mehrere Pins mit einem Pull-Down versehen werden sollen, empfiehlt sich der Einsatz des MPCMASK-Register.
Mit diesem Register können mehrere Pins eines Portes gleichzeitig z.B. als Ausgang oder als Eingang deklariert werden. Es kann aber auch genutzt werden um die Eigenschaften mehrerer Pins gleichzeitig zu verändern.
Als erstes schreibt man eine Maske in das Register, welche den Pins entspricht die man verändern möchte.
Sollen z.B. Pin0 und Pin7 eines Portes verändert werden schreibt man diese Zeile:

Nun ist der Pin0 und der Pin7 maskiert. Anschließend legt man noch den Inhalt des Pin Control-Registers“ fest. Da Pin0 und Pin7 mit einem Pull-Down Widerstand versehen werden lautet die nächste Zeile also so:

Nun wird der Pin0 und der Pin7 mit einem Pull-Down Widerstand versehen.
Dies kann man natürlich auch für mehrere Pins machen. Wenn z.B. vier Pins mit einem Pull-Up Widerstand versehen werden sollen kann man entweder

schreiben, oder man macht es ein wenig übersichtlicher und verwendet stattdessen eine Maske. Der Code dafür lautet:

Diese zwei Zeilen bewirken genau dasselbe wie die vier Zeilen dadrüber. Nur es sieht ein wenig übersichtlicher aus und vorallem die Pins werden alle gleichzeitig mit einem Pull-Up versehen. Bei den vier Zeilen dadrüber werden die Pins alle einzelnt und nacheinander mit einem Pull-Up versehen.

– Invertieren:

Zudem bietet das Pin Control-Register auch die Möglichkeit ein Signal, welches an einem Pin anliegt zu invertieren. Diese Möglichkeit besteht sowohl für Pins die als Ausgang deklariert sind wie auch für Pins die als Eingang funktionieren.
mit dem Befehl

wird vom PortX der Pin0 invertiert.
Normal wird mit dieser Codezeile

der Pin auf Low gelegt. Dadurch das der Pin aber invertiert ist, liegt der Pegel aber auf High.

-> Clock and Event Out Register

– Ausgabe der Taktfrequenz:

Die XMegas bieten auch noch die Möglichkeit die Taktfrequenz auf einem I/O Pin auszugeben. Zur Auswahl stehen die Pins C7, D7 und E7.
Um die Taktfrequenz auf einen Pin zu legen, muss man ledeglich das CLKEVOUT-Register beschreiben.
Die Bitkombinationen seht ihr auf dem Bild:

XMega_IO(2)

Wenn nun also die Taktfrequenz an C7 ausgegeben werden soll, wird das so gemacht:

Erst wird der Pin C7 als Ausgang definiert und anschließend schreibt man in das CLKEVOUT-Register eine 0x01 um Pin C7 als Taktausgang zu verwenden.

 

-> Zurück zum XMega Tutorial

6 thoughts on “I/O
  1. Hello there! I know this is somewhat off topic but I was wondering which
    blog platform are you using for this website?

    I’m getting tired of WordPress because I’ve had problems with hackers
    and I’m looking at options for another platform. I would be awesome if you could point me in the direction of a good platform.

    • I´m using WordPress for my Homepage.

      In addition of WordPress i use Capcha to disable Spambots and my Theme is
      „Atmosphere 2010“.

  2. Hallo,

    bezüglich „CLKEVOUT“: Kennst du eine Möglichkeit den Clock auf einen andern Pin als Pin7 zu geben? Konkret bräuchte ich das Signal auf PD1. Die PWM steht dabei leider nicht mehr zur Verfügung, weil ich damit schon ein Signal auf PD0 erzeuge.

    Viele Grüße,
    Timo

    • Hallo Timo,
      laut Datenblatt kann der Takt nur jeweils am Pin 7 ausgegeben werden.
      Kannst du nicht einfach über einen Timer den Pin togglen? So erstellst du auch quasi einen Takt.
      Ich weiß allerdings nicht ob das für dich ausreicht und wie schnell das ganze dann maximal werden kann.

      Gruß
      Daniel

      • Hallo Daniel,

        daran hatte ich auch gedacht, allerdings wäre das die unsauberste Methode. Ich habe bereits zwei UART- und eine SPI-Schnittstelle auf Interrupts laufen. Da mache ich mir dann schon etwas sorgen um die Sauberkeit des Clocks. In einem Sunny-Day-Szenario müsste das passen. Ich habe einen SysClock von 32MHz, die PWM macht nur 125kHz und an PD1 brauche ich nur 32kHz. Naja, ich werde mich noch etwas umsehen – zur not muss dann das PCB-Design geändert werden ;-)
        Vielen Dank für die schnelle Antwort!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload CAPTCHA.