2016年7月16日土曜日

Arduino AD9850 DDS VFO Ver.1.2

 Arduino AD9850 DDS VFOを作ってから約2年経過する。現在も、多くの方からアクセスがあるが、機能追加する事にした。初版(2014/2/28)のPCBをそのまま流用し、H/Wはスイッチ周りの変更のみに留めた。固有要素であるIF周波数、Offset周波数、VFOモードは、EEPに保存し、読込/書込み出来る様にした。RIT/SPLIT動作も見直しを行った。
また、自動Mode(LSB,USB,CW) 切替方式を採用。操作説明を含む関連資料は、JA2GQP's Download site
Arduino AD9850 DDSフォルダにアップロードしてある。

 

回路図である。 チャンネル切替をロータリSWからプッシュSWに変更し、ENT SWを追加。

Program

スケッチは、Arduino IDE1.6.9で開発したが、1.0.6で動作する事を確認している。

//////////////////////////////////////////////////////////////////////
//  AD9850 DDS VFO Premixed type program ver.1.2
//
//    Copyright(C)2014-2016.JA2GQP.All rights reserved.
//
//                                                  2016/7/16
//                                                  JA2GQP
//--------------------------------------------------------------------
//  Function
//    1.RIT Operation(-50kHZ to 50kHZ)
//    2.STEP(1M,100k,10k,1k,100,10)
//    3.Memory Operation is Push ENT
//      (Frequency and Step)
//    4.Protection Operation At The Time Of Transmission
//    5.Channel Memory(0-9ch)
//    6.Split Operation
//--------------------------------------------------------------------
//  Library
//  http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html
//
//////////////////////////////////////////////////////////////////////

#include <LiquidCrystal.h>
#include <rotary.h>
#include <EEPROM.h>

//----------  LCD Pin Assign  ------------------

LiquidCrystal lcd(13, 12, 11, 10, 9, 8);   // RS,R/W,DB4,DB5,DB6,DB7

//----------  Define Constant Value   ----------

////////////////////////////////
// I/O assign
////////////////////////////////
const byte  ENC_A = 2;                     // Encorder A
const byte  ENC_B = 3;                     // Encoeder B
const byte  SW_STEP = 4;                 // STEP Sw
const byte  SW_RIT = 5;                    // RIT Sw
const byte  SW_SPLIT = 6;                // SPLIT Sw
const byte  SW_TX = 7;                     // TX Sw
const byte  W_CLK = 14;                   // DIO14(A0)
const byte  FQ_UD = 15;                   // DIO15(A1)
const byte  DATA = 16;                    // DIO16(A2)
const byte  SW_CH = 17;                   // DIO17(A3)
const byte  SW_ENT = 18;                  // ENT SW

////////////////////////////////
// default value
////////////////////////////////
const long DEF_LSB = -1500L;           // LSB Offset(IF-1500Hz)
const long DEF_USB = 1500L;            // USB Offset(IF+1500Hz)
const long DEF_CW  = -600L;             // CW Offset(IF-600Hz)
const long DEF_IF  = 10700000L;         // 10.7000MHz

const long  DEF_VFO  = 3;                 // Vfo Mode(TR+IF)
const long  DEF_FRQ = 7050000L;      // Init Frequency
const long  DEF_STP = 1000L;            // Init STEP

////////////////////////////////
// Limited range
////////////////////////////////
const long  LW_FRQ = 0L;                   // Frequency Lower Limit
const long  HI_FRQ = 30000000L;         //           Upper Limit

const long  LW_VFO80 = 3500000L;      // 3.5MHz Lower
const long  MI_VFO80 = 3535000L;      //        Middle
const long  HI_VFO80 = 3575000L;       //        Upper
const long  LW_VFO40 = 7000000L;      // 7MHz   Lower
const long  MI_VFO40 = 7045000L;       //        Middle
const long  HI_VFO40 = 7200000L;       //        Upper
const long  LW_VFO20 = 14000000L;    // 14MHz  Lower
const long  MI_VFO20 = 14100000L;     //        Middle
const long  HI_VFO20 = 14350000L;     //        Upper
const long  LW_VFO15 = 21000000L;     // 21MHz  Lower
const long  MI_VFO15 = 21150000L;      //        Middle
const long  HI_VFO15 = 21450000L;      //        Upper
const long  LW_VFO10 = 28000000L;     // 28MHz  Lower
const long  MI_VFO10 = 28200000L;      //        Middle
const long  HI_VFO10 = 29000000L;       //        Upper

const long  LW_OFT = -10000L;            // Offset Lower Limit
const long  HI_OFT = 10000L;               //        Upper Limit

const long  LW_RIT = -50000L;             // RIT Lower Limit
const long  HI_RIT = 50000L;                // RIT Upper Limit

////////////////////////////////
// DDS parameter
////////////////////////////////
const unsigned long  DDS_CLK = 125000000L; // AD9850 Clock
const unsigned long  TWO_E32 = 4294967295L;// 2^32
const byte  DDS_CMD = B00000000;           // AD9850 Command

////////////////////////////////
// etc
////////////////////////////////
const byte  Max_Chn = 10;                       // Max Channel(10ch)
const byte  Int_End = 73;                          // Initial end code
const char *CALL = "JA2GQP  ";             // Display Call sign


//----------  EEPROM Memory Address   ----------

const byte  Frq_Eep = 0x00;                 // Frequency(4byte*10)
const byte  Stp_Eep = 0x30;                 // STEP(4byte*10)
const byte  Mode_Eep = 0x60;               // Mode(1byte*10)
const byte  Care_Eep = 0x70;               // Career point(4byte* 4)
const byte  If_Eep = 0x80;                    // IF(4byte*1)
const byte  Chn_Eep = 0x90;                // Channel(1byte*1)
const byte  Vfo_Eep = 0x92;                 // Vfo mode(1byte*1)
const byte  Sav_Eep = 0x94;                // Vfo Frequency save(4byte*1)
const byte  Eep_Int = 0x9e;                  // Eep Init(1byte*1)

//----------  Encorder Pin Assign(INT)  --------

Rotary r = Rotary(ENC_A,ENC_B);            // 2 = ENC_A,3 = ENC_B

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

long Vfo_Dat;                             // Vfo Frequency
long Vfo_Datb;                            // Vfo data(old)
long RX_Dat;                              // RX DDS Out Data
long TX_Dat;                              // TX DDS Out Data
long Rit_Dat;                             // RIT Data
long Rit_Datb;                            // RIT Data Old
long Enc_Stp;                             // STEP
long Lng_Wk1;                             // Long Work1
long Lng_Wk2;                             // Long Work2
long If_Dat;                              // IF Frequency
char *Lcd_Dat = "           ";            // Lcd Display Buffer

byte Byt_Chn;                             // Channel SW
byte Byt_Chnb;                            // Channel SW Old
byte Flg_Rit;                             // RIT Flag
byte Flg_Ritb;                            // RIT Flag Old
byte Flg_Tx;                              // TX Flag
byte Flg_Spl;                             // SPLIT Flag
byte Flg_Mode;                            // Mode Flag
byte Byt_Mode;                            // Mode
byte Flg_LSB;                             // LSB Flag
byte Flg_USB;                             // USB Flag
byte Flg_CW;                              // CW Flag
byte Flg_SUB;                             // SUB Flag
byte Flg_Over;                            // Over Flag
byte Flg_Ent;                             // ENT Flag
byte Byt_Ent;                             // ENT Mode
byte Flg_If;                              // IF Flag
byte Flg_Vfo;                             // DDS Flag
byte Byt_Vfo;                             // VFO Mode

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

void setup(){
  lcd.begin(16, 2);                       // LCD 16*2

  pinMode(SW_STEP,INPUT_PULLUP);
  pinMode(SW_RIT,INPUT_PULLUP);
  pinMode(SW_SPLIT,INPUT_PULLUP);
  pinMode(SW_TX,INPUT_PULLUP);
  pinMode(SW_CH,INPUT_PULLUP);
  pinMode(SW_ENT,INPUT_PULLUP);

  PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
  sei();                                    // INT Enable

  pinMode(FQ_UD,OUTPUT);
  pinMode(W_CLK,OUTPUT);
  pinMode(DATA,OUTPUT);

  Flg_Tx = 0;
  Flg_Rit = 0;
  Flg_Spl = 0;
  lcd.clear();

  if(EEPROM.read(Eep_Int) != Int_End){        // Eep initialaz
    delay(10);
    Fnc_Eep_Int();
  }
  Byt_Chn = EEPROM.read(Chn_Eep);             // Channel
  Byt_Chnb = Byt_Chn;
  Fnc_Eep_Rd();                              // EEPROM Read
}

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

void loop() {
  if(Flg_Tx == 0){                            // Tx off?
    if(digitalRead(SW_STEP) == LOW)           // STEP Sw On?
      Fnc_Stp();                          

    if(digitalRead(SW_ENT) == LOW)            // ENT SW On?
      Fnc_Ent();                          

    if((Flg_Mode == 0) && (Flg_Spl != 2)){
      if(digitalRead(SW_RIT) == LOW)          // RIT Sw On?
        Fnc_Rit();
    }                          

    if((Flg_Ent == 0) && (Flg_Rit != 2)){
      if(digitalRead(SW_SPLIT) == LOW)      // SPLIT Sw On?
        Fnc_Spl();                        
      if((digitalRead(SW_CH) == LOW))       // CH SW On?
        Fnc_Chsw();                          
    }

    if(Byt_Chnb != Byt_Chn){                 // CH SW OLD != NEW?
      Fnc_Eep_Wt(Byt_Chnb);
      Byt_Chnb = Byt_Chn;
      Fnc_Eep_Rd();
    }

    if(Flg_Ent == 1)                         // ENT proc.?
      Fnc_Prm();
  }

  if(digitalRead(SW_TX) == LOW)              // Tx On?
    Flg_Tx = 1;                          
  else                                
    Flg_Tx = 0;                                        

  Fnc_Band(Vfo_Dat+Rit_Dat);              // Range check
  Fnc_If(Byt_Vfo);

  if(Flg_Tx == 0)
    Fnc_Dds(RX_Dat);                      // AD9850 DDS RX set
  else{
    if(Flg_Over == 0)                     // Frequency not range over?
      Fnc_Dds(TX_Dat);                    // AD9850 DDS TX set
    else                    
      Fnc_Dds(0L);                        // DDS 0Hz
  }

  Fnc_Lcd();                               // LCD Display
}

//----------  Encorder procedure(INT)  ---------------

ISR(PCINT2_vect) {
  unsigned char result = r.process();

  if(Flg_Tx == 0){
    if(result) {
      if(result == DIR_CW){
        Lng_Wk1 = Vfo_Dat + Enc_Stp;
        Lng_Wk2 = Rit_Dat + Enc_Stp;
      }
      else{
          Lng_Wk1 = Vfo_Dat - Enc_Stp;
          Lng_Wk2 = Rit_Dat - Enc_Stp;
      }  

      if((Flg_Rit == 1) || (Flg_Spl == 1))
        Rit_Dat = Lng_Wk2;
      else{
        if((Flg_Rit == 2) || (Flg_Spl == 2) || (Flg_Rit == 0) || (Flg_Spl == 0))
          Vfo_Dat = Lng_Wk1;
        else
          Rit_Dat = 0;
      }

      if(Flg_Mode == 0)
        Vfo_Dat = constrain(Vfo_Dat,LW_FRQ,HI_FRQ);// VFO range check
      else
        Vfo_Dat = constrain(Vfo_Dat,LW_OFT,HI_OFT);// Offset range check
       
      Rit_Dat = constrain(Rit_Dat,LW_RIT,HI_RIT);  // RIT range check
    }
  }
}

//----------  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);   // AD9850 command

  digitalWrite(FQ_UD,HIGH);
}

//----------  Function Encorder STEP  ---------

void Fnc_Stp(){
  if(Enc_Stp == 10)                       // Step = 10Hz ?
    Enc_Stp = 1000000;                    //   Yes,1MHz set
  else
    Enc_Stp = Enc_Stp / 10;               // Step down 1 digit

  Fnc_Step_Disp();
  while(digitalRead(SW_STEP) == LOW)
    ;
}

//----------  Function STEP Display  ----------

void Fnc_Step_Disp(){
  lcd.setCursor(0,1);
  switch(Enc_Stp){
    case 10:
      lcd.print("10  ");
      break;
    case 100:
      lcd.print("100 ");
      break;
    case 1000:
      lcd.print("1k  ");
      break;
    case 10000:
      lcd.print("10k ");
      break;
    case 100000:
      lcd.print("100k");
      break;
    case 1000000:
      lcd.print("1M  ");
      break;
    default:
      lcd.print("1k  ");
      Enc_Stp = 1000;
      break;
  }
}

//----------  Function String Dot Edit  --------
 
char *Fnc_Dot_Edit(char *str,long n){
  int  i = 0;                           // Write the number
  char *p = str;
  unsigned long  u = abs(n);

  do{
    *p++ = "0123456789"[u % 10];
    u = u / 10;
    i++;
    if((0 != u) && (0 == (i % 3)))
      *p++ = '.';
    }
  while( 0 != u );

  if ( n < 0 )
     *p++ = '-';
   *p = '\0';
   Fnc_Revr( str );
   return str;
}

//----------  Function String Reverse  ---------

void Fnc_Revr(char *str){
  int i,n;
  char c;

  n=strlen(str);
  for(i = 0;i < n / 2;i++){
    c=str[i];
    str[i]=str[n - i - 1];
    str[n - i - 1]=c;
  }
}

//----------  Function Save EEPROM 4byte  ---------

void Fnc_Eep_Sav4(long value,int address){
  address += 3;
  for(int i = 0;i < 4;i++){
    byte toSave = value & 0xFF;
    if(EEPROM.read(address) != toSave){
      EEPROM.write(address,toSave);
      }
    value = value >> 8;
    address--;
  }
}

//----------  Function Load EEPROM 4byte  ---------

long Fnc_Eep_Lod4(int address){
  long value = 0;
  for(int i = 0;i < 4;i++){
    value = value | EEPROM.read(address);
    if( i < 3){
      value = value << 8;
      address++;
      }
  }
  return value;
}

//----------  Function LCD Display  ---------

void Fnc_Lcd(){
  lcd.setCursor(0,0);
  if(Flg_Tx == 1)
    lcd.write('T');
  else if(Flg_Ent == 1)
    lcd.write('P');
  else
    lcd.print(Byt_Chn);

  Fnc_Step_Disp();

  if(Flg_Rit == 1){                              // Rit display
    lcd.setCursor(5,1);
    if(Rit_Dat != Rit_Datb){
      lcd.print("R          ");
      Rit_Datb = Rit_Dat;
    }
    lcd.setCursor(6,1);
    if(Rit_Dat >=0)
      lcd.write('+');
    Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
    lcd.print(Lcd_Dat);
  }

  if(Flg_Spl == 1){                              // Split display
    lcd.setCursor(5,1);
    if(Rit_Dat != Rit_Datb){
      lcd.print("T          ");
      Rit_Datb = Rit_Dat;
    }
    lcd.setCursor(6,1);
    if(Rit_Dat >=0)
      lcd.write('+');
    Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
    lcd.print(Lcd_Dat);
  }

    if((Flg_Over == 1) && (Flg_Ent == 0)){
      Fnc_Fdsp(Vfo_Dat);
      lcd.setCursor(14,1);
      lcd.print("ov");
    }
    else
      Fnc_Fdsp(Vfo_Dat);

    if((Flg_Over == 0) && (Flg_Ent == 0)){
      lcd.setCursor(14,1);
      lcd.write(' ');
      lcd.write(' ');
    }

  if((Flg_Vfo == 0) && (Flg_If == 0) && (Flg_Rit == 0) && (Flg_Spl == 0) && (Flg_Mode == 0)){
    lcd.setCursor(5,1);
    lcd.print(CALL);
  }
}

//----------  Function Frequency Display  -------------------

void Fnc_Fdsp(long f_disp){
  Fnc_Dot_Edit(Lcd_Dat,f_disp);
  lcd.setCursor(1,0);
  if(f_disp != Vfo_Datb){
    lcd.write(':');
    for(int i=0;i<10;i++)
      lcd.write(' ');
    Vfo_Datb = f_disp;
  }

  lcd.setCursor(2,0);
  lcd.print(Lcd_Dat);
  if(Flg_Mode == 0)
    Fnc_Mdisp();
  if((Flg_If == 1) || (Flg_Vfo == 1)){
    lcd.setCursor(13,0);
    for(int i=0;i<3;i++)
      lcd.write(' ');
  }
}

//----------  Function Mode Display  -----------------------

void Fnc_Mdisp(){
  lcd.setCursor(13,0);
  switch(Byt_Mode){
    case 0:                              // LSB
      lcd.print("LSB");
      break;
    case 1:                              // USB
      lcd.print("USB");                
      break;
    case 2:                              // CW
      lcd.print("CW ");                
      break;
  }
}

//----------  Function Rit  ---------

void Fnc_Rit(){
  if(Flg_Vfo == 0){
    if(Flg_Rit == 0){
      if(Flg_Spl == 1)
        Flg_Spl = 0;
      Flg_Rit = 1;
      lcd.setCursor(5,1);
      lcd.print("R          ");
      if(Rit_Dat >=0){
        lcd.setCursor(6,1);
        lcd.write('+');
        Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
        lcd.print(Lcd_Dat);
      }
    }
    else{
      lcd.setCursor(5,1);
      lcd.print(CALL);
      Flg_Rit = 0;
      Rit_Dat = 0;
    }
  }
  else
    Byt_Vfo++;

  while(digitalRead(SW_RIT) == LOW)
    ;
}

//----------  Function Channel SW Check  ---------

void Fnc_Chsw(){
  byte cnt = 0;

  Byt_Chn++;
  while(digitalRead(SW_CH) == LOW){
    delay(500);
    cnt++;
    if(6 <= cnt){                            // Eep Initial start(3sec)?
      Fnc_Eep_Int();
      Byt_Chn = EEPROM.read(Chn_Eep);         // Channel
      Byt_Chnb = Byt_Chn;
      Fnc_Eep_Rd();                           // EEPROM Read
      lcd.setCursor(0,0);                     // LCD display
      lcd.print(Byt_Chn);
      Fnc_Fdsp(Vfo_Dat);
      lcd.setCursor(5,1);
      lcd.print("Init End   ");
    }
  }
}

//---------- Function Eeprom Initialization -----------------

void Fnc_Eep_Int(){
  int i;

  for (i=0;i<160;i++)                            // 0 clear(160byte)
    EEPROM.write(i, 0);

  for(i=0;i<Max_Chn;i++){
    Fnc_Eep_Sav4(DEF_FRQ,Frq_Eep+i*4);            // Frequency(7.05MHz)
    Fnc_Eep_Sav4(DEF_STP,Stp_Eep+i*4);            // Step(1kHz)
  }

  Fnc_Eep_Sav4(DEF_IF,If_Eep);                         // IF(10.7MHz)
  Fnc_Eep_Sav4(DEF_LSB,Care_Eep+0);              // LSB Offset(-1500Hz)
  Fnc_Eep_Sav4(DEF_USB,Care_Eep+4);              // USB Offset(1500Hz)
  Fnc_Eep_Sav4(DEF_CW,Care_Eep+8);                // CW Offset(-600Hz)
  EEPROM.write(Vfo_Eep,DEF_VFO);                 // Vfo Mode
  EEPROM.write(Eep_Int,Int_End);                      // Init end set(73)
}

//----------  Function EEPROM Read  ---------

void Fnc_Eep_Rd(){
  if((0 <= Byt_Chn) && (Byt_Chn < Max_Chn))
    Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep+Byt_Chn*4);
  else{
    Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep+0*4);
    Byt_Chn = 0;
  }

   if((0 <= Byt_Chn) && (Byt_Chn < Max_Chn))
    Enc_Stp = Fnc_Eep_Lod4(Stp_Eep+Byt_Chn*4);
  else
    Enc_Stp = Fnc_Eep_Lod4(Stp_Eep+0*4);

  If_Dat = Fnc_Eep_Lod4(If_Eep);
  Byt_Vfo = EEPROM.read(Vfo_Eep);
}

//----------  Function EEPROM Write  -----------------------

void Fnc_Eep_Wt(byte chn){
  if((0 <= chn) && (chn < Max_Chn)){
    Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep+chn*4);
    Fnc_Eep_Sav4(Enc_Stp,Stp_Eep+chn*4);
  }
  EEPROM.write(Chn_Eep,Byt_Chn);
}

//----------  Function Split  ---------

void Fnc_Spl(){
  if(Flg_Spl == 0){
    if(Flg_Rit == 1)
      Flg_Rit = 0;
    Flg_Spl = 1;
    lcd.setCursor(5,1);
    lcd.print("T          ");
    if(Rit_Dat >=0){
      lcd.setCursor(6,1);
      lcd.write('+');
      Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
      lcd.print(Lcd_Dat);
    }
  }
  else{
    lcd.setCursor(5,1);
    lcd.print(CALL);
    Flg_Spl = 0;
    Rit_Dat = 0;
  }

  while(digitalRead(SW_SPLIT) == LOW)
    ;
}

//----------  Function ENT  --------------------------------

void Fnc_Ent(){
  byte cnt = 0;

  if(Flg_Ent == 0){
    if(Flg_Rit == 1){
      Flg_Rit = 2;
      lcd.setCursor(5,1);
      lcd.write('r');
    }
     else
      if(Flg_Rit == 2){
        Flg_Rit = 1;
        lcd.setCursor(5,1);
        lcd.write('R');
      }

    if(Flg_Spl == 1){
      Flg_Spl = 2;
      lcd.setCursor(5,1);
      lcd.write('t');
    }
    else
      if(Flg_Spl == 2){
        lcd.setCursor(5,1);
        lcd.write('T');
        Flg_Spl = 1;
      }

    Fnc_Eep_Wt(Byt_Chn);

    while(digitalRead(SW_ENT) == LOW){
      delay(500);
      cnt++;
      if(6 <= cnt){                              // Parameter change mode(3sec)
        lcd.setCursor(0,0);
        lcd.print("P");
        Flg_Ent = 1;
        Flg_Rit = 0;
        Flg_Spl = 0;
        Byt_Ent = 0;
        if(Flg_If == 0){
          Fnc_Eep_Sav4(Vfo_Dat,Sav_Eep);
          Vfo_Dat = Fnc_Eep_Lod4(If_Eep);
          Flg_If = 1;
        }
        Fnc_Fdsp(Vfo_Dat);
        lcd.setCursor(5,1);
        lcd.print("IF    ");
      }
    }
  }

  else{
    while(digitalRead(SW_ENT) == LOW){
      delay(500);
      cnt++;
      if(6 <= cnt){                              // Return Parameter cahne mode(3sec)
        lcd.setCursor(0,0);
        lcd.print(Byt_Chn);
        Flg_Ent = 0;
        Flg_Vfo = 0;
        Flg_If = 0;
        Vfo_Dat = Fnc_Eep_Lod4(Sav_Eep);
        Fnc_Fdsp(Vfo_Dat);
        lcd.setCursor(5,1);
        lcd.print(CALL);
        EEPROM.write(Vfo_Eep,Byt_Vfo);
      }
      else
        Byt_Ent++;
    }
  }

}

//----------  Function Prameter PROC  ----------------------

void Fnc_Prm(){
  lcd.setCursor(5,1);
  switch(Byt_Ent){
    case 0:                                         // IF Frequency load
      if(Flg_If == 0){
        Vfo_Dat = Fnc_Eep_Lod4(If_Eep);
        Flg_If = 1;
      }
      lcd.setCursor(5,1);
      lcd.print("IF         ");
      break;
    case 1:                                         // IF Frequency proc.
      if(Flg_If == 1){
        Fnc_Eep_Sav4(Vfo_Dat,If_Eep);
        If_Dat = Vfo_Dat;
        Flg_If = 0;
      }
      lcd.setCursor(5,1);
      lcd.print("Offset");
      if(Flg_LSB == 0){                             // LSB Offset data load
        Vfo_Dat = Fnc_Eep_Lod4(Care_Eep+0);
        Flg_LSB = 1;
        Flg_Mode = 1;
      }
      lcd.setCursor(13,1);
      lcd.print("LSB");
      break;
    case 2:                                         // LSB Offset proc.
      if(Flg_LSB == 1){
        Fnc_Eep_Sav4(Vfo_Dat,Care_Eep+0);
        Flg_LSB = 0;
      }
      if(Flg_USB == 0){                             // USB Offset data load                      
        Vfo_Dat = Fnc_Eep_Lod4(Care_Eep+4);
        Flg_USB = 1;
      }
      lcd.setCursor(13,1);
      lcd.print("USB");
      break;
    case 3:                                         // USB Offset proc.
      if(Flg_USB == 1){
        Fnc_Eep_Sav4(Vfo_Dat,Care_Eep+4);
        Flg_USB = 0;
      }
      if(Flg_CW == 0){                            // CW Offset
        Vfo_Dat = Fnc_Eep_Lod4(Care_Eep+8);
        Flg_CW = 1;
      }
      lcd.setCursor(13,1);
      lcd.print("CW ");
      break;
    case 4:                                       // VFO Mode Set
      if(Flg_CW == 1){
        Fnc_Eep_Sav4(Vfo_Dat,Care_Eep+8);
        Flg_CW = 0;
        Flg_Mode = 0;
      }
      if(Flg_Vfo == 0){
        Byt_Vfo = EEPROM.read(Vfo_Eep);          // Vfo Mode data
        if(Byt_Vfo < 0)
          Byt_Vfo = 0;
        Flg_Vfo = 1;
      }
      Vfo_Dat = Fnc_Eep_Lod4(Sav_Eep);
      lcd.setCursor(5,1);
      lcd.print("VFO  ");
      lcd.setCursor(10,1);
      switch(Byt_Vfo){
        case 0:
          lcd.print("Roff  ");                  // TX=VFO RX=0
          break;
        case 1:
          lcd.print("TR    ");                  // TX=VFO RX=VFO
          break;
        case 2:
          lcd.print("R+IF  ");                  // TX=VFO RX=VFO+IF
          break;
        case 3:
          lcd.print("TR+IF ");                  // TX=VFO+IF RX=VFO+IF
          break;
        default:
          Byt_Vfo = 0;
          lcd.print("Roff  ");
          break;
      }
      break;
    default:
      if(Flg_Vfo == 1){
        EEPROM.write(Vfo_Eep,Byt_Vfo);
        Flg_Vfo = 0;
      }
      lcd.setCursor(5,1);
      lcd.print("IF    ");
      Byt_Ent = 0;
      break;
  }
}

//----------  Function Band  -------------------------------

void Fnc_Band(long vfo){
  if((vfo >= LW_VFO80) && (vfo < MI_VFO80)){          // 3.5MHz
    Flg_Over = 0;
    Byt_Mode = 2;                                     // CW
  }
  else if((vfo >= MI_VFO80) && (vfo <= HI_VFO80)){
    Flg_Over = 0;
    Byt_Mode = 0;                                     // LSB
  }

  else if((vfo >= LW_VFO40) && (vfo < MI_VFO40)){     // 7MHz
    Flg_Over = 0;
    Byt_Mode = 2;                                     // CW
  }
  else if((vfo >= MI_VFO40) && (vfo <= HI_VFO40)){
    Flg_Over = 0;
    Byt_Mode = 0;                                     // LSB
  }

  else if((vfo >= LW_VFO20) && (vfo < MI_VFO20)){     // 14MHz
    Flg_Over = 0;
    Byt_Mode = 2;                                     // CW
  }
  else if((vfo >= MI_VFO20) && (vfo <= HI_VFO20)){
    Flg_Over = 0;
    Byt_Mode = 1;                                     // USB
  }

  else if((vfo >= LW_VFO15) && (vfo < MI_VFO15)){     // 21MHz
    Flg_Over = 0;
    Byt_Mode = 2;                                     // CW
  }
  else if((vfo >= MI_VFO15) && (vfo <= HI_VFO15)){
    Flg_Over = 0;
    Byt_Mode = 1;                                     // USB
  }

  else if((vfo >= LW_VFO10) && (vfo < MI_VFO10)){     // 28MHz
    Flg_Over = 0;
    Byt_Mode = 2;                                     // CW
  }
  else if((vfo >= MI_VFO10) && (vfo <= HI_VFO10)){
    Flg_Over = 0;
    Byt_Mode = 1;                                      // USB
  }

  else if (Vfo_Dat < 10000000L){
    Byt_Mode = 0;                                      // LSB
    Flg_Over = 1;                                
  }
  else{
    Byt_Mode = 1;                                      // USB
    Flg_Over = 1;
  }
}

//----------  Function IF Proc.  ---------------------------

void Fnc_If(byte if_mode){
  long bfo = Fnc_Eep_Lod4(Care_Eep+Byt_Mode*4);

  switch(if_mode){
    case 0:                                      // Roff
      RX_Dat = 0L;                            // RX = off
      TX_Dat = Vfo_Dat;                     // TX = VFO
      break;
    case 1:                                      // TR
      RX_Dat = Vfo_Dat;                     // RX = VFO
      TX_Dat = Vfo_Dat;                     // TX = VFO
      break;
    case 2:                                      // R+IF
      RX_Dat = Vfo_Dat + If_Dat + bfo;  // RX = VFO + IF + bfo
      TX_Dat = Vfo_Dat;                     // TX = VFO
      break;
    case 3:                                      // TR+IF
      RX_Dat = Vfo_Dat + If_Dat + bfo;  // RX = VFO + IF + bfo
      if(Byt_Mode == 2)                      // CW Mode?
        TX_Dat = Vfo_Dat + If_Dat;        // TX = VFO + IF
      else
        TX_Dat = Vfo_Dat + If_Dat + bfo;// TX = VFO + IF + bfo
      break;
    default:
      RX_Dat = 0L;                            // RX = off
      TX_Dat = Vfo_Dat;                     // TX = VFO
      break;
    }
  if((RX_Dat != 0) && ((Flg_Rit == 1) || (Flg_Rit == 2)))
    RX_Dat = RX_Dat + Rit_Dat;
  if((Flg_Spl == 1) || (Flg_Spl == 2))
    TX_Dat = TX_Dat + Rit_Dat;
}


3 件のコメント:

  1. Hello, the annoying thing can be changed of FI, and add or subtract the FI from already thank you very much from Argentina

    返信削除
  2. hi
    i get an error,, rotary.h , no such file ,, in fact i have rotary.h, any help please
    thank you
    Jameel

    返信削除
  3. Hi Unknown.

    Please download the following zip file from JA2GQP's download site.
    AD9850 DDS folder ad9850_V1.2.zipplease download it.
    Included rotary.h in this zip file and modified it.

    返信削除