bit-banging control for AD9850.
こちらのnoteに書いてます。
/users/ohneta/notebook/DDS-AS9850_softSPI/
Diff: AD9850.cpp
- 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) { + // + } +} +*/