bit-banging control for AD9850.

こちらのnoteに書いてます。
/users/ohneta/notebook/DDS-AS9850_softSPI/

Files at this revision

API Documentation at this revision

Comitter:
ohneta
Date:
Thu Jun 18 05:23:11 2015 +0000
Commit message:
1st commit

Changed in this revision

AD9850.cpp Show annotated file Show diff for this revision Revisions of this file
AD9850.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 25d6d7c1a48a AD9850.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AD9850.cpp	Thu Jun 18 05:23:11 2015 +0000
@@ -0,0 +1,135 @@
+//----------------------------------------------------------------
+/**
+ * 中華DDS AD9850のコントロール
+ * 
+ * mbed LPC1768では SPIを操作することで40bitの出力ができるが、
+ * mbed HRM1017等ではSPIの動作が違うためソフトウェアでシリアルデータを出力する
+ * 
+ * 参考資料
+ *   AD9850データシート
+ *     http://www.analog.com/static/imported-files/data_sheets/AD9850.pdf
+ *   mbed LPC1768 SPIでの実装例
+ *     http://developer.mbed.org/users/liamg/code/AD9850-function-generator-SPI-driver/
+ */
+//----------------------------------------------------------------
+
+#include "AD9850.h"
+
+#define AD9850_FREQ_CONST   34.359738368
+/*
+ * AD9850/clock=125MHz 
+ * 2の32乗=4294967296、DDSクロック==125MHzを前提とすると...
+ * 1Hz設定時の値 = 4294967296/125000000 = 34.359738368 となる
+ */
+
+//----------------------------------------------------------------
+/**
+ * コンストラクタ
+ *
+ * @param PinName data   データ転送ピン
+ * @param PinName w_clk  クロックピン
+ * @param PinName fu_ud  モジュール選択
+ * @param PinName reset  リセット
+ */
+AD9850::AD9850(PinName data, PinName w_clk, PinName fu_ud, PinName reset)
+    : _outBit(data), _w_clk(w_clk), _fu_ud(fu_ud), _reset(reset)
+{
+    init();
+}
+
+//----------------------------------------------------------------
+/**
+ * デストラクタ
+ */
+AD9850::~AD9850()
+{
+}
+
+//----------------------------------------------------------------
+/**
+ * 初期化
+ */
+void AD9850::init()
+{
+    reset();
+}
+
+//----------------------------------------------------------------
+/**
+ * リセット
+ */
+void AD9850::reset()
+{
+    _reset = 0; wait_ms(5);
+    _reset = 1; wait_ms(5);
+    _reset = 0; wait_ms(5);
+}
+
+//----------------------------------------------------------------
+/**
+ * 周波数設定
+ *
+ * @param int freq  設定する周波数(Hz)
+ *                  AD9850ボードに依存するがクロック125MHzで概ね 1〜40000000(1Hz〜40MHz)程度まで安定して動作する模様
+ * @param int pdwon パワーダウンビット (W34)
+ * @param int phase コントロール/フェーズ等データ (W32〜W39)
+ *
+ * AD9850へ送信する40bit
+ *  W0〜W31:
+ *    freqにAD9850_FREQ_CONSTを乗算した32bit値
+ *  W32, W33:
+ *    コントロールビット。常に0
+ *  W34:
+ *    1でパワーダウン(通常は0)
+ *  W35〜W39:
+ *    位相オフセット調整値 (11.25度単位)
+ */
+void AD9850::setFrequency(int freq, int pdwon, int phase)
+{
+    int freqParam = (int)((double)freq * AD9850_FREQ_CONST);    // 周波数に対応した32bitデータ(W0〜W31)
+
+    _w_clk = 0;
+    _fu_ud = 0; wait_ms(5);
+    _fu_ud = 1; wait_ms(5);
+    _fu_ud = 0;
+
+    for (int i = 0; i < 32; i++) {
+        int bit = ((freqParam >> i) & 0x01);    // LSBから送信
+        _w_clk = 0;
+        _outBit = bit;
+        wait_ms(0.1);
+        _w_clk = 1; wait_ms(2);
+        _w_clk = 0; wait_ms(2);
+    }
+
+    for (int i = 0; i < 8; i++) {
+        int bit = ((phase >> (7 - i)) & 0x01);
+        _w_clk = 0;
+        _outBit = bit;
+        wait_ms(0.1);
+        _w_clk = 1; wait_ms(2);
+        _w_clk = 0; wait_ms(2);
+    }
+
+    _fu_ud = 0; wait_ms(5);
+    _fu_ud = 1; wait_ms(5);
+    _fu_ud = 0;
+}
+
+//----------------------------------------------------------------
+/*
+
+// mbed HRM1017の場合
+AD9850 dds(P0_20, P0_25, P0_24, P0_23);
+
+int main()
+{
+    int frq = 10 * 1000 * 1000; // 10MHz
+    int phase = 0;
+    
+    dds.setFrequency(frq, phase);
+    while(1) {
+        // 
+    }
+}
+*/
diff -r 000000000000 -r 25d6d7c1a48a AD9850.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AD9850.h	Thu Jun 18 05:23:11 2015 +0000
@@ -0,0 +1,29 @@
+//----------------------------------------------------------------
+//----------------------------------------------------------------
+/**
+ * 中華DDS AD9850のコントロール
+ * 
+ */
+//----------------------------------------------------------------
+//----------------------------------------------------------------
+
+#include "mbed.h"
+
+
+class AD9850 {
+
+public:
+    AD9850(PinName data, PinName w_clk, PinName fu_ud, PinName reset);
+    ~AD9850();
+
+    void init();
+    void reset();
+    void setFrequency(int freq, int pdwon = 0, int phase = 0);
+
+private:
+    DigitalOut  _outBit;
+    DigitalOut  _w_clk;
+    DigitalOut  _fu_ud;
+    DigitalOut  _reset;
+};
+