Thursday, February 9, 2017

AD9850 Clock Generator with Arduino

AD9850 Clock Generator 
With Arduino
5/7/2016


Project Scope:

Create an adjustable frequency generator.  One encoder for frequency step adjustment and another one is for frequency adjustment.  Frequency range:  See AD9850 for detail.


Material:

1x Arduino Uno
2x AD9850
3x LCD Display
2x Encoder


Circuit Connection:

Arduino to AD9850
 Vcc ------- Vcc
      8 ------- W_CK
      9 ------- FU_UD
     10 ------- DATA
     11 ------- RESET
GND ------- GND

Arduino to LCD
   A5  -------  SCL
   A4  -------  SDA
  Vcc  -------  Vcc
GND  -------  GND

Arduino to Encoder #1
       4  -------  CLK
       5  -------  DT
               x     SW
   Vcc  ------- Vcc
GND  ------- GND

Arduino to Encoder #2
       2  -------  CLK
       3  -------  DT
               x     SW
   Vcc  ------- Vcc
GND  ------- GND


Pictures:

LCD Module

AD9850 Module (Front)

AD9850 Module (Back)

Encoder Module


Integrated Module -1

Integrated Module -2

Integrated Module -3

Output from ZOUT1

Adjustment Demo


/*
 * Original AD9851 DDS sketch by Andrew Smallbone at www.rocketnumbernine.com
 * Modified by Samson with frequency adjustment feature
 * 9850 datasheet at http://www.analog.com/static/imported-files/data_sheets/AD9850.pdf
 *
 * LCD Display, use the following libery
 * https://arduino-info.wikispaces.com/LCD-Blue-I2C
 * Choose NewliquidCrystal_1.3.4.zip
 */

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

 #define W_CLK 8       // Pin 8 - connect to AD9850 module word load clock pin (CLK)
 #define FQ_UD 9       // Pin 9 - connect to freq update pin (FQ)
 #define DATA 10       // Pin 10 - connect to serial data load pin (DATA)
 #define RESET 11      // Pin 11 - connect to reset pin (RST).
 #define R11 2
 #define R12 3
 #define R21 4
 #define R22 5

 #define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); }
 #define BACKLIGHT_PIN     13

LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3,POSITIVE);  // Set the LCD I2C address

 // 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
}

void setup() {
 // configure arduino data pins for output
  Serial.begin(9600);
  pinMode(R11, INPUT);
  pinMode(R12, INPUT);
  pinMode(R21, INPUT);
  pinMode(R22, INPUT);

  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);
    pinMode ( BACKLIGHT_PIN, OUTPUT );
  digitalWrite ( BACKLIGHT_PIN, HIGH );

  lcd.begin(16,2);               // initialize the lcd
  cleanLCD(0);lcd.setCursor ( 0, 0 ); lcd.print ("Signal Generator");
  cleanLCD(1);lcd.setCursor ( 0, 1 ); lcd.print ("V1.0 5/7/2016 SY");
  delay (5000);
  cleanLCD(1);lcd.setCursor ( 0, 1 ); lcd.print ("Step: 100 KHz");
}
double set_freq=1.1e6;
double set_incem=100000;
int r11pv=0;
int r12pv=0;
int r21pv=0;
int r22pv=0;

void cleanLCD(int i){
  lcd.setCursor ( 0, i );
  lcd.print ("                      ");
}
void loop() {
  int r11v = digitalRead(R11);
  int r12v = digitalRead(R12);
  int r21v = digitalRead(R21);
  int r22v = digitalRead(R22);

  int k=1;
  if (r11v!=r11pv){
    if(r11v==1)k=1;else k=-1;
    if (r12v==0)set_freq=set_freq+set_incem*k;
    if (r12v==1)set_freq=set_freq-set_incem*k;
    if (set_freq<0)set_freq=0;
    if (set_freq>1e8)set_freq=1e8;
    sendFrequency(set_freq);  // freq
    Serial.print("Frequency: ");
    if ((set_freq<1000)){Serial.print(set_freq,0);Serial.println("Hz.");}
    if ((set_freq>=1000)*(set_freq<1000000)){Serial.print((set_freq/1000),3);Serial.println("KHz.");}
    if ((set_freq>=1000000)){Serial.print((set_freq/1000000),3);Serial.println("MHz.");}
 
   if ((set_freq<1000)){cleanLCD(0);lcd.setCursor ( 0, 0 ); lcd.print ("Set: ");lcd.print (set_freq,0);lcd.print (" Hz");}
   if ((set_freq>=1000)*(set_freq<1000000)){cleanLCD(0);lcd.setCursor ( 0, 0 ); lcd.print ("Set: ");lcd.print (set_freq/1000,3);lcd.print (" KHz");}
   if ((set_freq>=1000000)){cleanLCD(0);lcd.setCursor ( 0, 0 ); lcd.print ("Set: ");lcd.print (set_freq/1000000,3);lcd.print (" MHz");}
 

 
  }

  if (r21v!=r21pv){
    if ((r22v==0)*(r21v==1))set_incem=double(set_incem*10);
    if ((r22v==0)*(r21v==0))set_incem=double(set_incem/10);
    if ((r22v==1)*(r21v==1))set_incem=double(set_incem/10);
    if ((r22v==1)*(r21v==0))set_incem=double(set_incem*10);
    if (set_incem<1)set_incem=1;
    if (set_incem>1e7)set_incem=1e7;
    //sendFrequency(set_freq);  // freq
    //Serial.print("Set increatment:");Serial.println(set_incem,0);
    Serial.print("Frequency increament: ");
    if ((set_incem<1000)){Serial.print(set_incem,0);Serial.println("Hz.");}
    if ((set_incem>=1000)*(set_incem<1000000)){Serial.print((set_incem/1000),0);Serial.println("KHz.");}
    if ((set_incem>=1000000)){Serial.print((set_incem/1000000),0);Serial.println("MHz.");}

    Serial.print("Frequency increament: ");
    if ((set_incem<1000)){cleanLCD(1);lcd.setCursor ( 0, 1 ); lcd.print ("Step: ");lcd.print (set_incem,0);lcd.print (" Hz");}
    if ((set_incem>=1000)*(set_incem<1000000)){cleanLCD(1);lcd.setCursor ( 0, 1 ); lcd.print ("Step: ");lcd.print (set_incem/1000,0);lcd.print (" KHz");}
    if ((set_incem>=1000000)){cleanLCD(1);lcd.setCursor ( 0, 1 ); lcd.print ("Step: ");lcd.print (set_incem/1000000,0);lcd.print (" MHz");}
 
    }


  r11pv=r11v;r12pv=r12v;
  r21pv=r21v;r22pv=r22v;
  //delay(50);
}

No comments:

Post a Comment