A sine wave generator using AD9833 and AD9850 using STM32F103RB
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
AD9850.cpp
- Committer:
- roland_tmm
- Date:
- 2017-11-21
- Revision:
- 2:602f7589c53e
- Parent:
- 1:9dcccb399f0b
File content as of revision 2:602f7589c53e:
/****************************************************************************************************************** * AD9850 library for AD9850 * Created 11/21/2017 * Roland Pelayo * * Use this library freely * * Hardware connections : * W_CLK -> any pin * FQ_UD -> any pin * DATA/D7 -> any pin * RESET -> any pin * * Functions : * dds.begin(W_CLK pin, FQ_UD pin, DATA pin, RESET pin); Initialize the output pins and master reset the AD9850 * dds.calibrate(frequency); Compensation of crystal oscillator frequency * dds.setfreq(frequency,phase); frequency in Hz, phase coded on 5 bits * dds.down(); power down mode reducing the dissipated power from 380mW to 30mW @5V * dds.up(); wake-up the AD9850 * * AD9850 datasheet at http://www.analog.com/static/imported-files/data_sheets/AD9850.pdf * *****************************************************************************************************************/ #include "AD9850.h" #include "mbed.h" #define W_CLK PB_10 #define FQ_UD PB_11 #define DATA PB_1 #define RESET PB_0 SPI SPI_dev2(DATA, PB_8, W_CLK); DigitalOut wclk(W_CLK); DigitalOut fq_ud(FQ_UD); DigitalOut dat(DATA); DigitalOut res(RESET); AD9850::AD9850() { } void AD9850::Begin() { SPI_dev2.format(16,0); deltaphase = 0; phase = 0; calibFreq = 125000000; begin_priv(); } void AD9850::begin_priv() { res = 0; wait_us(5); res = 1; wait_us(5); res = 0; wclk = 0; wait_us(5); wclk = 1; wait_us(5); wclk = 0; fq_ud = 0; wait_us(5); fq_ud = 1; wait_us(5); fq_ud = 0; } void AD9850::update() { uint32_t d,p; for (int i=0; i<4; i++, deltaphase>>=8) { d = ReverseBits(deltaphase); SPI_dev2.write((d>>16) & 0x000000FF); SPI_dev2.write(d & 0x000000FF); // shiftOut(DATA, W_CLK, LSBFIRST, deltaphase & 0xFF); } p = ReverseBits(phase); SPI_dev2.write((p>>16) & 0x000000FF); SPI_dev2.write(p & 0x000000FF); //shiftOut(DATA, W_CLK, LSBFIRST, phase & 0xFF); fq_ud = 0; wait_us(5); fq_ud = 1; wait_us(5); fq_ud = 0; } void AD9850::SetDDSFrequency(double f, uint8_t p) { deltaphase = f * 4294967296.0 / calibFreq; phase = p << 3; update(); } void AD9850::down() { fq_ud = 0; wait_us(5); fq_ud = 1; wait_us(5); fq_ud = 0; SPI_dev2.write((ReverseBits(0x00000004))>>16); SPI_dev2.write(ReverseBits(0x00000004)); //shiftOut(DATA, W_CLK, LSBFIRST, 0x04); fq_ud = 0; wait_us(5); fq_ud = 1; wait_us(5); fq_ud = 0; } void AD9850::up() { update(); } void AD9850::CalibrateDDS(double TrimFreq) { calibFreq = TrimFreq; } int AD9850::ReverseBits(int value) { // Unfortunately need to invert bit order of the desired frequency setting since MBED only allows for MSB first from SPI. We need LSB first for AD9850 int mask=0;; int i=0; int target=0; int bitTarget=0x80000000; // Hard-wired for 32-bit inversion for (i=0;i<32;i++) { // ditto mask=1<<i; bitTarget=1<<(31-i); // ditto if(value & mask) target=target | bitTarget; } return target; }