Hallo zusammen, versuche gerade einen Atmel XMEGA128A1 mit einem DDS-Chip AD9835 ans Laufen zu bekommen. Die Verbindung erfolgt über Port D und einen Pegelwandler 74HC244 für die drei Datenleitungen: #define DDSPORT PORTD #define FSYNC_bm 0b00000001 // Pin D0 #define SDATA_bm 0b00000010 // Pin D1 #define SCLK_bm 0b00000100 // Pin D2 Für die Ansteuerung verwende ich die angehangene Datei main.c. Die Funktion set_frequency(<Frequenz>,<Initmode>) soll zwei Modi realisieren: Initmode Funktion 0 nur Frequenz ändern 1 AD9835 sleepmode => reset => clear => Frequenz einstellen => wakeup Die Routine scheint vom Timing her zu passen, funktioniert aber nicht zuverlässig d.h. der DDS-Chip springt nicht immer auf die gewünschte Frequenz sondern auf völlig andere Werte. Hat jemand eine Idee, woran das liegen könnte ? Tnx & Viele Grüsse, Klaus
Hab mit das Timing des DDS jetzt nicht ansgeschaut .... ... aber auf den ersten Blick fällt auf dass du in der Funktion <spi_send_bit> das Datum und den Clock gleichzeitig setzt. Um sicher zu gehen sollte das nacheinander erfolgen. Damit würde man die Unsicherheit vermeiden dass die (möglicher- weise) sensitive Flanke des Clocks wechselnde Daten sieht. Dann fällt noch auf dass du Double Variablen und -Rechnung verwendest die beim AVR GCC in "einfacher" Float-Rechnung mündet was die Gesamtberechnung evtl. für manche Werte zu ungenau werden lässt. Solche Rechnungen müssen hier mit langen Integer-Variablen gelöst werden.
Der AD9835 samplet seine Daten auf der fallenden Taktflanke! Sinngemäß:
1 | if (sbit){ |
2 | CLOCK_HIGH; |
3 | DATA_HIGH; |
4 | _shortDelay(); |
5 | CLOCK_LOW; |
6 | _delay(); |
7 | }else{ |
8 | CLOCK_HIGH; |
9 | DATA_LOW; |
10 | _shortDelay(); |
11 | CLOCK_LOW; |
12 | _delay(); |
13 | }
|
Siehe Datenblatt Seite 3. Ansonsten dein Datenstrom mal posten. Ggf. etwas Abstand zwischen den Aktionen (Data & Clock). >d.h. der DDS-Chip springt nicht immer auf die gewünschte >Frequenz sondern auf völlig andere Werte. Wie bekommst du das mit? Du lässt ja nur 1ms zur nächsten Frequenz zu, das ist weniger als die Periodendauer deines Signals! P.S.: Deine Kommentare bringen garnichts, dokumentiere lieber die eigentlich Aktion.
:
Bearbeitet durch User
>> Der AD9835 samplet seine Daten auf der fallenden Taktflanke! Genau das habe ich ja versucht in send_bit() umzusetzen. Die Hälfte der Zeit ist SDATA Low oder High und gleichzeitig SCLK High. In der zweiten Hälfte bleibt SDATA auf dem vorigen Wert und SCLK wird Low. D.h. die fallende Flanke kommt genau in der Mitte des SDATA-Signals. Ich habe die andere Variante (SCLK einzeln von High auf Low nach SDATA setzen) ausprobiert, brachte noch keine Verbesserung. >> Wie bekommst du das mit? Du lässt ja nur 1ms zur nächsten Frequenz zu, > das ist weniger als die Periodendauer deines Signals! Stimmt, den Fehler hatte ich bemerkt wenn ich das Programm neu starte. Er beginnt nicht immer mit 1 Hz, sondern er gibt entweder gar kein Signal oder ein völlig andere Frequenz aus. Erhöht man die 1 ms auf z.B. 1 sec zeigt sich der Fehler nach einigen Durchläufen auch.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.