Forum: Mikrocontroller und Digitale Elektronik AVR 10-Bit-DAC


von Georg M. (g_m)


Angehängte Dateien:

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"?

von N. M. (mani)


Lesenswert?

So macht es halt am meisten Sinn.
Wenn morgen noch ein paar Bits bei einem anderen uC dazu kommen, dann 
ändert sich das Alignment nicht.

von Peter D. (peda)


Lesenswert?

Welcher AVR?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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.

: Wiederhergestellt durch Moderator
von Georg M. (g_m)


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 vom Autor gelöscht.
von Harald K. (kirnbichler)


Lesenswert?

Adam P. schrieb im Beitrag #7699544:
> 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.

von Adam P. (adamap)


Lesenswert?

Harald K. schrieb:
> Adam P. schrieb im Beitrag #7699544:
>> 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.

von Georg M. (g_m)


Lesenswert?

Harald K. schrieb:
> ... dann kümmert sich der Compiler um das Shiften

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

???

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Google findet nach 1 Minute sowas:
- 
https://github.com/microchip-pic-avr-examples/avr128da48-using-10-bit-dac/blob/master/avr128da48-using-10-bit-dac/Generating_Constant_Signal_Example/main.c
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.

: Bearbeitet durch Moderator
von Harald K. (kirnbichler)


Lesenswert?

Lothar M. schrieb:
> Google findet nach 1 Minute sowas:

Dann ist das kein Bitfeld, sondern DATAH/DATAL sind die beiden 
kompletten Bytes der Register.

Und dann muss natürlich geshiftet werden.

Da im Datenblatt aber die zehn relevanten Bits im Register als 
"Data[9..0]" bezeichnet werden, war ich davon ausgegangen, daß im Code 
ein Bitfeld verwendet wird.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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.

: Bearbeitet durch Moderator
von Georg M. (g_m)


Lesenswert?

Lothar M. schrieb:
> Google findet nach 1 Minute sowas:

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

Deswegen war meine ursprüngliche Frage.

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Georg M. schrieb:
> dachte, wenn man das "Complete DataSheet" hat, dann braucht man
> keine Google-Funde.

Aber nachdenken und notfalls ein kleines Testprogramm schreiben ist 
schon erlaubt. Du bist hier 1,5 Stunden dran. In der Zeit hättest du 
x-Mal ein Testprogramm schreiben können. Oder geht es dir nur ums 
Prinzip?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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?

von Adam P. (adamap)


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"

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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

: Bearbeitet durch Moderator
von Bruno V. (bruno_v)


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.

von Adam P. (adamap)


Lesenswert?

Lothar M. schrieb:
> 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...

Seite 6

"The output will be updated after DACn.DATAH is written"

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Adam P. schrieb:
> "The output will be updated after DACn.DATAH is written"
Blöd, genau andersrum wie bei den 16-Bit-Timern. Da hätten sich die 
Spezialisten bei der Entwicklung doch mal über die Reihenfolge 
austauschen sollen.

von Peter D. (peda)


Lesenswert?

Adam P. schrieb:
> "The output will be updated after DACn.DATAH is written"

Das ist sinnvoll, wenn man nur einen 8Bit-DAC benötigt.
Das DATAL kann dann im Resetzustand verbleiben.

von Adam P. (adamap)


Lesenswert?

Peter D. schrieb:
> Das ist sinnvoll, wenn man nur einen 8Bit-DAC benötigt.
> Das DATAL kann dann im Resetzustand verbleiben.

Du meinst wenn man nur 8Bit Auflösung haben möchte und dafür die größere 
Abstufung in kauf nimmt?

Klingt logisch, aber warum sollte man sowas machen wollen?

von Norbert (der_norbert)


Lesenswert?

Adam P. schrieb:
> Klingt logisch, aber warum sollte man sowas machen wollen?

Möglicherweise falls man das Ding per DMA** betanken möchte.
(Halbe RAM-Puffergröße)

**Unter der Annahme das die Dinger DMA können.

von Bruno V. (bruno_v)


Lesenswert?

Adam P. schrieb:
> Klingt logisch, aber warum sollte man sowas machen wollen?

Manchmal weil es kompatibel ist mit alter HW (die nur 8 Bit hatte), bzw. 
mit neuer, die 12 oder 14 hat.

Immer, wenn die untersten 3(!) Bit nicht signifikant sind oder 
anderweitig gebraucht werden.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.