I'm trying to understand how Timer2 works in sleep modes on Atmega328P
set_sleep_mode(SLEEP_MODE_PWR_SAVE); TCNT2 = 0; TIFR2 = _BV(OCF2B) | _BV(OCF2A) | _BV(TOV2); TCCR2A = (1 << WGM21)|(0 << WGM20); TIMSK2 = (0 << TOIE2) | (1 << OCIE2A); OCR2A = 0x26; while (ASSR & (_BV(TCN2UB) | _BV(OCR2AUB) | _BV(OCR2BUB) | _BV(TCR2AUB) | _BV(TCR2BUB))); sleep_enable(); sei(); //timer2 and sleep mode prepared //run timer2 and go to sleep as fast as possible PORTD |= _BV(PORTD2); // high TCCR2B |= (0 << CS22) | (0 << CS21) | (1 << CS20); //1 - 256us sleep_cpu(); sleep_disable(); cli(); PORTD &= ~_BV(PORTD2); // low TCCR2B = 0;
Clock is 1Mhz, so 0 to 0xff lasts 256us, so 1us per tick.
OCR2A = 0x26, so it should sleep 38us
The real time from high to low is 116us. Sounds ok (sleeping + start-up time + disabling interrupts + changing port to low etc.)
But the next try was with OCR2A = 0x27. I expected the real time something about 117us, but it is 91us.
My first thought was that with 0x26 I'm missing the counter, so it has to count to 0xff, wrap around and count to 0x26, but in that case sleeping should lasts 256us + 38us, so much more than 116us.
0x27 - 91us
+1us - 0x28 - 92us
+8 us - 0x30 - 100us
with those three values it looks ok, but something is happening between 0x26 and 0x27 - Can anyone explain it?