DIYstompboxes.com

DIY Stompboxes => Digital & DSP => Topic started by: ExpAnonColin on March 20, 2007, 02:37:19 PM

Title: Best way to create a tone on PIC?
Post by: ExpAnonColin on March 20, 2007, 02:37:19 PM
I'm using a PIC16f877a.  I want to have one of the pins output an audio frequency (square wave is fine).  You can do this by setting a pin high, pausing, setting a pin low, pausing, and looping, but that makes doing just about anything other than interrupts a bit difficult.  You can also do it with the built in timers-set a timer to count down, when it finishes, have it interrupt and change the state of the pin, which is less intrusive.  But is there some other function that will allow me to essentially tell the chip to oscillate one of the pins, at an audio-or-so-frequency, and then continue to do so until I tell it to stop or change the frequency?   I am programming in C and using a compiler to get it onto the chip.

-Colin
Title: Re: Best way to create a tone on PIC?
Post by: R.G. on March 20, 2007, 02:57:33 PM
That's about it - counting loops, interrupts, timers. There is a combination of timers and counting loops that does not require interrupts, but it requires that whatever else you're doing will complete every single loop iteration in less than the counter time-out.

If you can live with the timer doing it, that's by far the lowest load on the uC. That *is* the way provided for uCs to output a frequency without computing about it.
Title: Re: Best way to create a tone on PIC?
Post by: ExpAnonColin on March 20, 2007, 04:23:30 PM
Quote from: R.G. on March 20, 2007, 02:57:33 PM
That's about it - counting loops, interrupts, timers. There is a combination of timers and counting loops that does not require interrupts, but it requires that whatever else you're doing will complete every single loop iteration in less than the counter time-out.

If you can live with the timer doing it, that's by far the lowest load on the uC. That *is* the way provided for uCs to output a frequency without computing about it.

Thanks RG.  Just wanted to make sure there wasn't some special function I hadn't discovered.

-Colin
Title: Re: Best way to create a tone on PIC?
Post by: RaceDriver205 on March 20, 2007, 08:34:38 PM
Well one normally uses the PWM for this. Im pretty sure the 877 will have a PWM.
Title: Re: Best way to create a tone on PIC?
Post by: ExpAnonColin on March 20, 2007, 11:49:19 PM
Quote from: RaceDriver205 on March 20, 2007, 08:34:38 PM
Well one normally uses the PWM for this. Im pretty sure the 877 will have a PWM.

Do you know of any source code/projects on the net that use the PWM for tone generation?

-Colin
Title: Re: Best way to create a tone on PIC?
Post by: RaceDriver205 on March 21, 2007, 05:27:16 AM
Yes, I just recently used a PWM in a remote-control car I made. But that was for an AVR, not a PIC.
The datasheets are generally very complicated, so its best to do some searching for basic PWM usage instructions on the net.
I believe PICLIST is a good place to search: piclist.com

You might like this: http://www.piclist.com/techref/microchip/16F877/pwm.htm (http://www.piclist.com/techref/microchip/16F877/pwm.htm)  ;)
Title: Re: Best way to create a tone on PIC?
Post by: ExpAnonColin on March 21, 2007, 12:58:40 PM
Quote from: RaceDriver205 on March 21, 2007, 05:27:16 AM
Yes, I just recently used a PWM in a remote-control car I made. But that was for an AVR, not a PIC.
The datasheets are generally very complicated, so its best to do some searching for basic PWM usage instructions on the net.
I believe PICLIST is a good place to search: piclist.com

You might like this: http://www.piclist.com/techref/microchip/16F877/pwm.htm (http://www.piclist.com/techref/microchip/16F877/pwm.htm)  ;)

Thanks, I'll look into that.

-Colin
Title: Re: Best way to create a tone on PIC?
Post by: R.G. on March 21, 2007, 01:22:17 PM
In general, if you can use a square wave, use a timer. Using PWM to create a waveform uses a a timer to create the basic frequency, but then uses either the arithmetic functions or another timer to vary the duty cycle inside the basic frequency to make waveform values other than full on or full off. Usually the intermediate values are stored in a table and looked up in sequence.
Title: Re: Best way to create a tone on PIC?
Post by: Dave_B on March 22, 2007, 10:15:16 AM
It might be worth looking at the code for this project.

http://www.elby-designs.com/avrsynth/avrsyn-about.htm (http://www.elby-designs.com/avrsynth/avrsyn-about.htm)

It's AVR based, not PIC, but he's taken the concept quite a distance.
Title: Re: Best way to create a tone on PIC?
Post by: The Tone God on March 22, 2007, 02:09:41 PM
I agree with R.G. that in most cases using a standard timer over PWM is a good option and would far more available. The only time I would use PWM, for an assumed 50% fixed duty cycle signal, is when the timer cannot hit the desired frequency with the system clock but the timer when in PWM mode uses a separate faster clock which would get you to the target frequency.

Andrew
Title: Re: Best way to create a tone on PIC?
Post by: ExpAnonColin on March 22, 2007, 05:30:44 PM
Quote from: The Tone God on March 22, 2007, 02:09:41 PM
I agree with R.G. that in most cases using a standard timer over PWM is a good option and would far more available. The only time I would use PWM, for an assumed 50% fixed duty cycle signal, is when the timer cannot hit the desired frequency with the system clock but the timer when in PWM mode uses a separate faster clock which would get you to the target frequency.

Andrew

I'm actually having the reverse problem-Timer1 can count down 65535 steps, interpreted in terms of notes taht means I can't go below C2.  This of course can be fixed in a number of ways, either counting overflows, or by using it in DIV_BY_4 or 8 mode instead.  But I want accuracy (you want the frequency of a note to be as close to the correct frequency as possible!) and counting overflows is a pain.  So for now I am dealing with only going to C2, which is really not a big deal for this app.

-Colin
Title: Re: Best way to create a tone on PIC?
Post by: The Tone God on March 22, 2007, 05:59:56 PM
I'm not familiar with that PIC but you could possible do the interrupt dance. Specifically if it has a timer compare match interrupt.

Andrew
Title: Re: Best way to create a tone on PIC?
Post by: R.G. on March 22, 2007, 08:08:47 PM
QuoteSo for now I am dealing with only going to C2, which is really not a big deal for this app.
You know, letting us know what notes you want to synthesize, and how many at a time would be a big help in letting us help you. Also a little more about how much else the cpu is doing would help. Is it just a tone generator, a full digital synth, monophonic, polyphonic, top octave generator, whatever.

Your options are
1 - use one or more timers as a standalone peripheral
2 - use a timer and read the timers in software
3 - use a time as an interrupt source
4 - use an external interrupt
5 - do the counting in software
6 - use a combination of some or all of the above

A really tricky hack would be to set two timers going at slightly different rates so that the difference between the timers would create the frequency you wanted.  :icon_biggrin:

It would probably do you some good to read the top octave generator code. Google "top octave", PIC, and "old crow".

The guy generates a full octave of notes without timers or interrupts using isochronous code based
Title: Re: Best way to create a tone on PIC?
Post by: ExpAnonColin on March 22, 2007, 08:16:24 PM
Thanks RG.  It reallyisn't anything.  It's just a program that outputs notes.  Monophonic.  Just feeling out C, I guess.  Nothing glamorous, and as I said, if I was really bummed about not getting below C2 I'd probably be trying to figure out a way!  :)

-Colin
Title: Re: Best way to create a tone on PIC?
Post by: Transmogrifox on March 25, 2007, 03:28:10 AM
If I remember correctly from the last time I used the PWM register in the PIC, it was a nice set and forget signal generator.  You set up the PWM period with the appropriate timer, then  all you have to do is write the duty cycle to the appropriate register.  After that, it just does its thing, and manages its own operations as a peripheral function, so you don't ever have to touch it in code until you either want to change the duty cycle or the PWM period (frequency) 

Using interrupts, you have to write in a routine that toggles the pin on every interrupt.  It's no big deal to do this, but if in the future you want to start modulating the pulse width for an audio effect, then it's easier that you have started with the PWM peripheral to begin with.   I can already see the immediate application for a PIC tone generator with a software generated LFO assigned to the pulse width for use with a ring modulator.  That would be a truly legitimate noise maker.