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--; } }