View previous topic :: View next topic |
Author |
Message |
geolover
Joined: 08 Feb 2011 Posts: 18
|
software DDS |
Posted: Mon Mar 14, 2011 2:35 pm |
|
|
Hello!
I want to implement a software DDS with a PIC and a DAC chip.
I know the standard procedure involves generate phase first then put phase into a sin function.
However, when trying to generate a 480 points sine wave look up table of 500Hz, I began to experiencing problem: I found a lot of numbers in the sine wave table are repeative and therefore useless!
This is the following equation I used to generate the sine wave table:
Phase=2*pi*f0*i/N;
f0 = 500;
i= from 0 to 479;
N=480
sample = 2^14+(2^14 - 1)*sin(phase);
because the DAC is 16-bit and its largest positive representation is 0x7FFF.
Also, could anyone explains to me about the relation of digital output rate, number of points in the look up table, and the frequency of synthesized waveform ? |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Mon Mar 14, 2011 3:52 pm |
|
|
If the 480 points is over one sine wave, you really only need to calculate 120 points( first 90*)...
it's a 'cheat' I found on the web called 'magic sinewaves'.....years ago... |
|
![](templates/subSilver/images/spacer.gif) |
geolover
Joined: 08 Feb 2011 Posts: 18
|
|
Posted: Mon Mar 14, 2011 4:50 pm |
|
|
temtronic wrote: | If the 480 points is over one sine wave, you really only need to calculate 120 points( first 90*)...
it's a 'cheat' I found on the web called 'magic sinewaves'.....years ago... |
Well, I got enough program memory on my PIC so wouldn't mind to put extra 16-bit integers on it at all thanks to modern flash memory technology
However, could you tell me how to create sine waves by a look up table... |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 14, 2011 4:59 pm |
|
|
The following CCS example files use a lookup table to create a sine wave:
Quote: |
c:\program files\picc\examples\ex_dtmf.c
c:\program files\picc\examples\ex_sine.c
|
Forum posts:
http://www.ccsinfo.com/forum/viewtopic.php?t=33020 |
|
![](templates/subSilver/images/spacer.gif) |
newguy
Joined: 24 Jun 2004 Posts: 1903
|
|
Posted: Mon Mar 14, 2011 5:00 pm |
|
|
geolover wrote: | However, could you tell me how to create sine waves by a look up table... |
As an example, let's say that you set aside 91 LUT values, corresponding to sin(0), sin(1), ...., up to sin (90). To "play" a complete sine wave through the DDS, you need to set up a stable timer "tick" which then dictates how often you send a new value to your DDS. You start by sending LUT index 0, then LUT index 1 on the next tick, and so on up to index 90. Then you reverse direction and send LUT index 89, LUT index 88, and so on down to index 0. Then you reverse direction yet again but now you send the inverse (* -1) of each LUT index. I'm sure you can figure out the rest for yourself. |
|
![](templates/subSilver/images/spacer.gif) |
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Mon Mar 14, 2011 5:26 pm |
|
|
With any DDS work I have done the number of points in a full cycle is always a power of 2, generally 256 for crude 8-bit stuff, or 2^16 for fine (but slow)16-bit stuff. It is basically the length of the phase register. That way when the phase register rolls over you simply start on the next cycle. The resulting frequency is therefore the DDS clock speed * phase increment / phase register size. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
![](templates/subSilver/images/spacer.gif) |
geolover
Joined: 08 Feb 2011 Posts: 18
|
|
Posted: Mon Mar 14, 2011 5:54 pm |
|
|
SherpaDoug wrote: | With any DDS work I have done the number of points in a full cycle is always a power of 2, generally 256 for crude 8-bit stuff, or 2^16 for fine (but slow)16-bit stuff. It is basically the length of the phase register. That way when the phase register rolls over you simply start on the next cycle. The resulting frequency is therefore the DDS clock speed * phase increment / phase register size. |
Thank you so much!
Does this means if I want to get a 500Hz sine wave at the output of a 16-bit DAC, a 2^16 size register is required, while the PIC write data to DAC every 2ms? By increasing the phase increment, I will be able to get 1000Hz, 1500Hz, etc. sine wave? |
|
![](templates/subSilver/images/spacer.gif) |
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Mon Mar 14, 2011 6:20 pm |
|
|
If you only update the phase register every 2ms, the output state will only change 500 times each second. Frequencies over 500 Hz are clearly not possible. Actually Nyquist sampling tells you you can only get a theoretical maximum of 250Hz with a 2ms update cycle.
I generally start with the max frequency I need to generate. I need my DDS cycle to be 2.5 or 3 times that fast. Then I see how wide a phase register I can update at that speed. The DDS work I have done has all been square wave output. But you need to see if you get the sine amplitude resolution you need with the width of phase register you can update. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
![](templates/subSilver/images/spacer.gif) |
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Mon Mar 14, 2011 6:59 pm |
|
|
Here is another way to look at it. Your sine wave is going to be built of little stair step blocks. Decide how long, in time, each of these blocks can be. That is how long you have to update your phase register, do your sine lookup, and load your DAC.
If you only have 20 blocks in a full cycle, that is 5 steps up and 5 down for each half cycle, and each cycle is 10ms (100Hz), you need to run your DDS loop every 0.5ms. If you can only loop your software every 2ms you either limit yourself to 25Hz output, or you make your blocks bigger and your sine wave gets really ragged. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
![](templates/subSilver/images/spacer.gif) |
|