Úsporné režimy procesora: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace |
|||
| (64 medziľahlých úprav od rovnakého používateľa nie je zobrazených.) | |||
| Riadok 14: | Riadok 14: | ||
* [https://wolles-elektronikkiste.de/en/sleep-modes-and-power-management Sleep Modes and Power Management] | * [https://wolles-elektronikkiste.de/en/sleep-modes-and-power-management Sleep Modes and Power Management] | ||
* [https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf Dokumentacia k ATmega328P ] | * [https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf Dokumentacia k ATmega328P ] | ||
* [https://developerhelp.microchip.com/xwiki/bin/view/products/mcu-mpu/8-bit-avr/structure/sleep/ AVR® Low Power Sleep Modes] | |||
* [https://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html <avr/sleep.h>: Power Management and Sleep Modes] | |||
__TOC__ | __TOC__ | ||
| Riadok 28: | Riadok 32: | ||
'''Nam sú dostupné 6 úsporných režimov:''' | |||
:Idle | :- Idle | ||
:ADC noise Reduction | :- ADC noise Reduction | ||
: | :- Power-down | ||
:- Power-save | |||
:- Standby | |||
:- Extended standby | |||
| Riadok 37: | Riadok 44: | ||
==== Idle ==== | |||
Vypína iba procesor, a necháva dosť veľa možnosti zobudenia z vonku aj z vnutra. | |||
Môže byť zobudený: Pretečením časovača , USART prenosom , prerušením prostrednictvom Analógového komparatora, ADC prevodnika, Timer/Counters, Watchdog , zmenou na pinoch. | |||
==== ADC noise Reduction ==== | |||
Veľmi podobný ako '''Idle''' s rozdielom v tom, že vypína aj ''SPI'' a ''USART''. Toto umožňuje zväčšiť kvalitu merania ADC prevodnika. | |||
==== Power-down ==== | |||
Vypína skoro všetko. Zobudenie je možne iba cez ''(TWI) 2-wire serial interface'', ''Watchdog'', ''prerušenie na pinoch INT0'' a ''INT1 z vonka'', ''prerušenie z ostatných pinov''. | |||
Má možnosť vypnúť BOD - Brown-out Detector | |||
==== Power-save ==== | |||
Od '''Power-down''' sa líši možnosťou zapnúť ''Timer/Counter2'' v synchronnom alebo asynchronnom režime. Ak ''Timer/Counter2'' nepotrebujem, tak lepšie zapnúť '''Power-down''' režim. | |||
==== Standby ==== | |||
Mal by sa používať s vonkajším krýštalom alebo rezonatorom v role časovača. Je identický ku '''Power-DOWN''' s jednou vynimkou - oscilator pokračuje pracovať. | |||
==== Extended standby ==== | |||
Mal by sa používať s vonkajším krýštalom alebo rezonatorom v role časovača. Je identický ku '''Power-SAVE''' s jednou vynimkou - oscilator pokračuje pracovať. | |||
---- | |||
=== Zapojenie, algoritmus, program === | |||
Ku doske je pripojene jedno tlačitko s rezistorm na pine PD4 ( INT0 ). Bude využité na externe prerušenie. | |||
[[Obrázok:Schema_zpojenia_usporne_rezimy.png|300px|thumb|center|Jednoduché zapojenie na zobudenie externou zmenou stavu pinu s použitim tlačidla.]] | |||
Knižnica avr/interrupt.h je opcionálna. Potrebujem iba na krásne blikanie LEDky. | |||
V '''main''' nastavime zabudovanú LED ako výstup a Tlačitko na PD4 ako vstup s pull-up. | |||
Následne mame vybrať úsporný režim, ktorý chceme využiť. | |||
Môžeme to spraviť dvoma spôsbmi: | |||
* Ručne nastavime register '''SMCR''' | |||
:: Ma 4 piny - ''SM2'', ''SM1'' a ''SM0'' určuje úsporný režim. SE, ktorý povoluje spustenie uspania. Bit SE je najlepšie aktivovať tesne pred spustenim uspania, aby nenastalo skôr než potrebujeme. | |||
* Využijeme funkciu set_sleep_mode() z knižnice sleep.h ''[ Nastavuje SMCR za nas ]'' | |||
:: Do zatvoriek doplnime SLEEP_MODE_'''''"nazov_režimu"'''''. Povolenie uspania dávame neskôr, inými funkciami. | |||
V loope najprv vypneme prerušenie. Zapneme vtedy, kedy potrebujeme. | |||
Zablika LEDka - signál, že procesor nespi. | |||
Na uspanie použieme funkcie z sleep.h | |||
* '''sleep_mode()''' | |||
:: Tesné pred sleep_mode() treba povoliť prerušenie [ funkcia sei() ]. | |||
:: Funkcia nastavuje SE bit na log. 1 a tymto povoluje uspanie. Spušťa uspanie. Po zobudeni nastavuje SE bit na log. 0. | |||
* '''sleep_enable() , sleep_cpu() , sleep_disable''' | |||
:: Funkciu na povovlenie prerušenia sei() volame medzi sleep_enable() a sleep_cpu(). | |||
:: ''sleep_enable()'' - nastavuje SE bit na log. 1. | |||
:: ''sleep_cpu()'' - uspava procesor. | |||
:: ''sleep_disable()'' - nastavuje SE bit na log. 0. | |||
sleep.h ma funkcia na vypnutie BOD (Brown-out Detector) - sleep_bod_disable(). Najlepšie vyvolať pred povolnim prerušenia. | |||
Stlačenie zapojeneho tlačitka zmeni stav na pine PD4, čo bude signalom na zobudenie. | |||
<tab name="Usporne_rezimy_Gordii_Chornyi.c"><syntaxhighlight lang="c++" style="background: LightYellow;"> | |||
#include <avr/io.h> | #include <avr/io.h> | ||
#include <avr/sleep.h> | |||
#include <avr/interrupt.h> | |||
#include <util/delay.h> | |||
int | // Delay funkcia pre požadované medzery | ||
void delay(int delay) | |||
{ | { | ||
for (int i=1; i<=delay; i++) | |||
_delay_ms(1); | |||
} | |||
#define LED PB5 // Zabudovaná LED dioda | |||
#define SW1 PD4 // Tlacitko ako zdroj externého prerušenia | |||
int main(void) | |||
{ | |||
DDRB |= ( 1 << LED ); | |||
DDRD &= ~( 1 << SW1 ); | |||
PORTD |= ( 1 << SW1 ); | |||
// SMCR - Sleep Mode Control Regiter | |||
// Ma 4 bity: SM2 , SM1 , SM0 , SE | |||
// SM2..0 zodpovedaju za výber úsporného režimu. | |||
// SE (Sleep Enable) umoznuje uspanie pri vyvolaní SLEEP inštrukcie. | |||
/* | |||
SMCR |= ( 0 << SM2 ) | ( 1 << SM1 ) | ( 0 << SM0 ); // 0 1 0 = Power-down. | |||
SMCR |= ( 1 << SM1 ); // To iste ako o riadok vyššie. Power-down | |||
SMCR |= ( 1 << SE ); // Umožnime uspanie. Radšej aktivovat tesne pred vyvolaním SLEEP inštrukcie, aby omylom neuspat skôr než treba | |||
*/ | |||
// set_sleep_mode umož?uje vybra? úsporný režim | |||
set_sleep_mode(SLEEP_MODE_IDLE); // IDLE | |||
//set_sleep_mode(SLEEP_MODE_ADC); // ADC noise Reduction | |||
//set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Power-down | |||
//set_sleep_mode(SLEEP_MODE_PWR_SAVE); // Power-save | |||
//set_sleep_mode(SLEEP_MODE_STANDBY); // Standby | |||
//set_sleep_mode(SLEEP_MODE_EXT_STANDBY); // Extended standbys | |||
while(1) | |||
{ | |||
cli(); // Zatial vypnime prerušenie. Potrebujeme ho aktívnym pred uspanim | |||
PORTB |= ( 1 << LED ); // Zapni LED a cakaj 2 sekudny | |||
delay(2000); | |||
PORTB &= ~ ( 1 << LED ); // Vypni LED a cakaj pol sekundy | |||
delay(500); | |||
PORTB |= ( 1 << LED ); // Ešte ráz zapnut a vypnut LED na kratšiu dobu | |||
delay(500); | |||
PORTB &= ~( 1 << LED ); | |||
// sleep_bod_disable(); // Deaktivujeme Brown-out Detector ak ho nepotrebujeme | |||
sei(); // Umožnit prerušenie | |||
sleep_mode(); // Aktivovat úspanie. | |||
// ako alternativa môžeme postupovat podla jednotlivých krokoch | |||
/* | |||
sleep_enable(); // Nastavi sa SE (Sleep Enable) bit | |||
sleep_bod_disable(); // Deaktivujeme Brown-out Detector ak ho nepotrebujeme | |||
sei(); // Umožnit prerušenie | |||
sleep_cpu(); // Uspi procesor | |||
sleep_disable(); // PO zobudení vycisti SE bit | |||
*/ | |||
} | |||
} | } | ||
</syntaxhighlight ></tab> | </syntaxhighlight ></tab> | ||
Zdrojový kód: [[Médiá:Usporne_rezimy_Gordii_Chornyi.7z|Usporne_rezimy_Gordii_Chornyi.7z]] | |||
== Čo by som urobil inak == | |||
Chýba praktická ukážka. | |||
Aktuálna revízia z 15:39, 23. jún 2026
Záverečný projekt predmetu MIPS / LS2026 - Gordii Chornyi
Zadanie
Cieľom tohto projektu je oboznámenie s zabudovanymí úspornymí režimami procesora.
Hardware v tomto projekte je doska ACROB s mikrokontroler ATmega328P.

Literatúra:
- How to optimize Arduino for low power design
- Sleep Modes and Power Management
- Dokumentacia k ATmega328P
- AVR® Low Power Sleep Modes
- <avr/sleep.h>: Power Management and Sleep Modes
Analýza a opis riešenia
Arduino doska može byť použitá v strojoch, ktoré s spoliehaju na externý zdroj energie a hlavné na uchovanú energiu v akumulatori. Prístup ku externému zdroju môže byť nepravidelný a nie je tak efektívny, ako by sme chceli.
V takejto situácii chceme, aby komponenty stroja využívalí čo najmenej energie a zaroveň zachovávali požadovanú efektivnosť a potrebné schopnosti.
V tomto momente, pravdepodobne, nastane problem: Chceme zobrať malu dosku s malou spotrebou energie, ale pre správnu prácu stroja musime zobrať väčšiu dosku, s väčšou spotrebou, s požadovaným výkonom a funkciami.
Ako jeden zo spôsobov vyriešiť problem veľkej spotreby energie je použiť jeden z úsporných režimov.
Nam sú dostupné 6 úsporných režimov:
- - Idle
- - ADC noise Reduction
- - Power-down
- - Power-save
- - Standby
- - Extended standby

Idle
Vypína iba procesor, a necháva dosť veľa možnosti zobudenia z vonku aj z vnutra.
Môže byť zobudený: Pretečením časovača , USART prenosom , prerušením prostrednictvom Analógového komparatora, ADC prevodnika, Timer/Counters, Watchdog , zmenou na pinoch.
ADC noise Reduction
Veľmi podobný ako Idle s rozdielom v tom, že vypína aj SPI a USART. Toto umožňuje zväčšiť kvalitu merania ADC prevodnika.
Power-down
Vypína skoro všetko. Zobudenie je možne iba cez (TWI) 2-wire serial interface, Watchdog, prerušenie na pinoch INT0 a INT1 z vonka, prerušenie z ostatných pinov.
Má možnosť vypnúť BOD - Brown-out Detector
Power-save
Od Power-down sa líši možnosťou zapnúť Timer/Counter2 v synchronnom alebo asynchronnom režime. Ak Timer/Counter2 nepotrebujem, tak lepšie zapnúť Power-down režim.
Standby
Mal by sa používať s vonkajším krýštalom alebo rezonatorom v role časovača. Je identický ku Power-DOWN s jednou vynimkou - oscilator pokračuje pracovať.
Extended standby
Mal by sa používať s vonkajším krýštalom alebo rezonatorom v role časovača. Je identický ku Power-SAVE s jednou vynimkou - oscilator pokračuje pracovať.
Zapojenie, algoritmus, program
Ku doske je pripojene jedno tlačitko s rezistorm na pine PD4 ( INT0 ). Bude využité na externe prerušenie.

Knižnica avr/interrupt.h je opcionálna. Potrebujem iba na krásne blikanie LEDky.
V main nastavime zabudovanú LED ako výstup a Tlačitko na PD4 ako vstup s pull-up.
Následne mame vybrať úsporný režim, ktorý chceme využiť.
Môžeme to spraviť dvoma spôsbmi:
- Ručne nastavime register SMCR
- Ma 4 piny - SM2, SM1 a SM0 určuje úsporný režim. SE, ktorý povoluje spustenie uspania. Bit SE je najlepšie aktivovať tesne pred spustenim uspania, aby nenastalo skôr než potrebujeme.
- Využijeme funkciu set_sleep_mode() z knižnice sleep.h [ Nastavuje SMCR za nas ]
- Do zatvoriek doplnime SLEEP_MODE_"nazov_režimu". Povolenie uspania dávame neskôr, inými funkciami.
V loope najprv vypneme prerušenie. Zapneme vtedy, kedy potrebujeme.
Zablika LEDka - signál, že procesor nespi.
Na uspanie použieme funkcie z sleep.h
- sleep_mode()
- Tesné pred sleep_mode() treba povoliť prerušenie [ funkcia sei() ].
- Funkcia nastavuje SE bit na log. 1 a tymto povoluje uspanie. Spušťa uspanie. Po zobudeni nastavuje SE bit na log. 0.
- sleep_enable() , sleep_cpu() , sleep_disable
- Funkciu na povovlenie prerušenia sei() volame medzi sleep_enable() a sleep_cpu().
- sleep_enable() - nastavuje SE bit na log. 1.
- sleep_cpu() - uspava procesor.
- sleep_disable() - nastavuje SE bit na log. 0.
sleep.h ma funkcia na vypnutie BOD (Brown-out Detector) - sleep_bod_disable(). Najlepšie vyvolať pred povolnim prerušenia.
Stlačenie zapojeneho tlačitka zmeni stav na pine PD4, čo bude signalom na zobudenie.
#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <util/delay.h>
// Delay funkcia pre požadované medzery
void delay(int delay)
{
for (int i=1; i<=delay; i++)
_delay_ms(1);
}
#define LED PB5 // Zabudovaná LED dioda
#define SW1 PD4 // Tlacitko ako zdroj externého prerušenia
int main(void)
{
DDRB |= ( 1 << LED );
DDRD &= ~( 1 << SW1 );
PORTD |= ( 1 << SW1 );
// SMCR - Sleep Mode Control Regiter
// Ma 4 bity: SM2 , SM1 , SM0 , SE
// SM2..0 zodpovedaju za výber úsporného režimu.
// SE (Sleep Enable) umoznuje uspanie pri vyvolaní SLEEP inštrukcie.
/*
SMCR |= ( 0 << SM2 ) | ( 1 << SM1 ) | ( 0 << SM0 ); // 0 1 0 = Power-down.
SMCR |= ( 1 << SM1 ); // To iste ako o riadok vyššie. Power-down
SMCR |= ( 1 << SE ); // Umožnime uspanie. Radšej aktivovat tesne pred vyvolaním SLEEP inštrukcie, aby omylom neuspat skôr než treba
*/
// set_sleep_mode umož?uje vybra? úsporný režim
set_sleep_mode(SLEEP_MODE_IDLE); // IDLE
//set_sleep_mode(SLEEP_MODE_ADC); // ADC noise Reduction
//set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Power-down
//set_sleep_mode(SLEEP_MODE_PWR_SAVE); // Power-save
//set_sleep_mode(SLEEP_MODE_STANDBY); // Standby
//set_sleep_mode(SLEEP_MODE_EXT_STANDBY); // Extended standbys
while(1)
{
cli(); // Zatial vypnime prerušenie. Potrebujeme ho aktívnym pred uspanim
PORTB |= ( 1 << LED ); // Zapni LED a cakaj 2 sekudny
delay(2000);
PORTB &= ~ ( 1 << LED ); // Vypni LED a cakaj pol sekundy
delay(500);
PORTB |= ( 1 << LED ); // Ešte ráz zapnut a vypnut LED na kratšiu dobu
delay(500);
PORTB &= ~( 1 << LED );
// sleep_bod_disable(); // Deaktivujeme Brown-out Detector ak ho nepotrebujeme
sei(); // Umožnit prerušenie
sleep_mode(); // Aktivovat úspanie.
// ako alternativa môžeme postupovat podla jednotlivých krokoch
/*
sleep_enable(); // Nastavi sa SE (Sleep Enable) bit
sleep_bod_disable(); // Deaktivujeme Brown-out Detector ak ho nepotrebujeme
sei(); // Umožnit prerušenie
sleep_cpu(); // Uspi procesor
sleep_disable(); // PO zobudení vycisti SE bit
*/
}
}
Zdrojový kód: Usporne_rezimy_Gordii_Chornyi.7z
Čo by som urobil inak
Chýba praktická ukážka.
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.