Jump to content
43oh

Recommended Posts

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);
  }
}

 

 

Link to post
Share on other sites

Just a suggestion, perhaps Energia should also have a Code Vault. This is because most of the working code samples (like above) get lost in the myriad of questions that is on this sub-forum. Or maybe invent some kind of a rule like prefixing the thread titles with [Q], [ code], ...

 

Edit: now that I think more, a nice code should be commited to Energia.

Link to post
Share on other sites
  • 6 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...