Playing with the OSCCAL register of an ATmega168

I was having problems with the “led ring” boards. Their internal oscillators were not ticking with the same speed and required constant re-syncing. I tried to improve the situation by recalibrating by adjusting the OSCCAL registers. Recalibration can be done quite easily with an oscilloscope. Either assuming that the _delay_ms() routine is reasonably correct for say 5ms (easy to measure on a scope), or using that “out 0x05 r9” (e.g. “PORTB = 0x00”) executes in just one clock cycle. Register r9 contains e.g. 0x00 to turn on a LED by pulling its cathode LOW. At 8MHz a single cycle should take 125ns.

The following graph is taken from the old! ATmega168 datasheet. It is not valid for the newer P or PA series. For the newer series there is also a difference between chips with different memory sizes. As usual, reading the datasheet is necessary.


Here’s the Arduino code used to find good values for OSCCAL using an oscilloscope. The current value of OSCCAL is sent to a terminal. Note that you’ll probably want to use your own pins, as I used my custom boards for this test. So better use pinMode() and digitalWrite() as usual for the LED. But on the other hand, if you already have an oscilloscope, you’ll probably know what you’re doing anyway ;-)

For code download click on ‘Projects –> GIT repo’ in the menu above.

I used the “measure the 5ms delay” method, as it was easier than measuring 125ns on my old 10MHz scope. I got values for OSCCAL of 104 and 122 for the two boards. That’s a relative deviation of 17.3% between the boards, using 104 as reference.

Final thoughts:

I still need to re-sync the two boards. Not much gained, but learned something new. It might have been a good idea to use the CLKO (clock output) pin of one board as the clock source for the other. But unfortunately that is on PB0 again. PORTB is used for driving the cathodes of the LEDs already. And I still want/need/crave a new digital scope. Maybe I should get a cheap 50MHz Rigol just so the ‘itching’ stops. I can still buy a good 4CH 100MHz one later.

This entry was posted in Arduino., Electronics. and tagged , , , , , . Bookmark the permalink.

One Response to Playing with the OSCCAL register of an ATmega168

  1. ericwertz says:

    Send me an email if you’re serious about the 50MHz scope. I know someone who’s got one to sell unopened.

Comments are closed.