Forum: Mikrocontroller und Digitale Elektronik MSP430 DAC - Sinus m. variabler Frequenz


von Guenter (Gast)


Lesenswert?

Hallo Zusammen.
Ich habe folgendes Problem:
Ich brauche einen Sinus mit variabler Frequenz irgendwo im kHz Bereich.
Habe mich schon ein bisschen mit dem DAC gespielt und ein Sinussignal 
mit Hilfe einer Wertetabelle ausgegeben.
Soweit hat das auch funktioniert. Nun nutze ich zusätzlich den ADC um 
eine Spannung zu messen. Diese gemessene Spannung soll die Frequenz 
meines Sinussignals verändern können.
Das große Problem an der Sache ist, dass während ich das Analog Signal 
konvertiere ja eine gewisse Zeit vergeht, in der ich keinen neuen Wert 
in den DAC schreiben kann. Somit sieht mein Sinus nicht mehr aus wie er 
sollte.
Ich vermute mal, dass ich irgendwas völlig falsch angehe, aber irgendwie 
weiß ich grad nicht mehr weiter.
Hat jemand vielleicht eine Idee?
Viele Grüße...

von Nils S. (kruemeltee) Benutzerseite


Lesenswert?

>Das große Problem an der Sache ist, dass während ich das Analog Signal
>konvertiere ja eine gewisse Zeit vergeht, in der ich keinen neuen Wert
>in den DAC schreiben kann. Somit sieht mein Sinus nicht mehr aus wie er
>sollte.
>Ich vermute mal, dass ich irgendwas völlig falsch angehe, aber irgendwie
>weiß ich grad nicht mehr weiter.

Der ADC und der DAC braucht seine Zeit. Du musst das jetzt so 
hinbekommen dass du den ADC ausliest, während du auf den DAC warten 
musst. Dann musst du auf den ADC warten und in der Zeit schreibst du auf 
den DAC.

von LuXXuS 9. (aichn)


Lesenswert?

Hier musst du Interrupt-gesteuert arbeiten - warten mit
1
while( ADC_NOCH_NICHT_FERTIG )
2
{}
ist dafür ungeeignet

von Guenter (Gast)


Lesenswert?

LuXXuS 909 schrieb:
> Hier musst du Interrupt-gesteuert arbeiten

Das habe ich mir durch rumsuchen auch schon gedacht.
Aber wie genau funktioniert das.
Habe ein paar Beispiel Programme gesehen, aber so ganz versteh ich es 
nicht...

von LuXXuS 9. (aichn)


Lesenswert?

Da solltest du dir für ADC und DAC jeweils eine State-Machine basteln, 
die eigenständig läuft.
1
adc_value;
2
3
main()
4
...
5
...
6
while(1)
7
{
8
  ...
9
  ...
10
  update_adc_state-machine();
11
  ...
12
  ...
13
  if( new_adc_value() )
14
  {
15
    adc_value = get_new_value();
16
  }
17
  ...//do something wirh adc_value
18
}
19
20
update_adc_state_machine( void )
21
{
22
  switch( state )
23
  {
24
    case ADC_START_CONVERSION:
25
    {
26
      ADC_SELECT;
27
      ...
28
      ADC_SEND_CONVERSION_COMMAND;
29
      break;
30
    }
31
    ...
32
    case ADC_START_TRANSMISSION:
33
    {
34
      ADC_SELECT;
35
      ...
36
      ADC_SEND_DUMMY_BYTE;
37
      receive_byted = RECEIVED_BYTE;
38
      break;
39
    }
40
  }
41
}

Auf jeden Fall überall ohne Warteschleifen.

von Guenter (Gast)


Lesenswert?

Leider verstehe ich das nicht.
Ist es wohl doch nicht so einfach wie ich dachte.
Ist es denn überhaupt möglich auf einfache Art und Weise eine 
Wertetabelle am DAC auszugeben und gleichzeitig irgendetwas in der main 
ablaufen zu lassen?

von Arc N. (arc)


Lesenswert?

Günstig wäre es auch zu wissen welcher MSP430 das ist...
Einige haben DMA + DAC und können den DMA-Transfer autom. von einem 
Timer auslösen lassen...

von Guenter (Gast)


Lesenswert?

Also nicht falsch verstehen. Ich weiß an sich schon, wie eine 
Zustandsmaschine funktioniert. Aber irgendwie kann ich das nicht 
übertragen...

von Guenter (Gast)


Lesenswert?

Okay, sorry.
Also es ist ein MSP430 F2619

von Klaus der 3. (Gast)


Lesenswert?

Theoretisch könnte man auch einfach ein VCO kaufen.
Mit einem Schwingkreis und ner Kapazitätsdiode müsste man das auch 
hinbekommen.

Hat der MSP vielleicht einen DMA-Kanal den man dafür benutzen könnte?
Dann wäre der uC komplett entlastet und hätte genug Zeit für die ADC 
Messung!

Grüße

von Helmut L. (helmi1)


Lesenswert?

Klaus der 3. schrieb:
> Theoretisch könnte man auch einfach ein VCO kaufen.
> Mit einem Schwingkreis und ner Kapazitätsdiode müsste man das auch
> hinbekommen.

Aber nicht bei ein paar kHz.

Klaus der 3. schrieb:
> Hat der MSP vielleicht einen DMA-Kanal den man dafür benutzen könnte?
> Dann wäre der uC komplett entlastet und hätte genug Zeit für die ADC
> Messung!

Ja hat er. Er kann den DAC12 anstossen.

von Klaus der 3. (Gast)


Lesenswert?

Helmut Lenzen schrieb:
> Klaus der 3. schrieb:
>> Theoretisch könnte man auch einfach ein VCO kaufen.
>> Mit einem Schwingkreis und ner Kapazitätsdiode müsste man das auch
>> hinbekommen.
>
> Aber nicht bei ein paar kHz.

Ok...hast Du natürlich wieder recht!
Gibt es aber nicht auch von Analog oder Linear "Clock Generation 
Module"?
Die können dass soweit ich weis.

Helmut Lenzen schrieb:
> Klaus der 3. schrieb:
>> Hat der MSP vielleicht einen DMA-Kanal den man dafür benutzen könnte?
>> Dann wäre der uC komplett entlastet und hätte genug Zeit für die ADC
>> Messung!
>
> Ja hat er. Er kann den DAC12 anstossen.

Ja, hab es auch gerade gesehen:
The DAC12 module is a 12-bit R-ladder voltage-output digital-to-analog 
converter (DAC). The DAC12 may be used in 8-bit or 12-bit mode and may 
be used in conjunction with the DMA controller.

Dann wäre dass in meinen Augen der richtige Ansatz.

Der ADC misst im Hauptprogramm in gewissen Abständen die Steuerspannung 
und ändert bei einer Änderung der Steuerpannung die Werte im Speicher.
Nach der Änderung wird der DAC wieder gestartet...

Anonsten macht man dass doch normalerweise über DDS,oder?

Grüße

von Guenter (Gast)


Lesenswert?

Helmut Lenzen schrieb:
> Ja hat er. Er kann den DAC12 anstossen.

Und wie würde das dann funktionieren?
Habe mit DMA noch nie gearbeitet.

von Guenter (Gast)


Lesenswert?

Klaus der 3. schrieb:
> Der ADC misst im Hauptprogramm in gewissen Abständen die Steuerspannung
> und ändert bei einer Änderung der Steuerpannung die Werte im Speicher.
> Nach der Änderung wird der DAC wieder gestartet...

So wäre es ziemlich genau das was ich mir anfangs gedacht habe...

von Klaus der 3. (Gast)


Lesenswert?

Guenter schrieb:
> So wäre es ziemlich genau das was ich mir anfangs gedacht habe...

Nur dass der DMA die ganze Datenübertragung zwischen Speicher und DAC 
übernimmt!
Somit hat der uC bei einer konstanten Eingangsspannung theoretisch 
garnichts zu tun (außer ab und zu mal die Eingangsspannung zu messen).
Das messen der Eingangsspannung könnte man dann auch noch 
Interruptgesteuert über einen Timer machen. Das heißt ein Timer stoßt 
z.B. alle 10ms den ADC an. Nach Beendung der ADC-Messung wird ein 
Interrupt ausgelöst und der uC holt den neuen Wert ab. Anschließend 
berechnet er die neuen Werte (wie er dass macht müsste man sich noch 
überlegen) und ändert anschließend die Werte im Speicherbereich des DMA.
Der DMA schaufelt weiterhin die Daten raus...so könnte man evtl. bei 
einer guten Programmierung auch einen sanften Übergang zwischen 
unterschiedlichen Frequenzen hinbekommen!

Ist aber dann mit Sicherheit "etwas" aufwändiger.

Grüße

von Helmut L. (helmi1)


Lesenswert?

Klaus der 3. schrieb:
> Anonsten macht man dass doch normalerweise über DDS,oder?

Das ist dann eine DDS nur halt in Software b.z.w. Ausnutzung der 
Hardware des uC.

Guenter schrieb:
> Und wie würde das dann funktionieren?
> Habe mit DMA noch nie gearbeitet.

Timer triggert DMA. DMA holt aus Tabelle Wert und schickt dem zum DAC12.

So in groben Zuegen. Im feinen durch setzen diverser Register im uC.

von Guenter (Gast)


Lesenswert?

Klaus, genau so hab ich mir das gedacht.
Aber langsam glaube ich, dass das für einen Anfänger wie mich doch ne 
Nummer zu hoch ist...

von Klaus der 3. (Gast)


Lesenswert?

Guenter schrieb:
> Klaus, genau so hab ich mir das gedacht.
> Aber langsam glaube ich, dass das für einen Anfänger wie mich doch ne
> Nummer zu hoch ist...

Wahrscheinlich ja...

von Klaus der 3. (Gast)


Lesenswert?

Helmut Lenzen schrieb:
> Das ist dann eine DDS nur halt in Software b.z.w. Ausnutzung der
> Hardware des uC.

Ok, gut zu wissen...muss ich mich auch mal dringenst genauer einlesen in 
das Thema. Danke

von Guenter (Gast)


Lesenswert?

Aber dennoch vielen Dank euch allen!
Beeindruckend wie einem hier geholfen wird!

von Klaus der 3. (Gast)


Lesenswert?

Guenter schrieb:
> Aber dennoch vielen Dank euch allen!
> Beeindruckend wie einem hier geholfen wird!

Evtl. findest Du im Internet Beispielcode, den Du nur noch kopieren und 
anpassen muss...kenne mich mit den MSP430 nicht aus.
Dann wäre es vielleicht möglich, je nach dem wie fit dass Du bist.
Anonsten würde ich erst mal mit den Standarddingen anfangen wie Port 
setzen/lesen, Interrupt, Timer, UART, LCD, PWM usw.

Grüße

von Henrik Haftmann (Gast)


Lesenswert?

DDS oder nicht DDS sollte noch geklärt werden.

Der Taktgenerator (Timer) muss natürlich so schnell laufen wie das 
Rekonstruktionsfilter am D/A-Wandler-Ausgang dimensioniert ist, aber 
auch der Mikrocontroller (CPU oder DMA) noch hinterherkommt.

1. DDS: Ein Taktgenerator mit konstanter Frequenz (Timer) inkrementiert 
den momentanen Phasenwinkel um einen einstellbaren 
frequenzproportionalen Wert. Dann Zugriff Phasenwinkel → Sinustabelle → 
D/A-Wandler.
Vorteil:
* Addierwert ist frequenzproportional
* Sofortige Kurvenform-Änderung möglich
* Weiter, sehr fein einstellbarer Frequenzbereich
* Amplituden- und Phasenmodulation problemlos
* Konstante Abtastrate vereinfacht Rekonstruktionsfilterdimensionierung
Nachteil:
* Nicht sinnvoll per DMA lösbar, vergleichsweise hohe CPU-Belastung mit 
Interrupts (ISR vorzugsweise in Assembler schreiben und Register 
reservieren)
* Jitter je nach Interrupt-Sperrzeiten im Hauptprogramm

2. Kein DDS: Ein Taktgenerator mit variabler Frequenz (Timer im 
CTC-Modus) stößt die Ausgabe des nächsten Tabellenwertes an
Vorteil:
* Ideal für DMA (Modus: Einzel-Übertragung mit Blockwiederholung)
* Gute Äquidistanz der Abtastwerte (Jitter max. 4 CPU-Takte)
Nachteil:
* CTC-Wert ist umgekehrt proportional zur Frequenz, recht grobe Stufung
  (Je höher die Abtastfrequenz, desto gröber die Stufung!)
* Nicht so weiter Frequenzbereich sinnvoll, oder mehrere Tabellen
* Keine (schnelle) Amplituden- und Phasenmodulation

Ob DDS oder DMA entscheidet sich für 1 kHz vor allem an der 
Frequenzauflösung vs. Abtastfrequenz.

Je nach MSP430 kann die tatsächliche D/A-Wertausgabe auch 
timer-gesteuert erfolgen und damit der Jitter zu Null gemacht werden.

henni

von Henrik Haftmann (Gast)


Lesenswert?

Kein Jitter:

Mit DAC12LSELx kann man als Ausgabetrigger Timer_A.OUT1 (TA1) oder 
Timer_B.OUT2 (TB2) auswählen. Dann erfolgt das Nachladen von DAC12_xDAT 
per DAC-Interrupt, und die Ausgabe verzögert sich so nur um 1 Sample. 
(Die Puffertiefe des DAU ist gleich 1.) Der DAC-Interrupt kann auch DMA 
anstoßen.

Die tatsächliche Sample-Ausgabe erfolgt exakt timer-gesteuert, und die 
Latenz bis zum Nachladen von DAC12_xDAT darf nicht länger als 1 
Abtastperiode betragen.

Die Slew-Rate des DAU ist 0,12 bis 2,7 V/µs, je nach ausgewählter 
Ausgangstreiberstärke. Bei voller Amplitude sind so 40 kHz bis 1 MHz 
drin. Mit geringer Treiberstärke kann man evtl. auf das 
Rekonstruktionsfilter verzichten.

henni

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.