_delay_ms() across different AVRs

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello. I'm trying to come up with some functional, fault-resistant I2C multimaster code (it's difficult to work out all the possibilities, though a timeout will go a long way when I add that)..

I've got some basic code written up that successfully compiles to the ATmega16L and Atmega2560 one on the STk500 the other the STk600..

I've got the 2560 clocked by the Stk600 @ 8Mhz, and the Atmega16 is clocked by internal RC at 8Mhz, no CLKDIV fuses enabled.

Both chips are on the same I2C Bus, and they're both programmed to poll a value from an SMBus device attached (commercial evaluation board)...

I have them programmed to poll this device 98 times then divide by 14 and display it as a percentage of successful reads on the 500/600's LEDs (leds 0-6) with LED7 blinking in step after the 98 requests have been attempted.

Anyways, I've also got the same RS232 code being used across the chips (with #ifdefs to account for register name differences), and the chips are both able to communicate fine at 38400 baud with identical UBRRs, so their speeds do indeed appear to be 8Mhz.

I'm also sure device/clock speed have been correctly selected when compiling then downloading code. (reiterate: 8Mhz both chips)..

However, there's a vast difference in speed (remember the single blinking LED) between the two.. If I remove the _delay_ms() call entirely they seem to operate at the same speed.

I can't explain why this is happened. I've checked CLKDIV/fuses of both, UARTs are working which suggests pretty solidly that they're each at 8Mhz. (note using a usb-serial converter)

Anyone have any thoughts on this? Is there some caveat about _delay_ms not working as expected (using 20ms delays, within the allowable range)?

I'm hoping someone has ran into this before, or it's just a simple bug that someone might figure out from the description.

-Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Problem appears to be on line 47.

(or to put it another way - show your use of _delay_ms() and your definition of F_CPU that it uses to calculate the number of delay loops)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The mega16 does not have CKDIV8 fuse.
However only the 1MHz calibration is loaded at startup. This may well be very different to the 8MHz calibration value.

You can manually read the 8MHz factory calibration from your programmer. Then add

OSCCAL=factory_8MHz_value;   // as read by you

to each mega16 program that you run.

Occasionally the factory calibration is not good enough. So do a AVR053 calibration to get a "better" value.

Regarding _delay_ms():
avr-gcc has a special feature that it introduces completely unnecessary bloated code if you use the -O0 optimisation setting. thus rendering the delays useless.

The compiler should have whinged at you.

David.