2 Festfrequenzen mit dem AD9833 erzeugen

Ich habe einen AD9833, ein programmierbaren Generator und einen Arduino uno R3.
Ich möchte gern mittels einem Umschalter 2 Festfrequenzen, 73,2421875 kHz und 36,6210938 kHz realisieren. Ich habe mir bereits das Programmierhandbuch ausgedruckt, aber noch nie eine Programmzeile geschrieben. Ich glaube, es ist für ein fast unerreichbares Ziel.
Kann mir bitte Jemand schildern, wie man dieses Ziel erreichen kann?
Für eine Antwort bedanke ich mich bereits im Voraus.

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Hallo urlauber

Nehme eine Suchmaschine deiner Wahl und befrage das WWW mit 'AD9833 +arduino'.

Hallo,

vielen Dank für diesen Hinweis.

Mit freundlichen Grüßen

Roland Pötzsch

Hallo paulpaulsen,
Danke für diesen Hinweis. Ich habe bereits in diese Richtung recherchiert, aber nur einen Beitrag gefunden, wie ein durchstimmbarer Generator programmieret wird.

Ich glaube Du kannst eine Frequenz etwas um die beiden Frequenzen herum bekommen aber nicht genau diese.
73,2421875 kHz und 36,6210938 kHz haben so geschrieben eine Genauigkeit unter 1PPM
Der AD9833 erzeugt aus eine gegebenen Frequenz eine andere. Die erzeugte Frequenz hat aber nur die Genauigkeit der gegebenen Frequenz.
Ein normaler Quarzoszillator hat typischerweise eine Genauigkeit von 100ppm.
Du brauchst aber eine Genauigkeit von ca 0,1ppm. Das einzige was mir da so einfällt ist die Trägerfrequenz des DCF77. Wie jetzt eine Frequenz aus dem DCF77 Signal hergeleitet werden kann, (mit welcher Schaltung Du das Tun kannst) weiß ich nicht.

Welchen Oszillator mit welcher Frequenz willst Du verwenden?

Grüße Uwe

Die Suche mit "ad9833 arduino library" bringt Dir keine Bibliotheken mit Beispielen?
In der IDE im Bibliotheksverwalter nach AD9833 suchen? Findest Du nicht eine Bibliothek?.

Grüße Uwe

Hallo Uwe,
vielen Dank für Deine Ausführungen. Ich glaube, ich muß meine Frequenzangabe auf 4 Stellen nach dem Komma reduzieren, weil der AD 9833 laut Datasheet nur auf 0,1 Hz auflösen kann.

MfG

Roland

Da hast Du nicht genau genug gelesen. Die Auflösung hängt von der Referenzfrequenz ab. 0,1Hz sind es bei 25MHz Referenz.
Laut Datenblatt ist die Auflösung 0,004 Hz bei 1MHz Referenzfrequenz.
Die Genauigkeit der Ausgangsfrequenz hängt von der Genauigkeit der Referenzfrequenz ab.

Grüße Uwe

Danke für diesen, für mich sehr wichtigen Hinweis. Ich hatte lediglich die technischen Daten des kompletten Moduls vom Anbieter gelesen. Ich habe nun auch nach den techn. Daten des Arduino uno R3 nach geschaut. Er hat eine Taktfrequenz von 16 MHz. Da ergibt sich für mich die nächste Frage: Kann man die Taktfrequenz des Uno auch auf 1 MHz herab setzen?
Zwischenzeitlich habe ich ein Programm gefunden, welches einen durchstimmbaren Generator realisiert.

//AD9833 Frequenzgenerator 0-12.5 MHz Auflösung 1 Hz

//

// Sinus und Dreieck:

// Frequenz 0 - 12.499.999 Hz (Ri ca. 700 Ohm)

// Amplitude ca. 0,6 VSS hochohmig und ca. 0,042 VSS an 50 Ohm

// Ab ca. 1 MHz nimmt die Amplitude ab.

//

// Rechteck:

// Frequenz 0-6.245.000 Hz (Ri ca. 500 Ohm)

// Amplitude ca. 5 VSS hochohmig und ca. 0,45 VSS an 50 Ohm

// Die Amplitude ist konstant bis hoch zu 6,2 MHz

//

// Matthias Busse 12.4.2018 Version 1.0

#include "Wire.h"

int FSYNC = 6;

int SDATA = 7;

int SCLK = 8;

unsigned long freq;

byte wave=1;

void setup() {

pinMode(FSYNC, OUTPUT);

pinMode(SDATA, OUTPUT);

pinMode(SCLK, OUTPUT);

digitalWrite(FSYNC, HIGH);

digitalWrite(SDATA, LOW);

digitalWrite(SCLK, HIGH);

Wire.begin();

Serial.begin(38400);

UpdateRegister(0x2100); // Nach Application Note AN-1070 von Analog Devices

UpdateRegister(0x50C7);

UpdateRegister(0x4000);

UpdateRegister(0xC000);

UpdateRegister(0x2000);

freq=1000;

wave=1;

UpdateFreq(freq, 0x2000); // Sinus 1000 Hz

}

void loop() {

int ser, len;

char buf[10];

if (Serial.available() > 0) {

ser = Serial.read();

if(ser == 'h') {

Serial.println("AD9822 Software Version 1.0");

Serial.println("Help:");

Serial.println(" s: Sinus + Frequency 0...12499000 Hz (12.5MHz) Examples: s1000 | s 12345678");

Serial.println(" t: Triangle + Frequency 0...12499000 Hz (12.5MHz) Examples: d2000 | d 12400000");

Serial.println(" r: Rectangle + Frequency 0... 6244000 Hz (6.24MHz) Examples: r3000 | r 123456");

Serial.println(" g: get frequency");

Serial.println(" f: get waveform");

Serial.println(" d: device class");

Serial.println(" w: who");

Serial.println(" v: version");

Serial.println(" 1: min. frequency");

Serial.println(" 2: max. frequency");

Serial.println(" 3: frequency step");

}

if(ser == 'd') Serial.println("Sythesizer"); // device ?

if(ser == 'w') Serial.println("AD9833"); // who ?

if(ser == 'v') Serial.println("1.0"); // version ?

if(ser == '1') Serial.println("0"); // 0 Hz fmin

if(ser == '2') Serial.println("12499999"); // 12.5 MHz fmax

if(ser == '3') Serial.println("1"); // 1 Hz Frequenzschritte

if(ser == 'f') { // Wellenform

if(wave==1) Serial.println("Sinus");

if(wave==2) Serial.println("Dreieck");

if(wave==3) Serial.println("Rechteck");

}

if(ser == 'g') Serial.println(freq); // Frequenz in Hz

if(ser == 's') { // Sinus ausgeben: s100 | s 10000000

Serial.setTimeout(15);

len = Serial.readBytes(buf,12);

if((len>2) && (len<11)) { // s und was dahinter ?

freq = atof (buf);

if((freq >= 0.0) && (freq < 12500000.0)) {

UpdateFreq(freq, 0x2000); // Sinus

wave=1;

}

}

} // Sinus

if(ser == 't') { // Dreieck ausgeben: d100 | d 10000000

Serial.setTimeout(15);

len = Serial.readBytes(buf,12);

if((len>2) && (len<11)) { // d und was dahinter ?

freq = atof (buf);

if((freq >= 0.0) && (freq <= 12500000.0)) {

UpdateFreq(freq, 0x2002); // Dreieck

wave=2;

}

}

} // Dreieck

if(ser == 'r') { // Rechteck ausgeben: r100 | r 10000000

Serial.setTimeout(15);

len = Serial.readBytes(buf,12);

if((len>2) && (len<11)) { // r und was dahinter ?

freq = atof (buf);

if((freq >= 0.0) && (freq <= 6244500.0)) {

wave=3;

UpdateFreq(freq, 0x2020); // Rechteck

}

}

}

}

}

void UpdateFreq(long freq, int form){

// Die Frequenz Register schreiben.

long FreqReg;

unsigned int MSB, LSB;

FreqReg = (freq * pow(2, 28)) / 25000000; // 25MHz Quarz

if (form == 0x2020) FreqReg = FreqReg << 1; // Rechteck 1/2 Frequenz

MSB = (int)((FreqReg & 0xFFFC000) >> 14);

LSB = (int)(FreqReg & 0x3FFF);

LSB |= 0x4000;

MSB |= 0x4000;

UpdateRegister(0x2100); // Control Register, Reset Bit DB8 gesetzt

UpdateRegister(LSB); // Frequency Register 0 LSB

UpdateRegister(MSB); // Frequency Register 0 MSB

UpdateRegister(0xC000); // Phase Register

UpdateRegister(form); // Exit Reset : Wellenform nach dem Reset

}

void UpdateRegister(unsigned int data){

// Ein DDS Register schreiben

unsigned int pointer = 0x8000;

digitalWrite(FSYNC, LOW);

for (int i=0; i<16; i++){

if ((data & pointer) > 0) {

digitalWrite(SDATA, HIGH);

}

else {

digitalWrite(SDATA, LOW);

}

digitalWrite(SCLK, LOW);

digitalWrite(SCLK, HIGH);

pointer = pointer >> 1 ;

}

digitalWrite(FSYNC, HIGH);

Ich habe auch auf youtube gesehen, dass es Lehrvorführungen für das programmieren gibt. Es liegt also viel Arbeit für mich an, um zu verstehen, was im Programm steht.
Roland

Setze Deinen Sketch bitte in Codetags. Wie das geht, steht hier.
Außerdem formatiere den Code bitte ordentlich. Strg+T in der IDE hilft Dir dabei.
Entferne bitte auch die unnötigen Leerzeilen, sie stören den Lesefluss.
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

Hallo Tommy,

Danke für die Hinweise, die ich gern beherzigen werde. Dazu muss ich erst lernen, wie man es macht. Ich hatte lediglich dieses Programm von einer Internetseite kopiert. Ich bitte deshalb um etwas Geduld.

MfG Roland

Das in code Tags setzen geht auch nachträglich. Du kannst Deinen Post auch nachbearbeiten.

Schlechte Idee. Der Takt des Arduino UNO wird von einem Resonator mit einer Genauigkeit von 0,5% erzeugt. Das sind 5000ppm. Wenn Du einen nicht orginalen suchst kannst Du UNOs mit Quarz finden.
Die Taktfrequenz kannst Du nicht am Resonator/Quarz abnehmen da Du darduch sicher den Oszillator blockierst. Der ATmega328 müßte die Möglichkeit haben den Takt mit eine selektierbaren Teilerfaktor an einem Pin auszugeben.
ATmega haben auch interne RC Oszillatoren, die man für den Systemtakt verwenden kann, die sind aber noch ungenauer als die Resonatoren.

Wie bereits gesagt besorg Dir einen genauen Taktgenerator

Grüße Uwe

Hallo Uwe,

herzlichen Dank für den konstruktiven Vorschlag.
Ich habe folgende Überlegung angestellt. Mein Uno ist mit dem IC ATMEGA328P und einem Quarz 16 MHz bestückt.
Wenn ich nun diesen Quarz gegen einen Präzisionsquarz tausche und dieses Signal (wenn man denn an den Schaltplan vom Uno heran kommt) extern auf 1MHz herunter teile und dieses Signal für den Takt des AD 9833 einspeise. Was meinst Du zu dieser Lösung?

MfG
Roland

ich habe einen Beitrag zur genaueren Takt Erzeugung gefunden. Habe ihn in den Anhang gelegt, wenn Interesse besteht.

Atmega 32 Takterzeugung mit Quarz.pdf (1.2 MB)

Der ATmega32 ist nicht der ATmega328.

Laß das. Wieso willst Du beim Arduino herumlöten, wenn Du nur einen Taktgenerator für den AD 9833 nehmen mußt.
Ich denke an sowas: Afug-Info.de - Amateurfunk und mehr...
zB
%product-title% kaufen
hat aber nur +/- 25 ppm aber das ist immernoch besser als Du das mit dem Arduino UNO zusammenbringst.

Grüße Uwe

Den TFT660 =TTL Pegel hat Conrad nicht, der 680 hat Ausgangsspannung High 0.9 V, Ausgangsspannung Low 0.1 V ist ein wenig zu klein :wink:
Wurde den empfehlen, aber die HL Pegel sind auch niedrig
0utputlevel TTL2.4V min (High), TTL0.4V max (Low), ob das Reicht bei 5V Arduino, eher nicht.
Ob die mit Levelschifter arbeiten keine Ahnung

TTL Pegel, ich meine dabei die Pegel der SN7400 Serie ist etwas anderes als TTLPegel in der Seriellen Schnittstelle wie zB der ATmega328 hat. SN7400 Ausgangspegen sind nicht CMOS Eingangs-Pegel kompatibel. Heutzutage gibt es aber kaum noch echte TTL Bausteile (SN7400 Serie) sondern man verwendet deren CMOS - Varianten der Serie 74HTC00 bzw 74HC00 .

Bitte übernimm nicht die Fehler die Conrad in der Beschreibung macht.
Das sind nicht 0,1V bzw 0,9V sondern laut verlinkten Datenblatt VOL max = 0,1 * VDD bzw VOH min = 0,9 * VDD. Wobei VDD als 5,0V +/- 10% spezifiziert ist.
Die Ausgangsspannung ist somit bei 5,0V Versorgungsspannung für LOW zwischen 0V und ca 0,5V und für HIGH von 4,5V bis 5,0V.

Also genau die gleichen Ausgangsspannungsbereiche, die das von Dir verlinkte Datenblatt angibt:

Also liegen die Werte innerhalb der Standart-Eingangsbereiche von C-MOS schaltungen.

Grüße Uwe

Das habe falsch verstanden, ist OK

Hallo Uwe,

ich denke, Du hast Recht und danke Dir für den Vorschlag.
Einen schönen Abend wünscht Dir Roland