AVR 10-Bit-DAC

OP #7699518
Lesenswert?

Das DATA-Register des 10-Bit-DAC sieht "left-adjusted" aus. Aber nirgendwo im Text steht, dass der 10-Bit-Wert entsprechend angepasst werden muss. Wie ist dies zu verstehen? Als "selbstverständlich"?

Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #7699528
Lesenswert?

Georg M. schrieb:

Aber nirgendwo im Text steht, dass der 10-Bit-Wert entsprechend angepasst werden muss.

Doch, da steht sogar explizit der Name der Bits: DACn.DATA

Wie ist dies zu verstehen? Als "selbstverständlich"?

Ja, selbstverständlich musst du die 10 Bits Data[9:0] so verwenden, dass ein für dich taugliches Ergebnis herauskommt. Deshalb ist die Position dieser Bits im Datenblatt ausdrücklich beschrieben.

Bei ganz, ganz vielen anderen Bits ist das ja auch so.

Der Witz an diesem Alignment ist, dass im Highbyte "automatisch" die signifikanten 8 Bit stehen. Wenn dir also 8 Bit Auflösung ausreichen, musst du einfach nur dieses Byte verarbeiten.

dass der 10-Bit-Wert entsprechend angepasst werden muss.

Wenn du es schaffst, diesen Faktor 64 in deiner Rechnung zu "verstecken", dann musst du da gar nichts extra anpassen.

N. M. schrieb:

Wenn morgen noch ein paar Bits bei einem anderen uC dazu kommen, dann

... kommen die garantiert immer bei den LSB dazu.

OP #7699541
Lesenswert?

Peter D. schrieb:

Welcher AVR?

AVR32DA28, AVR32DA32, AVR32DA48, AVR64DA28, AVR64DA32, AVR64DA48, AVR64DA64, AVR128DA28, AVR128DA32, AVR128DA48, AVR128DA64

AVR32DB28, AVR32DB32, AVR32DB48, AVR64DB28, AVR64DB32, AVR64DB48, AVR64DB64, AVR128DB28, AVR128DB32, AVR128DB48, AVR128DB64

AVR16DD14, AVR16DD20, AVR16DD28, AVR16DD32, AVR32DD14, AVR32DD20, AVR32DD28, AVR32DD32, AVR64DD14, AVR64DD20, AVR64DD28, AVR64DD32

AVR16EA28, AVR16EA32, AVR16EA48, AVR32EA28, AVR32EA32, AVR32EA48, AVR64EA28, AVR64EA32, AVR64EA48

Beitrag #7699544 wurde von einem Moderator gelöscht.
#7699547
Lesenswert?

Harald K. schrieb:

Adam P. schrieb:

dac_value = (DACn.DATA >> 6);

Wenn DACn ein Bitfeld ist ... dann kümmert sich der Compiler um das Shiften, das musst Du nicht selbst machen. Sonst hätte das Bitfeld auch irgendwie wenig Sinn.

Ja ne, vergiss es, hatte den Beitrag gelöscht, weil ich falsch herum gedacht habe.

Right Shift 6 wäre beim ADC richtig, beim DAC müsste es ja dann Left Shift sein.

Aber wenn der Compiler das macht, ist ja top, kannte ich so auch noch nicht.

Moderator (Firma: Titel) Persönliche Seite #7699553
Lesenswert?

Google findet nach 1 Minute sowas:

1
static void DAC0_setVal(uint16_t value)
2
{
3
    /* Store the two LSbs in DAC0.DATAL */
4
    DAC0.DATAL = (value & LSB_MASK) << 6;
5
    /* Store the eight MSbs in DAC0.DATAH */
6
    DAC0.DATAH = value >> 2;
7
}

Ich hätte das einfach mal so wie du probiert, den 16-Bit Wert um 6 Bits nach links geshiftet und das komplette 16 Bit Register DAC0.DATA angesprochen.

Moderator (Firma: Titel) Persönliche Seite #7699570
Lesenswert?

Harald K. schrieb:

daß im Code ein Bitfeld verwendet wird

Ja, das wäre natürlich ziemlich ungeschickt dokumentiert, wenn ein 16-Bit Zugriff auf das Register DATA nach rechts justiert ist, Zugriffe auf die 8-Bit Register DATAH und DATAL dann aber nach links.

Aber ich denke, der Faktor 64 bei der ausgegebenen Spannung macht sich ganz schnell bemerkbar. Deshalb schrieb ich dass ich es "probiert" hätte.

Und möglicherweise komme ich dann genau dort raus, wie es der Code von Github auch macht. Einfach, weil das explizit und sonnenklar ist.

#7699594
Lesenswert?

Lothar M. schrieb:

Georg M. schrieb:

Ich dachte, wenn man das "Complete DataSheet" hat, dann braucht man keine Google-Funde.

Dein Glaube ehrt dich, aber was meinst du, warum es Errata auch zu Datenblättern gibt?

Was ich bei der Arbeit mit Atmel/Microchip Datenblättern in den ganzen letzten Jahren gelernt habe:

Vertraue nicht nur auf das Datenblatt.

Aber das hier ist richtig:

Lothar M. schrieb:

Google findet nach 1 Minute sowas:

Siehe ApplicationNote, die sind auch mal nützlich wenn das Datenblatt alleine nicht ausreicht: https://ww1.microchip.com/downloads/aemDocuments/documents/MCU08/ApplicationNotes/ApplicationNotes/Using-10Bit-DAC-for-Generating-Analog-Signals-DS90003235C.pdf

Seite 7 "Starting a Conversion"

Moderator (Firma: Titel) Persönliche Seite #7699606
Lesenswert?

Adam P. schrieb:

Seite 7 "Starting a Conversion"

Da steht dann auch sowas Halbgares:

1
Starting a Conversion
2
...
3
a conversion starts as soon as the Data (DACn.DATA) register is written.
4
...
5
DAC0.DATAL = (value & (0x03)) << 6;
6
DAC0.DATAH = value >> 2;

Denn lustigerweise wird hier das Register DAC0.DATA gar nie explizit beschreiben, sondern nur DAC0.DATAL und DAC0.DATAH nacheinander.

Welcher der beiden Zugriffe triggert jetzt die Ausgabe? Hoffentlich nur der auf DATAH? Oder wird die Ausgabe 2x angestoßen?

Das würde ich dann aber sicherheitshalber auch mal ausprobieren. Könnte ja hässliche Effekte geben...

#7699612
Lesenswert?

Georg M. schrieb:

Harald K. schrieb:

... dann kümmert sich der Compiler um das Shiften

Wie denn? Was soll ich schreiben:DAC0.DATA = dac_value; oder dochDAC0.DATA = dac_value << 6;

???

Bitfelder wäre sowas:

1
struct myDAC_s
2
{
3
   uint16_t value:10;
4
   uint16_t      :6; /* unused */
5
};
6

7
volatile struct myDAC_s myDAC @ 0x1000; /* Adresse vom Register in HW, Compilerspezifisch */
8
...
9
    xy = myDAC.value;

Da kümmert sich der Compiler um alles. In der Praxis scheitert es manchmal daran, dass die Reihenfolge der Bits per Schalter umgedreht werden kann oder dass die Register in bestimmter Art und Weise ausgelesen werden müssen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren