STM32 Systick

Systick je jednoduchý časovač, který je součástí jádra. Najdete ho tudíž asi u každého mikrokontroléru s jádrem Cortex. Jeho použití je triviální. Jediné co umí je totiž odpočítávat od vámi stanovené hodnoty do nuly. A jakmile podteče, vyvolá přerušení. Periodické přerušení je velmi užitečné (uživatelé Arduina by bez něj ani nerozblikali ledku), takže si v tomto minitutoriálu ukážeme jak na to.

Funkce pro konfiguraci přerušení od Systick je součástí CMSIS, takže ji musíte hledat v souboru core_cm0plus.h pod názvem SysTick_Config(). Jejím argumentem je číslo, které musí být menší jak 2^24, tedy 16777216. Toto číslo vyjadřuje počet tiků procesoru mezi dvěma přerušeními od Systicku. Pokud tedy máte frekvenci jádra dejme tomu 8MHz, a do Systicku nahrajete hodnotu 8000, dostanete přerušení každou ms. Co v rutině přerušení uděláte je už čistě na vás. Vyloženě se nabízí použít Systick na pravidelnou kontrolu klávesnice, tlačítek, potenciometrů nebo na "refresh" displeje.

Konfigurace je tak jednoduchá že nestojí za komentář. Ten zasluhuje pouze rutina přerušení. Přerušení od Systick je trochu odlišné od všech ostatních přerušení která budete používat (nebo používáte) a to tím že jej nekonfigurujete pomocí NVIC. Nepřidělujete mu prioritu a nic podobného. Vše za vás udělá funkce SysTick_Config() a vy jen musíte definovat rutinu přerušení SysTick_Handler().

// 2A) Systick
// Periodické přerušení od Systick bliká s LED na PC8
// Deska STM32F051 Discovery
#include "stm32f0xx.h"
#include "stm32f0xx_ll_bus.h" // kvůli fcím pro povolování clocku periferiím
#include "stm32f0xx_ll_gpio.h" // kvůli fcím pro práci s GPIO

int main(void){
// spustit clock pro GPIOC (LEDka)
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC);
// PC8 jako výstup
LL_GPIO_SetPinMode(GPIOC,LL_GPIO_PIN_8,LL_GPIO_MODE_OUTPUT);
// nastavíme periodu přerušení od Systicku, max 24bit číslo !
SysTick_Config(4000000); // přerušení každých 4000000 tiků procesoru
// CPU běží na 8MHz => přerušení 2x za sekundu

while (1){
 // STMko nemá co dělat...
 }
}

// Rutina přerušení Systick
void SysTick_Handler(void){
 LL_GPIO_TogglePin(GPIOC,LL_GPIO_PIN_8); // přepni LED
}

Systick bez přerušení

Pro ty z vás, kteří chtějí používat "delay" funkce a jsou ochotni kvůli nim obětovat Systick, je připravena sada funkcí v souboru stm32f0xx_ll_utils.c. Funkce LL_Init1msTick() nastavuje systick ab přetekl každou milisekundu, ale nevolal přerušení. Jejím argumentem je aktuální frekvence jádra. Přímo se proto nabízí předhodit ji proměnnou SystemCoreClock (kterou udržujeme aktuální pomocí fce SystemCoreClockUpdate() - více o tom v tutoriálu o cloku). Po konfiguraci Systicku, pak můžeme volat funkce LL_mDelay(), která čekací smyčkou (čeká na nastavení vlajky přetečení Systicku) realizuje zpoždění.

// 2B) Systick bez přerušení
// delay funkce pomocí Systick
// Deska STM32F051 Discovery
#include "stm32f0xx.h"
#include "stm32f0xx_ll_bus.h" // kvůli fcím pro povolování clocku periferiím
#include "stm32f0xx_ll_gpio.h" // kvůli fcím pro práci s GPIO
#include "stm32f0xx_ll_utils.h"

int main(void){
// spustit clock pro GPIOC (LEDka)
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC);
// PC8 jako výstup
LL_GPIO_SetPinMode(GPIOC,LL_GPIO_PIN_8,LL_GPIO_MODE_OUTPUT);
// kalkulace frekvence jádra
SystemCoreClockUpdate();
// konfigurace Systicku na 1ms periodu
LL_Init1msTick(SystemCoreClock);

while (1){
 LL_GPIO_SetOutputPin(GPIOC,LL_GPIO_PIN_8); // rozsviť LED
 LL_mDelay(500); // počkej 500ms
 LL_GPIO_ResetOutputPin(GPIOC,LL_GPIO_PIN_8); // zhasni LED
 LL_mDelay(500); // počkej 500ms
 }
}

Home
V1.00 23.7.2017
By Michal Dudka (m.dudka@seznam.cz)