mbed HRM1017によるAD9850の操作
Dependencies: BLE_API mbed nRF51822
what's this ? / 概要
あとで、ちゃんと書く(とおもう)
detail / 詳細
あとで、ちゃんと書く(とおもう)
BEL command format / BLEコマンドフォーマット
あとで、ちゃんと書く(とおもう)
BLE App for iPhone
iOS用アプリソースコード App source codes for iOS
https://github.com/ohneta/AD9850BLE
pictures / とりあえず写真など
外観
アプリ画面
more ...
Revision 0:cc32f8c167de, committed 2015-06-18
- Comitter:
- ohneta
- Date:
- Thu Jun 18 03:58:23 2015 +0000
- Commit message:
- 1st commit
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AD9850/AD9850.cpp Thu Jun 18 03:58:23 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) { + // + } +} +*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AD9850/AD9850.h Thu Jun 18 03:58:23 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; +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BLE_API.lib Thu Jun 18 03:58:23 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#c4436674db7b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Jun 18 03:58:23 2015 +0000 @@ -0,0 +1,191 @@ +#include "mbed.h" +#include "AD9850.h" +#include "BLEDevice.h" + +#define DEBUG 1 + +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +Ticker ticker; +Serial pc(P0_9, P0_11); +DigitalOut led1(P0_18); +DigitalOut led2(P0_19); +DigitalIn btn1(P0_16); +DigitalIn btn2(P0_17); + +AD9850 dds(P0_20, P0_25, P0_24, P0_23); + +//----------------------------------------------------------------------- + +uint32_t targetFreq = 10 * 1000 * 1000; // 10MHz - default +uint32_t incrementFreq = 100 * 1000; // This is a 100KHz frequency increment + +//----------------------------------------------------------------------- + +BLEDevice ble; + +const static char DEVICE_NAME[] = "DDS-CTRL 0.2"; +static const uint16_t uuid16_list[] = {0xFFFF}; // Custom UUID, FFFF is reserved for development + +// Set Up custom Characteristics +static uint8_t deviceValue = 0; +static uint8_t outputValue = 0; +static uint32_t frequencyValue = 0; + +ReadWriteArrayGattCharacteristic<uint8_t, 1> deviceChar(0xA201, &deviceValue); +ReadWriteArrayGattCharacteristic<uint8_t, 1> outputChar(0xA202, &outputValue); +ReadWriteArrayGattCharacteristic<uint32_t, 1> frequencyChar(0xA203, &frequencyValue); + +// Set up custom service +GattCharacteristic *characteristics[] = { + &deviceChar, + &outputChar, + &frequencyChar, +}; +GattService customService(0xA001, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *)); + + +//----------------------------------------------------------------------- +/** + * + */ + void connectionCallback(Gap::Handle_t Handle_t, + Gap::addr_type_t peerAddrType, const Gap::address_t peerAddr, + Gap::addr_type_t ownAddrType, const Gap::address_t ownAddr, + const Gap::ConnectionParams_t *params) +{ + pc.printf("connectionCallback\n"); +} + +//-------------------------------- +/* + * Restart advertising when phone app disconnects + */ +void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) +{ + pc.printf("disconnectionCallback\n"); + ble.startAdvertising(); +} + +//-------------------------------- +/* + * handle writes to writeCharacteristic + */ +void writeCharCallback(const GattCharacteristicWriteCBParams *params) +{ + led2 = !led2; + + pc.printf("BLE:onDataWritten\n"); + + if (params->charHandle == deviceChar.getValueHandle()) { + memcpy(&deviceChar, params->data, params->len); + pc.printf("deviceChar\n"); + pc.printf("deviceChar: deviceValue: %x\n", deviceValue); + + } else + if (params->charHandle == outputChar.getValueHandle()) { + memcpy(&outputValue, params->data, params->len); + pc.printf("outputChar : outputValue: %x\n", outputValue); + + } else + if (params->charHandle == frequencyChar.getValueHandle()) { + memcpy(&targetFreq, params->data, params->len); + pc.printf("frequencyChar\n"); + pc.printf("targetFreq: %d\n", targetFreq); + } + +} + +//----------------------------------------------------------------------- + +void tickerCallback() +{ + led1 = !led1; +} + +char guruguru(int cnt) +{ + static char gurus[] = {'-', '\\', '|', '/'}; + return gurus[cnt % 4]; +} + +//-------------------------------- + +int main(void) +{ + ticker.attach(&tickerCallback, 0.5); + + pc.baud(115200); + pc.printf("\n"); + pc.printf("------------------------\n"); + pc.printf("DDS-CTRL start\n"); + led1 = 0; led2 = 0;; + + + ble.init(); + ble.onConnection(connectionCallback); + ble.onDisconnection(disconnectionCallback); + ble.onDataWritten(writeCharCallback); + + // setup advertising + { + // BLE only, no classic BT + ble.accumulateAdvertisingPayload( GapAdvertisingData::BREDR_NOT_SUPPORTED | + GapAdvertisingData::LE_GENERAL_DISCOVERABLE ); + // advertising type + ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + // add name + ble.accumulateAdvertisingPayload( GapAdvertisingData::COMPLETE_LOCAL_NAME, + (uint8_t *)DEVICE_NAME, + sizeof(DEVICE_NAME) ); + // UUID's broadcast in advertising packet + ble.accumulateAdvertisingPayload( GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, + (uint8_t *)uuid16_list, + sizeof(uuid16_list) ); + ble.setAdvertisingInterval(100); // interval is 100ms. + // add my service + ble.addService(customService); + + // start advertising + ble.startAdvertising(); + } + pc.printf("BLE init\n"); + + + // DDS 初期化 + { + dds.init(); +pc.printf("\nFREQ: %d [default]\n", targetFreq); + dds.setFrequency(targetFreq, 0, 0); + dds.setFrequency(targetFreq, 0, 0); + // TODO: なぜか最初だけ2回ださないと設定されない... + } + pc.printf("DDS init\n"); + + + int loopCounter = 0; + int lastFreq = targetFreq; + while (true) { + ble.waitForEvent(); + + loopCounter++; + //pc.putc(guruguru(loopCounter)); + //pc.putc('\r'); + pc.putc('*'); + wait_ms(100); + + if (lastFreq != targetFreq) { +pc.printf("\nFREQ: %d\n", targetFreq); + dds.setFrequency(targetFreq, 0, 0); + + //gInternalStorageBuffer.freq = targetFreq; + //nRF51822_internalStorage_write(); + + lastFreq = targetFreq; + } + } + +} + +//--------------------------------------------------------- +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Jun 18 03:58:23 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/7cff1c4259d7 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nRF51822.lib Thu Jun 18 03:58:23 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#d0fc349b9a1b