This code has been updated - see later posting!!
Here's the code for a VFO using the AD9851, up to 70MHz. The AD9851 code is here
// VFO_ADS51_OLED // V1.0 16-4-17 VFO for the AD9851, 30MHz external xtal, x6 180MHz internal clock // freq steps 10Hz, 100Hz, 1kHz, 10kHz, 100kHz, 1MHz // AD9851 // RESET 8 // DATA 9 // FQ_UD 10 // W_CLK 11 // OLED 128x64 // SDA = A4 // SCL = A5 // rotary encoder pins // CLK = 2 // DT = 3 // SW = 4 // OLED, AD9851, Rotary Encoder & I2C libraries #include "Oled_128X64_I2C.h" #include "ADS9851.h" #include "Rotary.h" // AD9851 pins #define RESET 8 #define DATA 9 #define FQ_UD 10 #define W_CLK 11 // xtal calibration (30MHz external x6 REFCLK = 180MHz internal #define CALIBRATE 180002300 // cal against SDR (cal at 7070 against CORRA) // encoder #define CLK 2 #define DT 3 #define SW 4 // ads (analog-output digital synthesiser) object ADS9851 ads; // Encoder object Rotary enc = Rotary(DT, CLK); // phase coding, 0-180 [0-5] uint8_t ph[] = {0x00, 0x01, 0x02, 0x04, 0x08, 0x10}; // initial settings volatile double freqHz = 7100000; // (Hz) start frequency 7.1MHz volatile double freqChz = 0; // (cHz) additional 0cHz volatile double freqStep = 10; // (Hz) init 10Hz freqStep uint8_t phase = ph[0]; // init phase // freq change flag volatile bool freqChange; void setup() { // encoder, button pins pinMode(DT, INPUT_PULLUP); pinMode(CLK, INPUT_PULLUP); pinMode(SW, INPUT_PULLUP); // setup interrupts from DT or CLK for tuning attachInterrupt(digitalPinToInterrupt(DT), freqTune, CHANGE); attachInterrupt(digitalPinToInterrupt(CLK), freqTune, CHANGE); interrupts(); // enable // oled init, sets I2C addr to 0x3C oled.begin(); // init ads, executes down() to flush buffers ads.begin(W_CLK, FQ_UD, DATA, RESET); // calibrate to xtal actual frequency ads.calibrate(CALIBRATE); ads.setFreq(freqHz, freqChz, phase); freqChange = false; dispUpdate(); } // check button & freq tune, update display void loop() { if (button()) { dispUpdate(); } if (freqChange) { // freq updated ads.setFreq(freqHz, freqChz, phase); freqChange = false; dispUpdate(); } } // ISR - encoder interrupt service routine void freqTune() { unsigned char result; result = enc.process(); if (result == DIR_CW ) { freqHz += freqStep; freqChange = true; } else if (result == DIR_CCW) { freqHz -= freqStep; freqChange = true; } } // change freqStep, 10Hz to 1MHz bool button() { if (digitalRead(SW) == LOW) { // button pressed? while (!digitalRead(SW)); // wait for release if (freqStep == 1000000) freqStep = 10; // back to 10Hz else freqStep = freqStep * 10; // or increase by x10 return true; } else { return false; } } // picture loop, display init data void dispUpdate() { oled.firstPage(); do { dispMsg(50, 0, "VFO"); dispFreq(15, 25, freqHz, freqChz, 2); dispMsg(15, 50, "<--"); dispStep(45, 50, freqStep); dispMsg(95, 50, "-->"); } while ( oled.nextPage() ); }
No comments:
Post a Comment