Pages: 1 2 [3]   Go Down
Author Topic: How much can 328p handle?  (Read 2250 times)
0 Members and 1 Guest are viewing this topic.
Rapa Nui
Offline Offline
Edison Member
*
Karma: 60
Posts: 2073
Pukao hats cleaning services
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The only correct calculation of the DDSword is with 64bit multiplication and LL integers (as above). Some sites show calculation with floating point - bad idea - as the float is not precise enough for the DDSword calculation! (there are even AD DDS chips with 48bit DDSword!).
I would use the libraries, but applying the above LL calc for DDSword.
Also mind when doing sweep with "adding the frequency step" (instead of a freq calculation of each sweep point) the error of the frequency accumulates, when the step is not a precise number.. The same occur when using an encoder as the input dial (and doing adding/subtracting a fixed step).
« Last Edit: May 06, 2013, 06:57:25 pm by pito » Logged

0
Offline Offline
Full Member
***
Karma: 2
Posts: 226
#include˂baby.h˃™
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi All,

I finally got the DDS freq update to happen via an spi transfer (The spi divider is set to 4, mode0, and LSB first).

I call the SetFrequency function via a while loop, which happens quickly for each frequency setting. I print a time before and after the loop completes and calculate the point-to-point sweep time. Without the below function, the loop takes about 4 us to complete (might be faster, but that is all I'm able to count). When I add the SetFrequency function, I get a freq set time of ~280 us.

I would like to get the function to process faster if I can.

Code:
void SetFrequency(unsigned long frequency)
{
int32_t tuning_word = (frequency * 0x100000000LL)/124999100L; //calc tuning word
PORTB = PORTB & B11111011; // clear pin 10
SPI.transfer(tuning_word);
SPI.transfer(tuning_word >> 8);
SPI.transfer(tuning_word >> 16);
SPI.transfer(tuning_word >> 24);
SPI.transfer(0x0);
PORTB = PORTB | B00000100; // set pin 10



I think crossroads mentioned something about a control word and I'm also not sure the last byte is correct. I also wonder if it's better to put the spi transfer in a for loop rather than coding each byte manually as I have? It seems it would take longer for the for loop since that is just one more thing to do...?

Also, the datasheet seems to say that each bit is transferred on rising edge of W_CLK. If W_CLK is 4 MHz (the spi clock with 4 x divider), then 40 bits would take 10 us, plus some settling time for the device to process (18 clocks of DDS system clock, 125 MHz?, plus a few more ns...). So it seems that if I'm able to get on the order of 10 us frequency switching time, then I'm done!
Logged

Offline Offline
God Member
*****
Karma: 25
Posts: 526
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
int32_t tuning_word = (frequency * 0x100000000LL)/124999100L; //calc tuning word

On my Arduino Uno, this formula takes almost 250 us.  I expect the divide is the time suck.
Logged

Rapa Nui
Offline Offline
Edison Member
*
Karma: 60
Posts: 2073
Pukao hats cleaning services
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Try to go with 8Mhz SPI - 9850 is fast enough..
Why do you try to calculate ddsfreqword at each sweep step??
Do calculate the ddsword for fstart and fstop, do calculate the ddsword for fstep and simply add it to dds_freq within a loop - that must be faster (when you do a linear sweep).

Code:
unsigned long ddsword_fstart = calculate...
unsigned long ddsword_fstop = calculate...
unsigned long ddsword_fstep = (ddsword_fstop - ddsword_fstart)/number of sweep points


unsigned long ddsword_freq = ddsword_fstart

while (ddsword_freq <= ddsword_fstop)
   {
      send ddsword_freq to 9850 via SPI @8MHz
      ddsword_freq = ddsword_freq + ddsword_fstep
}

That will take 11usec a loop, I bet smiley
« Last Edit: May 28, 2013, 04:12:39 pm by pito » Logged

0
Offline Offline
Full Member
***
Karma: 2
Posts: 226
#include˂baby.h˃™
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
int32_t tuning_word = (frequency * 0x100000000LL)/124999100L; //calc tuning word

On my Arduino Uno, this formula takes almost 250 us.  I expect the divide is the time suck.

 smiley-eek

Thanks, pito. I might even get those calcs out of the function and move them to the config function. Nothing should happen until the parameters are configured and then exit setup mode.
Logged

Pages: 1 2 [3]   Go Up
Jump to: