Bresenham's Algorithm is a system where 2 imperfect periods can be
alternated to produce an average that matches any "perfect" period.

With most modern micros the easiest time period to generate is an
overflow of the internal timer, generally 256 ticks or 65536 (256x256)
ticks. Unfortunately, since most of these Micros run at crystal speeds
like 4MHz and 20MHz, these overflow timed periods generated are binary and
cannot be evenly divided into 1 second or any easily usable
real-world clock value.

Brilliant programmer Bob Ammerman recognised this fact and mentioned
his use of a Bresenham-type system for PIC micros.
Later I did some more work on the idea to speed-optimise it for the PIC
timer0 overflow which is available on all PICs and release the results as
public domain open source. It should also work on any other micro
with a binary-multiple internal timer.

All code on this page is open-source, please mention me if you use my
methods or code.

Basic Theory

Bresenham's algorithm was originally designed for speedily calculating
imperfect periods in grid movement on a 2 dimensional matrix like an
X-Y Plotter. A similar system can be used for generating one average timed
period from ANY other timed period (like the PIC
timer0 overflow period).

So we can generate a "perfect" average 1 second
period from the imperfect PIC timer0 overflow in a way which
is very fast and leaves the PIC with a lot of free time for other tasks.
The big advantage is that the 2 periods are completely independant, so
ANY crystal speed can be used to generate ANY timed period.

The basic theory is shown above.
A 20 unit period is needed, but the closest period the PIC can
generate is 16 or 24 units (for example). So the PIC alternates between
periods of 16 and 24 to generate a "perfect" period of 20.
Athough each generated period itself is imperfect, the overall
average period is perfect because this is a "Zero Cumulative Error"
system.

Making a 1 second period with any PIC (assembler)

Basic procedure to generate a 1 second period;
(assuming a 4MHz crystal, and 1000000 timer0 ticks/second)

Every timer0 overflow; subtract 256 from our Period variable

When Period variable gets less than zero; generate the 1 second event
and ADD another 1000000 to it

Because we ADD the next 1000000 ticks to the next second,
the cumulated error is still
contained within the Period variable. This means that the NEXT second will
be adjusted by the error that was left in the variable. Every period
will self-adjust it's length so over time there is Zero Cumulative Error.

My optimisation for the PIC timer0;

Using a 3 byte Period variable means it can subtract 256 simply by decrementing
the MID byte

Instead of going BELOW zero, event is generated on HIGH and MID bytes both equal zero,
which is easier to test and avoids handling negative values

When event is detected, HIGH and MID bytes must equal zero, so the 24-bit add
becomes many times faster than a "proper" 24-bit add

To summarise, it is extremely quick and easy to subtract the 256 ticks for
every timer0 overflow, and it is extremely quick and easy to ADD the 24-bit
value for the next timed period.

PIC assembler source code!

This first source code generates a 1 second event from a PIC with 4MHz
crystal and the timer0 overflow interrupt. This is the code that is easiest
to use for most designs.

This next source code generates a 1 second event from a PIC with 4MHz
crystal and timer0, but does not require an interrupt so it will
still work with the cheapest PICs, or for designs where you choose
not to use the interrupt.

Note!
You can use the 2 code examples above on any PIC and with any crystal.
Just adjust the 24-bit period value bres_ to the number of timer0 ticks
per second
and it will generate a 1 second period. You can also generate
longer or shorter periods than 1 second simply by changing that value.

Making a 1 second period using C code

This system will work on a PIC or any micro that has a timer and can use
C source code. This does the same thing as the assembler code above.

This next one is similar to the 1 second generators above. However
it is optimised for speed and code space,
because it uses a 16bit unsigned int variable for bres instead of a
32bit unsigned long. We do this by using values for the int period
and the 1second period that are in the same ratio to each other,
but smaller! We divide both values by 16;

The next one was for my master LED clock for my home automation
system. It uses a Dallas DS32KHz temperature compensated high accuracy
oscillator module. But I need to display hundredths of seconds
on my nice 12digit LED display, and the oscillator produces
32768 pulses/second, so a hundredth of a second is 327.68 pulses...
Ouch!

Fortunately it is easy to make hundredths of seconds (with zero error)
from 32768Hz using a bresenham algorithm.
I just test TMR1 bit3 in another interrupt, and check for
anytime TMR1L.F3 toggles, which occurs 2048 times each second.
This next math may not be immediately obvious
but if we have an event every 1/2048th of a second, and add 100
every event, then after 1 second we have a total of 204800.
So now it becomes obvious that every 1/100th of a second that
value grows by 2048. See below;

The next example was to allow generating of 100th second period
from a incoming frequency of 120Hz from the US mains voltage.
I wrote this code for someone who wanted to build my
12 digit LED clock with hundredths of seconds
and have it synchronised to the US mains for timekeeping accuracy.
In Australia the mains is 50Hz, so that is easy.
But for "frequency impaired" people in the USA they can use
this code to get 100Hz events from the rectified mains signal at 120Hz;

With this specific example the per-unit jitter is quite large, the
max jitter error is 1/120th of a second (see below).
However the clock will still keep perfect time, it is only
the "hundredths" digit that will be affected and that is
too fast to read anyway. The overall visual effect of the clock
displaying hundredths and tenths of a second is maintained.

Advanced bresenham timing techniques

Clock xtal super-fine calibration.

The int period and 1second period value can both be multiplied by the
same number, giving an increase in the timer resolution much greater
than the original resolution of the xtal value in Hz.

This next example uses a PIC with 1Mhz xtal, and testing against a
GPS receiver over a month shows the PIC clock is 9 seconds fast.
So the 1second correction value is calculated as;(1month+9secs) / 1month which in seconds is; 2678409 / 2678400
Which is 1.0000033602
Multiply by 1Mhz to give the correct 1 second period; = 1000003.3602 ticks

Since we are using an unsigned long variable for the bresenham accumulator
the same code will take a value up to 4.29 billion with no issues.
So we just multiply both the periods by 1000, which gives 1000 times
finer resolution to calibrate the clock but still uses the same
simple C code;

This is an advanced technique to reduce jitter where the two periods
are similar or where the output frequency is higher than the input
frequency. It works better at low frequencies and requires the
input frequency to be fixed and known. This is ideal to fix the
type of jitter seen in the 120Hz -> 100Hz picture above.

It generates 1200Hz from the 120Hz input, by generating 10 "fake"
events from each real 120Hz input event. Then the bresenham system
generates the 100Hz output frequency from the "fake" 1200Hz
frequency. This reduces jitter by a factor of 10.

The code above behaves much like a digital PLL (Phase Locked Loop)
in that it MUST generate 10 pulses for very real input pulse
(zero cumulative error) and the output is generated from that,
again with zero cumulative error.

The two advanced techniques above can be used to provide very fine
adjustment of virtually any periods or frequencies.

ZEZJ algorithm - Zero-Error and Zero-Jitter
New 21 Nov 2009.

This new algorithm is an adaptation of my zero-error system, that again
uses one easy constant to generate any period from any xtal. It also cancels
any timer error with every new TMR0 interrupt. However this system is more
sophisticated in that it also has zero jitter. This makes it ideal for
generating exact frequencies, like a precise 1 second xtal locked output
or an exact zero-jitter 50Hz reference or 1kHz reference etc.

Zero Error Zero Jitter algorithm;

(define PERIOD as the period to be generated, in TMR0 ticks)

1. Make X TMR0 interrupts, each is 100 ticks long (zero error)

2. Make 1 TMR0 interrupt of 100-199 tick remainder (zero error)

3. Generate the event (toggle a PIC pin etc).

This is a pretty clever system, as it can make any length period, exactly,
and the period is a simple constant defined in TMR0 ticks.

The period is broken down into X delays of 100 TMR0 ticks, and a remainder
that must be from 100 to 199 TMR0 ticks. The beauty of this very simple
system is that the PERIOD value can never conflict with the TMR0 overflow
that causes the interrupt. So the user can simply set the one simple PERIOD
constant to any number of TMR0 ticks, and the software generates an exact
zero-jitter period automatcially!

I have supplied code below as a complete PIC 12F675 project to generate
xtal-locked exact 50Hz frequency from a 4MHz xtal. The TMR0 runs at 1:1
prescaler ie 1MHz. The period generated is 10000 TMR0 ticks, which makes
a 100Hz event. The event just toggles PIC pin GP0, obviously the toggling
causes the frequency to be halved so it makes exactly 50 Hz. It was tested
on a 12F675 with 4MHz xtal and made 50.000Hz.

Note! If you wanted to use the code below to generate other xtal-locked
frequencies, you just need to change the PERIOD value (and maybe the xtal);

This is a variation of the ZEZJ code shown above. It generates a period
of mains freq * 8, then actives 2 PIC pins to give push-pull FET driving,
so just one PIC and one XTAL makes a complete xtal-locked square-wave
mains inverter brain. Code is fully tested.

PIC pins;

GP0 - outputA, sequence; 01110000

GP1 - outputB, sequence; 00000111

Output frequency;

50Hz (use 10 MHz xtal)

60Hz (use 12 MHz xtal)

Note! Frequency is exact, as good as the xtal accuracy. It also has zero jitter.
So an inverter based on this brain will be accurate enough to drive clocks etc.

For the power stage of an inverter you can use any schematic that uses
2 FETs (or 2 power transistors) driving a mains transformer. The 2 PIC
outputs are active HIGH, so when the PIC pin is +5v it turns on the FET.
This brain can even be suitable for high power square-wave inverters.
There is a crude schematic below that shows the output stage.

This code runs a push-pull squarewave inverter (like the project above) but
it is mains-locked and frequency converting. So it will generate 50Hz mains
from a 60Hz input, or the other way around. Only one line of code needs to be
changed to select which way the conversion is done.

Accuracy will be as good as the mains frequency, so it should be perfect
for clocks etc. Code is fully tested.

PIC pins;

GP0 - outputA

GP1 - outputB

GP2 - mains freq input, 0v to 5v, half cycle

The output pins will drive push-pull FETs etc (like the project above).
The mains input pin must be approx 0v to 5v waveform on PIC pin GP2. What I used
connected 12v AC through a diode into a voltage divider, which gives half-wave
pulses. The voltage divider used a 1k resistor into a 5k pot which was adjusted
to make the pulses safe at 0v to 5v. I also added a 0.47uF greencap (polyester
cap) from GP2 to ground. Coupled with the 5k pot this gave a nice smooth
5v pulse on GP2 when checked with the oscilloscope. If you don't have a
'scope, just turn the pot right down (so it stops working) then turn it up
until the pulses are large enough so it is working reliably, then a
touch more.

I was pleasantly surprised with just how well this simple code works to generate a
perfect 60Hz push-pull waveform from my 50Hz mains (or vice versa). The code
uses a 4MHz xtal and a zero-error routine using TMR1 to generate 600Hz,
a figure that works with both 50Hz and 60Hz. This is sync-locked to the
incoming mains frequency, and generates exactly 10 or 12 pulses for
each incoming mains cycle;

Converting 50Hz to 60Hz (12 : 10);

Generate exactly 12 pulses for each 50Hz mains pulse

Generate a 60Hz push-pull output from 10 pulses

Converting 60Hz to 50Hz (10 : 12);

Generate exactly 10 pulses for each 60Hz mains pulse

Generate a 50Hz push-pull output from 12 pulses

The push-pull waveforms I saw on the 'scope were very nice, with jitter
that was only a couple of uS. This requires a 4MHz xtal to make the precise
pulse periods, AND a properly smoothed 12v AC half-cycle waveform
(from a 12v AC transformer) to detect the incoming mains frequency.
If your mains frequency is a bit rough it will still produce a perfect
freq output, but the jitter may be larger. I suggest using the parts values
shown above for the incoming mains freq.

The same principle I described above can be used to make a more sophisticated
50Hz to 60Hz converting inverter, but now generating a "sinewave" made of 20
or more PWM steps.

The procedure is basically the same as the project above, but it generates
24 "virtual pulses" per incoming 50Hz mains cycle, not 12. Using 24 pulses
gives smoother steps of the sinewave. Then the 60Hz output frequency is
generated from 20 pulses. This gives the required 24:20 conversion, similar
to the project above that uses 12:10.

The method for generating the voltage steps of the sinewave is optional.
It could be done with multiple PIC outputs and a DAC, to generate voltage
steps. Or a more energy efficient system could be used, such as using
PWM on the PIC pin.

Of course you would not be limited to 20 sine "steps" as shown here.
20 sine steps allows an easy conversion of 50Hz to 60Hz (freq), which is a
conversion of 24 to 20 (as a period). 20 output sine steps is enough to
give a reasonable quality sine after filtering, but there is no reason
to be limited to only 20 sine steps.

Accurate xtal-locked Sinewave inverter!
New 8th Dec 2009.

This is a full 2 output push-pull PWM sinewave inverter.
With a 10MHz xtal it will generate 50Hz dual sinewaves.
With a 12MHz xtal it will generate 60Hz dual sinewaves.

This manually generates the sinewave PWM using 20 small simple code loops,
(most loops are copies of each other, some inverted). It does not require
a PWM module and will run fine on any low-end PIC that has a TMR1.
This code example was hardware tested on a 12F675
but a 12F629 or other cheap PIC would work as well.

Sequencing the 20 PWM loops is done in a very simple zero-error TMR1
interrupt, that just subtracts the fixed period from TMR1 and increments
the step variable (the only RAM variable used!).

Above is shown the 2 PWM sine push-pull outputs, for display purposes
each output was filtered into a RC low-pass filter (39k, 0.1uF) and it
shows dual sines of 3v peak to peak.

Below is shown the PWM output (0v-5v digital) and the other PWM output
is shown still filtered with the RC filter.

Note I didn't count cycles to create the
PWM loops, instead I just locked the PIC in each loop and measured
the DC voltage on its output pin to determine the duty cycle, these
were referenced to a 50:50 loop that was tested and produced 2.42v.
I only had to create 4 PWM loops really, which were then copied and/or
inverted (and 2 of the loops are 50:50 and 2 are 0:100 and 100:0). You can
tweak my values if you like but as you can see from the sines on the
CRO above they are probably good enough to build an inverter.

This one has push-pull sinewave outputs, and does not require a PIC with
PWM module as the sinewave PWM is generated in software.

This produces an exact 60Hz output which is mains-locked to the national
50Hz grid. It uses the same manual PWM loops as used in the project
directly above.

The procedure to convert 50Hz to 60Hz is the same as my other systems seen above;

For every 50Hz incoming mains cycle it generates 24 "virtual pulses"

Push-pull 60Hz sinewave outputs are sequenced over 20 virtual pulses.

However this one does the freq conversion in an interrupt;

1 int of 24; wait for GP2 \ edge (synchronise to 50Hz \ edge)

23 ints of 24; generate the virtual pulse periods using TMR1

The schematic above shows how to connect the 12v AC mains sensing input
to GP2 and the 2 PWM sinewave push-pull outputs are GP0 and GP1.

The code below is fully tested in hardware and I fine tuned the TMR1
"virtual pulse" period to remove interrupt latency, so it produces a
VERY nicely locked 60Hz sinewave. Below is the result; the 50Hz is shown
as the top waveform on PIC pin GP2 (filter values as seen above), and
below it is one of the 60Hz sinewave outputs (filtered with 39k and 0.1uF
for ease of display).

This circuit generates a much nicer looking sinewave than my mains! :)

I tested my 50Hz mains frequency which was running about 200 PPM fast, and then
tested the 60Hz sine output was also running about 200 PPM fast, so that's perfect.
(Not that it has much choice seeing that it's mains-locked.)

This is a based on a form of DDS (Direct Digital Synthesis) which is
a modern name used as a "catch all" phrase to describe pretty much any
form of making frequencies digitally (ie using a microcontroller).
The actual mechanism is a "binary divided accumulator" which differs
from the "Bresenham" systems above by being faster, but cruder.

With a Bresenham system the frequency is generated by a ratio of
the value added to the accumulator compared to the Bresenham overflow
value of the accumulator. As both values are adjustable the Bresenham
system is superior as it can replicate any ratio of the 2 values with
absolute average frequency accuracy.

A binary divided accumulator DDS (generally just called "DDS") still
works as a ratio division of the value added to the accumulator compared
to the accumulator overflow, but the accumulator overflow is fixed
as a binary value. This adds speed as the Bresenham compare is no longer
needed, but is inferior as a frequency generator as you can only really
set one of the 2 values. For this reason a DDS system needs a higher
resolution accumulator, and the value added to the accumulator must
be chosen to give as close as possible to the desired output
frequency but will generally never give the exact output frequency,
just get very close to it.

The DDS system below generates two combined (added) sinewaves as a
single waveform, to generate DTMF with 2 combined sinewaves of very high accuracy
frequencies. Commercial DTMF generator ICs will have a freq error in the region
0.2% to 0.7%. The code below that uses a 24bit accumulator will produce
DTMF sinewaves better than 0.00001% frequency accuracy for each sine.

The algorithm basics.
1. Wait for sync with the PWM module (or interrupt)
2. Add the constant period to the accumulator
3. Use a high byte from the accumulator to reference position in a binary waveform table, load it in PWM
4. Repeat!

Note! The waveform table must be size in a round binary number; 32, 64, 128 or 256 etc.

Implementation.
The accumulator cycle is based on the PIC PWM module period, for
speed and simplicity. Then once per PWM period the addition calc is done
and a new value loaded from the sine table into the PWM duty so that
the output of the PWM module generates a sinewave of exact and
selectable frequency.

The code below makes a reasonably accurate single sinewave (typically less than 0.1% freq error)

Calculating the constant to make a desired frequency;
Each freq you want to generate needs a costant. This is a simple ratio that
is determined by the PWM cycle frequency, the desired output frequency and
the number of samples in the waveform table. It is also dependant on the
size of the accumulator, ie 16bit, 24bit etc.

A 16 bit system uses the high byte of a 16bit accumulator. So it is a factor of 256.
Assuming a waveform table of 64 entries, the formula to make an output frequency
is this;BDA_period = Fout * 64 * 256 / Fpwm

It uses a 24bit system, where the byte2 is used for the binary table, so is 65536;
To generate the 697 Hz sinewave, with the 24bit system, as seen in example above;BDA_period = 697 * 64 * 65536 / 62500
BDA_period = 46775

Freqency accuracy;
Using a constant of about 46000 and max error is 1/2 a count, means the max error
is 1 part in 92000 or about 11 parts per million. This is better than the
frequency accuracy of the PIC xtal, so this 24bit produced sinewave will have an
output frequency accuracy around as good as the xtal itself. So this can be
considered a "perfect" frequency xtal-locked sinewave. Also, with the DTMF
example above this is the worst freq of the 8, so the other sine
frequencies range up to twice this accuracy.

And the nature of the system means that BOTH of the simultaneously
generated sinewaves will each have this individual accuracy.

Note! I have not provided a 32bit example, but you can see how easy
it would be from the above examples. A 32bit system will have a sinewave
frequency accuracy typically better than 50 parts per billion, a level
of accuracy so much higher than the xtal accuracy it is not necessary.
However it may be useful in some frequency conversion situations.

Speed issues and variable overloading;
The 3 code examples above use variable overloading to provide instant access
to the higher byte in the multi-byte accumulator. Luckily the MikroC for PIC
compiler allows this feature.
If your C compiler does not allow 2 variables to be assigned to the same
byte in PIC ram you can use a /256 or /65536 operation instead.

Depending how well your C compiler optimises the divide it may be
as fast as the variable overloading, but most compilers are not that good as they
will use a Div32/32 function which is slower and will use a lot of ROM.

A flawless looking 697 Hz sinewave, 2.6v p/p, made from the PIC PWM module and
filtered simply through a 2k7 resistor and 0.1uF capacitor. I tested with
my good frequency meter and it said 697.00 Hz.

Accurate sine DTMF project with C source code;
I have done a PIC 18F project that generates all the DTMF codes with sinewaves,
using a SmartGLCD module, you can see it on
this tutorials page.

I put my original "Zero-error 1 second Timer" up on my web page in
June 2001 and it has been used by a huge amount of people making
PIC clocks and for other timing uses to make one timing frequency
from another. Since then it practically become the "standard" way of
making a 1 second clock period in a PIC interrupt. :)

This web page was updated in June 2009 to add all the C-code
examples and the advanced techniques.

Tools

If using large numbers with assembler, you need to convert large decimal
numbers (like 1000000) to a 24-bit hex value for the PIC to use,
so I created a simple decimal-hex-binary converter;