bit-banging control for AD9850.

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

AD9850.cpp

Committer:
ohneta
Date:
2015-06-18
Revision:
0:25d6d7c1a48a

File content as of revision 0:25d6d7c1a48a:

//----------------------------------------------------------------
/**
 * 中華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) {
        // 
    }
}
*/