Professional Documents
Culture Documents
AD9850 Waveform Generator
AD9850 Waveform Generator
1
An interrupt-driven rotary encoder, connected to the ATmega328 interrupt pins ( D2 and D3), adjus
steps. Pushing the rotary encoder's button (connected to D4) resets the frequency to 1 kHz.
The steps are set with a second rotary encoder (not interrupt-driven) connected to ATmega328 pin
them to 1 Hz, 10 Hz, 50 Hz, 100 Hz, 500 Hz, 1 kHz, 2.5 kHz, 5 kHz, 10 kHz, 100 kHz and 500 kH
the step to 1 Hz.
The 1.8" TFT display connects to the ATmega328 pins A1, A0, D13, D12, D11 and D10. D10 to D13
Adafruit library. Pin D9 connects to the display's LED pin via a 100 ohm resistor. D9 is a PWM pin s
desired. I've set it in software to '255' -ie maximum brightness.
There are some very similar 1.8" TFT displays available - the one I used has an ST7735 controller
(and different Adafruit library) and - not provided for in the PCB layout - require 1k series resisto
I've used a 5 volts 1.5A regulator in the power supply section. With a 12v DC input, the regulator
I included a jumpered link in the PCB design so an on/off switch could easily be added.
2
The two rotary encoders are soldered to the small front-panel-mounted PCB with the track side up
of thin insulation under them.
PCB Layout
Download Circuit Wizard PCB Layout.
Construction
3
4
Main Components
1.8" TFT Display Module (ST7735 Controller)
50x130x100mm enclosure
5
AD9850 DDS Module
Arduino Libraries:
Adafruit_GFX Library
Adafruit_ST7735 Library
Rotary Encoder Library
/* Based on AD9851 code from Andrew Smallbone - modified for AD9850
http://www.rocketnumbernine.com/2011/10/25/programming-the-ad9851-dds-synthesizer
*/
int TFT_LED = 9;
#define TFT_SCLK 13 // 1.8" TFT Display.
#define TFT_MOSI 11 //
#define TFT_CS 10
#define TFT_RST A1
#define TFT_DC A0
#define AD9850_CLOCK 125000000 // Module crystal frequency. Tweak here for accur
char* stepText[11] = {" 1 Hz", " 10 Hz", " 50 Hz", "100 Hz", "500 Hz", " 1 kHz", "2.5
" 5 kHz", " 10 kHz", "100 kHz", "500 kHz"};
int stepPointer = 0;
unsigned long incr = 0;
String units = stepText[stepPointer];
// transfers a byte, a bit at a time, LSB first to the 9850 via serial DATA line
void tfr_byte(byte data) {
for (int i = 0; i < 8; i++, data >>= 1) {
digitalWrite(DATA, data & 0x01);
6
pulseHigh(W_CLK); //after each bit sent, CLK is pulsed high
}
}
void setup() {
tft.setRotation(3);
tft.setTextWrap(false); // Allow text to run off right edge
tft.fillScreen(ST7735_BLACK);
void getStep() {
switch(stepPointer) {
case 0: incr = 1; break;
case 1: incr = 10; break;
case 2: incr = 50; break;
case 3: incr = 100; break;
7
case 4: incr = 500; break;
case 5: incr = 1000; break;
case 6: incr = 2500; 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];
tft.setTextColor(ST7735_YELLOW);
tft.setCursor(10, 20);
tft.setTextSize(1);
tft.print("Step: ");
tft.setTextSize(2);
tft.setCursor(60, 15);
tft.print(units);
void loop() {
// Check 'Step' rotary encoder.
unsigned char result = i.process();
8
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;
sendFrequency(freq);
updateDisplay();
delay(350);
}
if (freqOld != freq) {
sendFrequency(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) >= 10) freq -= incr;
}
if (freq <= 10) freq = 10;
if (freq >=10000000) freq = 10000000;
}
}