LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

STM32F0Discovery: jak zacząć

Ostatnia funkcja z dostępnych w omawianym pliku pobiera stan linii PA0 i zwraca wartość SET (przycisk włączony) lub RESET (przycisk wyłączony):

uint32_t STM_EVAL_PBGetState(Button_TypeDef Button){
  /* There is no Wakeup button on STM32f0-Discovery Kit */
  return GPIO_ReadInputDataBit(BUTTON_PORT[Button], BUTTON_PIN[Button]);
}

Program główny

Algorytm działania programu głównego jest następujący:

  • po podłączeniu układu do portu USB komputera zaczyna migać zielona dioda LED z częstotliwością 2,5 Hz,
  • jeżeli zostanie wciśnięty przycisk USER i przytrzymany aż do zapalenia się niebieskiej diody LED to zielona dioda zacznie migać szybciej, z częstotliwością 5 Hz,
  • ponowne wciśnięcie i przytrzymanie przycisku USER do ponownego zapalenia się niebieskiej diody powoduje, że zielona dioda zostanie wyłączona,
  • kolejne wciśnięcia przycisku powodują powtórzenie powyższych działań.

Listing funkcji main() z pliku main.c przedstawiono poniżej:

int main(void){
  RCC_ClocksTypeDef RCC_Clocks;
  
  /* Konfiguracja wyprowadzeń z diodami LED3 i LED4 */
  STM_EVAL_LEDInit(LED3);
  STM_EVAL_LEDInit(LED4);
  
  /* Konfiguracja wyprowadzenia z przyciskiem USER */
  STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_GPIO);
  
  /* Konfiguracja SysTick do odliczania 1 ms */
  RCC_GetClocksFreq(&RCC_Clocks);
  SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
   
  /* Wybór trybu migania diody */
  BlinkSpeed = 1;
  
  while(1){  
    /* Czy przycisk USER jest wciśnięty? */
    if(STM_EVAL_PBGetState(BUTTON_USER)== SET){
      /* Jeżeli wciśnięty, to wykonaj poniższy fragment program */
      /* BlinkSpeed: 1 -> 2 -> 0, then re-cycle */
      /* Włącz niebieską diodę LED4 na czas 1s */
      STM_EVAL_LEDOn(LED4);
      
      /* Czekaj 1s */
      Delay(1000);
      
      /* Wyłącz diodę LED4 */
      STM_EVAL_LEDOff(LED4);
      
      /* Wybierz kolejny tryb migania */
      BlinkSpeed++;
      
      /* Jeżeli BlinkSpeed == 3 */
      if(BlinkSpeed == 3){
        /* Wybierz tryb 0 – dioda nie świeci */
        BlinkSpeed = 0;
      }
    }
    
    /* Sprawdź jaki tryb wybrano */
    if(BlinkSpeed == 2){
      /* LED3 zmienia stan co 100 ms */
      STM_EVAL_LEDToggle(LED3);
      
      /* Czekaj 100ms */
      Delay(100);
    }
    else if(BlinkSpeed == 1){
      /* LED3 zmienia stan co 200 ms */
      STM_EVAL_LEDToggle(LED3);
      
      /* Czekaj 200ms */
      Delay(200);
    }
    else{  
      /* Wyłącz diodę LED3 */
      STM_EVAL_LEDOff(LED3);
    }
  }
}

Odliczanie czasu 1 ms jest realizowane przez systemowy timer SysTick, który domyślnie zlicza kolejne takty sygnału zegarowego HCLK do zadanej przez użytkownika wartości, a po przekroczeniu jej zeruje licznik i generuje zdarzenie, które skutkuje pojawieniem się przerwania i wywołaniem funkcji obsługi przerwania SysTick_Handler(), której zawartość może być modyfikowana w pliku SysTick_Handler(). Częstotliwość sygnału HCLK wynosi 48 MHz – szczegóły znajdują się w pliku system_stm32f0xx.c.

Na początku funkcji main() jest deklarowana zmienna RCC_Clocks, która jest przekazywana jako argument do funkcji RCC_GetClocksFreq(). Jest to potrzebne do pobrania informacji o częstotliwościach poszczególnych zegarów w systemie, a w danym przypadku interesuje nas częstotliwość zegara HCLK, która zostanie podzielona przez 1000 i przekazana do funkcji SysTick_Config(). Oznacza to w danym konkretnym przypadku, że jeżeli wartość pola HCLK_Frequency podzielimy przez 1000 to otrzymamy 48,000 i po przekazaniu jej do powyższej funkcji SysTick będzie zliczał 48,000 impulsów sygnału zegarowego HCLK po czym wygeneruje przerwanie. Podczas działania programu przerwanie to będzie generowane przez cały czas co 1 ms.

Wywołanie funkcji Delay() z argumentem w jednostkach 1 ms powoduje zapisanie do zmiennej TimingDelay wartości tego argumentu oraz oczekiwanie w pętli while() dopóki zmienna ta jest różna od 0:

void Delay(__IO uint32_t nTime){
  TimingDelay = nTime;
  while(TimingDelay != 0);
}

Zmienna TimingDelay jest dekrementowana (jeżeli jest różna od zera) w funkcji TimingDelay_Decrement() wywoływanej co 1 ms z funkcji obsługi przerwania od SysTick:

void TimingDelay_Decrement(void){
  if (TimingDelay != 0x00){
    TimingDelay--;
  }
}
Autor: Jan Szemiet