Forum: Mikrocontroller und Digitale Elektronik STM32 Sinussignal via DAC


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Don K. (donkey)


Lesenswert?

Moin zusammen,

heute wende ich mich mit einer Programmierfrage an euch, ich stehe 
offenbar total auf dem Schlauch.

Will eigentlich ein 0 bis 3,3V Sinussignal an meinem 12Bit-DAC erzeugen 
und nutze dafür die folgende Schleife:
1
#define PI 3.1415926
2
3
void calcsin(void){
4
5
  for (int i = 0; i<100; i++){
6
7
             sine_value[i] = (sin(i*2*PI/100)+1)*2048;
8
9
    }
10
}

Also eigentlich nichts Spannendes. Die Ausgabe klappt auch an sich 
(nutze Timer 6 + DMA) - leider wird mir das Signal oben und unten ein 
wenig abgeschnitten. Woran könnte das liegen? Ich nahm an, die 
Skalierung sei so in Ordnung.

Vielen Dank schon Mal!

: Bearbeitet durch User
von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Welcher DAC-Typ?
Welche Versorgungsspannung?
Welche Referenzspannung?
Schaltplan?
Oszillogramm?

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Don K. schrieb:

>              sine_value[i] = (sin(i*2*PI/100)+1)*2048;
                                                   ^^^^

> (nutze Timer 6 + DMA) - leider wird mir das Signal oben und unten ein
> wenig abgeschnitten. Woran könnte das liegen?

Daran.

von Rainer W. (rawi)


Lesenswert?

Don K. schrieb:
> Woran könnte das liegen?

Ein 12-Bit DAC kann als höchsten Wert 0x0FFF ausgeben, nicht 0x1000

Warum rechnest du eigentlich jeden Sinus-Wert im Prinzip 4 Mal aus, 
statt die Symmetrien der Sin-Funktion auszunutzen?

: Bearbeitet durch User
von Bauform B. (bauformb)


Lesenswert?

Ob S. schrieb:
> Don K. schrieb:
>>              sine_value[i] = (sin(i*2*PI/100)+1)*2048;
>                                                    ^^^^

Das ist nur die halbe Miete, bei 0.0 Volt würde immer noch 
abgeschnitten, sin() darf auch nicht 0 werden. 6% weniger sind bei 3.3V 
ca. 0.2V weniger, das verspricht ST z.B. für den STM32F334 mit 
eingeschaltetem Buffer. Ohne Buffer wären es nur einstellige mV, aber 
der Ausgang ist dann so hochohmig (15k), dass man das kaum nutzen kann. 
Vielleicht so:
1
sine_value[i] = lround ((sin(i*2.0*PI/100.0)*0.94+1.0)*2048.0);

von Norbert (der_norbert)


Lesenswert?

Don K. schrieb:
> leider wird mir das Signal oben und unten ein
> wenig abgeschnitten. Woran könnte das liegen? Ich nahm an, die
> Skalierung sei so in Ordnung.

Zusätzlich zu den Hinweisen bezüglich Skalierung noch Folgendes:
Man kann für den STM DAC einen Buffer/Verstärker ein/ausschalten.
Mit Buffer kann man zwar besser/stärker belasten, jedoch nicht die 
volle rechnerische Amplitude verwenden.

BB war schneller…

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Norbert schrieb:

> Mit Buffer kann man zwar besser/stärker belasten, jedoch nicht die
> volle rechnerische Amplitude verwenden.

Er benutzt ja schon mehr als die "volle rechnerische Amplitude". Also 
ein Problem nach dem anderen. In Reihenfolge der Relevanz...

von Norbert (der_norbert)


Lesenswert?

Ob S. schrieb:
> Er benutzt ja schon mehr als die "volle rechnerische Amplitude".

Deshalb schrieb ich ja:
> Zusätzlich zu den Hinweisen bezüglich Skalierung…

Aber danke für's weglassen. ;-)

Außerdem schrieb der OP:
> leider wird mir das Signal oben und unten ein wenig abgeschnitten.

Das ist nur mit Multiplikation 2048 überhaupt nicht zu bewerkstelligen, 
da würde ausschließlich oben eine einzelne Pixelhöhe abgeschnitten.

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Norbert schrieb:

> Das ist nur mit Multiplikation 2048 überhaupt nicht zu bewerkstelligen,
> da würde ausschließlich oben eine einzelne Pixelhöhe abgeschnitten.

Ähemm, welche Pixel?

Im Übrigen: -1 ist für den DAC ungefähr genauso sinnvoll wie +2048...

von Rainer W. (rawi)


Lesenswert?

Norbert schrieb:
> Das ist nur mit Multiplikation 2048 überhaupt nicht zu bewerkstelligen,
> da würde ausschließlich oben eine einzelne Pixelhöhe abgeschnitten.

Falsch, das ergibt einen Full-Scale Sprung von 4092 auf 0.

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Ob S. schrieb:
> Norbert schrieb:
>
>> Das ist nur mit Multiplikation 2048 überhaupt nicht zu bewerkstelligen,
>> da würde ausschließlich oben eine einzelne Pixelhöhe abgeschnitten.
>
> Ähemm, welche Pixel?
>
> Im Übrigen: -1 ist für den DAC ungefähr genauso sinnvoll wie +2048...

Du meine Güte, man kann sich auch künstlich dumm stellen.

Ein Sinus von -1 … +1 mit 248 multipliziert ergibt einen Bereich von 
-2048 … +2048. Da packt man einen +2048 Offset dazu und so geht die 
Kurve ›unten‹ genau bis 0 und oben schießt es um ein LSB (besser so?) 
über's Ziel hinaus.
Also skaliert man mit 2047 und ist aus dem Schneider.

von Norbert (der_norbert)


Lesenswert?

Rainer W. schrieb:
> Falsch, das ergibt einen Full-Scale Sprung von 4092 auf 0.

Das stimmt, wenn man nicht mit Rechenoperationen arbeitet die Sättigung 
berücksichtigen.

: Bearbeitet durch User
von Rainer W. (rawi)


Lesenswert?

Norbert schrieb:
> Das stimmt, wenn man nicht mit Rechenoperationen arbeitet die Sättigung
> berücksichtigen.

Der TO könnte einfach ein Oszillogramm und die Wertetabelle mit den 100 
Werten zeigen, die zum DAC geschickt werden.

: Bearbeitet durch User
von Rainer W. (rawi)


Lesenswert?

Ob S. schrieb:
> Im Übrigen: -1 ist für den DAC ungefähr genauso sinnvoll wie +2048...

Dem DAC ist das egal. Ein 12 Bit DAC versteht eine -1 (im 
Zweierkomplement) als 4095, d.h. FS

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Rainer W. schrieb:
> Norbert schrieb:
>> Das stimmt, wenn man nicht mit Rechenoperationen arbeitet die Sättigung
>> berücksichtigen.
>
> Der TO könnte einfach ein Oszillogramm und die Wertetabelle mit den 100
> Werten zeigen, die zum DAC geschickt werden.

Das kannst du von einem offensichtlichen Troll nicht wirklich verlangen. 
Da müsste er ja arbeiten.

Aber OK, manche Trolle sind zu einigem bereit, um den Thread am Laufen 
zu halten. Schau'n wir mal.

Ich denke aber mal: Er hält sich erstmal raus. Läuft doch noch gut genug 
ohne weiteres Futter.

Wenn, dann kommt das erst, wenn der Thread einzuschlafen droht.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Norbert schrieb:

> Also skaliert man mit 2047 und ist aus dem Schneider.

Ach? Echt?

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.