2015年8月27日木曜日

AD9851 DDS 50Mhz水晶発振子代替PCB版

Arduino UNOを使ったAD9851 DDS水晶発振子代替PCB版。公開中のプロトタイプをPCB化した物で、パターン引き回し上、DIOアドレスを変更。 水晶発振子代替と表現しているが、水晶発振クオリティを目指したものでは無い。 DDSクオリテイのチャンネル切替式である。バッファアンプは同調方式を採用し、クリーンな増幅をしている。簡易スペアナで見る限り、スプリアスは見当たらない。ただ、受信機でモニターすると、多少、ざわつき(DDS固有かも知れないが・・・)を感じる。問題になるレベルでないと思う。 
回路図である。チャンネル切替方式に必要な所以外、書いてない。チェンネル切替が不要であれば、50.6Mhz(デフォルト)一波となる。送信切替は、接点入力/電圧入力可能。出力は、真空管ドライブ可能なレベルである。

基板サイズ 69 x 54














Program(スケッチ)

50Mhz AM 送信用水晶発振子の代替とすべく、チャンネル周波数を設定している。このプログラムでは、受信時、DDS発振を停止している。送受用DDSに変更も簡単だ。

//////////////////////////////////////////////////////////////////////
//  AD9851 DDS VFO Premixed type program ver.1.0
//
//    Copyright(C)2014-2015.JA2GQP.All rights reserved.
//     Crystal replacement
//                                                  2015/8/26
//                                                  JA2GQP
//--------------------------------------------------------------------
//  Function
//    1.ch0=50.6Mhz ch1=50.55Mhz ch2=50.62Mhz ch3=50.69Mhz
//    2.TX=chenel frequency RX=0Hz(off)
//////////////////////////////////////////////////////////////////////

//----------  Define Constant Value   ----------
                                             
const byte  DATA = 12;                       // DIO12
const byte  W_CLK = 14;                      // DIO14
const byte  FQ_UD = 15;                      // DIO15

const byte  SW_CH1 = 9;                      // Channel 1
const byte  SW_CH2 = 10;                     //         2
const byte  SW_CH3 = 11;                     //         3
const byte  SW_TX = 13;                      // TX Sw
const byte  DDS_RST = 8;                     // DDS Reset

const long  FRQ_CH0 = 50600000L;             // CH0=50.6Mhz
const long  FRQ_CH1 = 50550000L;             // CH1=50.55Mhz
const long  FRQ_CH2 = 50620000L;             // CH2=50.62Mhz
const long  FRQ_CH3 = 50690000L;             // CH3=50.69Mhz

const unsigned long  DDS_CLK = 192000000L;   // AD9851 Clock(32MHz * 6)
const unsigned long  TWO_E32 = 4294967295L;  // 2^32
const byte  DDS_CMD = B00000001;             // AD9851 Command

//----------  Memory Assign  -------------------

long Dds_Dat = 0;                             // DDS Data

//----------  Initialization  Program  ---------------

void setup(){
  pinMode(SW_TX,INPUT_PULLUP);                // Input pin set
  pinMode(SW_CH1,INPUT_PULLUP);
  pinMode(SW_CH2,INPUT_PULLUP);
  pinMode(SW_CH3,INPUT_PULLUP);

  pinMode(DDS_RST,OUTPUT);                   // Output pin set
  pinMode(FQ_UD,OUTPUT);
  pinMode(W_CLK,OUTPUT);
  pinMode(DATA,OUTPUT);

  Fnc_Dds_Int();                             // DDS Initial
}

//----------  Main program  ---------------

void loop() {
  if(digitalRead(SW_CH1) == LOW){
    Dds_Dat = FRQ_CH1;
    }
  else if(digitalRead(SW_CH2) == LOW){
    Dds_Dat = FRQ_CH2;
    }
  else if(digitalRead(SW_CH3) == LOW){
    Dds_Dat = FRQ_CH3;
    }
    else{
      Dds_Dat = FRQ_CH0;
      }

  if(digitalRead(SW_TX) == HIGH){            // Rx?
    Dds_Dat = 0L;
    }

  Fnc_Dds(Dds_Dat);
  delay(100);
}


//----------  Function DDS Initialization  ---------------

void Fnc_Dds_Int(){
  digitalWrite(DDS_RST,HIGH);
  delay(1);
  digitalWrite(DDS_RST,LOW);
  digitalWrite(W_CLK,HIGH);
  digitalWrite(W_CLK,LOW);
  digitalWrite(FQ_UD,HIGH);
  digitalWrite(FQ_UD,LOW);
}

//----------  Function DDS set  ---------------

void Fnc_Dds(double frquency){
  unsigned long wrk = frquency * TWO_E32 / DDS_CLK;

  digitalWrite(FQ_UD,LOW);

  shiftOut(DATA,W_CLK,LSBFIRST,wrk);
  shiftOut(DATA,W_CLK,LSBFIRST,(wrk >> 8));
  shiftOut(DATA,W_CLK,LSBFIRST,(wrk >> 16));
  shiftOut(DATA,W_CLK,LSBFIRST,(wrk >> 24));
  shiftOut(DATA,W_CLK,LSBFIRST,DDS_CMD);   // AD9851 command

  digitalWrite(FQ_UD,HIGH);
}


2015年8月3日月曜日

AD9851 DDS 水晶発振子代替

50Mhz AM送信機の水晶発振子代替として、AD9851 DDSを使った。送受信機の場合、一般的にDDS発振周波数を替えて、VFO送受共用にしている。しかし、送信機に使う場合、常時発振していては、受信機にキャリア漏れで、悪影響がある。そこで、送信時のみDDS発振し、受信時はDDS発振停止とした。DDS出力は、真空管ドライブ可能な+10dbm程。

回路図は、DDS VFOとして機能する様、フルスペックで書いて有る。今回の仕様は、チャンネル切替式の為、破線部分は不要。












program

最小限の機能なので、DDS入門に適している。公開済のArduino AD9851 VFOでDDSが発振しない事(原因は、DDS Reset)が有った。今回、DDS Resetを含め、シンプルに纏めた。


//////////////////////////////////////////////////////////////////////
//  AD9851 DDS program ver.1.0
//
//    Copyright(C)2014-2015.JA2GQP.All rights reserved.
//     Crystal replacement
//                                                  2015/8/3
//                                                  JA2GQP
//--------------------------------------------------------------------
//  Function
//    1.ch0=50.6Mhz ch1=50.55Mhz ch2=50.62Mhz ch3=50.69Mhz
//    2.TX=chenel frequency RX=0Hz(off)
//////////////////////////////////////////////////////////////////////

//----------  Define Constant Value   ----------
                                                
const byte  DATA = 4;                        // DIO4
const byte  W_CLK = 5;                       // DIO5
const byte  FQ_UD = 6;                       // DIO6

const byte  SW_CH1 = 10;                     // Channel 1
const byte  SW_CH2 = 11;                     //         2
const byte  SW_CH3 = 12;                     //         3
const byte  SW_TX = 13;                      // TX Sw
const byte  DDS_RST = 14;                    // DDS Reset

const long  FRQ_CH0 = 50600000L;             // CH0=50.6Mhz
const long  FRQ_CH1 = 50550000L;             // CH0=50.55Mhz
const long  FRQ_CH2 = 50620000L;             // CH0=50.62Mhz
const long  FRQ_CH3 = 50690000L;             // CH0=50.69Mhz

const unsigned long  DDS_CLK = 192000000L;   // AD9851 Clock(32MHz * 6)
const unsigned long  TWO_E32 = 4294967295L;  // 2^32
const byte  DDS_CMD = B00000001;             // AD9851 Command

//----------  Memory Assign  -------------------

long Dds_Dat = 0;                             // DDS Data

//----------  Initialization  Program  ---------------

void setup(){
  pinMode(SW_TX,INPUT_PULLUP);                // Input pin set
  pinMode(SW_CH1,INPUT_PULLUP);
  pinMode(SW_CH2,INPUT_PULLUP);
  pinMode(SW_CH3,INPUT_PULLUP);

  pinMode(DDS_RST,OUTPUT);                   // Output pin set
  pinMode(FQ_UD,OUTPUT);
  pinMode(W_CLK,OUTPUT);
  pinMode(DATA,OUTPUT);

  Fnc_Dds_Int();                             // DDS Initial
}

//----------  Main program  ---------------

void loop() {
  if(digitalRead(SW_CH1) == LOW){
    Dds_Dat = FRQ_CH1;
    }
  else if(digitalRead(SW_CH2) == LOW){
    Dds_Dat = FRQ_CH2;
    } 
  else if(digitalRead(SW_CH3) == LOW){
    Dds_Dat = FRQ_CH3;
    }
    else{
      Dds_Dat = FRQ_CH0;
      }
  
  if(digitalRead(SW_TX) == HIGH){            // Rx?
    Dds_Dat = 0L;
    }

  Fnc_Dds(Dds_Dat);
  delay(100);
}  


//----------  Function DDS Initialization  ---------------

void Fnc_Dds_Int(){
  digitalWrite(DDS_RST,HIGH);
  delay(1);
  digitalWrite(DDS_RST,LOW);
  digitalWrite(W_CLK,HIGH);
  digitalWrite(W_CLK,LOW);
  digitalWrite(FQ_UD,HIGH);
  digitalWrite(FQ_UD,LOW);
}

//----------  Function DDS set  ---------------

void Fnc_Dds(double frquency){
  unsigned long wrk = frquency * TWO_E32 / DDS_CLK;
  
  digitalWrite(FQ_UD,LOW);

  shiftOut(DATA,W_CLK,LSBFIRST,wrk);
  shiftOut(DATA,W_CLK,LSBFIRST,(wrk >> 8));
  shiftOut(DATA,W_CLK,LSBFIRST,(wrk >> 16));
  shiftOut(DATA,W_CLK,LSBFIRST,(wrk >> 24));
  shiftOut(DATA,W_CLK,LSBFIRST,DDS_CMD);   // AD9851 command

  digitalWrite(FQ_UD,HIGH);
}