----- Original Message ----- From: "Scott Dattalo" To: Sent: Tuesday, January 21, 2003 12:48 AM Subject: Re: Dual sine wave generation. > 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 > -- http://www.piclist.com#nomail Going offline? Don't AutoReply us! email listserv@mitvma.mit.edu with SET PICList DIGEST in the body