Hi all,

Here's my attempt to make the millis and micros function smaller and faster with a fast ISR .

Please feel free to point out any oversights since I'm more of a tinkerer than a programmer.

I realize this will only work with chips that use TIFR0 since you can set OCR0A other than 255.

You also need a 16Mhz (OCR0A = 249) or 8Mhz clock (OCR0A = 124).

#IFDEF statements could make wiring.c compatible with older chips by using the original method when TIFR is used.

So here's what I did for a 16Mhz clock:

The init() function has two lines added

1- Set Timer0 to Fast PWM mode 7. It's normally set to Fast PWM mode 3. See Page 108 Table 14-8 ATMega48/88/168/328

sbi(TCCR0B, WGM02); // Yes in TCCR0B

sbi(TCCR0A, WGM01);

sbi(TCCR0A, WGM00);

2- Set OCR0A to 249. Including 0 this will make 250 ticks.

16Mhz / (64 * (249 + 1)) = 1000uS per Overflow

OCR0A = 249; // For 16Mhz clock

The ISR would now be much shorter because fractions are gone:

SIGNAL(TIMER0_OVF_vect)

{unsigned long m = timer0_millis;

m++;

timer0_millis = m; }

The millis() function stays the same

The micros() function has 3 lines changed

m = timer0_millis; // used to be m = timer0_overflow_count;

if ((TIFR0 & _BV(TOV0)) && (t < 249)) // 249 instead of 255

return ((m * 1000ul) + (unsigned int(t) * 4); // (64 / clockCyclesPerMicrosecond()) would also work in place of 4

// An 8Mhz clock would use 8 since it has a resolution of 8uS

For testing, the only thing the ISR for Timer0 did was toggle pin 13: PORTB ^= B00100000.

I checked the frequency with a frequency counter on my DMM and it was super close to calculated = 500HZ.

I am using an ATMega168 Boarduino with 16Mhz resonator.

I didn't test with 8Mhz.

Thanks for reading,

Charlie Hughes