Atmega328P Timer2 in sleep mode

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

Hello,

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?

 

0x26:

0x27:

0x28:

0x30:

This topic has a solution.
Last Edited: Wed. Jan 1, 2020 - 06:58 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Show a complete test program.  Tell toolchain, version, and optimization levels.  Might want to post the generated code also.  What are the results of using the output compare pin, and measure that?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This seems like a perfect application for the simulator, where you can run it and watch what is happening.

I have to agree with theusch, post a zip of your project with your test code so others can examine what is happening.

 

Jim

 

 

 

 

 

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

I have used the simulator and found the answer - second interrupt happened before cli() after sleep_disable() and that additional time was spent on calling ISR second time.

Thanks for help:)

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

garvie.b5 wrote:
I have used the simulator and found the answer - second interrupt happened ...

 

Now do you see why we asked for a complete, small, test program?  With my crystal ball in the shop for repairs I could not divine the answer from your original post.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.