Been playing with the AD9851 DDS for a while now using other people's software mostly written in assembly language that I find rather hard to get my head around. Finally tonight, with the help of several others who have published their work on the internet I have got some simple code to drive this chip the way I want.
This can tell it the frequency the generate in Hz and it just works.
This minimal example does a small sweep from 10Mhz so it's easy to listen to on a radio.
While I prefer to use the atmel chips "naked" I do find the Arduino board a very convenient way to muck around and get things going in an interactive environment. This code doesn't rely on any magic Arduino libraries so it should be easy to port, I'll post a straight ATMEGA version soon.
The code presented here shows some things I've struggled to figure out: how to calculate the tuning word from the frequency and how to send the serial commands to the chip. I hope this helps someone else.
// Control a AD9851 DDS based on the good work of others including:
// Mike Bowthorpe, http://www.ladyada.net/rant/2007/02/cotw-ltc6903/ and
// http://www.geocities.com/leon_heller/dds.html
// This code by Peter Marks http://marxy.org
#define DDS_CLOCK 180000000
byte LOAD = 8;
byte CLOCK = 9;
byte DATA = 10;
byte LED = 13;
void setup()
{
pinMode (DATA, OUTPUT); // sets pin 10 as OUPUT
pinMode (CLOCK, OUTPUT); // sets pin 9 as OUTPUT
pinMode (LOAD, OUTPUT); // sets pin 8 as OUTPUT
pinMode (LED, OUTPUT);
}
void loop()
{
// Do a frequency sweep in Hz
for(unsigned long freq = 10000000; freq < 10001000; freq++)
{
sendFrequency(freq);
delay(2);
}
}
void sendFrequency(unsigned long frequency)
{
unsigned long tuning_word = (frequency * pow(2, 32)) / DDS_CLOCK;
digitalWrite (LOAD, LOW); // take load pin low
for(int i = 0; i < 32; i++)
{
if ((tuning_word & 1) == 1)
outOne();
else
outZero();
tuning_word = tuning_word >> 1;
}
byte_out(0x09);
digitalWrite (LOAD, HIGH); // Take load pin high again
}
void byte_out(unsigned char byte)
{
int i;
for (i = 0; i < 8; i++)
{
if ((byte & 1) == 1)
outOne();
else
outZero();
byte = byte >> 1;
}
}
void outOne()
{
digitalWrite(CLOCK, LOW);
digitalWrite(DATA, HIGH);
digitalWrite(CLOCK, HIGH);
digitalWrite(DATA, LOW);
}
void outZero()
{
digitalWrite(CLOCK, LOW);
digitalWrite(DATA, LOW);
digitalWrite(CLOCK, HIGH);
}
The board I'm using is the excellent carrier from AmQRP.
0 comments:
Post a Comment