On Sun, 2007-02-25 at 11:22 +0100, Dig Kleppe wrote: > 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.
All good arguments. I've dropped this whole notion, and switched to external crystals. Seems one of my suppliers offers a 13.56MHz crystal. With UBRR set to 7, this allows for 115.2kb/s serial with < 4.2% error - very much good enough. Cheers David > > 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 > >AVR-GCC-list@nongnu.org > >http://lists.nongnu.org/mailman/listinfo/avr-gcc-list > > > > > > _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list