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 (フィルタあり)



逓倍している分スプリアスが多いようです。


ZOUT1 (フィルタなし)


  1. トップ
  2. tech
  3. AD9851 DDS モジュール
▲ この日のエントリ