Very simple code to get the AD9850 [ebay] module up and running. I will use Energia whenever possible because it results in more portable code.
/*
Using the AD9850 DDS ebay module with Stellaris Launchpad.
Code based on http://nr8o.dhlpilotcentral.com/?p=83 and https://gist.github.com/raivisr/3861473
PA2 - W_CLK
PA3 - FQ_UD
PA4 - DATA
PB6 - RESET
VCC - VCC (5V can also be used but will dissipate more heat)
GND - GND
Serial comms - 9600, NewLine (0x0A) denotes end of input,
f 10000 - set frequency
s 20 20000 10 1000 - sweep from frequency to frequency using this step size in that many milliseconds
o 10 10000 5 3000 - oscillating sweep from frequency to frequency and back using this step size in that many ms
*/
#define MAXBUF 40
#define W_CLK PA_2 // Pin 8 - connect to AD9850 module word load clock pin (CLK)
#define FQ_UD PA_3 // Pin 9 - connect to freq update pin (FQ)
#define DATA PA_4 // Pin 10 - connect to serial data load pin (DATA)
#define RESET PB_6 // Pin 11 - connect to reset pin (RST).
#define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); }
// transfers a byte, a bit at a time, LSB first to the 9850 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
}
}
// frequency calc from datasheet page 8 = <sys clock> * <frequency tuning word>/2^32
void sendFrequency(double frequency) {
int32_t freq = frequency * 4294967295/125000000; // note 125 MHz clock on 9850
for (int b=0; b<4; b++, freq>>=8) {
tfr_byte(freq & 0xFF);
}
tfr_byte(0x000); // Final control byte, all 0 for 9850 chip
pulseHigh(FQ_UD); // Done! Should see output
}
double freqValue = 0;
double freqStart = 0;
double freqEnd = 0;
double freqStep = 0;
int sweepDelay = 0;
char freqStr[MAXBUF];
int bufPos = 0;
char byteIn = 0;
int mode = 0;
void setup() {
// configure arduino data pins for output
pinMode(FQ_UD, OUTPUT);
pinMode(W_CLK, OUTPUT);
pinMode(DATA, OUTPUT);
pinMode(RESET, OUTPUT);
pulseHigh(RESET);
pulseHigh(W_CLK);
pulseHigh(FQ_UD); // this pulse enables serial mode - Datasheet page 12 figure 10
Serial.begin(9600);
memset(freqStr,0,sizeof(freqStr));
sendFrequency(1e7);
}
void loop()
{
if (mode == 1 || mode == 2)
{
delay(sweepDelay);
if (((freqStep > 0.0) && (freqValue + freqStep <= max(freqStart,freqEnd))) || ((freqStep < 0.0) && (freqValue + freqStep >= min(freqStart,freqEnd))))
freqValue += freqStep;
else
if (mode == 1)
freqValue = freqStart;
else
{
freqStep *= -1;
freqValue += freqStep;
}
sendFrequency(freqValue);
}
while (Serial.available())
{
byteIn = Serial.read();
if (bufPos < sizeof(freqStr))
freqStr[bufPos++] = byteIn;
else
{
bufPos = 0;
byteIn = 0;
memset(freqStr,0,sizeof(freqStr));
Serial.println("Command too long. Ignored.");
}
}
if (byteIn == 0x0a)
{
switch (freqStr[0])
{
case 'f':
mode = 0;
freqValue = strtod(freqStr+2,NULL);
freqEnd = 0;
freqStep = 0;
sweepDelay = 0;
Serial.print("Frequency ");
Serial.println(freqValue);
break;
case 's':
case 'o':
char *fEnd1, *fEnd2;
freqStart = abs(strtod(freqStr+2,&fEnd1));
freqEnd = abs(strtod(fEnd1,&fEnd2));
freqStep = abs(strtod(fEnd2,&fEnd1));
if (freqStep == 0)
{
Serial.println("You gotta be kidding me, step can not be 0");
break;
}
sweepDelay = abs(atoi(fEnd1));
if (freqStr[0] == 's')
{
mode = 1;
Serial.print("Sweep");
}
else
{
mode = 2;
Serial.print("Oscillate sweep");
}
Serial.print(" start freq. ");
Serial.print(freqStart);
Serial.print(" end freq. ");
Serial.print(freqEnd);
Serial.print(" step ");
Serial.print(freqStep);
Serial.print(" time ");
Serial.println(sweepDelay);
sweepDelay /= abs(freqEnd - freqStart) / freqStep;
if (mode == 2)
sweepDelay /= 2;
if (freqStart > freqEnd)
freqStep *= -1;
freqValue = freqStart;
break;
default:
Serial.println("AI blown up - unknown command. Available commands:");
Serial.println(" f 10000 - set frequency");
Serial.println(" s 20 20000 10 1000 - sweep from frequency to frequency using this step size in that many milliseconds");
Serial.println(" o 10 10000 5 3000 - oscillating sweep from frequency to frequency and back using this step size in that many ms");
Serial.println(" frequency can be given in floating point format: 1.23456e7");
}
memset(freqStr,0,sizeof(freqStr));
byteIn = 0;
bufPos = 0;
sendFrequency(freqValue);
}
}