5.5. ODSTAVENÝ REŽIM
V hlavním programu nastavíme všechny periferie, spustíme časovač a přepneme kontroler do odstaveného režimu s nastavením návratu do odstaveného režimu po opuštění obsluhy přerušení. int main(void) { zapniLse(); nastavUart(); nastavCasovac(); spustCasovac(); // vrati se do odstaveneho rezimu po opusteni ISR SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; // nastavi odstaveny rezim pri operaci "wfi" SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // zapne odstaveny rezim probuzeny prerusenim asm("wfi"); while(1); }
Tento program se nikdy nedostane k nekonečné smyčce na konci hlavního programu. Bude neustále v ostaveném režimu mimo momenty obsluhy přerušení. Do ní se dostane dvakrát za sekundu a odešle z ní pomocí sériové komunikace znak „x“. Odběr tohoto programu v odstaveném režimu je přibližně 16,8 µA. Odběr je v porovnání s předchozími příklady vyšší kvůli zapnutému LSE a zapnutému časovači.
91 Ukázka elektronické knihy, UID: KOS514568
KAPITOLA 5. ÚSPORNÉ REŽIMY A PERIFERIE
5.5.4
Příklad 17 – Probuzení pomocí RTC AWU
K probuzení z odstaveného režimu můžeme použít AWU (Automatic Wake Up – automatické probuzení) obvodu reálného času. K automatickému probuzení dojde při spuštění alarmu RTC periferie. To nám umožní kontroler probudit například jednou za minutu, hodinu, den, měsíc či rok. Náš příklad bude mít za úkol probudit kontroler 3 sekundy po startu programu a poté každou minutu. Po probuzení program odešle počet uběhlých minut po sériové lince. Nastavení LSI a USART2 je shodné s předchozím příkladem. V inicializaci RTC nejprve odblokujeme zápis do RCC konfiguračních registrů. Poté zavoláme funkci na nastavení času a alarmu (uvedena později) a povolíme všechna potřebná přerušení. Zajímavostí obvodu RTC je budící přerušení alarmu. To je totiž napojené na linku 17 obvodu EXTI . Proto ji musíme aktivovat a nastavit reakci na náběžnou hranu události.
Úryvek tabulky linek přerušení EXTI [1]
92 Ukázka elektronické knihy, UID: KOS514568
5.5. ODSTAVENÝ REŽIM
Inicializace vypadá následovně: void nastavRtcAwu(void) { // zapne periferii nastaveni napajeni RCC->APB1ENR |= RCC_APB1ENR_PWREN; // vypne ochranu pred zapisem do RCC->CSR registru // a do vsech registru RTC PWR->CR |= PWR_CR_DBP; // zvoli LSE jako zdroj hodinoveho signalu pro RTC a zapne jej RCC->CSR |= (RCC_CSR_RTCSEL_LSE | RCC_CSR_RTCEN); inicializaceCasuAAlarmu(); // povoli linku 17 externiho preruseni EXTI->IMR |= EXTI_IMR_IM17; // nastavi lince ext. preruseni 17 reakci na nabeznou hranu EXTI->RTSR |= EXTI_RTSR_RT17; // povoli preruseni linky ARM pro RTC NVIC->ISER[0] |= (1U << RTC_IRQn);
}
// povoli preruseni alarmu A RTC->CR |= RTC_CR_ALRAIE;
Inicializační funkce využívá funkci inicializaceCasuAAlaramu. Ta nastavuje aktuální čas a čas alarmu A. Právě tento alarm je v příkladu použit jako zdroj automatického probuzení AWU. Ve funkci nejprve odblokujeme zápis do konfiguračních registrů. RTC přepneme do inicializačního režimu, který nám dovolí vynulovat časový registr. Poté nastavíme alarm tak, aby mezi časovým registrem a registrem alarmu porovnával pouze hodnoty sekund (datum, hodiny a minuty budou ignorovány) Alarm nastavíme na hodnotu 3 sekundy. To se projeví tak, že k přerušení a probuzení dojde 3 sekundy po spuštění obvodu reálného času a poté každou minutu. Poznámka: Předdělička obvodu reálného času má ve výchozím nastavení hodnoty vytvářející ze zdroje hodinového signálu o frekvenci 32,768 kHz kmitočet 1 Hz, proto jej není nutné měnit.
93 Ukázka elektronické knihy