niedziela, 2 października 2016

[18] STM32F4 - Ustawianie Systicka

Ten post chciałbym poświęcić na opisanie generowania przerwania od Systicka co określoną ilość czasu.

Systick jest to 24 bitowy timer. Działa on na takiej zasadzie, że zlicza od podanej wartości do 0. Gdy dojdzie się do 0 to jest zgłaszane przerwanie. Dzięki temu można go wykorzystać do generacji funkcji opóźniających, czy odliczania czasu w mikrokontrolerze.

Programowanie:


Przykłady zaprezentuje w oparciu o biblioteki API. Na samym początku Systicka należy włączyć. Wykonuje się to w następujący sposób:

  1. uint8_t SYSTICK_ON(uint8_t value)
  2. {
  3.     if(value == 1)
  4.     {
  5.         if (SysTick_Config(SystemCoreClock / 1000000))
  6.         {   while (1);  }
  7.     }
  8.     else
  9.     {
  10.         if (SysTick_Config(SystemCoreClock / 1000))
  11.         {   while (1);  }
  12.     }
  13.     return 1;
  14. }

Jeśli do tej funkcji zostanie podany parametr value = 1, to przerwanie będzie wygenerowane co 1us. Gdy zostanie podana jakakolwiek inna wartość to przerwanie będzie wywołane co 1ms.

W przypadku pracy mikrokontrolera z częstotliwością wynoszącą 168MHz, przerwanie będzie wywołane co 168 taktów STM-a.

Kolejna funkcja ma za zadanie odliczyć czas jaki ma upłynąć w us.

  1. static __IO uint32_t TimingDelay;
  2. void DELAY_US(__IO uint32_t Time_us)
  3. {
  4.   TimingDelay = Time_us;
  5.   while(TimingDelay != 0);
  6. }


Podawany czas jest przypisywany do zmiennej systemowej. Następnie pętla while jest wykonywana do momentu gdy zmienna TimingDelay nie osiągnie wartości 0.

Jeśli przerwanie generowane jest co 1us to funkcja odliczająca czas w ms wygląda następująco:

  1. static __IO uint32_t TimingDelay;
  2. void DELAY_MS(__IO uint32_t Time_ms)
  3. {
  4.   TimingDelay = (Time_ms*1000);
  5.   while(TimingDelay != 0);
  6. }

W tym przypadku zmienna zostaje pomnożona przez 1000.

Ostatnia funkcja jaka będzie potrzebna to obsługa przerwania wywoływanego przez systicka. W niej należy zmniejszać wartość z zdeklarowanym czasem przerwania.

  1. void TimingDelay_Decrement(void)
  2. {
  3.   if (TimingDelay != 0x00) { TimingDelay--; }
  4. }

Może zajść potrzeba aby wyłączyć Systicka w pewnym momencie. Można ty wykonać na rejestrach w następujący sposób:

  1. SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;

Co do włączenia to wygląda następująco:

  1. SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;

Powyższe linie wpływają tylko na działanie przerwań, są one albo generowane albo nie. W kolejnym poście przedstawię bardzo podobny sposób odliczania czasu tylko, że na zwykłym timerze.