Den ADF4351 Frequenzgenerator 35MHz bis 4,4GHz vom Arduino Uno ansteuern

Mit dem AFD4351 von Analog Devices lassen sich Frequenzen von 35 MHz bis 4,4 GHz erzeugen. Er ist digital vom Arduino ansteuerbar. Die Frequenz und Ausgangsleistung kann eingestellt werden. Damit ist er prima als Synthesizer zur Frequenzerzeugung geeignet.

Der interne VCO erzeugt 2,2 – 4,4 GHz und ist PLL gesteuert stabil. Diese Frequenzen können direkt als Sinus ausgegeben werden. Die Frequenzen darunter werden über digitale Frequenzteiler erzeugt, das heißt es werden Rechteck Signale ausgegeben mit den entsprechenden Oberwellen nach der Fourier Reihe.

Vom PC ist das Programm über die serielle Ausgabe steuerbar. Mit der Eingabe von h im Seriellen Monitor des Arduino Programms oder einem anderen Terminal Programm gibt es die Hilfe für die akzeptierten Steuerbefehle.

Z.B. mit dem Kommando f1000 wird 1000MHz eingestellt und mit p5 die Ausgangsleistung auf den höchsten Wert eingestellt. Damit ist dieser Frequenzgenerator einfach einstellbar und läßt sich auch in ein Messsystem einbinden.

Zu den Anschlüssen:
Es gibt 3 Steuerleitungen vom Arduino, DATA, CLK und LE. Die digitalen Eingänge des ADF4351 sind nur für 3,3V ausgelegt. Das heißt bei meinem Arduino Uno muß ich einen Spannungsteiler oder Pegelwandler zwischen schalten.
Eine Leitung kommt vom ADF4351 zurück für lock detect, die 3,3V kann der Arduino aber direkt auswerten, da es auch in seinem HIGH Bereich liegt.

Bei der Versorgung des ADF4351 hat sich gezeigt, daß die höchste Ausgangsleistung eine Versorgungsspannung von mindestens 7,5 V benötigt, dann fliessen ca. 120mA.
Die Versorgung vom Arduino 5V Ausgang funktioniert zum Testen auch, nur wird der ADF die Ausgangsleistung reduzieren.

Das IC hat 6 Register für alle Einstellungen. Die meisten Einstellungen davon sind uninteressant für diese Anwendung, deshalb werden die Register am Programm Anfang mit Standard Werten gesetzt und nur die gewünschten Einträge werden im Programm geändert. Das sind die Frequenz und Ausgangsleistung. Nach der Frequenzänderung wartet das Programm bis Lock Detect vom IC zurück kommt und somit die Frequenz am Ausgang wirklich anliegt.

Hier nun das Programm:

// Den ADF4351 Frequenzgenerator ansteuern vom Arduino Uno
// Ausgang 35 MHz bis 4,4 GHz
//
// Spannungsteiler Uno 5V > ADF4351 Daten 3V:
// MOSI (pin 11) über Spannungswandler auf ADF DATA
// SCK (pin13) über Spannungswandler auf ADF CLK
// Select (PIN 3) über Spannungswandler auf ADF LE
//
// Direkt AFD4351 Daten > Uno
// ADF MUXOUT direkt an Arduino Pin 2 für Lock detect
// http://shelvin.de/den-adf4351-frequenzgenerator-35mhz-bis-44ghz-vom-arduino-uno-ansteuern/
//
// von Matthias Busse 10.3.2018 Version 1.0 auf shelvin.de

#include <SPI.h>
#define LE 3 // Load Enable Pin 3

                                  // die 6 Register einfach für 500 MHz mit einem 25 MHz Quarz vorbelegen
uint32_t registers[6]={0x500000, 0x8011, 0x4E42, 0x04B3, 0xBC802C, 0x580005};
byte RFDivider;                   // Ausgangs-Frequenzteiler
unsigned int long MOD, FRAC, INT; // INT FRAC MOD Werte lt. Datenblatt 
unsigned int long quarzFreq=25;   // Quarzfrequenz
double FRACF;  
double RFout;                     // Ausgangsfrequenz 
int RFpower=5;                    // Ausgangsleistung
double RFoutSchrittweite=0.01;    // 10 kHz
int lockdetect=2;                 // MIX Pin für Lock Detect

void setup() {
  Serial.begin (38400); 
  pinMode(lockdetect, INPUT);     // MUX Eingang für lock detect
  pinMode(LE, OUTPUT);            // Load Enable Pin
  digitalWrite(LE, HIGH);
  SPI.begin();                    // Init SPI bus
  SPI.setDataMode(SPI_MODE0);     // CPHA = 0  Clock positive
  SPI.setBitOrder(MSBFIRST);           
  SetFrequencyADF4351(437.0);     //437 MHz Startwert
  SetPowerADF4351(5);
}

void loop() {
  int ser, len, p;
  char buf[10];
  double freq;
  
  if (Serial.available() > 0) {
    ser = Serial.read();
    if(ser == 'h') {                          // Hilfe Text ausgeben
      Serial.println("Help");
      Serial.println(" f: set frequency 34...4400 MHz. Examples: f1000 | f300.35 | f 2000 | f99.99 ");
      Serial.println(" g: get frequency");
      Serial.println(" p: set output power (dBm). Allowed values are: p-4 | p-1 | p2 | p5");
      Serial.println(" o: get output Power");
      Serial.println(" d: device class");
      Serial.println(" w: who");
      Serial.println(" v: version");
      Serial.println(" 1: min. frequency");
      Serial.println(" 2: max. frequency");
      Serial.println(" 3: min. power");
      Serial.println(" 4: max. power");
      Serial.println(" 5: power step width");
    }  
    if(ser == 'd') Serial.println("Sythesizer"); // device ?
    if(ser == 'w') Serial.println("ADF4351"); // who ?
    if(ser == 'v') Serial.println("1.0");     // version ?
    if(ser == '1') Serial.println("35000000"); // 35 MHz fmin
    if(ser == '2') Serial.println("4400000000"); // 4.4 GHz fmax
    if(ser == '3') Serial.println("-4");      // -4  dB Pout min.
    if(ser == '4') Serial.println("5");       // +5 dB Pout max.
    if(ser == '5') Serial.println("3");       // Pout step
    if(ser == 'o') Serial.println(RFpower);   // Ausgangsleistung in dBm
    if(ser == 'g') Serial.println(RFout);     // Frequenz in MHz
    if(ser == 'f') {                          // Frequenz einstellen: f437 | f 1000
      Serial.setTimeout(15);
      len = Serial.readBytes(buf,12);
      if((len>2) && (len<11)) {               // f und was dahinter ?
        freq = atof (buf);
        if((freq >= 34.0) && (freq <= 4400.0)) {
          SetFrequencyADF4351(freq);
        }
      }
    }
    if(ser == 'p') {                          // Ausgangsleistung einstellen : p-4 | p-1 | p2 | p5
      Serial.setTimeout(15);
      len = Serial.readBytes(buf,8);
      //Serial.println(len);
      if((len>2) && (len<6)) {                // p und was dahinter ?
        p = atoi (buf);
        if(p==-4) {RFpower=-4; SetPowerADF4351(RFpower);}
        if(p==-1) {RFpower=-1; SetPowerADF4351(RFpower);}
        if(p==2) {RFpower=2; SetPowerADF4351(RFpower);}
        if(p==5) {RFpower=5; SetPowerADF4351(RFpower);}
      }  
    }
    Serial.setTimeout(500);  
  }
}

void SetPowerADF4351(int power) {
// Die Ausgangsleistung einstellen. 
// Datenblatt Seite 17

  if( power == -4) {
    bitWrite (registers[4], 4, 0);
    bitWrite (registers[4], 3, 0);
    WriteRegADF();
  }
  if( power == -1) {
    bitWrite (registers[4], 4, 0);
    bitWrite (registers[4], 3, 1);
    WriteRegADF();
  }
  if( power == 2) {
    bitWrite (registers[4], 4, 1);
    bitWrite (registers[4], 3, 0);
    WriteRegADF();
  }
  if( power == 5) {
    bitWrite (registers[4], 4, 1);
    bitWrite (registers[4], 3, 1);
    WriteRegADF();
  }
}

void SetFrequencyADF4351(double FreqMHz) {
// Die Frequenz einstellen. 

  RFout = FreqMHz; // aktuelle Frequenz speichern
  if (FreqMHz >= 2200) { 
      RFDivider = 1;           // keín Teiler, das heisst Sinus Frequenz Ausgang 2,2 ... 4,4 GHz
      bitWrite (registers[4], 22, 0);
      bitWrite (registers[4], 21, 0);
      bitWrite (registers[4], 20, 0);
    }
  if (FreqMHz < 2200) {
    RFDivider = 2;            // Frequenzteiler, das heisst Rechteck Ausgang mit entsprechenden Oberwellen
    bitWrite (registers[4], 22, 0);
    bitWrite (registers[4], 21, 0);
    bitWrite (registers[4], 20, 1);
  }
  if (FreqMHz < 1100) {
    RFDivider = 4;
    bitWrite (registers[4], 22, 0);
    bitWrite (registers[4], 21, 1);
    bitWrite (registers[4], 20, 0);
  }
  if (FreqMHz < 550)  {
    RFDivider = 8;
    bitWrite (registers[4], 22, 0);
    bitWrite (registers[4], 21, 1);
    bitWrite (registers[4], 20, 1);
  }
  if (FreqMHz < 275)  {
    RFDivider = 16;
    bitWrite (registers[4], 22, 1);
    bitWrite (registers[4], 21, 0);
    bitWrite (registers[4], 20, 0);
  }
  if (FreqMHz < 137.5) {
    RFDivider = 32;
    bitWrite (registers[4], 22, 1);
    bitWrite (registers[4], 21, 0);
    bitWrite (registers[4], 20, 1);
  }
  if (FreqMHz < 68.75) {
    RFDivider = 64;
    bitWrite (registers[4], 22, 1);
    bitWrite (registers[4], 21, 1);
    bitWrite (registers[4], 20, 0);
  }
  INT = (FreqMHz * RFDivider) / quarzFreq;    // PLL Teiler
  MOD = (quarzFreq / RFoutSchrittweite);
  FRACF = (((FreqMHz * RFDivider) / quarzFreq) - INT) * MOD;
  FRAC = round(FRACF); 
  registers[0] = 0;                           // Datenblatt Seite 15
  registers[0] += INT << 15;
  registers[0] += FRAC << 3;
  registers[1] = 1; 
  registers[1] += MOD << 3;
  bitSet (registers[1], 27);                  // Prescaler 8/9
  bitSet (registers[2], 28);                  // Datenblatt Seite 16
  bitSet (registers[2], 27);                  // Digital Lock Detect ist 110 
  bitClear (registers[2], 26); 
  WriteRegADF();
  while(digitalRead(lockdetect)==0) {}        // warten bis lock detect erkannt wird
}

void WriteRegADF() {
  for (int i = 5; i >= 0; i--){               // die 6 Register schreiben
    WriteRegister32(registers[i]);
  }
}

void WriteRegister32(const uint32_t value) {  // 32 Bit Register schreiben
  digitalWrite(LE, LOW);
  for (int i = 3; i >= 0; i--) {        
    SPI.transfer((value >> 8 * i) & 0xFF);
  } 
  digitalWrite(LE, HIGH);
  digitalWrite(LE, LOW);
}

Hier die Messungen der Ausgangsleistung in dBm über den Frequenzbereich von 35MHz bis 4480 MHz für alle 4 Ausgangsleistungen des ADF4351.

Unter 2,2GHz wird die Leistung des Rechtecksignals gemessen und darüber die des Sinus Signals. Auffällig ist der Anstieg der Leistung wenn der Teiler weg fällt und das Sinus Signal ausgegeben wird ab 2,2GHz und dann der Abfall der Leistung über 3,5GHz.
Der 3dB Abstand der 4 verschiedenen Ausgangsleistungen wird dabei relativ gut über den gesamten Frequenzbereich eingehalten und liegt immer innerhalb von 2-4 dB, meist nahe an 3dB.

Und der Vergleich zwischen den Ausgangsleistungen 1 und 2 in dBm. Einmal bei maximaler eingestellter Ausgangsleistung und bei minimaler Ausgangsleistung über den Frequenzbereich von 35MHz bis 4.4GHz.

Bei einem Meßfehler von ca. 0,1-0,2 dB hier kann man die Ausgangsleistungen als fast identisch ansehen. Nur bei voller Ausgangsleistung ab 4GHz unterscheiden sich die Leistungen um 0,6-0,9 dB.

Verwendet wurden:
ADF-4351 Platine
ADF-4351 Datenblatt
Pegelwandler 5V > 3,3V für 3 Datenleitungen
Arduino Uno
Arduino Software 1.8.0
Frequenzzähler AE20401
HP Powermeter 437B mit Messkopf HP8481H

von Matthias Busse

2 Gedanken zu „Den ADF4351 Frequenzgenerator 35MHz bis 4,4GHz vom Arduino Uno ansteuern

  1. Pingback: Ein Tiefpassfilter 5. Ordnung mit 69 MHz aufgebaut für den ADF4351 | Shelvin – Elektronik ausprobiert und erläutert

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.