Arduino AD9850 DDS

Het opwekken van analoog signaal op een bepaalde frequentie kan tegenwoordig eenvoudig gedaan worden met een DDS chip. (Direct Digital Synthesizer).

Waar je normaal een een oscillator een frequentie op laat wekken met een kristal, of PLL gestuurde oscillator die stabiel gehouden wordt aan de hand van een kristal oscillator als referentie, is het met een DDS mogelijk deze een willekeurige frequentie op te laten wekken binnen zijn bereik.

Een DDS heeft een interne referentie oscillator op basis van een kristal oscillator. Deze bevindt zich op de chip.  De maximale op te wekken uitgang frequentie is theoretisch . De maximaal op te wekken frequentie van een DDS is in de praktijk ongeveer .

De maximale frequentie van de AD9850 chip is ongeveer 40MHz. Echter neemt de zuiverheid van het opgewekte signaal af doordat het aantal samples om een sinus uit te reconstrueren ook afneemt. Zie datasheet van de AD9850 op pagina 9.

Hierdoor wordt er naast de het gewenste signaal ook en opgewekt. Filteren van het uitgangsignaal is dus noodzaak. Dat gebeurt dan ook op de AD9850 chip evaluatie board. (42 MHz low-pass, 5-pole elliptical filter, datasheet pagina 17).

Het voordeel van frequentie opwekking met het DDS principe is dat de faseruis van het signaal ten opzichte van een PLL laag is. Er is geen terugkoppeling zoals in een PLL schakeling.

Helaas rondom de opgewekte frequentie meer 'spurious' te vinden dan bij een andere methode. (DAC SFDR > 50Db @ 40Mhz) Dit kan voor sommige toepassingen niet gewenst zijn. Een mogelijkheid is dan om een oscillator die een zuiver signaal opwekt te stabiliseren met een PLL loop waarvan de referentie frequentie opgewerkt wordt met een DDS.


 

DDS AD9850 op frequentie zetten:

De AD9850 heeft een parallelle (D0 t/m D7) databus en een seriële databus om de data in een 40bit breed register in te laden. (32 bit frequentie, 5 bit fase modulatie en power-down ). Serieel moeten er dan 5 woorden van 8 bits ingelezen worden (40 bits). De seriële database is eenvoudig in gebruik en vergt minder poorten van de aansturende microcontroller. (CLK, FQ, DATA, RST).

[crayon]

/*
Berto van Oorspronk
PA3HFN
Set the DDS AD9850 on a frequency.
Step resolution AD9850 is 0.0291 Hz.
A simple single freq AD9850 Arduino test script.
Original AD9851 DDS sketch by Andrew Smallbone at www.rocketnumbernine.com
Modified for testing the DDS AD9850 chip.
*/

// PIN setup Arduino board --> DDS AD9850
const int W_CLK = 2;       // Pin 2 - connect to AD9850 module word load clock pin (CLK)
const int FQ_UD = 3;       // Pin 3 - connect to freq update pin (FQ)
const int DATA  = 5;       // Pin 5 - connect to serial data load pin (DATA)
const int RESET = 6;       // Pin 6 - connect to reset pin (RST).

// Setup
void setup() {
// Arduino setup port direction.
pinMode(FQ_UD, OUTPUT);
pinMode(W_CLK, OUTPUT);
pinMode(DATA, OUTPUT);
pinMode(RESET, OUTPUT);

// Init AD9850
pulseHigh(RESET);
pulseHigh(W_CLK);
pulseHigh(FQ_UD);  // Enable serial mode - Datasheet page 12 figure 10
}

// Loop
void loop() {
sendFrequency(10000000);  // freq 10MHz (10e6)
while(1);
}  // end loop

/******************************** Functions ****************************************/

// Toggle a pin.
void pulseHigh(int pin) {
digitalWrite(pin, HIGH);
digitalWrite(pin, LOW);
}

// transfers a byte, a bit at a time, LSB first to the AD9850 via serial DATA line
void tfr_byte(byte data)
{
for (int i=0; i<8; i++, data>>=1) {
digitalWrite(DATA, data & 0x01);
pulseHigh(W_CLK);   //after each bit sent, CLK is pulsed high
}
}

// Set the desired frequency.
// frequency calc from datasheet page 8 = * /2^32
void sendFrequency(double frequency) {
int32_t freq = frequency * 4294967295/125000000;  // note 125 MHz clock on AD9850
for (int b=0; b<4; b++, freq>>=8) {               // Send 4 words to AD9850
tfr_byte(freq & 0xFF);
}
tfr_byte(0x000);   // Final control byte, all 0 for AD9850 chip.
pulseHigh(FQ_UD);  // Frequency update, output is set.
}

[/crayon]

Overigens kan de code nog overzichtelijker als je gebruik maakt van een library:

[crayon]
/*
Berto van Oorspronk
PA3HFN
Set the DDS AD9850 on a frequency.
Step resolution AD9850 is 0.0291 Hz.
A simple single freq AD9850 Arduino test script.

Demonstrate use of the DDS Library. http://m0xpd.blogspot.com
include the DDS Library:
*/

#include

// PIN setup Arduino board --> DDS AD9850
const int W_CLK = 2; // Pin 2 - connect to AD9850 module word load clock pin (CLK)
const int FQ_UD = 3; // Pin 3 - connect to freq update pin (FQ)
const int DATA = 5; // Pin 5 - connect to serial data load pin (DATA)
const int RESET = 6; // Pin 6 - connect to reset pin (RST).

double sendFrequency = 10000000; // freq 10MHz (10e6)

// Instantiate the DDS...
DDS dds(W_CLK, FQ_UD, DATA, RESET);

// Setup
void setup() {
// start up the DDS...
dds.init();
// (Optional) trim if your xtal is not at 125MHz...
dds.trim(125000000); // enter actual osc freq
}

// Loop
void loop() {
// Load the DDS.
dds.setFrequency(sendFrequency);
} // End loop

[/crayon]