3.1.11 Using Sleep Mode
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(); } }
Todo:
- Build the project/solution (F7)
- Program the application into the target device using Start Without Debugging (Ctrl+Alt+F5)
- Switch to Data Visualizer to see the results
Important: Because the
previous example prescaled the clock to 8 MHz/64, the ISP programming clock must be
set to less than 32 kHz to be below 1/4 of the main clock.
Important: Remember to
disable on-board power on the Xplained Mini.
What can we see from this plot?
- The kit now draws less than 1 mA with the LED OFF
- Current draw increases to about 7 mA when the LED is pulsed ON
- The 1% duty cycle still seems approximately correct
Result: Power consumption has again been improved by using Sleep mode and disabling unused
peripherals.