bit-banging control for AD9850.

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

Committer:
ohneta
Date:
Thu Jun 18 05:23:11 2015 +0000
Revision:
0:25d6d7c1a48a
1st commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ohneta 0:25d6d7c1a48a 1 //----------------------------------------------------------------
ohneta 0:25d6d7c1a48a 2 /**
ohneta 0:25d6d7c1a48a 3 * 中華DDS AD9850のコントロール
ohneta 0:25d6d7c1a48a 4 *
ohneta 0:25d6d7c1a48a 5 * mbed LPC1768では SPIを操作することで40bitの出力ができるが、
ohneta 0:25d6d7c1a48a 6 * mbed HRM1017等ではSPIの動作が違うためソフトウェアでシリアルデータを出力する
ohneta 0:25d6d7c1a48a 7 *
ohneta 0:25d6d7c1a48a 8 * 参考資料
ohneta 0:25d6d7c1a48a 9 * AD9850データシート
ohneta 0:25d6d7c1a48a 10 * http://www.analog.com/static/imported-files/data_sheets/AD9850.pdf
ohneta 0:25d6d7c1a48a 11 * mbed LPC1768 SPIでの実装例
ohneta 0:25d6d7c1a48a 12 * http://developer.mbed.org/users/liamg/code/AD9850-function-generator-SPI-driver/
ohneta 0:25d6d7c1a48a 13 */
ohneta 0:25d6d7c1a48a 14 //----------------------------------------------------------------
ohneta 0:25d6d7c1a48a 15
ohneta 0:25d6d7c1a48a 16 #include "AD9850.h"
ohneta 0:25d6d7c1a48a 17
ohneta 0:25d6d7c1a48a 18 #define AD9850_FREQ_CONST 34.359738368
ohneta 0:25d6d7c1a48a 19 /*
ohneta 0:25d6d7c1a48a 20 * AD9850/clock=125MHz
ohneta 0:25d6d7c1a48a 21 * 2の32乗=4294967296、DDSクロック==125MHzを前提とすると...
ohneta 0:25d6d7c1a48a 22 * 1Hz設定時の値 = 4294967296/125000000 = 34.359738368 となる
ohneta 0:25d6d7c1a48a 23 */
ohneta 0:25d6d7c1a48a 24
ohneta 0:25d6d7c1a48a 25 //----------------------------------------------------------------
ohneta 0:25d6d7c1a48a 26 /**
ohneta 0:25d6d7c1a48a 27 * コンストラクタ
ohneta 0:25d6d7c1a48a 28 *
ohneta 0:25d6d7c1a48a 29 * @param PinName data データ転送ピン
ohneta 0:25d6d7c1a48a 30 * @param PinName w_clk クロックピン
ohneta 0:25d6d7c1a48a 31 * @param PinName fu_ud モジュール選択
ohneta 0:25d6d7c1a48a 32 * @param PinName reset リセット
ohneta 0:25d6d7c1a48a 33 */
ohneta 0:25d6d7c1a48a 34 AD9850::AD9850(PinName data, PinName w_clk, PinName fu_ud, PinName reset)
ohneta 0:25d6d7c1a48a 35 : _outBit(data), _w_clk(w_clk), _fu_ud(fu_ud), _reset(reset)
ohneta 0:25d6d7c1a48a 36 {
ohneta 0:25d6d7c1a48a 37 init();
ohneta 0:25d6d7c1a48a 38 }
ohneta 0:25d6d7c1a48a 39
ohneta 0:25d6d7c1a48a 40 //----------------------------------------------------------------
ohneta 0:25d6d7c1a48a 41 /**
ohneta 0:25d6d7c1a48a 42 * デストラクタ
ohneta 0:25d6d7c1a48a 43 */
ohneta 0:25d6d7c1a48a 44 AD9850::~AD9850()
ohneta 0:25d6d7c1a48a 45 {
ohneta 0:25d6d7c1a48a 46 }
ohneta 0:25d6d7c1a48a 47
ohneta 0:25d6d7c1a48a 48 //----------------------------------------------------------------
ohneta 0:25d6d7c1a48a 49 /**
ohneta 0:25d6d7c1a48a 50 * 初期化
ohneta 0:25d6d7c1a48a 51 */
ohneta 0:25d6d7c1a48a 52 void AD9850::init()
ohneta 0:25d6d7c1a48a 53 {
ohneta 0:25d6d7c1a48a 54 reset();
ohneta 0:25d6d7c1a48a 55 }
ohneta 0:25d6d7c1a48a 56
ohneta 0:25d6d7c1a48a 57 //----------------------------------------------------------------
ohneta 0:25d6d7c1a48a 58 /**
ohneta 0:25d6d7c1a48a 59 * リセット
ohneta 0:25d6d7c1a48a 60 */
ohneta 0:25d6d7c1a48a 61 void AD9850::reset()
ohneta 0:25d6d7c1a48a 62 {
ohneta 0:25d6d7c1a48a 63 _reset = 0; wait_ms(5);
ohneta 0:25d6d7c1a48a 64 _reset = 1; wait_ms(5);
ohneta 0:25d6d7c1a48a 65 _reset = 0; wait_ms(5);
ohneta 0:25d6d7c1a48a 66 }
ohneta 0:25d6d7c1a48a 67
ohneta 0:25d6d7c1a48a 68 //----------------------------------------------------------------
ohneta 0:25d6d7c1a48a 69 /**
ohneta 0:25d6d7c1a48a 70 * 周波数設定
ohneta 0:25d6d7c1a48a 71 *
ohneta 0:25d6d7c1a48a 72 * @param int freq 設定する周波数(Hz)
ohneta 0:25d6d7c1a48a 73 * AD9850ボードに依存するがクロック125MHzで概ね 1〜40000000(1Hz〜40MHz)程度まで安定して動作する模様
ohneta 0:25d6d7c1a48a 74 * @param int pdwon パワーダウンビット (W34)
ohneta 0:25d6d7c1a48a 75 * @param int phase コントロール/フェーズ等データ (W32〜W39)
ohneta 0:25d6d7c1a48a 76 *
ohneta 0:25d6d7c1a48a 77 * AD9850へ送信する40bit
ohneta 0:25d6d7c1a48a 78 * W0〜W31:
ohneta 0:25d6d7c1a48a 79 * freqにAD9850_FREQ_CONSTを乗算した32bit値
ohneta 0:25d6d7c1a48a 80 * W32, W33:
ohneta 0:25d6d7c1a48a 81 * コントロールビット。常に0
ohneta 0:25d6d7c1a48a 82 * W34:
ohneta 0:25d6d7c1a48a 83 * 1でパワーダウン(通常は0)
ohneta 0:25d6d7c1a48a 84 * W35〜W39:
ohneta 0:25d6d7c1a48a 85 * 位相オフセット調整値 (11.25度単位)
ohneta 0:25d6d7c1a48a 86 */
ohneta 0:25d6d7c1a48a 87 void AD9850::setFrequency(int freq, int pdwon, int phase)
ohneta 0:25d6d7c1a48a 88 {
ohneta 0:25d6d7c1a48a 89 int freqParam = (int)((double)freq * AD9850_FREQ_CONST); // 周波数に対応した32bitデータ(W0〜W31)
ohneta 0:25d6d7c1a48a 90
ohneta 0:25d6d7c1a48a 91 _w_clk = 0;
ohneta 0:25d6d7c1a48a 92 _fu_ud = 0; wait_ms(5);
ohneta 0:25d6d7c1a48a 93 _fu_ud = 1; wait_ms(5);
ohneta 0:25d6d7c1a48a 94 _fu_ud = 0;
ohneta 0:25d6d7c1a48a 95
ohneta 0:25d6d7c1a48a 96 for (int i = 0; i < 32; i++) {
ohneta 0:25d6d7c1a48a 97 int bit = ((freqParam >> i) & 0x01); // LSBから送信
ohneta 0:25d6d7c1a48a 98 _w_clk = 0;
ohneta 0:25d6d7c1a48a 99 _outBit = bit;
ohneta 0:25d6d7c1a48a 100 wait_ms(0.1);
ohneta 0:25d6d7c1a48a 101 _w_clk = 1; wait_ms(2);
ohneta 0:25d6d7c1a48a 102 _w_clk = 0; wait_ms(2);
ohneta 0:25d6d7c1a48a 103 }
ohneta 0:25d6d7c1a48a 104
ohneta 0:25d6d7c1a48a 105 for (int i = 0; i < 8; i++) {
ohneta 0:25d6d7c1a48a 106 int bit = ((phase >> (7 - i)) & 0x01);
ohneta 0:25d6d7c1a48a 107 _w_clk = 0;
ohneta 0:25d6d7c1a48a 108 _outBit = bit;
ohneta 0:25d6d7c1a48a 109 wait_ms(0.1);
ohneta 0:25d6d7c1a48a 110 _w_clk = 1; wait_ms(2);
ohneta 0:25d6d7c1a48a 111 _w_clk = 0; wait_ms(2);
ohneta 0:25d6d7c1a48a 112 }
ohneta 0:25d6d7c1a48a 113
ohneta 0:25d6d7c1a48a 114 _fu_ud = 0; wait_ms(5);
ohneta 0:25d6d7c1a48a 115 _fu_ud = 1; wait_ms(5);
ohneta 0:25d6d7c1a48a 116 _fu_ud = 0;
ohneta 0:25d6d7c1a48a 117 }
ohneta 0:25d6d7c1a48a 118
ohneta 0:25d6d7c1a48a 119 //----------------------------------------------------------------
ohneta 0:25d6d7c1a48a 120 /*
ohneta 0:25d6d7c1a48a 121
ohneta 0:25d6d7c1a48a 122 // mbed HRM1017の場合
ohneta 0:25d6d7c1a48a 123 AD9850 dds(P0_20, P0_25, P0_24, P0_23);
ohneta 0:25d6d7c1a48a 124
ohneta 0:25d6d7c1a48a 125 int main()
ohneta 0:25d6d7c1a48a 126 {
ohneta 0:25d6d7c1a48a 127 int frq = 10 * 1000 * 1000; // 10MHz
ohneta 0:25d6d7c1a48a 128 int phase = 0;
ohneta 0:25d6d7c1a48a 129
ohneta 0:25d6d7c1a48a 130 dds.setFrequency(frq, phase);
ohneta 0:25d6d7c1a48a 131 while(1) {
ohneta 0:25d6d7c1a48a 132 //
ohneta 0:25d6d7c1a48a 133 }
ohneta 0:25d6d7c1a48a 134 }
ohneta 0:25d6d7c1a48a 135 */