Kampis Elektroecke

XMega – DAC

XMega Blockdiagramm

Der XMega besitzt ein bis zwei DAC (Digital to Analog Converter), die es dem Mikrocontroller erlauben analoge Spannungen zu generieren. Jeder DAC besitzt zwei Kanäle und kann zudem auch als Referenzspannung für den internen ADC genutzt werden.

DAC konfigurieren:

In diesem Beispiel verwende ich den DACB (der andere DAC wäre der DACA). Über das CTRLC-Register wird die Referenzspannung des DAC, sowie die Ausrichtung des Datenwortes bestimmt:

Als Referenzspannung soll die interne 1 V Referenz verwenden werden soll, weshalb die Bits 3 und 4 gelöscht werden. Das Datenwort soll zudem rechts ausgerichtet sein, weshalb das LEFTADJ-Bit ebenfalls gelöscht werden muss.

DACB.CTRLC &= ~(DAC_REFSEL1_bm | DAC_REFSEL0_bm | DAC_LEFTADJ_bm);

Im nächsten Schritt wird das CTRLB-register beschrieben.

Über dieses Register wird die Anbindung des DAC an das Event-System, bzw. der Betriebsmodus des DAC konfiguriert. In diesem Beispiel soll nur der Kanal 0 genutzt werden, weshalb das Register wie folgt beschrieben wird:

DACB.CTRLB &= ~(DAC_CH1TRIG_bm | DAC_CH0TRIG_bm | DAC_CHSEL1_bm | DAC_CHSEL0_bm);
DACB.CTRLA |= DAC_CHSEL0_bm;

Jetzt muss noch das CTRLA-Register konfiguriert werden und danach ist der DAC einsatzbereit.

In diesem Register werden die einzelnen Ausgänge und der DAC aktiviert. Zudem kann hier noch ein Low Power Modus, bzw. die Nutzung des DAC als Referenc für den ADC aktiviert werden.

In diesem Fall soll lediglich der Ausgang 0 und der DAC aktiviert werden, was dem folgenden Bitmuster entspricht.

DACB.CTRLA = (DAC_CH0EN_bm | DAC_ENABLE_bm);

Wenn der DAC mit zwei Ausgängen arbeiten soll, muss die Konfiguration des CTRLB-Register entsprechend angepasst werden:

DACB.CTRLB = ~(DAC_CH1TRIG_bm | DAC_CH0TRIG_bm); 
DACB.CTRLB = (DAC_CHSEL1_bm | DAC_CHSEL0_bm);

Zudem müssen beide Ausgänge im CTRLA-Register aktiviert werden:

DACA.CTRLA = (DAC_CH1EN_bm | | DAC_CH0EN_bm | DAC_ENABLE_bm);

Ausgangsspannung einstellen:

Die Ausgangsspannung des DAC wird über das Datenregister des entsprechenden Kanals eingestellt. In diesem Beispiel wäre das das CH0DATA-Register. Um bereits aktivierte Wandlungen nicht zu beeinflussen, sollte mit dem Schreiben des neuen Wertes so lange gewartet werden, bis die aktuelle Wandlung abgeschlossen ist. Diese Information kann über das STATUS-Register abgeholt werden:

void DACB_Conversion(uint16_t Voltage)
{
   while(!DACB.STATUS & DAC_CH0DRE_bm);
   DACB.CH0DATA = Voltage;
}

Damit ist der Code vollständig. Ein Beispielprogramm kann z. B. so aussehen:

int main(void)
{
   DACB.CTRLC = ~(DAC_REFSEL1_bm | DAC_REFSEL0_bm | DAC_LEFTADJ_bm);
   DACB.CTRLB = ~(DAC_CH1TRIG_bm | DAC_CH0TRIG_bm);
   DACB.CTRLA = (DAC_CH0EN_bm | DAC_ENABLE_bm);
   
   while(!DACB.STATUS & DAC_CH0DRE_bm);
   DACB.CH0DATA = 0x100;

   while(1)
   {
   }
}

Wenn alles richtig gemacht wurde liegt an den dementsprechenden DAC-Pins des Mikrocontrollers eine Spannung an. Welche Pins das sind, kann dem Datenblatt des entsprechenden XMega entnommen werden. Für den DACB beim XMega128A1 sind es die Pins B.2 und B.3 (Pin 7 und 8) und für die Ausgangsspannung des DAC gilt:

Voltage= \frac{ReferenceVoltage}{2^{Resolution}}\cdot Data

Die Auflösung des DAC beträgt 12-Bit. Bei einer Referenzspannung von 1 V entspricht 1 Bit einer Spannung von ~244 µV.

Das komplette Beispielprojekt gibt es in meinem GitHub-Repository als Download.

6 Kommentare

  1. Hallo,
    ich will meine Vref für den DAC auf Vcc sprich 3,3V setzen, funktioniert aber leider nicht! :(
    Könntest du mir da evtl weiter helfen?

    Danke

  2. Hallo,
    Du schreibst: Wenn mein Beispielcode verwendet wird und die Variable Voltage einen Wert von 0xFFF besitzt, gibt der DAC eine Spannung von 1V aus (also genau die Spannung die die interne Referenz bereitstellt).
    Die Ausgangsspannung kann also auf 0,8mV genau eingestellt werden.

    Sollte die Auflösung nicht ca. 0,25mV bei 12 Bit betragen?

    Gruß Jürgen

    1. Hallo Jürgen,

      ja, du hast Recht. Meine Rechnung bezog sich auf 3,3V. Ich korrigiere das :)
      Danke für den Hinweis!

      Gruß
      Daniel

  3. Hallo,
    ich bin ein absoluter Laie und versuche gerade eine atxmega32a3u zu programmieren. Ich hänge gerade an der Programmierung des DAC. Ich habe ein Paar sehr grundsätzliche Fragen..

    So wie ich das verstanden habe wird doch am DAC Ausgang ein digitales Signal ausgesendet oder? Bei meinem Fall soll der Chip ein digitales Signal an einem DAC-Chip: http://www.analog.com/media/en/technical-documentation/data-sheets/AD5624_5664.pdf senden, der dann ein analoges Signal an den 4 Ausgängen schaltet.

    Könnntest du mir bei meinem Problem helfen?
    viele Grüße
    g44

    1. Hallo,

      der DAC erzeugt eine analoge Spannung (also z.B. eine Spannung von 0-5V) mit Hilfe eines digitalen Eingangswertes. Der digitale Eingangswert sind die Bits die du in den DAC rein schiebst.

      Gruß
      Daniel

Schreibe einen Kommentar

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