[DLA POCZĄTKUJĄCYCH] Pierwsze kroki z zestawami STM32NUCLEO

Zestawy STM32NUCLEO tworzą rodzinę tanich narzędzi startowych i ewaluacyjnych, umożliwiających szybkie i łatwe wejście w świat mikrokontrolerów 32-bitowych zarówno początkującym jak i zaawansowanym elektronikom. Są one przystosowane do współpracy z shieldami z systemu Arduino i przy tym wyposażone w profesjonalny interfejs do programowania oraz debugowania, który współpracuje z wieloma, także bezpłatnymi, środowiskami programistycznymi.
W artykule użyjemy zestawu o nazwie NUCLEO-F411RE, który jest wyposażony w szybki mikrokontroler o dużej mocy obliczeniowej należący do rodziny STM32F4 (rdzeń Cortex-M4F), ale prezentowany w artykule sposób przygotowania środowiska pracy jest identyczny dla wszystkich zestawów z rodziny STM32NUCLEO.




STM32NUCLEO jako baza prototypu
Nowoprojektowane urządzenie składa się zazwyczaj z kilku bloków funkcjonalnych. Obok mikrokontrolera może to być klawiatura, wyświetlacz, bloki interfejsów do komunikacji z otoczeniem, czujników itd. Ponieważ NUCLEO-F411RE nawiązuje do filozofii Arduino wyposażone zostało w standardowe co do wymiarów złącza do których można dołączać kolejne płytki z potrzebnymi układami bądź interfejsami w tym takie które mogą pracować z Arduino.


Wyposażenie płytki prototypowej
Zestawy STM32NUCLEO opracowano jako alternatywę płytek prototypowych STM32DISCOVERY. Płytki DISCOVERY z STM32 oprócz kontrolera mają zamontowany zestaw arbitralnie dobranych komponentów np. wyświetlacz, interfejsy, czujniki, pamięci, które są na stałe podłączone do określonych wyprowadzeń.
Na płytkach STM32NUCLEO oprócz mikrokontrolera, przycisku zerującego, stabilizatora i diody sygnalizacyjnej zamontowane są tylko dwa dodatkowe elementy, które można oprogramować: przycisk i dioda LED. Integralną częścią jest także programator zgodny z ST-Link. Pozostałe układy na dodatkowych płytkach można dobudowywać korzystając ze standardowych złącz Arduino Uno. Dodatkowo wszystkie wyprowadzenia kontrolera połączone są z osobnymi złączami szpilkowymi.
Zestaw NUCLEO-F411RE może być zasilany z jednego z 3 źródeł napięcia:



  • CN1 -złącza mini USB programatora. W tym przypadku maksymalne obciążenia wnoszone przez układ kontrolera i dołączonych rozszerzeń mogą być rzędu 100mA.

  • VIN -zewnętrzne napięcie stałe 7-12V doprowadzane do złącz CN6-8 lub CN7-24. W tym przypadku obciążenia wnoszone przez dołączane płytki nie mogą przekraczać 800 mA (dla 7V) i 250 mA (dla 12V).

  • E5V -zewnętrzne napięcie stabilizowane +5V o maksymalnej wydajności 500 mA.

W standardowej konfiguracji przy wykorzystaniu do zasilania złącza USB programatora powinny na płytce być założone następujące zwory: CN2 (2 zwory), JP6, JP5 (w pozycji U5V).


Sterowniki
Do uruchomienia komunikacji z zintegrowanym z płytką NUCLEO-F411RE programatorem prawdopodobnie trzeba będzie zainstalować sterowniki. W tym celu należy wejść na stronę i pobrać plik STSW-LINK007. Po rozpakowaniu i standardowej instalacji programator powinien być widziany w systemie i obsługiwany chociażby przez program ST-Link Utility.


Narzędzia do pisania oprogramowania
Oprócz wyposażenia sprzętowego o sile i funkcjonalności każdego urządzenia mikroprocesorowego decyduje jego oprogramowanie. Do pisania i testowania oprogramowania potrzebne są narzędzia programistyczne w tym kompilator. Dla kontrolera STM32F411 zamontowanego na płytce NUCLEO-F411RE istnieje sporo narzędzi programistycznych jednak najbardziej interesujące są te najbardziej dostępne czyli częściowo lub całkowicie bezpłatne. Dla porównania przedstawione zostaną trzy z nich: mbed, Keil/ARM MDK, CoIDE.


Środowisko programistyczne mbed
mBed jest czymś więcej niż środowiskiem programistycznym. Jest to portal internetowy, który oferuje narzędzia do szybkiego tworzenia oprogramowania dla wybranych typów płytek ewaluacyjnych z 32-bitowymi mikrokontrolerami rodziny ARM Cortex-M. Inicjatywa jest wspierana przez wiele firm produkujących mikrokontrolery ARM i urządzenia na nich oparte.
Warunkiem koniecznym do korzystania z portalu jest rejestracja i założenie swojego konta. Można wejść na stronę główną portalu https://mbed.org/ i klikając link Developer Site przejść do strony logowania bądź rejestracji. Po rejestracji i zalogowaniu się można przejść do strony środowiska programistycznego klikając na link Compiler. Powinien wyświetlić się pulpit przypominający ten z rysunku 1.



Rys. 1.


W prawym górnym rogu pulpitu znajduje się przycisk z nazwą platformy programistycznej czyli typem płytki ewaluacyjnej dla której tworzone będzie oprogramowanie. Klikając na ten przycisk można otworzyć okno wyboru platformy, takie jak na rysunku 2. W tym oknie można dodać do menu nowy rodzaj płytki lub z wcześniej wybranych wskazać tą z którą aktualnie chcemy pracować.



Rys. 2.


Mocną stroną platformy jest duża ilość programów demonstracyjnych dostępnych od ręki. Wystarczy użyć przycisku Import a na pulpicie wyświetlone zostaną dziesiątki kolejnych stron prostych programów pobieranych z bazy danych portalu. Dodatkowo możemy zawęzić ilość proponowanych programów tylko do tych związanych z interesującym nas problemem np. sterowaniem diody LED zainstalowanej na NUCLEO-F411RE. Należy w polu Search criteria wpisać słowo led i przycisnąć Search. Wyświetlone zostaną te programy w których nazwie lub opisie znajdzie się wyszukiwane słowo.
Jednym z najprostszych może być Nucleo_blink_led demonstrujący w jaki sposób na powitanie można zamigotać diodą LD2. Cały kod zawarty w pliku main.c jest następujący:


    while(1) {


        myled = 1; // LED is ON


        wait(0.2); // 200 ms


        myled = 0; // LED is OFF


        wait(1.0); // 1 sec


    }


}



Użytkownik może dowolnie modyfikować kod dostosowując do własnych potrzeb. Potem wystarczy nacisnąć klawisz Compile i po chwili potrzebnej na kompilację pojawi się komunikat z zapytaniem o miejsce zapisania otrzymanego pliku wynikowego. Po podaniu katalogu docelowego na dysku twardym użytkownika z portalu zostanie przesłany i zapisany plik Nucleo_blink_led_NUCLEO-F411RE.bin. Taki plik binarny nadaje się do zapisu do pamięci FLASH kontrolera za pośrednictwem zintegrowanego z płytką programatora. Do obsługi programatora można użyć firmowego programu firmy ST o nazwie STM32 ST-LINK UTILITY.
Innym prostym programem demonstrującym obsługę przycisku B1 na płytce NUCLEO-F411RE jest Nucleo_read_button. Cały kod źródłowy zawarty w pliku main.c wygląda następująco:


Tworzenie od podstaw przez użytkownika własnych programów wymaga znajomości bibliotek mbed.h. Biblioteki przeznaczone są do konkretnych typów płytek ewaluacyjnych więc trudno zastosować je do pisania programów dla kontrolerów we własnych urządzeniach. Bardzo jednak przyśpieszają testowanie poszczególnych rozwiązań i układów stosowanych w płytkach ewaluacyjnych.



Środowisko programistyczne Keil/ARM MDK
Zintegrowane środowisko programistyczne ARM-MDK jest płatnym pakietem programów dla mikrokontrolerów z rdzeniami ARM w tym STM32. W bezpłatnej wersji demo można generować kod wynikowy o objętości do 32kB. Nie jest to dużo ale zupełnie wystarcza dla prostych przykładów i nieskomplikowanych programów. Wielkim atutem Keil-a jest duża ilość przykładów w formie gotowych pakietów przygotowanych dla różnych typów kontrolerów. Dodatkową zaletą jest możliwość generowania szkieletów programów w formacie Keil-a przez graficzny konfigurator STM32CubeMX.


Graficzny konfigurator STM32CubeMX
Graficzny konfigurator STM32CubeMX jest narzędziem pozwalającym między innymi na wygenerowanie szkieletu programu źródłowego w formie pakietu gotowego do kompilacji w środowisku Keil-a. Po wybraniu obiektu (typu kontrolera lub płytki ewaluacyjnej) oraz pożądanych ustawień np. określeniu które porty będą używane jako wejścia, wyjścia, jakie interfejsy i zasoby sprzętowe będą używane (np. UART, timery itp.) automatycznie tworzone są pliki źródłowe dla środowiska Keil. W plikach zawarte są kompletne procedury inicjujące: procedura inicjacji kontrolera, podłączanie wewnętrznych impulsów zegarowych do wybranych interfejsów, ustawianie portów i interfejsów w wybranym trybie pracy. Resztę programu związanego z logiką jego działania użytkownik tworzy samodzielnie. Pliki instalacyjne konfiguratora można pobrać ze strony www.st.com/stm32cube.
Po zainstalowaniu programu i uruchomieniu wybieramy opcję nowego projektu. Teraz należy wskazać obiekt czyli typ kontrolera lub płytki. W (STM32CubeMX wersja 4.6.0 lub nowszych) można wybrać z listy płytkę ewaluacyjną NUCLEO-F411RE.



Rys. 3.


Po zaakceptowaniu wyboru wyświetli się pulpit podobny do tego z rysunku 3. Na rysunku obudowy mikrokontrolera, który jest zamontowany na płytce, kolorem zaznaczone są wyprowadzenia użyte do doprowadzenia zasilania, podłączenia oscylatorów oraz wyprowadzenia portów (kolor zielony) podłączonych do programatora oraz elementów oddanych do dyspozycji użytkownika: diody LED i przycisku. Widoczna z lewej lista dostępnych interfejsów kontrolera pozwala je aktywować i ustawić tryb ich pracy.


STM32CubeMX zakładka Clock Configuration
Po otwarciu tej zakładki możemy zmienić ustawienie wewnętrznych zegarów kontrolera płytki ewaluacyjnej. Należy zwrócić uwagę, że domyślnie jako główne źródło sygnałów taktujących ustawiony jest wewnętrzny oscylator HSI RC kontrolera. Na płytce NUCLEO-F411RE jako źródło impulsów zegarowych można także wykorzystać sygnał o częstotliwości 8MHz podawany z zintegrowanego z płytką programatora ST-LINK na pin oznaczony jako RCC_OSC_IN (PH0). Wybierając to źródło sygnałów taktujących należy:
• wrócić na zakładkę Pinout, na liście interfejsów wybrać RCC oraz High Speed Clock (HSE) zaznaczyć BYPASS Clock Source,
• na zakładce Clock Configuration zaznaczyć opcję PLL Source Mux->HSE lub System Clock Mux->HSE albo PLLClk,
• w przypadku zaznaczenia na czerwono któregoś z bloków skorygować ustawienia podzielników tak aby częstotliwości zegarów mieściły się w dopuszczalnych granicach.


STM32CubeMX zakładka Configuration
Na tej zakładce można podejrzeć i zmienić wstępne ustawienia portów i interfejsów. Np. klikając klawisz GPIO wyświetlone zostaną ustawienia portów do których podłączone są dioda LED i przycisk. Jeżeli użytkownik wybrał dodatkowe porty, w tym miejscu może ustawić ich parametry np. sposób podciągania do napięcia zasilania czy szybkość działania.


STM32CubeMX przygotowanie do generacji pakietu plików dla Keil-a:
• Należy otworzyć opcję Project->Settings…
• Wybrać nazwę projektu która będzie użyta podczas generacji plików.
• Wskazać katalog w którym mają być zapisane wygenerowane pliki.
• Jako środowisko (Tolchain/IDE) należy wybrać MDK-ARM (Jako MCU Reference powinien być wyświetlony STM32F411RETx).
Po wybraniu opcji Project->Generate Code zostaną wygenerowane i zapisane we wskazanym katalogu pliki pakietu programu dla środowiska Keil.


Szkielet programu i biblioteka HAL
Wygenerowany automatycznie przez STM32CubeMX szkielet oprogramowania po otwarciu w środowisku Keil-a powinien wyglądać podobnie jak na rysunku 4. W osobnych podkatalogach znajdują się najważniejsze pliki w tym pliki biblioteki HAL.



Rys. 4.


Biblioteka ta (Hardware Abstraction Layer) zawiera nisko poziomowe procedury obsługi interfejsów sprzętowych kontrolera. Producent czyli firma ST dla każdego typu kontrolera stworzyła osobne biblioteki które łączy interfejs API w tym ujednolicone nazwy procedur i sposób ich wywołania. Biblioteki nie mogą być wymiennie stosowane dla różnych typów kontrolerów chociażby z powodów różnic w wyposażeniu ilości i rodzajów dostępnych interfejsów. Jednak dzięki ujednoliconemu interfejsowi została ułatwiona przenośność oprogramowania między różnymi typami pokrewnych kontrolerów.
Pliki z oprogramowaniem STM32CubeF4 w tym bibliotekami HAL dla kontrolera STM32F411 zamontowanego na płytce NUCLEO-F411RE można znaleźć pod adresem: http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1743/LN1897/PF259243. Oprócz bibliotek można w plikach STM32CubeF4 znaleźć przykłady stosowania bibliotek HAL w tym dla NUCLEO-F411RE. Na tej samej stronie znajduje się link do pliku „UM1725: Description of STM32F4xx HAL drivers” z opisem drajwerów HAL, składnią wywołań funkcji i parametrami.


TestCube1 przykład sterowania portem z dołączoną diodą LED
W przykładowym programie testowym będziemy na powitanie migotali diodą LD2 na płytce  NUCLEO-F411RE. Dioda jest podłączona do portu PA5 kontrolera.
Wygenerowany przez STM32CubeMX szkielet programu zawiera procedury inicjujące a w podanym przykładzie należało dopisać jedynie 2 linijki kodu. Oczywiście wykorzystane zostały biblioteki HAL. Poniżej zasadnicza część programu zawarta w pliku main.c.



int main(void)
{


  /* MCU Configuration———————————————————-*/


  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();


  /* Configure the system clock */
  SystemClock_Config();


  /* Initialize all configured peripherals */
  MX_GPIO_Init();


  /* Infinite loop */
  while (1)
  {
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
   
    /* Insert delay 500 ms */
    HAL_Delay(500);
  }
}


void SystemClock_Config(void)
{


  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;


  __PWR_CLK_ENABLE();


  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);


  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 6;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);


  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
}


/** Configure pins as
        * Analog
        * Input
        * Output
        * EVENT_OUT
        * EXTI
     PA2   ——> USART2_TX
     PA3   ——> USART2_RX
*/
void MX_GPIO_Init(void)
{


  GPIO_InitTypeDef GPIO_InitStruct;


  /* GPIO Ports Clock Enable */
  __GPIOC_CLK_ENABLE();
  __GPIOH_CLK_ENABLE();
  __GPIOA_CLK_ENABLE();
  __GPIOB_CLK_ENABLE();


  /*Configure GPIO pin : PC13 przycisk B1*/
  GPIO_InitStruct.Pin = GPIO_PIN_13;
  GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);


  /*Configure GPIO pins : PA2 PA3 USART2*/
  GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


  /*Configure GPIO pin : PA5 LD2*/
  GPIO_InitStruct.Pin = GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


Na początku procedura HAL_Init() inicjuje między innymi systemowy zegar SysTick Timer odliczający czas z rozdzielczością 1ms. Zegar wykorzystywany jest przez procedurę pauzy i inne procedury biblioteki HAL. Procedura SystemClock_Config() inicjuje wewnętrzny system impulsów taktujących kontrolera. Źródłem jest wewnętrzny oscylator HSI RC kontrolera pracujący z częstotliwością 16 MHz. Procedura MX_GPIO_Init() ustawia wszystkie zaznaczone jako używane porty GPIO. Oprócz portu PA5 diody LD2 konfigurowanego jako wyjściowy ustawiane są nie używane w tym przykładzie porty przycisku i interfejsu szeregowego UART2. Jeżeli nie chcemy by były inicjowane nie używane porty w generowanym szkielecie kodu, należy otworzyć projekt dla konfiguratora  STM32CubeMX TestCube1.ioc i klikając na graficzny symbol portów ustawić je jako nie używane w trybie Reset_State. Następnie należy w opisany wcześniej sposób wygenerować przy pomocy STM32CubeMX nowy szkielet programu. W nieskończonej pętli while(1) umieszczone zostały dwie dopisane linijki kodu.
Instrukcja HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5) zmienia stan portu sterującego diodą na przeciwny. Jest ona opisana w dokumentacji bibliotek HAL „UM1725: Description of STM32F4xx HAL drivers” w sekcji poświęconej sterowaniu portami GPIO.
Kolejna instrukcja HAL_Delay(500) korzystając z systemowego zegara SysTick Timer odlicza czas 500 ms pauzy. Jest także opisana w dokumentacji bibliotek HAL w sekcji HAL System Driver.
Po kompilacji można zapisać plik wynikowy do pamięci FLASH kontrolera. Jeżeli zrobimy to z poziomu Keil-a najpierw należy przygotować kompilator do współpracy z zintegrowanym programatorem na płytce NUCLEO-F411RE.


W tym celu należy:
• wybrać opcję: Flash->Configure Flash Tools->Debug i z listy wybrać typ programatora jako ST-Link Debugger,
• w opcjach Settings->Flash Download->Add wybrać opcję  STM32F4xx 512kB Flash tak jak na rysunku 5.



Rys. 5.


Teraz można połączyć kablem port USB komputera z gniazdem Mini USB programatora na płytce NUCLEO-F411RE i zaprogramować pamięć Flash mikrokontrolera.


TestCube2 przykład na badanie stanu przycisku B1
Drugi przykład jest lekko zmodyfikowaną wersją poprzedniego. Jego działanie polega na badaniu stanu przycisku B1. Gdy przycisk jest naciśnięty dioda się świeci, gdy jest zwolniony dioda gaśnie. Tak jak poprzednio wykorzystany został szkielet kodu wygenerowany przez program  STM32CubeMX. Kolejne procedury inicjują impulsy taktujące kontrolera i ustawienia portów podłączonych do diody i przycisku. Zmieniona została treść instrukcji w obrębie pętli while (1).

Instrukcja HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) bada stan przycisku. Jeżeli zwracaną wartością jest ‘0’ oznacza to, że przycisk jest naciśnięty. Instrukcja HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET) ustawia wysoki poziom portu sterującego diodą LED. Jeżeli zwracana wartość jest różna od ‘0’ ustawiany jest niski poziom na porcie sterującym diodą LED. Obie instrukcje  opisane są w dokumentacji bibliotek HAL w sekcji poświęconej sterowaniu portami GPIO.


Środowisko programistyczne CooCox CoIDE
Pakiet programistyczny CooCox jest całkowicie darmowym środowiskiem nie nakładającym na użytkownika żadnych ograniczeń co do sposobu korzystania. Przystosowany jest do pisania oprogramowania dla kontrolerów ARM w tym dla rodziny układów produkowanych przez firmę ST. Do obsługiwanych typów nie dodano jeszcze na dzień dzisiejszy obsługi STM32F411. Jeżeli jednak zadeklarujemy jako mikrokontroler docelowy STM32F401VC większość napisanego oprogramowania po kompilacji bez problemu uruchomi się na płytce NUCLEO-F411RE.


Przygotowanie projektu CooCox CoIDE dla NUCLEO-F411RE
Po wybraniu opcji Project->New Project należy podać nazwę projektu i ścieżkę dostępu do katalogu w którym ma być zapisany.
Następnie wybieramy opcję Chip i wskazujemy STM32F401VC jako docelowy mikrokontroler projektu.
Po otwarciu zakładki Repository (View->Repository) zaznaczamy pozycje komponentów, które środowisko automatycznie doda do nowo utworzonego projektu. Dla prawidłowego działania pierwszego programu demonstracyjnego, którym będzie migotanie diodą na płytce należy zaznaczyć następujące komponenty:
• M4 CMSIS Core
• CMSIS BOOT
• RCC
• PWR
• GPIO
W tym momencie mamy utworzony szkielet projektu do którego można dodawać własne pliki. Można sobie ułatwić pracę wczytując jakiś przykładowy projekt dotyczący portów GPIO i przystosować go do wymagań płytki NUCLEO-F411RE. Należy w polu Components (lewy górny róg pulpitu) kliknąć na link do przykładów przy nazwie dodanego wcześniej komponentu GPIO. Automatycznie otworzy się zakładka GPIO Examples gdzie można wybrać np. IOToggle i dodać go do projektu klikając add. Widok pulpitu CoIDE z tak utworzonym projektem pokazany został na rysunku 6.



Rys. 6.


Dołączony do projektu przykład IOToggle posługuje się funkcjami standardowej biblioteki dla rodziny STM32F4 do której należą kontrolery STM32D401VC i STM32F411. Odpowiednie pliki biblioteki zostały już zainstalowane w projekcie podczas dodawania komponentów. Kompletną bibliotekę można pobrać ze strony http://www.st.com/web/en/catalog/tools/PF257901  w formie spakowanej  jako plik STSW-STM32065. Po rozpakowaniu dostępne stają się zarówno pliki samej biblioteki jak i liczne projekty przykładowe. Po uruchomieniu pliku wykonawczego stm32f4xx_dsp_stdperiph_lib_um.chm uruchamia się przeglądarka zasobów biblioteki. Wpisanie w pasku indeksu frazy GPIO wyświetla listę dostępnych funkcji związanych z dostępem i sterowaniem portami kontrolera.


TestCoIDE1 przykład sterowania portem z dołączoną diodą LED
Przykładowy program IOToggle po modyfikacji i dostosowaniu do płytki NUCLEO-F411RE wygląda tak:


   /* Configure PA5 in output pushpull mode */
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO_Init(GPIOA, &GPIO_InitStructure);


   while (1)
   {
     /* PA5 to be toggled */
     GPIO_SetBits(GPIOA, GPIO_Pin_5);
    
     /* Insert delay */
     Delay(0x3FFFFF);


     GPIO_ResetBits(GPIOA, GPIO_Pin_5);
    
     /* Insert delay */
     Delay(0x3FFFFF);


Najpierw instrukcją RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE) podłączany jest sygnał zegarowy do portu PA. Następnie port PA5 ustawiany jest w trybie pracy jako wyjście. W nieskończonej pętli while(1) naprzemiennie instrukcjami  GPIO_SetBitsGPIO_ResetBits ustawiany jest stan wysoki a potem niski na wyjściu portu. Procedura Delay(0x3FFFFF) zapewnia około 1s opóźnienie pomiędzy przełączeniami stanu diody LED.


TestCoIde2 przykład na badanie stanu przycisku B1
W lekko zmodyfikowanej wersji poprzedniego programu dioda LED świeci się w momencie naciśnięcia przycisku B1. Program wygląda tak:


   /* LED GPIOA Periph clock enable */
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);


   /* LED Configure PA5 in output pushpull mode */
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO_Init(GPIOA, &GPIO_InitStructure);


   /* Przycisk GPIOC Periph clock enable */
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);


   /* Przycisk Configure PC13 in inputt pushpull mode */
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;  // we want to configure PC13
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;     // we want it to be an input
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //this sets the GPIO modules clock speed
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;    // this sets the pin type to push / pull
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;    // this enables the pullup resistor
   GPIO_Init(GPIOC, &GPIO_InitStructure);



   while (1)
   {
    if(GPIO_ReadInputDataBit(button) == 0)
    {
     //przycisk naciśnięty, LD2 zapalony
     GPIO_SetBits(GPIOA, GPIO_Pin_5);
    }
    else
    {
     //przycisk zwolniony, LD2 zgaszony
     GPIO_ResetBits(GPIOA, GPIO_Pin_5);
    }
   }



Najpierw następuje deklaracja etykiety button jako portu PC13 do którego na płytce NUCLEO-F411RE podłączony jest przycisk B1. Następnie PA5 inicjowany jest jako port wyjściowy sterujący diodą a PC13 jako port wejściowy używany do odczytu stanu przycisku.
Potem w nieskończonej pętli while(1) badany jest stan portu PC13. Jeżeli podłączony do portu przycisk jest naciśnięty, port PA5 ustawiany jest w stanie wysokim. W przeciwnym wypadku port PA5 ustawiany jest w stanie niskim.
Ryszard Szymaniak