MSP430 DAC - Sinus m. variabler Frequenz

Gast #2298106
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...
Persönliche Seite #2298139
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.
#2298177
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.
#2298228
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.
Gast #2298234
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
Gast #2298255
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
#2298262
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.
Gast #2298273
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
Gast #2395736
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
Gast #2397306
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

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