06 lipca 2018

SysTick - timer systemowy

Skoro już pojawiły się przerwania wspomnę jeszcze o bardzo przydatnym module timera systemowego. Jest to 24-bitowy licznik, który można wykorzystać np. do generowania zdarzeń systemowych - tick-ów, stąd jego nazwa.
Sam timer jest podobnie jak NVIC nadzorowany bezpośrednio przez ARM-a, więc dokumentacji moża szukać tutaj: Cortex-M4 Programming manual
Aby skorzystać z tego timera wystarczy ustawić wartość dwóch rejestrów oraz napisać procedurę obsługi przerwania.
Najpierw omówmy rejestr kontrolny, czyli SysTick->CTRL. Znajdziemy w nim następujące, interesujące nas bity:
  • CLKSOURCE - ustawienie sprawia, że licznik używa bezpośrednio zegara systemowego (AHB), wyzerowanie włącza dzielnik /8
  • TICKINT - włącza generowanie przerwania
  • ENABLE - uruchamia licznik
Zanim uruchomimy licznik musimy jeszcze ustawić częstotliwość generowania przerwań. W tym celu do rejestru SysTick->LOAD wpisujemy pomniejszoną o 1 liczbę cykli zegara po których ma pojawić się przerwanie.
Pamiętamy, że domyślnym źródłem taktowania mikrokontrolera jest wbudowany generator 16MHz - teraz można napisać prosty przykładowy program.

#include <stdint.h>
#include <stdbool.h>
#include "stm32f429xx.h"

volatile uint32_t ms_counter = 0;

void SysTick_Handler(void)
{
        if (ms_counter)
                ms_counter--;
}

void delay_ms(uint32_t ms)
{
        ms_counter = ms;
        while (ms_counter) ;
}

int main(int argc, char *argv[])
{
        RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOGEN;

        GPIOG->MODER |= GPIO_MODER_MODE13_0|GPIO_MODER_MODE14_0;

        SysTick->LOAD = 16000-1;
        SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
                        SysTick_CTRL_TICKINT_Msk |
                        SysTick_CTRL_ENABLE_Msk;

        while (1) {
                GPIOG->BSRR = GPIO_BSRR_BS13;
                GPIOG->BSRR = GPIO_BSRR_BR14;
                delay_ms(500);

                GPIOG->BSRR = GPIO_BSRR_BS14;
                GPIOG->BSRR = GPIO_BSRR_BR13;
                delay_ms(500);
        }

        return 0;
}

Procedury delay_ms() wykorzystują omawiany timer do wprowadzania opóźnień w programie. To znacznie lepsza metoda niż używane wcześniej pętle.

Brak komentarzy:

Prześlij komentarz