AD9850 DDS モジュール に続き AD9851 で、別基板バージョンのものです。
ジャンパとかが一切ない簡略版?なのか進化版?でしょうか。
D0, D1 は 10kΩでプルアップされているので、これらは自分でプルアップする必要はありません。D2 を GND に接続するだけでシリアルモードに入れる実装になっています。
コード
#include <Arduino.h>
#include <Wire.h>
template <uint32_t CLKIN, bool MULTIPLIER>
class AD9851 {
static constexpr double PHASE_FACTOR = 0x100000000 / (double)(CLKIN * (MULTIPLIER ? 6 : 1));
const uint16_t PIN_DATA;
const uint16_t PIN_FQ_UD;
const uint16_t PIN_W_CLK;
const uint16_t PIN_RESET;
void serial_write(uint32_t freq, uint8_t phase, bool powerdown) {
// freq (delta phase)
for (int i = 0; i < 32; i++) {
digitalWrite(PIN_DATA, (freq>>i) & 1);
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
}
// control bits
digitalWrite(PIN_DATA, MULTIPLIER ? HIGH : LOW);
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
digitalWrite(PIN_DATA, LOW);
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
// powerdown
digitalWrite(PIN_DATA, powerdown ? HIGH : LOW);
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
// phase
for (int i = 0; i < 5; i++) {
digitalWrite(PIN_DATA, (phase>>i) & 1);
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
}
digitalWrite(PIN_FQ_UD, HIGH); delayMicroseconds(4);
digitalWrite(PIN_FQ_UD, LOW); delayMicroseconds(4);
}
public:
AD9851(
uint16_t data,
uint16_t fq_ud,
uint16_t w_clk,
uint16_t reset
) :
PIN_DATA(data),
PIN_FQ_UD(fq_ud),
PIN_W_CLK(w_clk),
PIN_RESET(reset)
{
pinMode(PIN_DATA, OUTPUT);
pinMode(PIN_FQ_UD, OUTPUT);
pinMode(PIN_W_CLK, OUTPUT);
pinMode(PIN_RESET, OUTPUT);
}
/**
* W0 ... W31 -> Freq (LSB first)
* W32, W33 -> Control (for factory test)
* W34 -> Power-Down
* W35 ... W39 -> Phase (LSB first)
*/
void reset() {
// ensure low
digitalWrite(PIN_DATA, LOW);
digitalWrite(PIN_FQ_UD, LOW);
digitalWrite(PIN_W_CLK, LOW);
// reset
digitalWrite(PIN_RESET, HIGH); delay(1);
digitalWrite(PIN_RESET, LOW); delay(1);
// reset to serial mode
// Pins of D0, D1 = HIGH, D2 = LOW for serial mode
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
digitalWrite(PIN_FQ_UD, HIGH); delayMicroseconds(4);
digitalWrite(PIN_FQ_UD, LOW); delayMicroseconds(4);
}
void set_frequency(uint32_t frequency) {
set_frequency(frequency, 0);
}
void set_frequency(uint32_t frequency, uint8_t phase) {
uint32_t deltaPhase = PHASE_FACTOR * frequency;
serial_write(deltaPhase, phase, 0);
}
void powerdown() {
serial_write(0, 0, 1);
}
};
AD9851<30000000, true> ad9851(9, 10, 11, 12);
void setup() {
Serial.begin(9600);
ad9851.reset();
ad9851.set_frequency(10e6);
}
void loop() {
}
AD9851 とほぼ同じですが、6倍の周波数逓倍器がの有効無効化のビットがあるので、その部分だけ実装を変えてあります。
出力
購入したモジュールは 30MHz の源発振のものなので、逓倍後は 180MHz になります。
40MHz ぐらいから出力が低くなります。
ZOUT2 (フィルタあり)
逓倍している分スプリアスが多いようです。