Power consumption has been reduced, but the CPU is still actively doing nothing. To benefit from an interrupt-driven model, the CPU can be put to sleep while waiting for interrupts. In addition we will power down all peripherals not used to further reduce power consumption. The code below is included in project low_power_103.
#include <avr/io.h> #include <avr/interrupt.h> #include <avr/sleep.h> #include <avr/power.h> ISR (TIMER2_OVF_vect) { if (PORTB == 0x00) { // LED is OFF, turn it on PORTB = (1 << 5); // Shortened timeout for on cycle TCNT2 = 0x102; } else { // LED is ON, turn it off PORTB = 0x00; } } int main(void) { // Disable digital input buffer on ADC pins DIDR0 = (1 << ADC5D) | (1 << ADC4D) | (1 << ADC3D) | (1 << ADC2D) | (1 << ADC1D) | (1 << ADC0D); // Disable digital input buffer on Analog comparator pins DIDR1 |= (1 << AIN1D) | (1 << AIN0D); // Disable Analog Comparator interrupt ACSR &= ~(1 << ACIE); // Disable Analog Comparator ACSR |= (1 << ACD); // Disable unused peripherals to save power // Disable ADC (ADC must be disabled before shutdown) ADCSRA &= ~(1 << ADEN); // Shut down the ADC power_adc_disable(); // Disable SPI power_spi_disable(); // Disable TWI power_twi_disable(); // Disable the USART 0 module power_usart0_disable(); // Disable the Timer 1 module power_timer1_disable(); // Disable the Timer 0 module power_timer0_disable(); // Change the clock prescaler CLKPR = (1 << CLKPCE); // Scale by DIV64 CLKPR = (1 << CLKPS2) | (1 << CLKPS1) | (0 << CLKPS0); // Port B5 to output DDRB = (1 << 5); // Timer2 DIV 1024 TCCR2B = (1 << CS22) | (1 << CS21) | (1 << CS20); // Overflow interrupt enable TIMSK2 = (1 << TOIE2); // Interrupts on sei(); while (1) { set_sleep_mode(SLEEP_MODE_PWR_SAVE); sleep_mode(); } }