avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] howto: accurate fast usart with IntRC clock and OSCCA


From: Dig Kleppe
Subject: Re: [avr-gcc-list] howto: accurate fast usart with IntRC clock and OSCCAL
Date: Sun, 25 Feb 2007 11:22:17 +0100
User-agent: Mozilla Thunderbird 1.0.7 (Windows/20050923)

Hi
If this is just for one device it will work fine , but for a bigger number it is tricky. You must keep in mind that theoretically the factory setting of OSCCAL can be 0 so you cannot lower its clk.
Also the temperature drift is important.

Dig Kleppe

David McNab wrote:

Hi,

I was musing over WormFood's AVR baud rate calculations page:

http://www.wormfood.net/avrbaudcalc.php

It seems for faster baudrates, the required UBRRL value is of such a low
resolution that major errors are unavoidable.

So it occurred to me that, if accurate timing for other functionality is
not critical, and if one is using the internal clock, one can tune
OSCCAL to get very close to the real target baudrate.

For example, consider an ATmega32 running with 8MHz internal RC
oscillator, wanting to talk at 115kb/s.

The required UBRRL value is 3, which unfortunately gives an effective
baud rate of 125000, which my tty port is not coping with.

However, writing a different value to OSCCAL has brought the effective
baud rate close enough so that the AVR UART is talking to my tty port
just fine, without errors.

Here's the math:

let:
- BRgot be the effective baud rate, when the AVR is running at its
  selected clock frequency (eg, 8MHz when CKSEL=0x04)

- BRwant be the desired baud rate

- OCgot be the factory OSCCAL value

- OCwant be the OSCCAL value required to give the desired baud rate

- Fmin be the frequency that the AVR's IntRC generates when
  OSCCAL=0

- Fmax be the frequency that IntRC generates at OSCCAL=255

- Fgot be the actual frequency that the AVR's IntRC generates with
  OSCCAL left at the factory value

- Fwant be the frequency required such that the uart generates the
  desired baud rate

Then, given that Fmax = 2 * Fmin,

  Fgot = Fmin * (1 + OCgot / 255)

and

  Fwant = Fmin * (1 + OCwant / 255)

Now,

  Fwant / Fgot = BRwant / BRgot

  (1 + OCwant / 255) / (1 + OCgot / 255) = BRwant / BRgot

  (1 + OCwant / 255) = BRwant / BRgot * (1 + OCgot / 255)

  OCwant / 255 = BRwant / BRgot * (1 + OCgot / 255) - 1

And finally:

  OCwant = 255 * (BRwant / BRgot * (1 + OCgot / 255) - 1)

So for an 8MHz IntRC ATmega, with a factory OSCCAL of 0xb1, wanting to
talk at 115k, the baudrate generated at UBRRL=3 is 125000 (according to
WormFood's page. My ATmega32 has a factory OSCCAL of 0xb1

So in this scenario:

  OCwant = 255 * (115200 / 125000 * (1 + 0xb1 / 255) - 1)
         = 0x8f

And we also get:

  Fwant = 115200 / 125000 * 8000000
        = 7372800 Hz

I tried this, and got mostly corrupted chars. But OSSCAL = 0x90 has
given me perfect 115200k comms. I'm wondering if it's an issue of
temperature - or whether the factory OSCCAL of 0xb1 might have been out.

If one wants good timing, one can recompile the code with:
 #define F_CPU 7372800
and end up with reasonable timing with the delay function

Anyway, I'm open to better ideas on this. I have an app that really
needs to talk as fast as possible without errors, so any better
suggestion would be appreciated. Keep in mind though that I only have
convenient access here to crystals of a fairly limited range of
frequencies (eg 4MHz, 8MHz, 10MHz, 20MHz)

Cheers
David





_______________________________________________
AVR-GCC-list mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list





reply via email to

[Prev in Thread] Current Thread [Next in Thread]