Searching \ for '[PIC]: Best frequency synthesis method' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'Best frequency synthesis method'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: Best frequency synthesis method'
2002\08\08@140555 by Kieren Johnstone

picon face
Hi,
This is question V2.. with new [PIC] symbol and revised ingredients.

Summary:
I'm trying to design a tone generator circuit (basically a PIC that can
generate musical notes).  I've been considering the possiblities, just
thought I'd share my thoughts for people to criticise etc.
Using software PWM (interrupts).  I want 3 or 4 channels, and I feel this is
relatively easy using this method:
 20Mhz crystal, clock divider = 5MIPS, TMR0 overflows 19531.25 times a
second - 19.5KHz is way higher than the range I need (4.9Khz being D#8,
quite a high note :D)
 Some example code (pseudocode) attached at end of doc.
Anyway, after looking through the datasheet some more, I found the
"prescaler" bits.. am I right in thinking that if I set PSA (assignment bit)
to WDT, the prescaler won't affect TMR0 at all?  (I plan to use the 19.5KHz
interrupt frequency, just checking if it's actually obtainible).

-Kieren

---------

// play_note plays a *note* on channel *chan*
// basically sets the timeout value for each pulse (measured in interrupts)
// data[] is a table of values, telling the number of interrupts to keep the
pulse high/low for.
// example: C5 @ 523.25 Hz.. 19531.25/523.25 = 37.2 (say 37)

play_note(chan,note)
 chandata[chan] = data[note]
 chantimer[chan] = chandata[chan]

// on_tmr0_overflow occurs at ~19.5Khz
// decrements timeouts, sees if it's time to switch pulse state
on_tmr0_overflow
 for (each in chan)
  dec chantimer[chan]
  if (chantimer[chan] == 0)
  {
    chantimer[chan] = chandata[chan]
    invert PWM_output_pin[chan]
  }
 next chan

(all PWM output pins are tied together as +ve for a speaker)

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email spam_OUTlistservTakeThisOuTspammitvma.mit.edu with SET PICList DIGEST in the body


2002\08\08@144148 by Scott Dattalo

face
flavicon
face
On Thu, 8 Aug 2002, Kieren Johnstone wrote:

> Hi,
> This is question V2.. with new [PIC] symbol and revised ingredients.
>
> Summary:
> I'm trying to design a tone generator circuit (basically a PIC that can
> generate musical notes).  I've been considering the possiblities, just
> thought I'd share my thoughts for people to criticise etc.
> Using software PWM (interrupts).  I want 3 or 4 channels, and I feel this is
> relatively easy using this method:
>   20Mhz crystal, clock divider = 5MIPS, TMR0 overflows 19531.25 times a
> second - 19.5KHz is way higher than the range I need (4.9Khz being D#8,
> quite a high note :D)
>   Some example code (pseudocode) attached at end of doc.
> Anyway, after looking through the datasheet some more, I found the
> "prescaler" bits.. am I right in thinking that if I set PSA (assignment bit)
> to WDT, the prescaler won't affect TMR0 at all?  (I plan to use the 19.5KHz
> interrupt frequency, just checking if it's actually obtainible).

You could use only 4 channels of this 8-channel software pwm routine in
your tmr0 interrupt handler:

http://www.dattalo.com/technical/software/pic/pwm8.asm

Since it only takes 15 cycles to process all 4 channels, you might
consider embedding this in an isochronous loop. The PWM carrier freqeuncy
would be at least 10 times higher than the 256 cycle tmr0 interrupt and
hence easier to filter.

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email .....listservKILLspamspam@spam@mitvma.mit.edu with SET PICList DIGEST in the body


2002\08\08@150235 by Olin Lathrop

face picon face
> I'm trying to design a tone generator circuit (basically a PIC that can
> generate musical notes).  I've been considering the possiblities, just
> thought I'd share my thoughts for people to criticise etc.
> Using software PWM (interrupts).  I want 3 or 4 channels, and I feel this
is
> relatively easy using this method:
>   20Mhz crystal, clock divider = 5MIPS, TMR0 overflows 19531.25 times a
> second - 19.5KHz is way higher than the range I need (4.9Khz being D#8,
> quite a high note :D)

Not really, see below.

> Anyway, after looking through the datasheet some more, I found the
> "prescaler" bits.. am I right in thinking that if I set PSA (assignment
bit)
> to WDT, the prescaler won't affect TMR0 at all?

Yup, you got it.

> (I plan to use the 19.5KHz
> interrupt frequency, just checking if it's actually obtainible).

Yes, it's obtainable.  However, that will be the PWM slice time, not the PWM
period.  If you want one part in 64 resolution, for example, then the PWM
period will be 63 PWM slices.  In that case the PWM frequency would be

 F = (instruction rate) / (timer 0 divide) / (PWM slices/period)
 F = 5MHz / 256 / 63 = 310Hz

You really need to use the hardware PWM for the combination of frequency and
resolution you want.  Some PICs have two CCP modules, like the 16F876, which
will give you two output channels.  You will need to use multiple PICs to
get more channels.

Then there is the question of where the data will come from to feed the PWM,
but that's another issue.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email listservspamKILLspammitvma.mit.edu with SET PICList DIGEST in the body


2002\08\08@160953 by Kieren Johnstone

picon face
I really don't understand what the problem is, or why I'd need to use
hardware PWM..
Anyway, I came up with this code (see end of post, and Copy/Paste into
notepad!).
Just looking out for any optimization wizards out there, anyone pointing out
any problems I'm likely to encounter etc :)

-Kieren

----- code -----
; demo only - wont compile
cblock 0x20
pwm1tot
pwm1left
pwm2tot
pwm2left
pwm3tot
pwm3left
pwm4tot
pwm4left
activepwms
endc

; activepwms = bitmask

; none active:
; 1+2+1+2+1+2+1+2
;   3 + 3 + 3 + 3
;     6   +   6  = 12 cycles

; all active, no changes:
; 1+1+1+1+1+1+1+1
;  2 + 2 + 2 + 2
;    4   +   4   = 8 (best case..?)

; all active, all change:
; 1+1+2+3+5 = 12
;      x4   = 48 ! (worst case!)

; example : 1,046.5 Hz target
; 5,000,000 Hz
; TMR0 overflow @
; 19,531.25 Hz
; 19531.25 / 1046.5
; = 18 interrupts
; (achieving 1,085.69Hz)
; (giving 5.76% error)

; lowest possible frequency
; = 255 interrupts
; (76.59 Hz, ~D#2)

; highest possible frequency
; = 1 interrupt
; (19.53125KHz, B6 < f > A#6)

; if all PWM outputs were at 19KHz,
; ~52 instructions total per interrupt, still
; only 20% of CPU used in interrupt....
; 80% of 5MIPS = 4MIPS!
; (that's still worst case)

interrupt
btfss activepwms, 0
goto afterpwm1
decfsnz pwm1left
goto resetpwm1
afterpwm1
btfss activepwms, 1
goto afterpwm2
decfsnz pwm2left
goto resetpwm2
afterpwm2
btfss activepwm3, 2
goto afterpwm1
decfsnz pwm3left
goto resetpwm3
afterpwm3
btfss activepwms, 3
goto afterpwm4
decfsnz pwm4left
goto resetpwm4
afterpwm4
retfie

resetpwm1
movfw pwm1tot
movwf pwm1left
;toggle bit here
goto afterpwm1
resetpwm2
movfw pwm1tot
movwf pwm1left
;toggle bit here
goto afterpwm2
resetpwm3
movfw pwm1tot
movwf pwm1left
;toggle bit here
goto afterpwm3
resetpwm4
movfw pwm1tot
movwf pwm1left
;toggle bit here
goto afterpwm4

{Original Message removed}

2002\08\08@163236 by Olin Lathrop

face picon face
> I really don't understand what the problem is, or why I'd need to use
> hardware PWM..

Just repeating what I said before won't do you any good.  It would be easier
to explain if you asked specific questions or indicated exactly which of my
statements you don't understand.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email .....listservKILLspamspam.....mitvma.mit.edu with SET PICList DIGEST in the body


2002\08\08@171220 by Kieren Johnstone

picon face
I just wrote a 2-page e-mail about what I didn't understand and why, then I
got it :)
Anyway, I'd be using 8-bit "resolution" and from my calcs. the frequency
range should be fine, if not by nocking off a higher octave I can half the
required frequency.

Thanks for the comments :)

Kieren

{Original Message removed}

2002\08\08@204114 by Olin Lathrop

face picon face
> I just wrote a 2-page e-mail about what I didn't understand and why, then
I
> got it :)
> Anyway, I'd be using 8-bit "resolution" and from my calcs. the frequency
> range should be fine, if not by nocking off a higher octave I can half the
> required frequency.

You wanted to interrupt once every timer 0 overflow (every 256
instructions).  8 bit resolution requires 255 time slices per PWM period.
5MHz / 256 / 255 = 76.6Hz.  And that is the sample frequency.  The highest
frequency you can reproduce is then 38.3Hz.  I rather doubt that is good
enough for your audio application.  Even if your PWM slice time were 32
instructions, that would only give you 8 times higher frequency, or about
306Hz.  If I remember, you wanted a few KHz.  Your simply not going to get
that with software PWM.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email EraseMElistservspam_OUTspamTakeThisOuTmitvma.mit.edu with SET PICList DIGEST in the body


2002\08\09@053402 by Kieren Johnstone

picon face
Surely if TMR0 overflows at 19.5 KHz, by switching a PWM every time I could
get 9.7 KHz, every 256 interrupts I could get about 76 Hz; in the original
post I mentioned 4.9 KHz being the highest note I'd consider..

-Kieren

{Original Message removed}

2002\08\09@075813 by Olin Lathrop

face picon face
> Surely if TMR0 overflows at 19.5 KHz, by switching a PWM every time I
could
> get 9.7 KHz,

Yes, but at what *resolution*.  You will make a descision and possibly
change the output at 19.5KHz rate, or every 51.2uS.  You can use this to
produce a square wave at half that rate, but I thought you originally wanted
sine waves and other arbitrary waveforms out.  At one point you said you
wanted 8 bit resolution.  Show me how you're going to create 256 different
average voltage levels with the averaging period less than 500uS.

> every 256 interrupts I could get about 76 Hz; in the original
> post I mentioned 4.9 KHz being the highest note I'd consider..

Yes, so doesn't that show this method won't work?  I don't understand your
point.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestspamspam_OUTmitvma.mit.edu


2002\08\09@081026 by Scott Dattalo

face
flavicon
face
On Fri, 9 Aug 2002, Kieren Johnstone wrote:

> Surely if TMR0 overflows at 19.5 KHz, by switching a PWM every time I could
> get 9.7 KHz, every 256 interrupts I could get about 76 Hz; in the original
> post I mentioned 4.9 KHz being the highest note I'd consider..

Kieren,

You misunderstood Olin.

PWM = Pulse Width Modulation, normally means constant frequency and
varying duty-cycle. What Olin said is that the constant frequency for what
you proposed is 76 Hz. But now, you seem to be suggesting that you want to
generate square waves for your tones!

However, let me suggest a slightly different way in which "PWM" can be
generated. Suppose you divide time into equal intervals. At each interval
you generate a high or a low; i.e. a pulse. Over a period of N pulses,
you're average ouput will be:

 avg = # of high's / total # of time slots

So for example, if you had 100 time slots and 10 of these were high
pulses (and 90 low ones) then the average would be 10/100 = 1/10.

With normal PWM, all of the high pulses are grouped together as one pulse.
But from a signal processing point of view, this is not necessary. So for
example to get the value 1/10 you could generate these various pulse
streams:


10 H, 90 L
5 H, 45 L, 5 H, 45 L,
1 h, 9 L, 1 H, 9 L

Or even this would work:
3 H, 20 L, 1 H, 33 L, 5 H, 7L, 1 H, 30 L

In other words, over the 100 pulses you want 10 high ones and 90 low ones.

If you're driving a motor (or some other big thing that can incur large
switching losses), you may want to minimize the switching and so you'd
choose the 10/90/10/90 approach which groups the highs together. If you're
generating audio, you may wish to *maximize* the carry frequency -
preferably beyond the range of human hearing, so that it is easier to
filter. Thus you'd choose the 1/9/1/9 approach.

To maximize the frequency, all you need to do is implement PWM with phase
accumulators. In this case, all you do is repeatedly add your "duty cycle"
to the phase accumulator. If the phase accumulator rolls over, you output
a "1" if not you output a "0".  So for example:


 unsigned char  phase = 0;
 unsigned char  analog = 15;   // i.e. 15 out of 256

 while (1) {

    old_phase = phase;
    phase = phase + analog;

    if(phase < old_phase)
      output = 1;
    else
      output = 0;

  }

Play with this for different values of "analog" and observe how "output"
changes.

Once you grasp it then consider this assembly code:

    movf   analog,w    ;Get the current analog value
    addwf  phase,f     ;Add it to the phase accumulator
                       ; carry get's set if we rollover.
    rlf    output,f    ;Lsb contains the "rollover" info

What's nice about this is that multiple PWM's can be constructed by just
repeating this snippet. The variable "output" is copied to the I/O port at
the last stage. For 4 outputs, the last rlf will look like this:

    rlf    output,w
    andlw  0x0f
    movwf  PORTB

With this scheme, the maximum frequency occurs at your 9.6 kHz for an
analog value of 1/2 and the minimum frequency is 76 Hz for analog value
1/256 or 255/256. I'd be inclined to write an isochronous loop so that the
frequencies are somewhat higher. You'll want to run this through a low
pass filter to knock off the edges.

Now, note that you don't get something for nothing. It still takes time to
achieve the "average" analog value you seek. It also takes time to
generate the desired signal. This scheme may help, but at these
frequencies you won't ever be competing with Yamaha synthesizers!

Scott

--
http://www.piclist.com hint: To leave the PICList
@spam@piclist-unsubscribe-requestKILLspamspammitvma.mit.edu


2002\08\09@092418 by Dave Tweed

face
flavicon
face
Scott Dattalo <KILLspamscottKILLspamspamDATTALO.COM> wrote:
> However, let me suggest a slightly different way in which "PWM" can be
> generated. Suppose you divide time into equal intervals. At each interval
> you generate a high or a low; i.e. a pulse. Over a period of N pulses,
> you're average ouput will be:
>
>   avg = # of high's / total # of time slots
>
> So for example, if you had 100 time slots and 10 of these were high
> pulses (and 90 low ones) then the average would be 10/100 = 1/10.
>
> With normal PWM, all of the high pulses are grouped together as one pulse.
> But from a signal processing point of view, this is not necessary. So for
> example to get the value 1/10 you could generate these various pulse
> streams:

You've described a first-order delta-sigma modulator. I've used this
technique myself in both hardware (FPGA) and software implementations
(but not on a PIC). See question #4 in the following quiz:

http://www.circuitcellar.com/library/eq/133/index.asp

... and also the first half of the article I wrote a while back, which goes
into more detail about the difference between this and PWM:

http://img.cmpnet.com/edtn/ccellar/e047pdf1.pdf

(For those interested, the first two parts of this series can be found at
http://www.circuitcellar.com/pastissues/articles/Tweed99/tweed99.pdf and
http://img.cmpnet.com/edtn/ccellar/e042pdf1.pdf)

The only thing I'd change in your description is this: you use the term
"phase accumulator" to describe the state variable -- it's really the
integrator portion of the delta-sigma modulator, and has nothing to do
with "phase", so it's a bit misleading.

The reason I bring it up is this: I was going to suggest using a DDS
(direct digital synthesis) technique to do the actual tone generation,
which does use a "phase accumulator".

The other thing I was going to suggest (as an alternative to PWM/delta-
sigma) was that if the software can produce events at 6x or 8x the desired
fundamental frequency, there's a relatively simple way to synthesize
sinewave approximations using a few resistors. Here's a series of quiz
questions I wrote that explain the concept:

www.chipcenter.com/circuitcellar/december01/ancil-1201/c1201eqa1.htm
www.chipcenter.com/circuitcellar/december01/ancil-1201/c1201eqa2.htm
www.chipcenter.com/circuitcellar/december01/ancil-1201/c1201eqa3.htm
http://www.chipcenter.com/circuitcellar/december01/ancil-1201/c1201eqa4.htm

-- Dave Tweed

--
http://www.piclist.com hint: To leave the PICList
RemoveMEpiclist-unsubscribe-requestTakeThisOuTspammitvma.mit.edu


2002\08\09@104354 by Kieren Johnstone

picon face
Apologies, 8-bit resolution was meant to mean the bits reserved for
specifying a PWM frequency.
You may have misunderstood my question about generating sine waves.  This
was in my *original* message: "Is it possible to attach caps in a "dodgy"
fashion to "smooth out" the square wave, creating a sine-ish wave?", I
wasn't referring to generating different levels, just looking for a hardware
square->sine "converter".
I decided against this, and so it wasn't included in my re-post of the
message.  Also, the code demonstrated used fixed output levels (on/off) and
I didn't mention other waveforms... but sorry to have confused you!

-Kieren

{Original Message removed}

2002\08\10@004516 by Michael Rigby-Jones

flavicon
face
> -----Original Message-----
> From: Kieren Johnstone [SMTP:spamBeGonemisterfugitspamBeGonespamHOTMAIL.COM]
> Sent: Friday, August 09, 2002 10:32 AM
> To:   TakeThisOuTPICLISTEraseMEspamspam_OUTMITVMA.MIT.EDU
> Subject:      Re: [PIC]: Best frequency synthesis method
>
> Surely if TMR0 overflows at 19.5 KHz, by switching a PWM every time I
> could
> get 9.7 KHz, every 256 interrupts I could get about 76 Hz; in the original
> post I mentioned 4.9 KHz being the highest note I'd consider..
>
> -Kieren
>
I think you and Olin are talking at cross purposes.  I *think* you wish to
produce tones using square waves only, which is acheivable in software.
However PWM does not come into the equation, what you would require in this
case is something called DDS (direct digital synthesis) to produce a wide
range of frequencies using a timer overflow etc.  This is where the
confusiuon is arrising.  With PWM, you are generating an average DC voltage
from a higher frequency variable duty cycle rectangular wave.  From this you
can produce any arbitrary analog signal, but the maximum frequency and
resolution of this signal is determined by the frequency of your PWM, which
is why Olin (correctly) stated you would not be able to achive 8 bit
resolution with a reasonable frequency range in software .

I'm guessing you are happy making notes with fixed amplitude square waves,
much like the ringtones from (most) mobile phones etc.  PWM would give you
the flexibility to play back notes at different amplitudes and with
different voices, using samples stored in memory.

Regards

Mike

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


More... (looser matching)
- Last day of these posts
- In 2002 , 2003 only
- Today
- New search...