mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik DDS AD9833 Werte aktualisieren


Autor: Christian Z. (blup)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

ich habe ein Problem bezüglich der Werteübergabe an einen AD9833 DDS-IC.
In einem Menü wird der Wert der gewünschten Ausgangsfrequenz gewählt und 
anschließend soll der Wert in den AD9833 übernommen werden. Bei 
einmaliger Wertübergabe zur Initialisierung (Ist im Programmausschnitt 
nicht enthalten) klappt das super - Phase und Frequenz stimmen.
Rufe ich den unten aufgeführten Programmausschnitt jedoch mehrmals auf 
springt das Signal des AD9833 in unregelmäßigen Abständen auf andere 
Frequenzen bzw. Phasenwinkel, selbst wenn ich anstatt des veränderlichen 
Wertes FREQ_VALUE einen konstanten Wert wähle und diesen immer wieder 
ausgebe, soll heisen obwohl ich den AD9833 mit ein und demselben Wert 
neu lade ändern sich die Parameter am Ausgang.

Der unten angefügte Programmausschnitt beinhaltet nur die Frequenz, mit 
dem Phasenwinkel bin ich nach dem selben Schema verfahren.

Ich habe nun schon 3 Tage daran rumexperimentiert es klappt einfach 
nicht, bin kurz vorm verrückt werden und für jede Hilfe dankbar.

Mfg Christian

Übrigens der CS Eingang kann nach jedem Wort wieder auf High gezogen 
werden, muss aber nicht - hab ich auch schon probiert, daran liegt es 
nicht.


rcall SPI_INIT_5MHZ_DDS

cbi PORTB, CS_DDS1  ;CS auf Low

;Reset + FREG0 wählen + Befehl nur die unteren 14Bit des FREQ0 Registers ändern die oberen 14Bit sind definiert und werden nicht verändert

ldi temp_0, 0x01
out SPDR, temp_0
rcall WAIT_SPI
ldi temp_0, 0x00
out SPDR, temp_0
rcall WAIT_SPI

;unteres Wort laden z.B. 0x746D für 50Hz darin enthalten ist die
;Bitkombi 01 am Anfang um FREG0 anzusprechen

ldi XL, LOW(FREQ_VALUE_L)
ldi XH, HIGH(FREQ_VALUE_L)
ld temp_0, X+  ;LOW Byte des Frequenzwortes z.B. 0x6D
ld temp_1, X  ;HIGH Byte des Frequenzwortes z.B. 0x74

;Daten an DDS IC senden
          
out SPDR, temp_1
rcall WAIT_SPI
out SPDR, temp_0
rcall WAIT_SPI

;Reset aufheben

ldi temp_0, 0x00
out SPDR, temp_0
rcall WAIT_SPI
ldi temp_0, 0x00
out SPDR, temp_0
rcall WAIT_SPI
sbi PORTB, CS_DDS1



SPI_INIT_5MHZ_DDS:  push temp_0
      ldi temp_0, (0<<SPI2X)
      out SPSR, temp_0
      ldi temp_0, (0<<SPIE)|(1<<SPE)|(0<<DORD)|(1<<MSTR)|(1<<CPOL)|(0<<CPHA)|(0<<SPR1)|(0<<SPR0)
      out SPCR, temp_0
      pop temp_0
ret


WAIT_SPI:  in temp_2, SPSR
    bst temp_2,7
    brts END_WAIT
    jmp WAIT_SPI
END_WAIT:  ret

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ganz kann ich nicht erkennen wo du die entsprechende Reihenfolge 
einhälts !?

Die Ansteuerung sollte wie folgt sein:

-1 framesync=1 /frame start
-2 framesync=0 /chip enable
-3 Signalform (8 BIT) hier Rechteck, Dreieck, Sinus
-4 LSW_H 6 BIT
-5 LSW_L 8 BIT // in Summe also 6+8=14 BIT
-6 MSW_H 6 BIT
-7 MSW_L 8 BIT //6+8=14 BIT => 14+14=28 BIT
-8 framesync=1 /frame end

so in etwa sollte der Ablauf aussehen.

Autor: Christian Z. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Joe, vielen Dank für deine Antwort aber genau in dieser 
Reihenfolge läuft es eigentlich ab...

1. /CS auf High zum Programmstart (hab ich oben vergessen gehabt)
sbi PORTB, CS_DDS1
2. /CS auf Low
cbi PORTB, CS_DDS1
3. Die Signalform enthält ja mein 16Bit Befehl bei dem ich auch festlege 
das ich nur 14Bit übertragen möchte und das höherwertige Wort 
unangetastet bleibt
ldi temp_0, 0x01
out SPDR, temp_0
rcall WAIT_SPI
ldi temp_0, 0x00
out SPDR, temp_0
rcall WAIT_SPI
4+5. Die niederwertigen 14Bit übertragen
ldi XL, LOW(FREQ_VALUE_L)
ldi XH, HIGH(FREQ_VALUE_L)
ld temp_0, X+  ;LOW Byte des Frequenzwortes z.B. 0x6D
ld temp_1, X  ;HIGH Byte des Frequenzwortes z.B. 0x74

;Daten an DDS IC senden
          
out SPDR, temp_1
rcall WAIT_SPI
out SPDR, temp_0
rcall WAIT_SPI

6.Reset aufheben
ldi temp_0, 0x00
out SPDR, temp_0
rcall WAIT_SPI
ldi temp_0, 0x00
out SPDR, temp_0
rcall WAIT_SPI
sbi PORTB, CS_DDS1

7./CS auf High
sbi PORTB, CS_DDS1

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zu meinem Verständnis Problem ;-)) Ich progamiere die AVR's nur in C, 
ich habe das Ganze vor etwa 2 Jahren in 8x51 Assembler mal gemacht. Ich 
verwende aber keine SPI sondern erzeuge mir das Ansteuersignal auf 
beliebeigen Pins.

Ich kann zwar deinen ASM Code lesen aber das Verhalten der SPI nicht 
beurteilen. Mit anderen Worten ich sehe keinen Fehler.

Kommt den die übermittelte Frequenz und Signalform heraus ?

>> springt das Signal des AD9833 in unregelmäßigen Abständen auf andere
>> Frequenzen bzw. Phasenwinkel

Obwohl du immer das gleiche sendest ? In diesem Fall schreib doch mal ne 
eigene Senderoutine und verwende nicht die SPI.

Autor: Christian Z. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das eigenartige ist das ich das Ausgangssignal über einen Audiverstärker 
verstärke der die Verstärkung ebenfalls über den SPI Bus bekommt 
verstärke. Bloß die Initialisierungssequenz ist an den Audioverstärker 
angepasst, wenn ich dort nach dem selben Schema die Daten übermittle 
funktioniert alles tadellos und die SPI Einstellung für den DDS IC sind 
nach dem Datenblatt vorgenommen (alle anderen Varianten habe ich 
ebenfalls ausprobiert) und somit MUSS es doch auch über die Standard SPI 
Schnittstelle funktionieren??? Bin auch noch grün hinter den Ohren was 
Assembler Programmierung angeht, daher schreckt es mich etwas ab das 
über eine Software SPI zu realisieren.
Wie gesagt wenn ich beim Programmstart vordefinierte Werte in den DDS IC 
lade stimmt alles bis ich die Werte ein paarmal überschreibe ob sie sich 
geändert haben oder nicht. In dem Fall ändert sich die Frequenz oder die 
Phasenlage auf total sinnfreie Art und Weise.

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Software SPI ist im Prinzip recht einfach. Du übermittelst ja jeweils 8 
Bit mit entsprechenden Takt. Wenn also im Accu irgendein Wert steht und 
du den Inhalt schiebst z.B. rlc a (hoffe du weist was ich meine, das ist 
8x51 Asm code) dann kannst du den Wert im carry einfach an den Datenpin 
legen, dann Taktsignal erzeugen, nächstes BIT raus.

Also, recht einfach.

Autor: Christian Z. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich danke Dir soweit erst einmal und werde es demnächst wohl mal 
ausprobieren, da ich ja wie gesagt auch am Ende bin mit meinem Latein.
Werde dann noch mal posten ob ich erfolgreich war oder nicht.

Autor: Christian Z. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem ist erkannt, nachdem ich laut der Application Note 151 von 
Atmel in Reihe zu den SPI Pins je einen 1kOhm Widerstand geschalten habe 
um den Strom zu begrenzen und somit einen Latch up zu verhindern war die 
Flankensteilheit des Signals für die AD´s nicht mehr ausreichend und 
somit ist es zu den Fehlern gekommen.

Freude...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.