// AD9834SG #include #include "rotary.h" #include #include //#define DEBUG 1 //デバッグモード(シリアル出力) //SPI Arduino UNO // AD9834 // 13 → SCK H/W Pin CLK // 12 ← MISO H/W Pin xxx // 11 → MOSI H/W Pin SDA // 10 → CS FSY LOWで選択 // #define PIN_RRIGHT 2 //ロータリーエンコーダ右回転 #define PIN_RLEFT 3 //ロータリーエンコーダ左回転 #define PIN_HWRSW A0 //H/Wロータリースイッチ #define CMD_RESET 0x0100 //内部レジスタを0にリセット #define CMD_B28 0x2000 //二つの連続した書き込みで周波数レジスタにロード #define CMD_OPBITEN 0x0020 //ピンSIGN BIT OUTをイネーブル #define CMD_SIGNPIB 0x0010 //1:方形波を出力 #define CMD_DIV2 0x0008 //1:直接出力,0:2分周出力 #define CMD_MODE 0x0002 //1:三角波出力 #define CMD_CTRL (CMD_B28|CMD_OPBITEN|CMD_SIGNPIB|CMD_DIV2) #define SEL_FREQ0 0x4000 //FREQ0レジスタ・ビット #define SEL_FREQ1 0x8000 //FREQ1レジスタ・ビット #define PIN_FSYNC 10 //CS Pin #define MIN_FREQ 400000 //400kHz #define MAX_FREQ 22000000 // 22MHz #define TM_DELAY 100 //0.1s #define TM_SAVEFREQ 5000 //5s #define MAGIC_NUM 0xeecc //2 bytes #define ADDR_MAGIC 0 //2 bytes #define ADDR_FREQ 4 //4 bytes #define FREQWRT_COUNT (TM_SAVEFREQ/TM_DELAY) Rotary r = Rotary(PIN_RRIGHT, PIN_RLEFT); SPISettings settings(SPISettings(1000000, MSBFIRST, SPI_MODE2)); //各変数の初期値 static long FREQ = 10000000; //DDS周波数初期値=10MHz static long STEP = 0; //STEP周波数初期値=0kHz static int stepNo = (-1); static int freqSaveTimming = 0; //DDS設定周波数セーブ //ロータリーエンコーダ処理 ISR(PCINT2_vect) { cli(); if(STEP != 0) { unsigned char result = r.process(); if(result){ if(result == DIR_CW) { if((FREQ += STEP) > MAX_FREQ) FREQ = MAX_FREQ; } else{ if((FREQ -= STEP) < MIN_FREQ) FREQ = MIN_FREQ; } setFreq(); dispFreq(); freqSaveTimming = 0; } } sei(); } //記録周波数読み込み long restoreFreq(void) { if(((EEPROM.read(ADDR_MAGIC)<<8) | EEPROM.read(ADDR_MAGIC + 1)) != MAGIC_NUM) { #ifdef DEBUG Serial.print("Write MAGIC Number"); #endif EEPROM.write(ADDR_MAGIC + 0, (MAGIC_NUM>>8)&0xff); EEPROM.write(ADDR_MAGIC + 1, MAGIC_NUM &0xff); saveFreq(); } long freq = ((unsigned long)EEPROM.read(ADDR_FREQ + 0)<<24) | ((unsigned long)EEPROM.read(ADDR_FREQ + 1)<<16) | ((unsigned long )EEPROM.read(ADDR_FREQ + 2)<<8) | ((unsigned long)EEPROM.read(ADDR_FREQ + 3)); #ifdef DEBUG Serial.print("Read FREQ = "); Serial.print(freq); Serial.println(" Hz"); #endif return(freq); } //周波数記録 void saveFreq(void) { if(FREQ != restoreFreq()) { #ifdef DEBUG Serial.print("Save FREQ = "); Serial.print(FREQ); Serial.println(" Hz"); #endif EEPROM.write(ADDR_FREQ + 0, ((unsigned long)FREQ>>24)&0xff); EEPROM.write(ADDR_FREQ + 1, ((unsigned long)FREQ>>16)&0xff); EEPROM.write(ADDR_FREQ + 2, ((unsigned long)FREQ>>8) &0xff); EEPROM.write(ADDR_FREQ + 3, (unsigned long)FREQ &0xff); } } void setup(void) { cli(); #ifdef DEBUG Serial.begin(9600); Serial.println("Program start"); #endif //ロータリーエンコーダ pinMode(PIN_RRIGHT, INPUT_PULLUP); pinMode(PIN_RLEFT, INPUT_PULLUP); //割込み設定 PCICR |= (1<>8); // MSB Reset SPI.transfer(CMD_RESET&0xff); // LSB SPI.transfer(CMD_CTRL>>8); // MSB Control register SPI.transfer(CMD_CTRL&0xff); // LSB digitalWrite(PIN_FSYNC, HIGH); //チップ・セレクト(OFF) SPI.endTransaction(); FREQ = restoreFreq(); dispStep(); dispFreq(); cli(); setFreq(); sei(); } //周波数表示 void dispFreq(void) { #ifdef DEBUG Serial.print("FREQ = "); Serial.print(FREQ); Serial.println(" Hz"); #endif } //STEP表示 void dispStep(void) { #ifdef DEBUG char *str; switch(STEP) { case 10: str = (char *)"10Hz"; break; case 100: str = (char *)"100Hz"; break; case 1000: str = (char *)"1kHz"; break; case 10000: str = (char *)"10kHz"; break; case 100000: str = (char *)"100kHz"; break; case 1000000: str = (char *)"1MHz"; break; } Serial.print("STEP = "); Serial.println(str); #endif } // 1-6: SW No. // (左)470k・180k・120k・68k・33k・18k(右) int getRswNo(void) { int val = analogRead(PIN_HWRSW); val = map(val, 0, 1023, 0, 50); #ifdef DEBUG // Serial.print("analog: "); // Serial.println(val); #endif if(val < 5) return(0); //スイッチの切り替わりが0になる if(val < 10) return(6); if(val < 15) return(5); if(val < 25) return(4); if(val < 30) return(3); if(val < 35) return(2); // return(1); if(val < 45) return(1); return(0); } void loop(void) { int nst = getRswNo(); if(stepNo != nst) { //後で0判定するのは初回設定(−1)に対応するため if(nst != 0) { //ステップ変更 switch(nst) { case 5: STEP = 1000000; break; //1M case 4: STEP = 100000; break; //100k case 3: STEP = 10000; break; //10k case 2: STEP = 1000; break; //1k case 6: STEP = 0; FREQ = 10000000; break; //fiexed 10M case 1: STEP = 0; FREQ = 455000; break; //fidxed 455k } stepNo = nst; cli(); setFreq(); sei(); dispStep(); dispFreq(); } } if(freqSaveTimming++ > FREQWRT_COUNT) { saveFreq(); freqSaveTimming = 0; } delay(TM_DELAY); } void setFreq(void) { //連続アドレス書き込みで上位下位14bitになる uint32_t Freq = FREQ /100 * 358; //1/0.28 = 3.57(先に×するとOFするので逆)誤差あり uint32_t Flsb = (Freq & 0x3fff) | SEL_FREQ0; //28ビットの下半分の14ビット分 uint32_t Fmsb = ((Freq>>14) & 0x3fff) | SEL_FREQ0; //上半分の14ビット分 SPI.beginTransaction(settings); digitalWrite(PIN_FSYNC, LOW); //チップ・セレクト(ON) SPI.transfer(Flsb>>8); // frequency register 0 LSB SPI.transfer(Flsb&0xff); SPI.transfer(Fmsb>>8); // frequency register 0 MSB SPI.transfer(Fmsb&0xff); digitalWrite(PIN_FSYNC, HIGH); //チップ・セレクト(OFF) SPI.endTransaction(); }