A sine wave generator using AD9833 and AD9850 using STM32F103RB

Dependencies:   mbed

This is a sine wave generator using DDS IC' AD9833 and AD9850. The STM32F1 microcontroller produces the SPI commands for the two DDS.

Learn more about STM32F1 in my blog: https://www.teachmemicro.com

Committer:
roland_tmm
Date:
Tue Nov 21 11:24:25 2017 +0000
Revision:
0:6069c0f2a245
Child:
1:9dcccb399f0b
Version 1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
roland_tmm 0:6069c0f2a245 1 /******************************************************************************************************************
roland_tmm 0:6069c0f2a245 2 * STM32F103 library for AD9850
roland_tmm 0:6069c0f2a245 3 * Created 11/21/2017
roland_tmm 0:6069c0f2a245 4 * Roland Pelayo
roland_tmm 0:6069c0f2a245 5 *
roland_tmm 0:6069c0f2a245 6 * Use this library freely
roland_tmm 0:6069c0f2a245 7 *
roland_tmm 0:6069c0f2a245 8 * Hardware connections :
roland_tmm 0:6069c0f2a245 9 * W_CLK -> any pin
roland_tmm 0:6069c0f2a245 10 * FQ_UD -> any pin
roland_tmm 0:6069c0f2a245 11 * DATA/D7 -> any pin
roland_tmm 0:6069c0f2a245 12 * RESET -> any pin
roland_tmm 0:6069c0f2a245 13 *
roland_tmm 0:6069c0f2a245 14 * Functions :
roland_tmm 0:6069c0f2a245 15 * dds.begin(W_CLK pin, FQ_UD pin, DATA pin, RESET pin); Initialize the output pins and master reset the AD9850
roland_tmm 0:6069c0f2a245 16 * dds.calibrate(frequency); Compensation of crystal oscillator frequency
roland_tmm 0:6069c0f2a245 17 * dds.setfreq(frequency,phase); frequency in Hz, phase coded on 5 bits
roland_tmm 0:6069c0f2a245 18 * dds.down(); power down mode reducing the dissipated power from 380mW to 30mW @5V
roland_tmm 0:6069c0f2a245 19 * dds.up(); wake-up the AD9850
roland_tmm 0:6069c0f2a245 20 *
roland_tmm 0:6069c0f2a245 21 * AD9850 datasheet at http://www.analog.com/static/imported-files/data_sheets/AD9850.pdf
roland_tmm 0:6069c0f2a245 22 *
roland_tmm 0:6069c0f2a245 23 *****************************************************************************************************************/
roland_tmm 0:6069c0f2a245 24
roland_tmm 0:6069c0f2a245 25 #include "AD9850.h"
roland_tmm 0:6069c0f2a245 26 #include "mbed.h"
roland_tmm 0:6069c0f2a245 27
roland_tmm 0:6069c0f2a245 28 #define W_CLK PB_10
roland_tmm 0:6069c0f2a245 29 #define FQ_UD PB_11
roland_tmm 0:6069c0f2a245 30 #define DATA PB_1
roland_tmm 0:6069c0f2a245 31 #define RESET PB_0
roland_tmm 0:6069c0f2a245 32
roland_tmm 0:6069c0f2a245 33 #define REVERSE_BITS(byte) (((reverse_lookup[(byte & 0x0F)]) << 4) + reverse_lookup[((byte & 0xF0) >> 4)])
roland_tmm 0:6069c0f2a245 34
roland_tmm 0:6069c0f2a245 35 static const uint8_t reverse_lookup[] = { 0, 8, 4, 12, 2, 10, 6, 14,1, 9, 5, 13,3, 11, 7, 15 };
roland_tmm 0:6069c0f2a245 36
roland_tmm 0:6069c0f2a245 37 SPI SPI_dev2(DATA, PB_8, W_CLK);
roland_tmm 0:6069c0f2a245 38
roland_tmm 0:6069c0f2a245 39 DigitalOut wclk(W_CLK);
roland_tmm 0:6069c0f2a245 40 DigitalOut fq_ud(FQ_UD);
roland_tmm 0:6069c0f2a245 41 DigitalOut dat(DATA);
roland_tmm 0:6069c0f2a245 42 DigitalOut res(RESET);
roland_tmm 0:6069c0f2a245 43
roland_tmm 0:6069c0f2a245 44 AD9850::AD9850() {
roland_tmm 0:6069c0f2a245 45
roland_tmm 0:6069c0f2a245 46 }
roland_tmm 0:6069c0f2a245 47
roland_tmm 0:6069c0f2a245 48 void AD9850::Begin() {
roland_tmm 0:6069c0f2a245 49 SPI_dev2.format(8,0);
roland_tmm 0:6069c0f2a245 50 deltaphase = 0;
roland_tmm 0:6069c0f2a245 51 phase = 0;
roland_tmm 0:6069c0f2a245 52 calibFreq = 125000000;
roland_tmm 0:6069c0f2a245 53 begin_priv();
roland_tmm 0:6069c0f2a245 54 }
roland_tmm 0:6069c0f2a245 55
roland_tmm 0:6069c0f2a245 56 void AD9850::begin_priv() {
roland_tmm 0:6069c0f2a245 57
roland_tmm 0:6069c0f2a245 58 res = 1;
roland_tmm 0:6069c0f2a245 59 wait(0.001);
roland_tmm 0:6069c0f2a245 60 res = 0;
roland_tmm 0:6069c0f2a245 61
roland_tmm 0:6069c0f2a245 62 wclk = 1;
roland_tmm 0:6069c0f2a245 63 wait(0.001);
roland_tmm 0:6069c0f2a245 64 wclk = 0;
roland_tmm 0:6069c0f2a245 65
roland_tmm 0:6069c0f2a245 66 fq_ud = 1;
roland_tmm 0:6069c0f2a245 67 wait(0.001);
roland_tmm 0:6069c0f2a245 68 fq_ud = 0;
roland_tmm 0:6069c0f2a245 69
roland_tmm 0:6069c0f2a245 70 }
roland_tmm 0:6069c0f2a245 71
roland_tmm 0:6069c0f2a245 72 void AD9850::update() {
roland_tmm 0:6069c0f2a245 73 uint32_t d,p;
roland_tmm 0:6069c0f2a245 74 for (int i=0; i<4; i++, deltaphase>>=8) {
roland_tmm 0:6069c0f2a245 75 d = REVERSE_BITS(deltaphase);
roland_tmm 0:6069c0f2a245 76 SPI_dev2.write(d & 0xFF);
roland_tmm 0:6069c0f2a245 77 // shiftOut(DATA, W_CLK, LSBFIRST, deltaphase & 0xFF);
roland_tmm 0:6069c0f2a245 78 }
roland_tmm 0:6069c0f2a245 79 p = REVERSE_BITS(phase);
roland_tmm 0:6069c0f2a245 80 SPI_dev2.write(p & 0xFF);
roland_tmm 0:6069c0f2a245 81 //shiftOut(DATA, W_CLK, LSBFIRST, phase & 0xFF);
roland_tmm 0:6069c0f2a245 82 fq_ud = 1;
roland_tmm 0:6069c0f2a245 83 wait(0.001);
roland_tmm 0:6069c0f2a245 84 fq_ud = 0;
roland_tmm 0:6069c0f2a245 85 }
roland_tmm 0:6069c0f2a245 86
roland_tmm 0:6069c0f2a245 87
roland_tmm 0:6069c0f2a245 88 void AD9850::SetDDSFrequency(double f, uint8_t p) {
roland_tmm 0:6069c0f2a245 89 deltaphase = f * 4294967296.0 / calibFreq;
roland_tmm 0:6069c0f2a245 90 phase = p << 3;
roland_tmm 0:6069c0f2a245 91 update();
roland_tmm 0:6069c0f2a245 92 }
roland_tmm 0:6069c0f2a245 93
roland_tmm 0:6069c0f2a245 94
roland_tmm 0:6069c0f2a245 95 void AD9850::down() {
roland_tmm 0:6069c0f2a245 96 fq_ud = 1;
roland_tmm 0:6069c0f2a245 97 wait(0.001);
roland_tmm 0:6069c0f2a245 98 fq_ud = 0;
roland_tmm 0:6069c0f2a245 99 SPI_dev2.write(REVERSE_BITS(0x04));
roland_tmm 0:6069c0f2a245 100 //shiftOut(DATA, W_CLK, LSBFIRST, 0x04);
roland_tmm 0:6069c0f2a245 101 fq_ud = 1;
roland_tmm 0:6069c0f2a245 102 wait(0.001);
roland_tmm 0:6069c0f2a245 103 fq_ud = 0;
roland_tmm 0:6069c0f2a245 104 }
roland_tmm 0:6069c0f2a245 105
roland_tmm 0:6069c0f2a245 106
roland_tmm 0:6069c0f2a245 107 void AD9850::up() {
roland_tmm 0:6069c0f2a245 108 update();
roland_tmm 0:6069c0f2a245 109 }
roland_tmm 0:6069c0f2a245 110
roland_tmm 0:6069c0f2a245 111
roland_tmm 0:6069c0f2a245 112 void AD9850::CalibrateDDS(double TrimFreq)
roland_tmm 0:6069c0f2a245 113 {
roland_tmm 0:6069c0f2a245 114 calibFreq = TrimFreq;
roland_tmm 0:6069c0f2a245 115 }
roland_tmm 0:6069c0f2a245 116
roland_tmm 0:6069c0f2a245 117 /*
roland_tmm 0:6069c0f2a245 118 void AD9850::pulse(int pin) {
roland_tmm 0:6069c0f2a245 119 digitalWrite(pin, HIGH);
roland_tmm 0:6069c0f2a245 120 digitalWrite(pin, LOW);
roland_tmm 0:6069c0f2a245 121 }*/