迷走の果て・Tiny Objects

迷走する日々の覚え書きです。自分で分かってることは省略してますので、念のため。

AD9833 DDSモジュールを試す(1)

アマゾンでAD9833DDSモジュールを買ってしまいました。
10月14日に発送通知があり、26日に到着しました。

商品の説明には
「オンボードの高速は300Mアンプと、低域通過フィルタリングされています。 」
とありますが、そんな部品は見当たりません。
ちゃんとしたした説明をつけてほしいものですが、これがチャイナクオリティでしょうか。
AD9833module表

先のAD9850DDSモジュールを使った記事で参考にしたサイトを書いた人が、AD9833 Waveform Generatorという記事を書かれていたので、これまた参考にしました。

回路図です、先のAD9850 Sinewave Generatorと同じく、表示にはI2C接続LCDを使いました。
AD9833DDS_ schematic

1MHz正弦波出力です。DDSモジュールのクロックである25MHzがのっかってます。LPFをつけるつもりです。
AD9833DDS1MHz.jpg
スケッチです、ちょっと問題があります。動作を優先させたためです。
次の休みにゆっくり見直します。


//AD9833 Signal  generator
// edy
//2016/10/25 First version(ver 0.1)
//
//参考にしたweb page
//AD9833 Waveform Generator
//http://www.vwlowen.co.uk/arduino/AD9833-waveform-generator/AD9833-waveform-generator.htm


// PCF8574を使ったI2C接続モジュールを使う
// https://www.amazon.co.jp/dp/B010Q000V2/
// arduino用ライブラリ
// https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library
//

#include <Rotary.h>            //  Rotary encoder: https://github.com/brianlow/Rotary
#include <SPI.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);

const int SINE = 0x2000;                    // Define AD9833's waveform register value.
const int SQUARE = 0x2020;                  // When we update the frequency, we need to
const int TRIANGLE = 0x2002;                // define the waveform when we end writing.

int wave = 0;
int waveType = SINE;
int wavePin = 7;
int freqUpPin = 2;                          // Define rotary encoder pins.
int freqDownPin = 3;
int stepUpPin = 5;
int stepDownPin = 6;

const float refFreq = 25000000.0;           // On-board crystal reference frequency

const int FSYNC = 10;                       // Standard SPI pins for the AD9833 waveform generator.
const int CLK = 13;                         // CLK and DATA pins are shared with the TFT display.
const int DATA = 11;

Rotary r = Rotary(freqUpPin, freqDownPin);    // Rotary encoder for frequency connects to interrupt pins
Rotary i = Rotary(stepUpPin, stepDownPin);    // Rotart encoder for setting increment.

long freq = 10000;               // Set initial frequency.
long freqOld = freq;

long incr = 1000;
long oldIncr = 1000;
char disp_buf[16];

char* stepText[18] = {
 "       1Hz",
 "       2Hz",
 "       5Hz",
 "      10Hz",
 "      20Hz",
 "      50Hz",
 "     100Hz",
 "     200Hz",
 "     500Hz",
 "   1,000Hz",
 "   2,000Hz",
 "   5,000Hz",
 "  10,000Hz",
 "  20,000Hz",
 "  50,000Hz",
 " 100,000Hz",
 " 200,000Hz",
 " 500,000Hz"
};

int stepPointer = 5;
//long  incr = 0;
String units = stepText[stepPointer];

void setup() {

 pinMode(freqUpPin, INPUT_PULLUP);      // Set pins for rotary encoders as INPUTS and enable
 pinMode(freqDownPin, INPUT_PULLUP);    // internal pullup resistors.
 pinMode(stepUpPin, INPUT_PULLUP);
 pinMode(stepDownPin, INPUT_PULLUP);
 pinMode(wavePin, INPUT_PULLUP);

 // Configure interrupt and enable for rotary encoder.
 PCICR |= (1 << PCIE2);
 PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
 sei();
 SPI.begin();
 delay(50);

 lcd.begin();
 lcd.clear();  // LCD画面消去
 lcd.setCursor( 0, 0 );
 lcd.print( "AD9833" );
 lcd.setCursor( 0, 1 );
 lcd.print( "Signal Generator" );
 delay(1000);
 lcd.clear();

 AD9833reset();                                   // Reset AD9833 module after power-up.
 delay(50);
 AD9833setFrequency(freq, SINE);                  // Set the frequency and Sine Wave output
 updateDisplay();
}

void getStep() {
 switch (stepPointer) {
   case 0:  incr = 1; break;
   case 1:  incr = 2; break;
   case 2:  incr = 5; break;
   case 3:  incr = 10; break;
   case 4:  incr = 20; break;
   case 5:  incr = 50; break;
   case 6:  incr = 100; break;
   case 7:  incr = 200; break;
   case 8:  incr = 500; break;
   case 9:  incr = 1000; break;
   case 10: incr = 2000; break;
   case 11: incr = 5000; break;
   case 12: incr = 10000; break;
   case 13: incr = 20000; break;
   case 14: incr = 50000; break;
   case 15: incr = 100000; break;
   case 16: incr = 200000; break;
   case 17: incr = 500000; break;
 }
}

void updateDisplay() {
 getStep();
 units = stepText[stepPointer];
 //lcd.clear();
 lcd.setCursor( 0, 0 );
 lcd.print( "STEP: " );
 lcd.print(units );

 lcd.setCursor( 0, 1 );
 lcd.print("FRQ:");
 if (freq < 1000) {
   sprintf(disp_buf, "%10ld", freq);
 }
 else if (freq < 1000000) {
   int freqL = freq % 1000;
   int freqM = freq / 1000;
   sprintf(disp_buf, "%6d,%03d", freqM, freqL);
 }
 else {
   int freqL = freq  % 1000;
   int freqM = (freq / 1000) % 1000;
   int freqH = freq / 1000000;
   sprintf(disp_buf, "%2d,%03d,%03d", freqH, freqM, freqL);
 }
 lcd.print(disp_buf);
 lcd.print("Hz");
}

void loop() {

 if (oldIncr != incr) {
   updateDisplay();
   oldIncr = incr;
 }

 // Check 'increment' rotary encoder. Increase or decrease 'increment' by a factor of x10
 // if encoder has been turned.
 unsigned char result = i.process();
 if (result) {
   if (result == DIR_CW)  {
     stepPointer++;
     if (stepPointer > 17) stepPointer = 0;
   }
   if (result == DIR_CCW) {
     stepPointer--;
     if (stepPointer < 0) stepPointer = 17;
   }
   updateDisplay();
 }

 // Check if push button on 'increment' rotary encoder is pushed and set Wave Type accordingly.
 if (digitalRead(wavePin) == LOW) {
   wave += 1;
   if (wave > 2) wave = 0;
   switch (wave) {
     case 0: waveType = SINE; break;
     case 1: waveType = SQUARE; break;
     case 2: waveType = TRIANGLE; break;
   }
   AD9833setFrequency(freq, waveType);     // Set AD9833 to frequency and selected wave type.
   updateDisplay();
   delay(200);
 }

 if (freq != freqOld) {                    // If frequency has changed, interrupt rotary encoder
   AD9833setFrequency(freq, waveType);     // must have been turned so update AD9833 and display.
   updateDisplay();
   freqOld = freq;                         // Remember new frequency to avoid unwanted display
 }                                         // and AD9833 updates.
}

// AD9833 documentation advises a 'Reset' on first applying power.
void AD9833reset() {
 WriteRegister(0x100);   // Write '1' to AD9833 Control register bit D8.
 delay(10);
}

// Set the frequency and waveform registers in the AD9833.
void AD9833setFrequency(long frequency, int Waveform) {

 long FreqWord = (frequency * pow(2, 28)) / refFreq;

 int MSB = (int)((FreqWord & 0xFFFC000) >> 14);    //Only lower 14 bits are used for data
 int LSB = (int)(FreqWord & 0x3FFF);

 //Set control bits 15 ande 14 to 0 and 1, respectively, for frequency register 0
 LSB |= 0x4000;
 MSB |= 0x4000;

 WriteRegister(0x2100);
 WriteRegister(LSB);                  // Write lower 16 bits to AD9833 registers
 WriteRegister(MSB);                  // Write upper 16 bits to AD9833 registers.
 WriteRegister(0xC000);               // Phase register
 WriteRegister(Waveform);             // Exit & Reset to SINE, SQUARE or TRIANGLE

}
void WriteRegister(int dat) {

 // Display and AD9833 use different SPI MODES so it has to be set for the AD9833 here.
 SPI.setDataMode(SPI_MODE2);

 digitalWrite(FSYNC, LOW);           // Set FSYNC low before writing to AD9833 registers
 delayMicroseconds(10);              // Give AD9833 time to get ready to receive data.

 SPI.transfer(highByte(dat));        // Each AD9833 register is 32 bits wide and each 16
 SPI.transfer(lowByte(dat));         // bits has to be transferred as 2 x 8-bit bytes.

 digitalWrite(FSYNC, HIGH);          //Write done. Set FSYNC high
}

// Interrupt service routine for the 'frequency' rotary encoder.

ISR(PCINT2_vect) {
 unsigned char result = r.process();
 if (result) {
   if (result == DIR_CW) {
     if ((freq + incr) <= 10000000) freq += incr;
   } else {
     if ((freq - incr) >= 1) freq -= incr;
   }
   if (freq <= 1)  freq = 1;
   if (freq >= 10000000) freq = 10000000;
 }
}

関連記事
スポンサーサイト

コメント

コメントの投稿

管理者にだけ表示を許可する

トラックバック

この記事へのトラックバックURL
http://edycube.blog.fc2.com/tb.php/933-3fe79703

 | HOME | 

文字サイズの変更

プロフィール

edy

最新記事一覧(サムネイル画像付き)

AC電力計(2) Nov 19, 2017
クリスマス電飾(2) Nov 12, 2017
クリスマス電飾(1) Nov 12, 2017
AC電力計(1) Nov 04, 2017
micro:bit(2)Arduino IDEで使う。 Oct 29, 2017
micro:bit(1) Oct 29, 2017
ブリッジドT発振回路(3)光るランプ Oct 16, 2017
ダイソーのかぼちゃで電飾 Oct 08, 2017
ブリッジドT発振回路(2)オペアンプとっかえひっかえ Oct 07, 2017
ブリッジドT発振回路(1) Oct 02, 2017

全記事表示リンク

全ての記事を表示する

リンク

このブログをリンクに追加する

月別アーカイブ

11  10  09  08  07  06  05  04  03  02  01  12  11  10  09  08  07  06  05  04  03  02  01  12  11  10  09  08  07  06  05  04  03  02  01  12  11  10  09  08  07  06  05  04  03  02  12  11  10  09  07  05  04  03  04  03  01  12  11  10  08  07  06  05  03  02  01  12  11  10  09  08  07  06  05  04  03  02  01  12  11  10  09  08  07  06  05  04  02  01  12  10  09  08  07  06  05  04  03  02  01  12  11  10  09  08  07  06  05  03  02  01  12  11  10  09  08  07  06  05  04  03  02  01  12  10  09  08  07  06  05  04  03  02  01 

カテゴリ

プログラミング (0)
freescale (1)
AVR (3)
テルミン (16)
緊急警報放送 (3)
78K (1)
PSoC (295)
地上デジタル放送 (2)
電子工作 (426)
HX711 (2)
ACS712 (6)
数学 (6)
パソコン (12)
PLC (14)
未分類 (39)
ブログ関係 (20)
スカイプ (37)
ロボット (1)
LTSpice (8)
OCXO (0)
arduino (32)
maxima (1)
フランクリン発振回路 (3)
GPS (3)
DTMF (1)
Linux (1)
KOMAINO (7)

タグリスト

最近のコメント

最近のトラックバック

メールフォーム

名前:
メール:
件名:
本文:

検索フォーム

アクセス

RSSリンクの表示

ブログリンク

FC2Ad

まとめ

Template by たけやん