-----------------------------------------------------------
"how_works.txt" for project; DecimalFreqLF.c
and DecimalFreqHF.c
Sep 2012 - www.RomanBlack.com/High_Acc_Timing.htm
----------------------------------------------------------- 
This PIC16F or PIC18F project generates a very exact frequency that is adjustable in real Hz steps, or actually in 0.00001 Hz steps.

The lowest freq possible is one unit, or 0.00001 Hz. (Please be warned, at this freq it will take 30 hours to make a single pulse!)

The highest freq possible is;
TMR2 freq / 200
For example; with a 4MHz xtal HS mode TMR2 is 1Mhz so the max freq is 1Mhz / 200 = 5000.00000 Hz. With a 10MHz xtal in HSPLL mode (40MHz) TMR2 is 10Mhz so the max freq would be 50000.00000 Hz.

----------------------------------------------------------- 
Theory;
----------------------------------------------------------- 
This uses a decimal recurring TMR2 period of 100 ticks, as a DDS addition into an accumulator. This is combined with a decimal setpoint used to trigger the toggling of the output pin. The decimal setpoint is implemented using a bresenham subtraction which keeps any remainder data so it does not need to be a direct multiple of the 100 tick TMR2 period.

Because of the decimal TMR2 period, the freq adjustment is in exact Hz in 0.00001 Hz steps, set by one simple user variable; freqHz.

Because of the bresenham subtraction used as the setpoint, any xtal frequency can be used and will not affect the operation of the decimal system. So you can use a 4Mhz xtal, 6MHz xtal, or even a junkbox TV colour xtal like 8.867238MHz, and still get exact 0.00001 Hz output resolution! 

----------------------------------------------------------- 
Simple example of how it works;
----------------------------------------------------------- 
Assuming a 4Mhz xtal so TMR2 freq is 1MHz (1 million ticks per second).
Every 100 ticks (100uS) a TMR2 interrupt occurs. If we add 100 to the accumulator, when the accumulator is >= 1 million ticks we generate an event.

As there are 1 million ticks per second (set by the xtal) that >= 1 million event will occur exactly once per second, so the value we added (100) represents exactly 1.00 Hz generated.

With the same setup if we added 200 the event would occur exactly twice as fast; at exactly 2Hz. So adding 200 = 2.00 Hz. Likewise adding 2000 = 20.00 Hz, and adding 23477 = 234.77 Hz.

----------------------------------------------------------- 
Generating a squarewave;
----------------------------------------------------------- 
To make a 1 Hz squarewave output with an average duty cycle of 50:50 means we need to make events at 2Hz, and on every event TOGGLE the output bit. So to generate 1 Hz output we still add 100, but make the event happen twice as often; at 500000 ticks (half the TMR2 freq).
So;
each TMR2 interrupt we add 100
toggle output if accum >= 500000 (toggle at 2Hz, makes 1Hz freq)

----------------------------------------------------------- 
Increasing resolution;
----------------------------------------------------------- 
Now we have a system to make squarewave frequencies in exact decimal 0.01 Hz steps. We can increase the freq resolution in decimal by multiplying all the factors by 10 or 100 etc.

The limiting point in resolution is caused by the PIC using 32bit unsigned long variables, which will crash if they exceed the max value of 4.29 billion. We have to allow for the highest expected TMR2 freq which is 10MHz (10MHz xtal HSPLL mode);
0.01 Hz resolution; add 100, event at (10Mil /2) 5 million
0.001 Hz resolution; add 1000, event at 50 million
0.0001 Hz resolution; add 10000, event at 500 million
0.00001 Hz resolution; add 100000, event at 5 billion (crash)

So with all PIC 16F and 18F xtal setups it should be safe at 0.0001 Hz resolution, which is pretty good!

Note! With a TMR2 freq of 4MHz or less you could run the top range at 0.00001 Hz resolution! I have made two projects, the LF project is in 0.00001 Hz resolution and is limited to max freq of 20kHz and PIC osc of 16MHz. The HF project is in 0.0001 Hz resolution and good for any PIC osc including 40MHz HSPLL and good for 50kHz max freq.

----------------------------------------------------------- 
Calculating "toggle" value based on osc;
----------------------------------------------------------- 
So to get the 0.00001 Hz resolution; event toggle is TMR2 freq * 500. And since TMR2 is osc / 4 that becomes;
osc / 4 * 500
which is simplified to; 
osc * 125

----------------------------------------------------------- 
Jitter;
----------------------------------------------------------- 
The system is based on the interrupt period which is 100 TMR2 ticks. This means that any point where the output pin toggles will be in sync with one of these TMR2 interrupts. This gives a limitation to the maximum frequency (which is TMR2 freq / 200), and also produces a significant amount of jitter (phase error) when generating higher frequencies.

The worst case jitter on any toggle transition will be 100 TMR2 ticks. At low frequencies this is generally insignificant;
Example TMR2 8MHz, max jitter = 100 / 8MHz = 12.5uS, so;
 Freq 100Hz max jitter is 0.125% of the total period.
 Freq 1000Hz max jitter is 1.25% of the total period.
 Freq 10000Hz max jitter is 12.5% of the total period.
 Freq 39999Hz (worst case) max jitter is about 50% of total period.

It's important to realise the frequency will still be exact, so if set to 123.45678 Hz that frequency will still be exact in average (measured over any significant amount of time) just that any individual toggle edge may have a jitter error of 12.5uS.

This project was optimised to give extremely fine adjustment resolution, in actual decimal 0.00001 Hz steps, from any xtal value. If the toggle edge jitter is not acceptable then there are other systems that will produce a zero-jitter frequency, including the ZEZJ (Zero Error Zero Jitter) system on my web page; www.RomanBlack.com/one_sec.htm however with a zero-jitter system it is not possible to produce the extremely fine resolution in decimal increments that this project has, as zero-jitter is limited to perfect divisors of the timer frequency.

-end-
