## #define calculation problem

10 posts / 0 new
Author
Message

Could you please give me some sort of hint as to why the following does not work:

```#define FOSC 4000000L
#define BAUDRATE 19200L
#define BAUDCOUNT (FOSC/(BAUDRATE*16) - 1)
```

(results in -195 being loaded into registers), but this does:

```#define FOSC 4000000L
#define BAUDCOUNT (FOSC/(307200) - 1)
```

I would have thought that they were identical!

Gavin

What seems to be happening is BAUDRATE remains a 16bit value even though the 'L' modifier is being used.
(19200UL*4) yields 11264 as the answer which is 0x2C00. The answer should have been 76800 which is 0x12C00.

How can I force the size of 19200 to be a long and thus have enough room to hold the result after the multiplication?

Try forcing all components of the calculation as longs.

```#define FOSC 4000000L
#define BAUDRATE 19200L
#define BAUDCOUNT (FOSC/(BAUDRATE*16L) - 1L)
```

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

Thanks, that seems to have done the trick!

BTW - Be careful with those style. Integer math trunacts - right?

For example if you have a clock of 3.68 MHz, and a baud of 115200. By integer math you get 0, by floating point you get 1. And the correct value is 1. Does the preprocessor use Integer or Floating Point style math here? Its late so I'm not going to worry about it tonight :p

-Colin

You can implement rounding by modifying the equation like this:

```#define BAUDCOUNT ((((FOSC / BAUDRATE) + 8L) / 16L) - 1L)
```

Be aware, however, that if rounding significantly affects the result, the actual bit rate may not be close enough to the required bit rate for reliable serial comm. The manual recommends, for best noise immunity, that the variance be no more than 0.5%.

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

I still seem to have a problem. Try something like the following:

```uint16_t Value;

Value = (256UL*256UL)/2UL);
```

You'll find that Value ends up with 0x0000 in it because when the two 256 values are multiplied they still seems to be stored as a 16 bit value which then overflows and 0x0000 / 2UL is still 0x0000!

Why does the 'UL' get ignored?

Not confirmed. The following code:

```int
main(void)
{
return (256UL * 256UL) / 2UL;
}
```

translates here into:

```...
/* prologue end (size=4) */
ldi r24,lo8(-32768)
ldi r25,hi8(-32768)
/* epilogue: frame size=0 */
...
```

which looks correct to me.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.