This will be verry short post. I just created a registration in GitHub. I'll be using it as a public repository for the program files, related with this blog.
You can see the repository itself at https://github.com/elektronchika/ddsTest At the moment of writing of this post it contains only the main.c file for initializing AD9834. I will no longer post the codes here, but I will give a link to the according repository.
elektronchika's blog
This blog is meant for everyone who is interested in electronic circuits design. You will be able to find articles concerning: choosing circuit topology, components pick-up, bread-boarding, routing a PCB to match best performance, test and measurement
Thursday, 23 October 2014
Wednesday, 3 September 2014
Waveform generator with frequency, amplitude and offset control: Part 2
Bread-boarding
For bread-boarding I will use universal SMD board I ordered from e-bay for about $10. I also ordered samples from ADI, two of each (this is the maximum allowed) and I received them after a week or so. I have one LPXpresso board with LPC1227, which is 64 pins, 30MHz Cortex-M0 microcontroller. I will use it to control the DDS and DACs via SPI interface.
I soldered the DDS chip, the 50MHz crystal oscillator and the components around them. I used a 2,54mm connector to connect this breadboard with the MCU kit.
The program I wrote is quite simple. It initializes the SSP module in SPI mode. After this is simply programs the frequency, phase and control registers in the DDS. Here is the code:
/*
===============================================================================
Name : main.c
Author : elektronchika
Version : v0.01
Copyright : Copyright (C)
Description : main definition
===============================================================================
*/
#ifdef __USE_CMSIS
#include "LPC122x.h"
#endif
#include <cr_section_macros.h>
#include <NXP/crp.h>
// Variable to store CRP value in. Will be placed automatically
// by the linker when "Enable Code Read Protect" selected.
// See crp.h header for more information
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
// TODO: insert other include files here
// TODO: insert other definitions and declarations here
void init();
void initSpi();
void spiWrite(uint16_t writeData);
void initDDS();
int i;
int main(void) {
// TODO: insert code here
// Enter an infinite loop, just incrementing a counter
//volatile static int i = 0 ;
init();
initSpi();
initDDS();
while(1) {
i++ ;
//initDDS();
}
return 0 ;
}
void init(){
// Enable clock
LPC_SYSCON->SYSAHBCLKCTRL |= 0xE001081F; // Enable clock for: Sys, Rom, Ram, FlashReg, FlashArray, SSP, IOCON, GPIO0, GPIO1, GPIO2
// init LED
LPC_GPIO0->MASK = 0xFFFE << 7;
LPC_GPIO0->DIR = 0xFFFF; // Set PIO0_7 (red LED) as output
}
void initSpi(){
// initialize SSP ports
LPC_IOCON->PIO0_14 |= 0x00000082; // SCK
LPC_IOCON->PIO0_15 |= 0x00000082; // SSEL
LPC_IOCON->PIO0_16 |= 0x00000082; // MISO
LPC_IOCON->PIO0_17 |= 0x00000082; // MOSI
// Initialize SSP module
LPC_SYSCON->SSPCLKDIV = 0xff;
LPC_SSP->CR0 = 0x0000ff8F; // Serial clock rate = ??, CPHA = 1, CPOL = 0, SPI, 16 bits
LPC_SSP->CPSR = 0x00000002; // Clock prescaler = 10
LPC_SSP->CR1 = 0x00000002; // SSP is master
}
void spiWrite(uint16_t writeData){
LPC_SSP->DR = writeData;
//while(LPC_SSP->SR != 0x00000003) {
//}
while((LPC_SSP->SR & (0x10|0x2)) != 0x2);
}
// This function initialize AD9834 with the AN-1070 method
// with 50MHz clock, this should give 200Hz output frequency
// (this is because the DDS clock is doubled)
// 2100 4432 4000 8432 8000 C000 E000 2000
void initDDS(){
spiWrite(0x01c0);
spiWrite(0X4ac7);
spiWrite(0X8000);
spiWrite(0x11c0);
spiWrite(0X400f);
spiWrite(0X8001);
spiWrite(0XC000);
spiWrite(0XE000);
spiWrite(0x0000);
}
And here are the results. The frequency doesn't correspond to the one I set. I checked everything - SPI communication waveforms, power supply, reference voltage, I debuged the program step by step. Everything looks perfect. When I set low frequency, where only the LSB frequency register is different from zero - the output was DC level. This make me look through the internet for similar behaviour.
I found this subject in ADI Engineering Zone https://ez.analog.com/thread/45413 This guy has the similar problem, I think. But I dont have 25MHz crystal oscillator to test this, and thats why I will order 2 and check if the DDS will work correctly with it. Till then I will continue looking for a solution. Be ready for the update
For bread-boarding I will use universal SMD board I ordered from e-bay for about $10. I also ordered samples from ADI, two of each (this is the maximum allowed) and I received them after a week or so. I have one LPXpresso board with LPC1227, which is 64 pins, 30MHz Cortex-M0 microcontroller. I will use it to control the DDS and DACs via SPI interface.
Figure 2. Universal SMD bread board
Figure 3. LPCxpresso LPC1227 development board
I soldered the DDS chip, the 50MHz crystal oscillator and the components around them. I used a 2,54mm connector to connect this breadboard with the MCU kit.
Figure 4. DDS bread board
The program I wrote is quite simple. It initializes the SSP module in SPI mode. After this is simply programs the frequency, phase and control registers in the DDS. Here is the code:
/*
===============================================================================
Name : main.c
Author : elektronchika
Version : v0.01
Copyright : Copyright (C)
Description : main definition
===============================================================================
*/
#ifdef __USE_CMSIS
#include "LPC122x.h"
#endif
#include <cr_section_macros.h>
#include <NXP/crp.h>
// Variable to store CRP value in. Will be placed automatically
// by the linker when "Enable Code Read Protect" selected.
// See crp.h header for more information
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
// TODO: insert other include files here
// TODO: insert other definitions and declarations here
void init();
void initSpi();
void spiWrite(uint16_t writeData);
void initDDS();
int i;
int main(void) {
// TODO: insert code here
// Enter an infinite loop, just incrementing a counter
//volatile static int i = 0 ;
init();
initSpi();
initDDS();
while(1) {
i++ ;
//initDDS();
}
return 0 ;
}
void init(){
// Enable clock
LPC_SYSCON->SYSAHBCLKCTRL |= 0xE001081F; // Enable clock for: Sys, Rom, Ram, FlashReg, FlashArray, SSP, IOCON, GPIO0, GPIO1, GPIO2
// init LED
LPC_GPIO0->MASK = 0xFFFE << 7;
LPC_GPIO0->DIR = 0xFFFF; // Set PIO0_7 (red LED) as output
}
void initSpi(){
// initialize SSP ports
LPC_IOCON->PIO0_14 |= 0x00000082; // SCK
LPC_IOCON->PIO0_15 |= 0x00000082; // SSEL
LPC_IOCON->PIO0_16 |= 0x00000082; // MISO
LPC_IOCON->PIO0_17 |= 0x00000082; // MOSI
// Initialize SSP module
LPC_SYSCON->SSPCLKDIV = 0xff;
LPC_SSP->CR0 = 0x0000ff8F; // Serial clock rate = ??, CPHA = 1, CPOL = 0, SPI, 16 bits
LPC_SSP->CPSR = 0x00000002; // Clock prescaler = 10
LPC_SSP->CR1 = 0x00000002; // SSP is master
}
void spiWrite(uint16_t writeData){
LPC_SSP->DR = writeData;
//while(LPC_SSP->SR != 0x00000003) {
//}
while((LPC_SSP->SR & (0x10|0x2)) != 0x2);
}
// This function initialize AD9834 with the AN-1070 method
// with 50MHz clock, this should give 200Hz output frequency
// (this is because the DDS clock is doubled)
// 2100 4432 4000 8432 8000 C000 E000 2000
void initDDS(){
spiWrite(0x01c0);
spiWrite(0X4ac7);
spiWrite(0X8000);
spiWrite(0x11c0);
spiWrite(0X400f);
spiWrite(0X8001);
spiWrite(0XC000);
spiWrite(0XE000);
spiWrite(0x0000);
}
And here are the results. The frequency doesn't correspond to the one I set. I checked everything - SPI communication waveforms, power supply, reference voltage, I debuged the program step by step. Everything looks perfect. When I set low frequency, where only the LSB frequency register is different from zero - the output was DC level. This make me look through the internet for similar behaviour.
I found this subject in ADI Engineering Zone https://ez.analog.com/thread/45413 This guy has the similar problem, I think. But I dont have 25MHz crystal oscillator to test this, and thats why I will order 2 and check if the DDS will work correctly with it. Till then I will continue looking for a solution. Be ready for the update
Friday, 29 August 2014
Waveform generator with frequency, amplitude and offset control: Part 1
The Basics
These days Direct Digital Synthesizers (DDS) are commonly used in many applications. Analog Devices (ADI) offer wide range of DDS ICs with 1 to 4 output channels, 10 to 14 bits output DAC, sampling rate up to 1Gsps and even higher.
Many information about the principle of DDS can be found in an A Technical Tutorial on Digital Signal Synthesis by ADI.
I decided to design a circuit for a waveform generator, which I will use to test other circuits I design. I will stick on the following parameters of the output signal:
I've already chosen the DDS IC, so the next steps are to choose the DACs for amplitude and offset control. As I need two of them, it's better to choose one IC with two DACs inside. I want to be able to control the amplitude and offset with at least 1mV, so I need
10V/1mV = 10000
combinations of each DAC. The resolution in bits is
2^bits = 10000
which is 13,29. There is no such DAC ever made, so if I take 14bits I will have
10/2^14 = 0,61mV
With 16 bits DAC I will have
10/2^16 = 0,15mV resolution.
I selected AD5663R
These days Direct Digital Synthesizers (DDS) are commonly used in many applications. Analog Devices (ADI) offer wide range of DDS ICs with 1 to 4 output channels, 10 to 14 bits output DAC, sampling rate up to 1Gsps and even higher.
Many information about the principle of DDS can be found in an A Technical Tutorial on Digital Signal Synthesis by ADI.
I decided to design a circuit for a waveform generator, which I will use to test other circuits I design. I will stick on the following parameters of the output signal:
- Frequency from 0 to 5MHz;
- Amplitude from 0 to 10Vpp;
- Offset from -5V to +5V.
Figure 1. Block diagram of the waveform generator
Many articles about DDS can be found on Direct Digital Synthesis (DDS) & Modulators page. Useful for me were Circuit Note CN-0156 and Application Note AN-1070. CN-0156 describes how to control the amplitude of the output signal and AN-1070 describes how to set the desired frequency. For more information you can follow the links.
Components pick-up
The previous links made me AD9834 as the heart of this project. It's main characteristics are:
- Output frequency up to 37.5MHz (25MHz for the grade I will use. We will see how close to the truth is this when I begin testing it);
- Sine or triangular and square wave output (using the on-board comparator);
- 2.3V to 5.5V power supply;
- 3 wire SPI interface;
- 20 pins TSSOP package.
I've already chosen the DDS IC, so the next steps are to choose the DACs for amplitude and offset control. As I need two of them, it's better to choose one IC with two DACs inside. I want to be able to control the amplitude and offset with at least 1mV, so I need
10V/1mV = 10000
combinations of each DAC. The resolution in bits is
2^bits = 10000
which is 13,29. There is no such DAC ever made, so if I take 14bits I will have
10/2^14 = 0,61mV
With 16 bits DAC I will have
10/2^16 = 0,15mV resolution.
I selected AD5663R
- On-chip 1.25V/2.5V, 5ppm/°C reference;
- 2.7V to 5.5V power supply;
- 3 wire SPI interface;
- 10 pins MSOP package.
Subscribe to:
Posts (Atom)