Best way to create a tone on PIC?

Started by ExpAnonColin, March 20, 2007, 02:37:19 PM

Previous topic - Next topic

ExpAnonColin

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

R.G.

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.
R.G.

In response to the questions in the forum - PCB Layout for Musical Effects is available from The Book Patch. Search "PCB Layout" and it ought to appear.

ExpAnonColin

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

RaceDriver205

Well one normally uses the PWM for this. Im pretty sure the 877 will have a PWM.

ExpAnonColin

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

RaceDriver205

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  ;)

ExpAnonColin

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  ;)

Thanks, I'll look into that.

-Colin

R.G.

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.
R.G.

In response to the questions in the forum - PCB Layout for Musical Effects is available from The Book Patch. Search "PCB Layout" and it ought to appear.

Dave_B

It might be worth looking at the code for this project.

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

It's AVR based, not PIC, but he's taken the concept quite a distance.
Help build our Wiki!

The Tone God

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

ExpAnonColin

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

The Tone God

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

R.G.

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
R.G.

In response to the questions in the forum - PCB Layout for Musical Effects is available from The Book Patch. Search "PCB Layout" and it ought to appear.

ExpAnonColin

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

Transmogrifox

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.
trans·mog·ri·fy
tr.v. trans·mog·ri·fied, trans·mog·ri·fy·ing, trans·mog·ri·fies To change into a different shape or form, especially one that is fantastic or bizarre.