C code for low-jitter generation of 100Hz from 120Hz mains
// PIC code, 4MHz xtal, TMR1 at 1:8 prescale
// uses 2 variables;
// unsigned int bres
// unsigned char pulse
start:
// wait here for 120Hz pulse
while(!check_120Hz());
// now generate 10 "fake" pulses, each is "1200Hz"
// which is 833uS. PIC 1Mhz xtal, TMR1 1:8 prescale,
// we use TMR1L period of 104 = 832uS
// note! TMR1L loop is also another zero-error system
// that we keep subtracting 104 from while retaining
// its internal error.
pulse = 10; // make 10 "fake" pulses
TMR1L = 0; // make first pulse immediately
while(pulse)
{
// wait here for fake 1200Hz pulse
while(TMR1L.F7);
// now fix TMR1L and do the main bres event
TMR1L -= 104; // subtract 1/1200th of a second
bres += 100;
if(bres >= 1200) // if 100th sec reached!
{
bres -= 1200;
do_100th_event(); // update clock, etc
}
// subract a pulse, see if 10 done yet
pulse--;
}
// gets here after 10 "fake" 1200Hz pulses,
// need to detect a real 120Hz pulse, then
// do it all again!
goto start;
The code above behaves much like a digital PLL (Phase Locked
Loop) in that it MUST generate 10 pulses for every real input
pulse (with zero cumulative error), and the output is generated
from that, again with zero cumulative error.