I am using a Mega 2560 and 2 x AD9833 programmable waveform generators.
The AD9833's use a SPI protocol and I have used vwlowen's code as a jumping off point (I'm not usng the display just the generators). I added a channel
variable to select the slave device.
It all works fine until I try to add a second AD9833. I saw this post about more than 1 peripheral using SPI & a Mega, that says I can use any pin for slave selection (SS) but the following code only ever works if I use pin 53. The upshot if which is that I can send the same data to both i.e. both share the same SS pin as long as that pin is 53. Any other SS pin selection is ignored by the devices. I tried pin 49 for both & no change, I''ve tried 53 & 49 yet only the device on 53 changes.
So what's going on here? What's so special about pin 53 that it cant be replicated by another output pin?
/*
Amended code for AD9833 Waveform Module originally from vwlowen.co.uk
Common SPI terminology & pinout on AD9833
MOSI - DATA
SCLK - CLK
SS - FSYNC
MISO - not implemented i.e. ther is no MISO pin on the AS9833
*/
#include <SPI.h>
const int SINE = 0x2000; // Define AD9833's waveform register value.
const int SQUARE = 0x2028; // When we update the frequency, we need to
const int TRIANGLE = 0x2002; // define the waveform when we end writing.
const float refFreq = 25000000.0; // On-board crystal reference frequency
const int FSYNCA = 53; // Standard SPI pins for the AD9833 waveform generator.
//const int FSYNCB = 49;
const int CLK = 52; // CLK and DATA pins.
const int DATA = 51;
unsigned long freq = 1000; // Set initial frequency.
void setup() {
pinMode(FSYNCA, OUTPUT);
// pinMode(FSYNCB, OUTPUT);
SPI.begin();
SPI.setDataMode(SPI_MODE2);
delay(50);
AD9833reset(); // Reset AD9833 module after power-up.
delay(50);
AD9833setFrequency(freq, SQUARE, FSYNCA); // Set the frequency and Sine Wave output
// AD9833setFrequency(freq, SINE, FSYNCB);
}
void loop() {
// TODO: PC control via USB
}
// AD9833 documentation advises a 'Reset' on first applying power.
void AD9833reset() {
WriteRegister(0x100, FSYNCA); // Write '1' to AD9833 Control register bit D8.
delay(10);
// WriteRegister(0x100, FSYNCB);
// delay(10);
}
// Set the frequency and waveform registers in the AD9833.
void AD9833setFrequency(long frequency, int Waveform, int channel) {
long FreqWord = (frequency * pow(2, 28)) / refFreq;
int MSB = (int)((FreqWord & 0xFFFC000) >> 14); //Only lower 14 bits are used for data
int LSB = (int)(FreqWord & 0x3FFF);
//Set control bits 15 ande 14 to 0 and 1, respectively, for frequency register 0
LSB |= 0x4000;
MSB |= 0x4000;
WriteRegister(0x2100, channel);
WriteRegister(LSB, channel); // Write lower 16 bits to AD9833 registers
WriteRegister(MSB, channel); // Write upper 16 bits to AD9833 registers.
WriteRegister(0xC000, channel); // Phase register
WriteRegister(Waveform, channel); // Exit & Reset to SINE, SQUARE or TRIANGLE
}
void WriteRegister(int dat, int channel) {
digitalWrite(channel, LOW); // Set FSYNC low before writing to AD9833 registers
delayMicroseconds(10); // Give AD9833 time to get ready to receive data.
SPI.transfer(highByte(dat)); // Each AD9833 register is 32 bits wide and each 16
SPI.transfer(lowByte(dat)); // bits has to be transferred as 2 x 8-bit bytes.
digitalWrite(channel, HIGH); //Write done. Set FSYNC high
}