sine wave using SPI

Hello,

I'm trying making a sine wave generator using the DAC MCP4921 via SPI, i wrote my code

#include <SPI.h>

const int sine[24]={14336,14865,15359,15783,16109,16313,16383,16313,16109,15783,15359,14865,14336,13806,13312,12888,12562,12358,12288,12358,12562,12888,13312,13806};
const int slaveSelectPin = 10;

void setup()
{
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE3);
SPI.setClockDivider(SPI_CLOCK_DIV2);
SPI.begin();
pinMode(slaveSelectPin,OUTPUT);
}

void loop()
{
int i;
for(i=0;i<=23;i++)
{
digitalWrite(slaveSelectPin,LOW);
SPI.transfer(highByte(sine*));*
_ SPI.transfer(lowByte(sine*));_
_
digitalWrite(slaveSelectPin,HIGH);_
_
}_
_
}_
_
[/quote]_
_as you see, my sine wave is made from 24 steps of voltage, each step needs 16 bits, with the SPI clock at 8MHz, i think the code above will create 8000000/(2416) ~ 20KHz sine wave. However, it can only make a 2.9KHz sine wave_

Can you help me with this problem?

Start by replacing the digitalWrite's for the slaveselectPin with direct port writes:
Say the pin in use is Port B, pin 2

PORTB = PORTB & B11111011;  // pin2 low
SPI.transers
PORTB = PORTB | B00000100;  // pin2 high

that will help a lot

Next, replace the highByte/lowByte function call with something more direct.
I would split the array into 48, and call two elements at a time

for (i=0; i<48; i=i+2){
PORTB = PORTB & B11111011;  // bit2 low (not 'pin' like I posted before)
SPI.transfer(sine(i));
SPI.transfer(sine(i+1));
PORTB = PORTB | B00000100;  // bit2 high
[code]

[/code]

This may be a dumb question, but what is the clock frequency of your Arduino?

Next, write the code so loop doesn't get execute - that add's some time while the 'hidden' main() { } gets executed to call void loop(){ } again:

void loop(){
while(;){  // while condition is true, do this stuff - may be a better way to do this
// your code
}
}

16,000,000 cycles/second/24 samples means absolute best frquency possible would be 666,667 Hz
divide by at least 6 if all the instructions in reply #2 executed in 1 clock cycle
down to 111,111 Hz
each SPI transfer is 8 clock cycles, so divide by 16
down to 6944 Hz.
So 20 KHz does seem like a stretch.

Let us know how fast you do manage tho.

It takes about 100 instructions to send a byte via software spi. So your case, it should be around 200 instructions or 12us per step. Times 24 steps gets you to about 300us for the whole cycle.

That's about 3Khz.

@dhenry, where'd you get software spi from? The instructions used are clearly the hardware SPI:
SPI.transfer();

I think he does that just to see if we are awake... I Sure wish he'd stop it... it doesn't bring anything new to the discussion but rather points out...

Bob

sorry all, i've just waken up, it's 8AM here
first, thank you all for answering my problem

yes, maximum frequency i can have is 3KHz
with CrossRoads's help, the frequency increases a bit. Actually, this project is for testing an amplifier, i need to make sine wave that have frequency range from 10Hz to about 20KHz in order to create the frequency response of the amplifier

i'm still trying all the solutions you gave but it seems it doesn't work. Maybe i should look for another solutions instead of using DAC

Anyway, thank you all

What you can find are Application Notes on making sine wave generators from a couple of op amps and some resistors & capacitors, such as this one.

If you translated those sine values to a resistor array, you could use a shift register to "Scan them" at any clock rate required and create sine waves from that method very easily just by clocking a shift register although the maf ferq is 1/8th of the clock rate, would require a 160 KHz shift clock for 20 KHZ...

Bob

thank you CrossRoads and Docedison, i'll try both method right away :slight_smile:

CrossRoads:
each SPI transfer is 8 clock cycles, so divide by 16

16 cycles minimum. Maximum SPI rate is clock/2 and you are clocking out 8 bits. Plus there is a school of thought in another thread that you need one more cycle.

dhenry:
It takes about 100 instructions to send a byte via software spi.

What is this software SPI? And what code are you quoting?

I thought we had talked about this before:

16 KHz is the theoretical maximum.

Read this:

http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/

it proved that my google skill is too bad =(
thank you very much