Hello,
I've the code ready for my application which is working correctly. Now I want to optimize power consumption by using an appropriate sleep mode.
The program consists of some ISR routines for timer0 and timer1, and pin change interrupts, see some pseudo code below. An atmega328p and an external quartz crystal or a ceramic resonator is used, some tact switches and some leds.
The main loop consits essentially of:
- a "do {} while (!keypressed)" loop.
- The program logic is handled via the interrupts
- compare match ISR for the timer and decreasing a counter and switching some LEDs
- as well as waiting for a button pressed (with a software debouncing waiting for a stable state over 50ms.). Using this second interrupts a global variable "keypressed" will be set.
Pseudo code looks like this:
// Interrupt for Timer/Counter0 Compare Match A ISR ( TIMER0_COMPA_vect ) { // interrupt routine fired every 1ms gone // button debounce mechanism for T1..3 (PC0..2) // - the button is assumed to be stable if "pressed" status occurs 50x (=50ms) in a row // - temp_state_button_pressed is set in pin change interrupt routine (ISR (PCINT1_vect)) // an orange led effect is done with timer0/A and a counter that reaches 0 } // Interrupt for Timer/Counter1 Compare Match A ISR ( TIMER1_COMPA_vect ) { // 1s gone // some other counter are decreased and some leds flipped if 0 is reached } } // Interrupt for Timer/Counter1 Compare Match B ISR ( TIMER1_COMPB_vect ) { // similar tasks as in ISR ( TIMER1_COMPA_vect ) } // Interrupt for switches ISR ( PCINT1_vect ) { // if an pin chance occures, a variable is changed to "pressed", which then will be evaluated in ISR ( TIMER0_COMPA_vect ) } int main(void) { // Initialization init_global_vars(); // initialize global variables init_io_pins(); // configure all I/O pins, active pin change interrupts, copy PINC state (should be 0) init_timers(); // initialize timer0 and timer1 sei (); // Enable global interrupts #ifdef _POWER_SAVE_ // disable unused modules enable_ppr(); // set PRR (power reduction register) // Initialize sleep mode set_sleep_mode(SLEEP_MODE_PWR_DOWN); // or SLEEP_MODE_IDLE SLEEP_MODE_PWR_SAVE SLEEP_MODE_STANDBY #endif //_POWER_SAVE_ while (1) { #ifdef _POWER_SAVE_ sleep_enable(); sleep_bod_disable(); sleep_cpu(); sleep_disable(); #endif //_POWER_SAVE_ // key pressed? do { // just wait for a key pressed } while ( !program_status.T1.button_pressed && !program_status.T2.button_pressed && !program_status.T3.button_pressed); // do some things } }
Thus, what I need to have available during sleep is:
- timer0 and timer1 including the compare match interrupts
- pin change interrupts
- external quartz/resonator
- I/O for the leds
Wakeup should be triggered using:
- pin chance
- timer compare match
In the datasheet, chapter 10.1 sleep modes it seems like only IDLE or STANDBY can be used.
Is that correct?
How can I check that the correct mode has been entered (I've got atmel-ice and dW available)?
What would be your best practive?
Thanks in advance for your support!
Regards
Andreas