# High frequency interrupt, question

So, my project is about generating sine wave
Currently i am using sine wave table, 256 point, the frequency of sine wave will be determined by interrupt on D2 pin, i use MCP4921 DAC to send out analog value
So, to generate 1khz sine wave, i must send 256khz Square wave signal to arduino. That's all, i keep my project as simple as i could, processing many things mess up many thing
The question is
How i speed up interrupt, my spi speed is set to DIV2, using arduino uno 16mhz, and what do you think max frequency it can generate
And
Is there other way to generate sine wave faster than this way
Thanks anybody

Any Code to share?

not sure but doing a rough calulation:
DIV2 means the max SPI speed should be 8MHz
sending 3bytes to MCP4921 (1 config + 2 data) I would assume that tthe max frequency you can send data to the DAC would be around (8MHz/8)/3=approx 333kHz which means that you could in theory generate a waveform of around that frequency.

with regards to speeding up the interrupt not sure what you mean there, to determine the number of pulses you might be using a pin interrupt together with a timer intr. sharing your code for that portion may help us help you speed it up if/where possible.

the max frequency you can send data to the DAC would be around (8MHz/8)/3=approx 333kHz which means that you could in theory generate a waveform of around that frequency.

With 256 samples per cycle that would be about 1.3 kHz.
Since all your ISR has to do is fetch a value from the lookup table, increment the pointer, and send three bytes to the SPI interface it might be possible to get 1 kHz. That is assuming that the SPI library code is very efficient. Hook the output to an oscilloscope and crank up the interrupt rate until the frequency stops climbing. That will tell you the upper limit using the SPI library.
If you need higher frequencies you could use a shorter lookup able.

Per Figure 5-1, the 4921 only needs 2 bytes, with the upper 4 bits being configuration data.
If you want to go really fast, use direct port manipulation for chip select, turn off interrupts so you don't have 'jitter' from 4uS and 1mS interrupts, and read data from an array without using a for loop:

``````void loop(){
while (1){
PORTD = PORTD & 0b11111011; //clear D2 as chip select
SPDR = array[0]; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; // wait out transfer
SPDR = array[1]; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; // wait out transfer
PORTD = PORTD | 0b00000100; //set D2 as chip select
PORTD = PORTD & 0b11111011; //clear D2 as chip select
SPDR = array[2]; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; // wait out transfer
SPDR = array[3]; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; // wait out transfer
PORTD = PORTD | 0b00000100; //set D2 as chip select
// etc
PORTD = PORTD & 0b11111011; //clear D2 as chip select
SPDR = array[510]; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; // wait out transfer
SPDR = array[511]; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; // wait out transfer
PORTD = PORTD | 0b00000100; //set D2 as chip select
}
}
``````

Each SPI transfer will take 17 clocks, just over 1uS. Each chip select change takes 2 clocks I think.
So 4 clocks + 34 clocks = 38 clocks, x 256 transfers = 9728 clocks, at 16 MHz = period of 608uS, frequency of 1644.7 Hz, which is in the ballpark of JohnWasser's estimate. 3 clocks for the chip selects would slow down the frequency to 1562.5 Hz.

Do you have an oscilloscope to check things out?