Searching \ for 'Frequency Generation' in subject line. () Help us get a faster server
FAQ page: techref.massmind.org/techref/index.htm?key=frequency+generation
Search entire site for: 'Frequency Generation'.

Truncated match.
'Frequency Generation'
1997\01\22@115409 by  I guess I wasn't clear before, the problem is calculating, or storing the
data to make all of the frequencies from 1 to 500Hz. The '54 only has
512bytes, the time to calculate the period changes the duty cycle too much.
If anyone has a quick way to get from a frequency to it's period quickly and
in integer math.

Thanks.

****************************************************
__           Micheal Yano
----          Internet:     myano cimtek.on.ca
-CIMTEK-        IBMMAIL:      i1320285 IBMMAIL.COM
------------      Voice:        (905)847-8811 x22
FAX:        (905)847-8822
****************************************************   Michael Yano wrote:
>
> I guess I wasn't clear before, the problem is calculating, or storing the
> data to make all of the frequencies from 1 to 500Hz. The '54 only has
> 512bytes, the time to calculate the period changes the duty cycle too much.
> If anyone has a quick way to get from a frequency to it's period quickly and
> in integer math.
>

In the spirit of this week's long answers...

Have you considered Phase Accumulators?

Suppose you wish to generate a frequency, f, that is not an integer
divisor of the main CPU crystal frequency. This case happens quite
often for UARTs that are required to generate many different baud
rates. In abstract terms, you wish to implement some form of this
equation:

f = K * f_cpu

Where K is a constant and f_cpu is the frequency of the crystal
oscillator driving your PIC. Without special hardware, you are
obviously limited to K's that are less than 1. And this implies
that some kind of floating point of arithmetic will be necessary.
However, the trick of phase accumulators is that the arithmetic

This can be seen more easily by looking at the reciprocal of this
equation. For example in terms of periods,

T = T_cpu / K

Where
T = 1/f
T_cpu = 1/f_cpu

And since K is constant, we can write:

T = T_cpu * K'

Where K' = 1/K > 1.0

The stumbling block for many people is the assumption that K' has
to be an integer. If you adhere to that assumption, then you're stuck
with having to find a T_cpu that when multiplied by an integer
produces the desired T. And that's why many times CPU's used for
serial communications have crystals with frequencies such 4.096Mhz
or 12.288Mhz, etc.

So far I've been assuming (more or less) hardware phase accumulators.
For software phase accumulators, there is unavoidable overhead that
reduces the maximum frequency that can be synthesized. So typically
the designer is faced with compromising choices: Maximize the update
rate of the synthesized frequency and have high resolution OR
backing off of the update rate so that the PIC can do something else
too. At some point you must decide, and then you're stuck with:

T = T_s * K"

Where T_s is the rate at which the PIC updates the frequency output
and K" is YAC (yet another constant). The updating could occur in a
Timer interrupt, part of an isochronous loop, etc.

While we could carry the discussion to another level of abstraction,
let's instead look at a specific example. Suppose we have a PIC16Cxx
that is running off of a 4Mhz crystal and we wish to generate a
314.16 Hz square wave. We can set the timer interrupt to occur once
every 256 t_cy cycles, where t_cy = 4*t_osc is the PIC instruction
cycle time and t_osc is oscillator cycle time.

T_s = 256 * 4 * t_osc = 256 * 4 * (1/4Mhz) = 256 us

The desired period is T = 1/314.16 = 3.183 ms
The desired K" is

K" = T/T_s = 3.183ms/256us = 12.434

This means that after about 12 and a half interrupts we must change
the state of our square wave output. How do we do this? Well, one
way is to have a floating point variable that is incremented by
1/K" at every interrupt. When it exceeds one, we toggle the output
and subtract one from it. In C parlance, (UNTESTED)

#define f_out 314.16
#define T_s   256e-6
#define K     (1/f_out/T_s)

float phase, phase_increment;
bit output;

a_function()
{
phase_increment = 1.0/K;   //

do
{
if(time_interrupt_has_occurred)
{
phase += phase_increment;
if(phase > 1.0)
{
output ^= 1;    // Toggle the output.
phase  -= 1.0;  // Phase rolled over.
}
}
} while(1);  // loop forever
}

In other words, at every interrupt we accumulate a phase
quantum. When we have accumulated 1 unit of phase, then
we have rolled over. 1 unit of phase is not standard. We
are more accustomed to 360 degrees or 2pi radians for
the rollover threshold. However, since this about to
be trashed, it doesn't matter.

There are two major problems with the above code. The
first is that while a 314.16 Hz square wave will be
generated, it will have quit a bit of jitter. This is
a direct result of the trade off I mentioned earlier.
The only way to decrease the jitter is to either
increase the update period or change the crystal.
The other major problem is the (unnecessary) floating
point arithmetic. In fact, we can kill two stones with
one bird by going over to integer arithmetic. Consider
this (UNTESTED) program:

#define f_out 314.16
#define T_s   256e-6
#define K     (1/f_out/T_s)
#define phase_increment ( (2^32) / K)   // Scale to a 32 bit integer.

unsigned long phase;

a_function()
{

do
{
if(time_interrupt_has_occurred)
{
phase += phase_increment;
if (phase & 2^31)   // If the most sig bit is set
output = 1;       // then the output is high
else
output = 0;       // else it is low.
}
} while(1);  // loop forever
}

The explicit check for rollover is no longer needed
since "phase" has been scaled to a 32 bit number. This
is because "phase_increment" has been chosen such that

2^32 ~= 12.434 * phase_increment

After 12 updates, "phase" is almost equal to 2^32. After
the 13'th update, it would be greater than 2^32 if phase
had more than 32 bits. Since phase is only a long int,
it will "roll over".
The other benefit with this approach is that the state
of the output is reflected in the most significant bit
of the phase.

There are other optimizations that are also available.
For example, 16 or even perhaps 8-bits may provide enough
dynamic range for the phase variable.

It is also possible to generate several different
frequencies simultaneously. This is useful for DTMF decoding
or software PWMs.

Variations of the phase accumulator theme can also be
applied to phase locked loops. For example, it is entirely
possible to dynamically adjust the phase increment.

Software pulse width modulators can also benefit from
this concept. In other words, instead of looking at just
the most significant bit, you could look at most significant
N-bits. The duty cycle can then be controlled by comparing
these bits to another N-bit variable.

Another application is for implementing real time clocks.

If you want to see some PIC code, then check out my sine
wave generator:

http://www.interstice.com/~sdattalo/technical/software/pic/picsine.html

There's some discussion in the comments on how a phase
accumulator can be used to improve the frequency resolution.

Scott

'Frequency Generation'
1999\02\27@001512 by  <x-html><!x-stuff-for-pete base="" src="" id="0"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
0000">
Hi PIClisters,
<P>For one of my projects,&nbsp; I need to generate a square wave from
500 Hz to 1200 Hz in steps of around 2 to 3 Hz.
<P>Any suggestons ?
<P>Thanks
<P>Pailoor
<P>----------------------------------------
<BR>CHIP TECHNOLOGIES
<BR>Microchip Design Consultant
<BR>INDIA.
<BR>email : chiptech vsnl.com
hiptech</A>
<BR>---------------------------------------
</BODY>
</HTML>

</x-html>  Hi PIClisters,

For one of my projects,  I need to generate a square wave from 500 Hz to
1200 Hz in steps of around 2 to 3 Hz.

Any suggestons ?

Thanks

Pailoor

----------------------------------------
CHIP TECHNOLOGIES
Microchip Design Consultant
INDIA.
email : chiptech vsnl.com
---------------------------------------  Ravi Pailoor wrote:

> For one of my projects,  I need to generate a square wave from 500 Hz
> to 1200 Hz in steps of around 2 to 3 Hz.

What is the acceptable jitter?

If 16µS is acceptable jitter, use a crystal which is any multiple of
65536 x 4 = 262144 Hz such as 3.670MHz and I think you can use a "phase
accumulator" technique where you add the frequency value (in Hertz) to
a 16-bit accumulator 65536 times per second, the MSB of which is your
desired square wave.

A 3.670 MHz crytal would require this to be performed in 14 clock
cycles (and no other calculations) but if you can tolerate a jitter of
32µS or use double the crystal frequency, you have 28 clock cycles in
which to loop and it becomes much easier.
--
Cheers,
Paul B.  Hi Paul,

I am working on a HOT project. I intend to use a 12C508 with internal
oscillator.

My problem as below.

I have 2 pins of the PICmicro to select the tones. Totally I have 4
sweeps
to generate.

I have to generate the following sweep freq's.

1. 500 Hz to 1200 Hz  - 3 Sec
2. 800 Hz to 970 Hz  - 1 Sec
3. 1200 Hz to 500 Hz  - 1 Sec
4. 2400  to 2850 Hz.  - 0.143 Sec

I have to check the DIP switch change to change the Freq band during my
freq generation. I also have to maintain 15 % duty cycle.

Could you expalin  "phase accumulator" technique in a bit more detail or
if
you can give me code snipped to try it out on a PICmicro it would be
great.
Expecting to finish the project with some help