Zachodniopomorski Uniwersytet Technologiczny WYDZIAŁ ELEKTRYCZNY Katedra Inżynierii Systemów, Sygnałów i Elektroniki LABORATORIUM Podstawy Programowania Mikroprocesorów i Procesorów DSP Timery w mikrokontrolerach STM32F3 Opracował: mgr inż. Andrzej Biedka 1
Komunikacja między blokami wewnętrznymi mikrokontrolera odbywa się za pośrednictwem magistral cyfrowych. System magistral w kontrolerach rodziny STM32 wykorzystuje kilka rodzajów magistral, różniących się prędkością pracy i wydajnością transmisji. Podstawowymi magistralami obsługującymi urządzenia peryferyjne są: AHB APB Advanced High-performance Bus Advanced Peripheral Bus Układy timerów mikrokontrolera STM32F303RE przyłączone są do dwóch różnych magistral APB. Timery 2, 3, 4 będące timerami ogólnego przeznaczenia (ang. general-purpose timers) oraz timery 6, 7 będące timerami podstawowymi (basic timers) przyłączone są do magistrali APB1, taktowanej z maksymalną częstotliwością 36 MHz. Timery 15, 16, 17 będące timerami ogólnego przeznaczenia (ang. general-purpose timers) oraz timery 1, 8, 20 będące timerami zaawansowanymi (advanced-control timers) przyłączone są do magistrali APB2, taktowanej z maksymalną częstotliwością 72 MHz. Timer 2 jest timerem 32-bitowym, pozostałe są 16-bitowe. Uproszczony schemat blokowy przyporządkowania magistral przedstawiony jest na rysunku 1 porównaj schemat blokowy mikrokontrolera zawarty w karcie katalogowej STM32F303RE.pdf dostępnej na stronie www.st.com. AHB1 APB1 APB1 (f max = 36 MHz) AHB Timer 2 (32-bit) Timer 3 Timer 4 Timer 6 Timer 7 AHB2 APB2 APB2 (f max = 72 MHz) Timer 15 Timer 16 Timer 17 Timer 1 Timer 8 Timer 20 Rys. 1. Schemat blokowy sterowania timerów mikrokontrolera STM32F303RE. Przed użyciem wybranego timera należy włączyć taktowanie właściwej magistrali oraz włączyć wybrany/wybrane timery. Poniższy schemat przedstawia ścieżkę źródeł sygnałów zegarowych niezbędnych do pracy timerów porównaj schemat blokowy bloku RCC dostępny w karcie STM32F303xB/C/D/E Reference Manual. 8MHz HSI RC HSI SYSCLK HCLK AHB bus max. 72MHz OSC_IN OSC_OUT /1...16 PLL x2...x16 PLL CLK AHB presk. /1...512 APB1 presk. /1...16 PPRE1 APB1 bus max. 36MHz PLL SRC PREDIV PLL MUL SW HPRE APB2 presk. /1...16 APB2 bus max. 72MHz 4-32 MHz HSE OSC HSE PPRE2 Rys. 2. Schemat blokowy źródeł taktowania magistral APB mikrokontrolera STM32F303RE. 2
Struktura i zasada pracy timerów w mikrokontrolerach STM32 jest zbliżona do rozwiązań stosowanych w mikrokontrolerach 8-bitowych. Jako przykładowy timer zostanie użyty Timer6 należący do grupy timerów podstawowych, wymagających najmniejszej ilości instrukcji konfiguracji. - zdarzenie - przerwanie Rys. 3. Schemat blokowy timera podstawowego (Timer6 i Timer7) mikrokontrolera STM32F3. Źródło: STM32F303 Reference Manual. Zgodnie ze schematami z rysunków 1 i 2 dla uruchomienia timera 6 konieczne będzie: odblokowanie taktowania magistrali APB1, ustawienie jej preskalera, (bity PPRE1), załadowanie rejestru preskalera timera 6, rejestr (PSC) jego rejestru automatycznego przeładowania, rejestr (ARR) odblokowanie timera6, co rozpocznie pracę bloku. Zdarzenie zrównania stanu licznika głównego (CNT counter) z zawartością rejestru automatycznego przeładowania ( Auto-reload register) spowoduje ustawienie flagi (bitu) UIF w rejestrze statusu timera 6. Jeśli program będzie wykorzystywał metodę pollingu, stan tego bitu powinien być sprawdzany w celu wykrycia chwili wystąpienia zdarzenia. Timery mikrokontrolerów STM32F3 mają do 24 rejestrów konfiguracyjnych - (plik stm32f303xe.h linie 665-697). Ilość rejestrów zależna jest od grupy, do której należy dany timer. Rejestry używane w podstawowych trybach pracy przedstawione są w tablicy 1. Lp Tablica 1. Rejestry konfiguracyjne timerów 6 i 7 mikrokontrolerów STM32F3 Nazwa rejestru Ilość bitów Opis rejestru Strona RefMan. 1 CR1 32 Rejestr sterujący 1 control register 1 677 2 CR2 32 Rejestr sterujący 2 control register 2 679 3 DIER 32 Rejestr masek przerwań i układu DMA 679 4 SR 32 Rejestr statusowy flag zdarzeń/przerwań 680 5 CNT 32 Główny licznik timera: timer2 32bity, pozostałe 16 bitów 680 6 PSC 16 Rejestr preskalera timera 681 7 ARR 16 Rejestr automatycznego przeładowania licznika głównego 681 3
Przykładowy program wykorzystujący timer nr 6 przedstawia listing: // Program generatora przebiegu symetrycznego, f = 1 Hz int main(void) RCC->AHBENR = RCC_AHBENR_GPIOAEN; // wlaczenie taktowania magstrali AHB GPIOA->MODER = GPIO_MODER_MODER5_0; // wybor trybu pracy linii 5 portu GPIOA // timer 6 RCC->APB1ENR = RCC_APB1ENR_TIM6EN; // wlaczenie taktowania bloku timera 6 TIM6->PSC = 2000; // preskaler timera 6 TIM6->ARR = 2000; // rejestr automatycznego przeladowania TIM6->CR1 = TIM_CR1_CEN; // wlaczenie zliczania impulsow wejsciowych timera 6 while ( 1 ) while(!(tim6-> SR & TIM_SR_UIF)); TIM6->SR &= ~TIM_SR_UIF; GPIOA->ODR ^= GPIO_ODR_5; //czekaj na ustawienie flagi zdarzenia //kasuj flage // neguj bit 5 GPIOA return 0; Zadania: 1. Zmodyfikować program wykorzystując timer 2, częstotliwość przebiegu wyjściowego = 2 Hz. 2. Zmodyfikować program wykorzystując timer 1, częstotliwość przebiegu wyjściowego = 3 Hz. 3. Wykorzystując dwa timery napisać program generowania impulsu o czasie 6 ms w okresie 1 s. Timer specjalny SysTick SysTick jest układem peryferyjnym rdzenia mikrokontrolera. Jest prostym timerem z licznikiem 24-bitowym, zliczającym w dół. Po osiągnięciu zera ponownie ładuje zaprogramowaną ilość impulsów i kontynuuje zliczanie. Może wygenerować przerwanie. SysTick nie posiada innych trybów pracy takich jak np.: PWM. Najczęstszym zastosowaniem tego timera jest generowanie tzw przerwania zegarowego w systemie. Do uruchomienia bloku przeznaczona jest funkcja biblioteczna: uint32_t SysTick_Config(uint32_t ticks) Argumentem funkcji jest ilość taktów systemu (SYSCLK) jakie upływają do chwili wyzerowania licznika. Przykładowy program wykorzystujący SysTick: int main(void) RCC->AHBENR = RCC_AHBENR_GPIOAEN; // wlaczenie taktowania magstrali AHB GPIOA->MODER = GPIO_MODER_MODER5_0; // wybor trybu pracy linii 5 portu GPIOA SysTick_Config(8000000); // ustawianie ilosci tickow zegara systemowego while ( 1 ); return 0; void SysTick_Handler(void) // funkcja obslugujaca zdarzenie GPIOA->ODR^= GPIO_ODR_5; // negacja bitu sterujacego LED 4
System przerwań System przerwań mikrokontrolerów STM32Fx oferuje więcej możliwości niż poznany wcześniej system stosowany w rodzinie AVR, co implikuje większą komplikację struktury wewnętrznej bloku przerwań rodziny STM32Fx. Blok obsługi przerwań nosi nazwę Nested Vectored Interrupt Controller NVIC, sterownik zagnieżdżonych przerwań wektoryzowanych. Podstawowe właściwości NVIC są następujące: ścisłe powiązanie NVIC z rdzeniem mikrokontrolera zapewnia małe opóźnienia obsługi przerwań wektory przerwań przekazywane są z tablicy bezpośrednio do rdzenia w obsłudze przerwania stan procesora jest zapamiętywany i odtwarzany automatycznie mikrokontroler STM32F3x obsługuje 74 źródeł przerwań pochodzących od urządzeń peryferyjnych mikrokontroler STM32F3x obsługuje 16 źródeł przerwań pochodzących zdarzeń rdzenia możliwa jest zmiana priorytetu przerwań 16 poziomów priorytetu nie jest używana flaga globalnego zezwolenia na przrerwanie W zakresie ćwiczeń przedmiotu stosowane będą podstawowe, ustawiane domyślnie, funkcje układu przerwań. Odblokowanie danego źródła przerwania dokonywane jest funkcją o konstrukcji: NVIC_EnableIRQ(TIM2_IRQn); Nazwa funkcji Nazwa wektora przerwania dla timera 2 jednakowa dla wszystkich (plik stm32f303xe.h linie 86-169) źródeł przerwań Jeśli zachodzi potrzeba zablokowania żądań pochodzących z danego źródła przerwania należy wywołać funkcję: NVIC_DisableIRQ(TIM2_IRQn); Czynności wchodzące w zakres obsługi danego przerwania należy umieścić w funkcji: void TIM2_IRQHandler(void) // obsluga przerwania timera 2 W odróżnieniu od rodziny AVR mikrokontrolery STM32Fx generują wektor przerwania przypisany do typu danego zasobu, np. timera. Jak wiadomo, dane urządzenie peryferyjne mikrokontrolera może generować przerwania z różnych przyczyn. Pozostając przy przykładzie timera przerwanie może być efektem przepełnienia licznika głównego timera, zrównania stanu licznika głównego z rejestrem porównawczym lub innymi zdarzeniami w timerze. Zatem w funkcji obsługi przerwania należy przeprowadzić analizę potencjalnych źródeł zgłoszonego przerwania i wykonać treść obsługi właściwą dla wykrytego źródła. Ogólna postać takiej funkcji będzie następująca: void TIM2_IRQHandler(void) if(tim2->sr & IntFlag_1)obsluga_1 // jeśli zglasza flaga 1 // wykonaj obsluge nr 1 if(tim2->sr & IntFlag_2)obsluga_2 // jeśli zglasza flaga 2 // wykonaj obsluge nr 2 if(tim2->sr & IntFlag_n)obsluga_n // jeśli zglasza flaga n // wykonaj obsluge nr n Przykładowy program generatora przebiegu o częstotliwości 2Hz przedstawiony jest na poniższym listingu: 5
int main(void) // program generatora przebiegu symetrycznego, f = 2Hz // GPIOA_5 RCC->AHBENR = RCC_AHBENR_GPIOAEN; GPIOA->MODER = GPIO_MODER_MODER5_0; // RM 237 // timer 2 RCC->CFGR = RCC_CFGR_PPRE1_DIV1; // preskaler magistrali APB1 RCC->APB1ENR = RCC_APB1ENR_TIM2EN; // odblokowanie zegara magistrali APB1 TIM2->PSC = 2000; // preskaler timera = 2000 TIM2->ARR = 1000; // rejestr przepelnienia = 1000 TIM2->CR1 = TIM_CR1_CEN; // start licznika TIM2->DIER = TIM_DIER_UIE; // odblokowanie maski przerwania od przepelnienia timera NVIC_EnableIRQ(TIM2_IRQn); // odblokowanie przerwania w sterowniku NVIC while(1); return 0; void TIM2_IRQHandler(void) if(tim2->sr & TIM_SR_UIF) // sprawdzenie wewnetrznego zrodla przerwania TIM2->SR &= ~TIM_SR_UIF; // skasuj flage zgloszenia przerwania GPIOA->ODR ^= GPIO_ODR_5; // algorytm przerwania neguj stan LED 6