/* * AD9834DDS VFO for AS40D * 2016.2.23 JH7UBC Keiji Hata */ #include #include #include #include LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3,POSITIVE); //各定数の定義 const byte ENC_A = 2; //Rotary encoder A const byte ENC_B = 3; //Rotary encoder B const byte SDATA = 4; //AD9834 SDATA const byte SCLK = 5; //AD9834 SCLK const byte FSYNC = 6; //AD9834 FSYNC const byte SW_STEP = 7; //Frequency Change Step const byte SW_RIT = 8; //Rit on/off const byte SW_MW = 9; //Memory Write const byte SW_MR = 10; //Memory Read const byte SW_TX = 12; //Tx/Rx SW_TX=1 Transmit const long IF_FREQ = 8466100; //中間周波数 const long LOW_FREQ = 7000000; //下限周波数 const long HI_FREQ = 7200000; //上限周波数 const int LOW_RIT = -980; //RIT下限 const int HI_RIT = 980; //RIT上限 const int EEPadd = 0; //EEPROM address //各変数の初期値 long FREQ = 7015000; //DDS周波数初期値=7.015MHz long STEP = 1000; //STEP周波数初期値=1KHz long DDS_Data = FREQ +IF_FREQ; int RIT_FREQ = 0; //フラッグ初期値 byte Flg_Rit = 0; //Ritフラッグ Rotary r = Rotary(ENC_A,ENC_B); //ENC_A=2,ENC_B=3 void setup() { pinMode(SDATA,OUTPUT); //SPI通信に使うSDATA,SCLK,FSYNCを出力に設定 pinMode(SCLK,OUTPUT); pinMode(FSYNC,OUTPUT); pinMode(SW_STEP,INPUT_PULLUP); //STEP SW 入力に設定しプルアップ pinMode(SW_RIT,INPUT_PULLUP); //RIT SW 入力に設定しプルアップ pinMode(SW_MW,INPUT_PULLUP); //MW SW 入力に設定しプルアップ pinMode(SW_MR,INPUT_PULLUP); //MR SW 入力に設定しプルアップ pinMode(SW_TX,INPUT); //TX SW 入力に設定 //ピン変化割り込みの設定 PCICR |= (1 << PCIE2); PCMSK2 |= (1 << PCINT18) | (1 << PCINT19); sei(); //割り込み許可 //LCD初期化 lcd.begin(16,2); //LCD表示開始(colums,rows) lcd.backlight(); //バックライト点灯 lcd.clear(); //LCDクリア //初期画面表示 lcd.setCursor(0,1); lcd.print("STEP"); lcd.setCursor(9,1); lcd.print("RIT "); Fnc_Lcd(); //周波数表示 Fnc_Step_Disp(); //STEP表示 } //Main Program void loop() { if(digitalRead(SW_TX) == LOW){ DDS_Data = FREQ + IF_FREQ; // lcd.setCursor(0,0); // lcd.print("T"); }else{ if(digitalRead(SW_STEP) == LOW){ Fnc_Stp(); } if(digitalRead(SW_RIT) == LOW){ Fnc_Rit(); } if(digitalRead(SW_MW) == LOW){ Fnc_Eep_Save(FREQ,EEPadd); } if(digitalRead(SW_MR) == LOW){ FREQ = Fnc_Eep_Load(EEPadd); } if (Flg_Rit == 1){ DDS_Data = FREQ + IF_FREQ +RIT_FREQ; }else{ DDS_Data = FREQ + IF_FREQ; } } Fnc_Dds(DDS_Data); Fnc_Lcd(); Fnc_Rit_Disp(); // delay(10); } //ロータリーエンコーダ処理(ISR=割り込みサービスルーチン) ISR(PCINT2_vect){ unsigned char result = r.process(); if(result){ if(result == DIR_CW){ if (Flg_Rit == 1){ RIT_FREQ =RIT_FREQ + 20; }else{ FREQ = FREQ + STEP; } }else{ if (Flg_Rit == 1){ RIT_FREQ = RIT_FREQ - 20; }else{ FREQ = FREQ - STEP; } } } RIT_FREQ = constrain(RIT_FREQ,LOW_RIT,HI_RIT); FREQ = constrain(FREQ,LOW_FREQ,HI_FREQ); // Fnc_Rit_Disp(); // Fnc_Lcd(); } //DDSにデータを送る。 void Fnc_Dds(long frequency){ long wrk = frequency << 2; // Serial.println(wrk); unsigned int wrk1,wrk2,wrk3; //DDSに送るデータwrk1,wrk2,wrk3は、16ビット wrk1 = 0x2000; //wrk1=コントロールデータ wrk2 = wrk & 0x3fff; //wrkの下位14ビットをwrk2にセット wrk2 = wrk2 | 0x4000; //D14に1をセット(FREQ0指定) wrk3 = wrk >> 14; //wrkを右に14ビットシフト wrk3 = wrk3 & 0x3fff; //wrkの上位14ビットをwrk3にセット wrk3 = wrk3 | 0x4000; //D14に1をセット(FREQ0指定) digitalWrite(SCLK,HIGH); //SCLKをHOGHにする digitalWrite(FSYNC,LOW); //FSYNCをLOWにする(送信開始) shiftOut(SDATA,SCLK,MSBFIRST,(wrk1 >> 8)); //コントロールデータを送信 shiftOut(SDATA,SCLK,MSBFIRST,wrk1); shiftOut(SDATA,SCLK,MSBFIRST,(wrk2 >> 8)); //周波数データ下位14ビットを送信 shiftOut(SDATA,SCLK,MSBFIRST,wrk2); shiftOut(SDATA,SCLK,MSBFIRST,(wrk3 >> 8)); //周波数データ上位14ビットを送信 shiftOut(SDATA,SCLK,MSBFIRST,wrk3); digitalWrite(FSYNC,HIGH); //FSYNCをHIGHにする(送信終了) } //STEPボタンが押された時の処理 void Fnc_Stp(){ if(STEP == 10){ STEP = 1000; } else{ STEP= STEP / 10; } delay(10); Fnc_Step_Disp(); while(digitalRead(SW_STEP) == LOW){ delay(10); } } //RITボタンが押された時の処理 void Fnc_Rit(){ if (Flg_Rit == 1){ Flg_Rit = 0; }else{ Flg_Rit = 1; } delay(10); Fnc_Rit_Disp(); while(digitalRead(SW_RIT) == LOW){ delay(10); } } //周波数表示 void Fnc_Lcd(){ lcd.setCursor(4,0); lcd.print(FREQ); } //STEP表示 void Fnc_Step_Disp(){ lcd.setCursor(4,1); switch(STEP){ case 10: lcd.print(" 10"); break; case 100: lcd.print("100"); break; case 1000: lcd.print(" 1k"); break; } } //RIT表示 void Fnc_Rit_Disp(){ char Rit_F[4]; lcd.setCursor(12,1); if (Flg_Rit == 1){ lcd.print(" "); lcd.setCursor(12,1); sprintf(Rit_F,"%4d",RIT_FREQ); lcd.print(Rit_F); }else{ lcd.print(" "); } } // 4byteをEEPROMにSAVE void Fnc_Eep_Save(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 --; } delay(10); while(digitalRead(SW_MW) == LOW){ delay(10); } } // 4byteをEEPROM からLOAD long Fnc_Eep_Load(int address){ long value = 0; for (int i=0; i<4;i++){ value = value | EEPROM.read(address); if (i<3){ value = value << 8; address ++; } delay(10); while(digitalRead(SW_MR) == LOW){ delay(10); } } return value; }