Sleep Timer Restarts after a few minutes

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

Hi guys,

I have been trying to create a basic application that goes into a sleep state during low power periods. It must use the timer during this time to increment and keep time. I have been having issues that the unit actually restarts when waking it up after it has been in a sleep state for several minutes. Initially I am simply using the PA2 Pin for testing the state, attaching to ground or pulling it high externally through a pin interrupt.

If i wake up it before 2-3 mins, no issues and the unit continues under normal operation.

Any ideas on what I may be doing wrong?

I am using the Atmega324PA running at 8MHZ with the fuses: L:0xFF H:0xD7 E:0xFE

#define F_CPU 8000000UL
#define UBRR_VALUE 16

#include 
#include 
#include 
#include 
#include 

uint16_t tim = 0;

void StartSleep()
{
	sei();
	set_sleep_mode(SLEEP_MODE_PWR_SAVE);
	sleep_mode();
}

int main(void)
{
	//init uart
	/* Set the baud rate */
	UBRR0H = (uint8_t)(UBRR_VALUE>>8);
	UBRR0L = (uint8_t)UBRR_VALUE;
	UCSR0A |= (1<<U2X0);
	UCSR0B = ( ( 1 << RXCIE0 ) | ( 1 << RXEN0 ) | ( 1 << TXEN0 ) );
	UCSR0C |= (1<<UCSZ01)|(1<<UCSZ00);            //For devices with Extended IO
	
	//init pin interrupt
	DDRA &= ~(1<<PA2);
	PCICR |= (1<< PCIE0);
	PCMSK0 |= (1<< PCINT2);
	
	//init timer2
	TCNT2 = 0;
	ASSR |= (1<< AS2);	//enable external clock
	TIMSK2 |= (1<<TOIE2);
	TCCR2B |= (1<<CS22)|(1<<CS21);
	
	tim = 0;
	//init LED's
	UDR0 = 'R';
	DDRC |= (1<<PC5);
	PORTC |= (1<<PC5);

	char x[6];
	sei();
	while(1)
	{
		_delay_ms(2000);
		ltoa(tim,x,10);
		for(uint8_t i = 0;i < 6;i++)
		{
			if (x[i] == 0)
			break;
			_delay_ms(1);
			UDR0 = x[i];
		}
		_delay_ms(1);
		UDR0 = '\n';
	}
}

ISR(TIMER2_OVF_vect)
{
	tim+=2;
	if (!(PINA & (1<<PA2)))
	{
		//If the device has no mains power - start sleep operation
		StartSleep();
	}
}

ISR(PCINT0_vect)
{
	if (!(PINA & (1<<PA2)))
	{
		//If the device has no mains power - start sleep operation
		StartSleep();
	}
	else
	{
		UDR0 = 'w';
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are going to sleep inside an ISR?!?

Worse you appear to be going to sleep inside the same ISR() that wakes it up?

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

Cheers, that fixed issue.

An overflow would occur after too many calls in the interrupt and the application could handle that many return references...I gather.