On Mon, 20 Jan 2003, Michael Rigby-Jones wrote: > > -----Original Message----- > > From: moonshadow [SMTP:moonshadow@NTLWORLD.COM] > > Sent: Monday, January 20, 2003 9:47 PM > > To: PICLIST@MITVMA.MIT.EDU > > Subject: Dual sine wave generation. > > > > I need to generate two sine waves. One fixed at 14 kHz and the other > > variable between 14 kHz and 14.250 kHz. I would prefer to use Crownhill's > > BASIC Compiler to do this. > > Can anyone suggest how I ought to go about this please ?. I had > > thought to use the two internal CCP modules and the PWM command. However > > both modules have the same output frequency. Same with FREQOUT. > > > > John Kent. > > > What resolution do you need for the adjustable frequency? How much jitter > can you tolerate? > > You can (maybe) use the hardware PWM, but not in the manner you are > thinking. One idea is to build a table of SIN values and step through the > table at a variable rate, outputing the table value to the CCP module. The > PWM output would need to be low pass filtered to remove the PWM frequency > components. This implies that the PWM frequency has to be significantly > higher than 14KHz. The higher the PWM frequency the worse the PWM > resolution, which will affect the the quality (e.g. distortion) of your sine > wave. You may wish to consider investigating: http://www.dattalo.com/technical/software/pic/picsine.html This sin() routine takes as its input a 14-bit frequency variable. (Scale 2^14 to 2*pi). Assign two 16-bit frequency variables to your 14kHz and 14.25 kHz frequencies. Advance each of these by a fixed (but different) amount in a timer based interrupt routine and call the sine routine mentioned above. The sine routine takes 48 cycles. If you based your frequencies on a TMR0 interrupt with the pre-scale = 1, you could easily run both of these routines (~100 cycles out of the 256). Choosing the update rate: Let's suppose you're running your PIC off of a 20MHz clock. That's 20/4 = 5 million cycles per second. A TMR0 interrupt can be programmed to occur every 256 / 5million = 51.2 uS. The period of a 14,000 Hz wave form is 71.42 uS. Oops. This ain't gonna work :(. --- Phase accumulators but no linear interpolation: The routine on my web page uses phase-accumulator techniques for the frequency variable (phase accumulator is just fancy term for rollover arithmetic) and linear interpolation for the sine computation. The linear interpolation takes quite a bit of time. So Eric Smith's sine computation is more suitable for your application: http://www.brouhaha.com/~eric/pic/sine.html His code will take about 13 cycles. Again, you'll want 16 bit phase accumulators for the frequency variables. Using Eric's code, it would take about 13*2 + 4*2 ~ 34 cycles to compute the two sine values. On a 20MHz pic will take 6.8 uS or roughly 10.5 samples per sine wave. The challenge now is designing the isochronous code to update at this rate. (You can make the TMR0 interrupt run fast than 256 cycles by manually writing to it.) --- A pure software technique sounds iffy. But as Michael asks, it really depends on your requirements. There is one more software technique using ADPCM but it would consume all of the PIC's resources. Scott -- http://www.piclist.com#nomail Going offline? Don't AutoReply us! email listserv@mitvma.mit.edu with SET PICList DIGEST in the body