bit-banging control for AD9850.

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

Revision:
0:25d6d7c1a48a
--- /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) {
+        // 
+    }
+}
+*/