Created
October 8, 2016 23:07
-
-
Save weldtype/47ebc8ebd9700782b1d1ea2e28003646 to your computer and use it in GitHub Desktop.
AD9850Sinewave generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//AD9850 sinewave generator | |
// edy | |
// | |
//2016/10/06 First version(ver 0.1) | |
// | |
//2016/10/08 ver 0.2 | |
// 周波数下限を 10Hz から 1Hz へ変更。 | |
// 変数 freq,freqOld,incr を負号なしから負号ありへ。引き算によるエラー回避のため。 | |
// 周波数ステップ 2.5KHz を 2KHz へ変更。 | |
// 周波数表示を3桁区切りにする。 | |
//参考にしたweb page | |
// http://www.vwlowen.co.uk/arduino/AD9850-waveform-generator/AD9850-waveform-generator.htm | |
/* Based on AD9851 code from Andrew Smallbone - modified for AD9850 | |
http://www.rocketnumbernine.com/2011/10/25/programming-the-ad9851-dds-synthesizer | |
*/ | |
#include <Rotary.h> // Rotary encoder: https://github.com/brianlow/Rotary | |
#include <LiquidCrystal.h> | |
//LiquidCrystal(rs, enable, d4, d5, d6, d7) | |
LiquidCrystal lcd(7, 6, 8, 9, 10, 11); | |
#include <EF_AD9850.h> | |
// EF_AD9850(CLK,FQ_UP,RESET,DATA) | |
EF_AD9850 AD9850(5, 4, A3, A4); | |
#define stepPin1 A0 // Set 'Step' rotary encoder pins | |
#define stepPin2 A1 | |
int forceHzStep = A2; // 'Step' rotary encoder's push button - Set 1 Hz steps. | |
int forcekHz = A5; // Interrupt-driven encoder's push button - force 1kHz freq. | |
Rotary i = Rotary(stepPin1, stepPin2); // Rotart encoder for setting increment. | |
Rotary r = Rotary(2, 3); // Rotary encoder for frequency connects to interrupt pins | |
//long unsigned int freq = 1000; // Set initial frequency. | |
long freq = 1000; | |
//long unsigned int freqOld = freq; | |
long freqOld = freq; | |
char disp_buf[16]; | |
char* stepText[11] = {" 1Hz", | |
" 10Hz", | |
" 50Hz", | |
" 100Hz", | |
" 500Hz", | |
" 1KHz", | |
" 2KHz", | |
" 5KHz", | |
" 10KHz", | |
" 100KHz", | |
" 500KHz" | |
}; | |
int stepPointer = 0; | |
long incr = 0; | |
String units = stepText[stepPointer]; | |
void setup() { | |
pinMode(2, INPUT_PULLUP); // Pins for interrupt-driven rotary encoder and push buttons | |
pinMode(3, INPUT_PULLUP); | |
pinMode(forceHzStep, INPUT_PULLUP); | |
pinMode(forcekHz, INPUT_PULLUP); | |
// Configure interrupt and enable for rotary encoder. | |
PCICR |= (1 << PCIE2); | |
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19); | |
sei(); | |
lcd.begin( 16, 2 ); // 16文字×2行 | |
lcd.clear(); // LCD画面消去 | |
lcd.setCursor( 0, 0 ); | |
lcd.print( "AD9850" ); | |
lcd.setCursor( 0, 1 ); | |
lcd.print( "sinewave generator" ); | |
delay(1000); | |
lcd.clear(); | |
// Initialise the AD9850 module. | |
AD9850.init(); | |
AD9850.reset(); | |
AD9850.wr_serial(0x00, freq); | |
updateDisplay(); | |
} | |
void getStep() { | |
switch (stepPointer) { | |
case 0: incr = 1; break; | |
case 1: incr = 10; break; | |
case 2: incr = 50; break; | |
case 3: incr = 100; break; | |
case 4: incr = 500; break; | |
case 5: incr = 1000; break; | |
case 6: incr = 2000; break; | |
case 7: incr = 5000; break; | |
case 8: incr = 10000; break; | |
case 9: incr = 100000; break; | |
case 10: 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() { | |
// Check 'Step' rotary encoder. | |
unsigned char result = i.process(); | |
if (result) { | |
if (result == DIR_CW) { | |
if (stepPointer < 10) stepPointer++; | |
} | |
if (result == DIR_CCW) { | |
if (stepPointer > 0) stepPointer--; | |
} | |
updateDisplay(); | |
} | |
if (digitalRead(forceHzStep) == LOW) { | |
stepPointer = 0; | |
updateDisplay(); | |
delay(50); | |
} | |
if (digitalRead(forcekHz) == LOW) { | |
freq = 1000; | |
AD9850.wr_serial(0x00, freq); | |
updateDisplay(); | |
delay(350); | |
} | |
if (freqOld != freq) { | |
AD9850.wr_serial(0x00, freq); | |
updateDisplay(); | |
freqOld = freq; | |
} | |
} | |
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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment