Kurs STM32L4 – #2 – platforma sprzętowa i środowisko

Kurs STM32L4 – #2 – platforma sprzętowa i środowisko

Mikrokontrolery z rodziny STM32L4 to niezwykle ciekawe układy, które łączą wysoką wydajność oraz niski pobór energii. Pora, aby przygotować się do poznania tych układów w praktyce.

Czym są widoki i perspektywy w STM32CubeIDE, jak utworzyć pierwszy projekt, wgrać go na płytkę Nucleo i wykorzystać debugger? Zaczynamy!

Czego dowiesz się z tej części kursu STM32L4?

Zaczynamy od krótkiego wprowadzenia do STM32L4 – m.in. omówimy rodziny popularnych układów i zapoznamy się z mikrokontrolerem, który będzie głównym bohaterem kursu. Najważniejsza część tego artykułu dotyczy przygotowania środowiska, utworzenia projektu i wgrania go na płytkę Nucleo.

Dlaczego STM32?

W rozwiązaniach hobbystycznych królowały kiedyś mikrokontrolery AVR. Układy takie jak ATmega8 czy ATmega16 znał chyba każdy hobbysta. Później przyszła era Arduino, które sprawiło, że programiści nie muszą „przejmować się” sprzętem – w teorii ten sam kod zadziała identycznie na różnych płytkach. Jednak nadal większość projektów bazuje na mikrokontrolerach AVR (np. ATmega328P z Arduino UNO).

Korzystanie z takich 8-bitowych układów ma wiele zalet, ale niestety ich możliwości są również bardzo mocno ograniczone. Mikrokontrolery STM32 to znacznie wydajniejsze układy, które z wielu względów stały się niezwykle popularne, zarówno wśród hobbystów, jak i w rozwiązaniach profesjonalnych. Dzięki nim możliwe jest po prostu tworzenie rozbudowanych urządzeń, które wymagają dużej mocy obliczeniowej oraz licznych peryferiów (np. wiele kanałów ADC, wiele SPI itd.).

Mikrokontrolery STM32 stosowane są głównie w profesjonalnych rozwiązaniach

Mikrokontrolery STM32 stosowane są głównie w profesjonalnych rozwiązaniach

Mikrokontrolery z rodziny STM32 zyskały olbrzymią popularność nie tylko ze względu na świetny sprzęt i mnogość dostępnych peryferiów. Czynnikami mocno przemawiającymi za tymi układami są również bardzo dobra dokumentacja techniczna i świetne wsparcie producenta, który m.in. dostarcza wygodne w użyciu biblioteki. Dzięki temu stosunkowo łatwo można przenosić programy z jednego typu układów na zupełnie inne (np. jeszcze wydajniejsze).

Naszym zdaniem układy STM32 są obecnie świetnym wyborem dla osób, które myślą o elektronice w bardziej poważnych kategoriach. Będzie to dobry wybór dla wszystkich, którzy chcieliby wejść na wyższy poziom programowania mikrokontrolerów, używany w profesjonalnych zastosowaniach.

Jak odnaleźć się w świecie STM32?

Mikrokontrolerów z rodziny STM32 jest bardzo dużo. W momencie tworzenia tego kursu w oficjalnym IDE do wyboru było ponad 1800 układów (a to i tak nie wszystkie). Tak wielka różnorodność jest z jednej strony dużą zaletą, bo pozwala na dobranie właściwego układu praktycznego do każdego projektu, z drugiej jednak strony wybór ten może być na początku wręcz przytłaczający. Warto zatem zacząć od ekspresowego rozeznania się w dostępnych rozwiązaniach.

Czym jest ARM?

Podczas programowania mikrokontrolerów często natrafia się na stwierdzenie, że dany układ posiada „rdzeń ARM” (np. Cortex-M). O co tu chodzi? Dawniej jedna firma projektowała od podstaw cały mikrokontroler, a następnie go produkowała. Z czasem uświadomiono sobie, że opracowanie nowego układu całkowicie od podstaw jest czasochłonne, a klienci wcale nie są zadowoleni z tego, że na rynku jest wiele niezgodnych ze sobą układów.

Pierwsze układy ARM zostały zaprojektowane przez firmę Acorn RISC Machines (stąd wzięła się ich nazwa). Z czasem wydzielono inżynierów odpowiadających za ten projekt do nowej firmy – Advanced RISC Machines (Arm Ltd.). Zmieniono również całkowicie model biznesowy.

Logo firmy Arm Ltd.

Logo firmy Arm Ltd.

Firma ta jako jedna z pierwszych doceniła wartość własności intelektualnej – zamiast inwestować w drogie fabryki i produkować własne układy, „jedynie” projektuje rdzenie i sprzedaje licencje. Producenci fizycznych układów (mikrokontrolerów i mikroprocesorów) kupują projekt rdzenia, który wykorzystują do stworzenia swojego układu. Dodają niezbędne pamięci i układy peryferyjne oraz produkują układy. Dzięki temu projektowanie całego mikrokontrolera jest o wiele łatwiejsze i szybsze, a klienci otrzymują rozwiązania opierające się na popularnym standardzie.

Architektury i rdzenie ARM

Tysiące pracowników Arm Ltd. zajmuje się tym tematem od wielu lat, więc powstało już sporo różnych rdzeni. Główny podział wyznaczają architektury – można o nich myśleć jak o generacjach procesorów. Nas interesuje architektura ARM w wersji ARMv7. W obrębie każdej architektury może być dostępnych wiele różnych rdzeni. W tym przypadku nadano im nazwy rozpoczynające się od „Cortex”:

  • Cortex-A – mikroprocesory, przeznaczone głównie do obsługi systemów operacyjnych, np. Linux, Android, Windows CE, iOS. Wymagają zewnętrznych układów do pracy.
  • Cortex-R – układy przeznaczone do systemów czasu rzeczywistego.
  • Cortex-M – mikrokontrolery, czyli układy, które mają zintegrowaną pamięć i układy peryferyjne.

Nas interesuje oczywiście rdzeń Cortex-M, który dzieli się jeszcze między innymi na:

  • Cortex-M0 – proste układy, które mają być konkurencją dla popularnych 8-bitowców.
  • Cortex-M3 – główna rodzina układów, która pojawiła się jako pierwsza na rynku.
  • Cortex-M4 – wersja wydajniejsza od Cortex-M3, dodatkowo wyposażona w koprocesor arytmetyczny (FPU) oraz zestaw instrukcji DSP (ang. digital signal processor).
  • Cortex-M7 – najszybsza i najbardziej rozbudowana wersja rdzenia.

Różne rodziny mikrokontrolerów

Za nami ekspresowe omówienie architektur i rdzeni ARM. Pora, aby odnieść to do układów STM32. Pomocny będzie prosty schemat blokowy. Przedstawione zostały tutaj rodziny mikrokontrolerów, które są produkowane przez firmę STMicroelectronics w ramach różnych rodzin, np. STM32F1, STM32L4 itd.

Na poziomej osi zaznaczone są znane nam już rdzenie – od Cortex-M0 do Cortex-M7. W uproszczeniu można zrozumieć tę ilustrację tak, że im układ jest bardziej na prawo, tym jest wydajniejszy. Ze względu na zastosowania mikrokontrolery STM32 zostały tutaj podzielone umownie na cztery grupy: układy o najwyższej wydajności, układy ogólnego przeznaczenia, układy energooszczędne oraz takie, które są przeznaczone do komunikacji bezprzewodowej.

Wybrane mikrokontrolery STM32 z różnymi rdzeniami Cortex-M

Wybrane mikrokontrolery STM32 z różnymi rdzeniami Cortex-M

Głównym bohaterem kursu będzie więc płytka NUCLEO-L476RG, na której znajduje się mikrokontroler STM32L476RG, będący częścią rodziny STM32L4. Układy te są wyposażone w rdzeń Cortex-M4, który jest częścią architektury ARMv7. Opis drogi od sformułowania „rdzeń ARM” do konkretnych układów był stosunkowo długi, ale warto znać podstawy, aby chociaż rozróżniać podane tu pojęcia.

W poprzednich kursach związanych z programowaniem mikrokontrolerów STM32 używaliśmy układów ogólnego zastosowania, odpowiednio typu STM32F1 oraz STM32F4. Tym razem chcieliśmy postawić na układy, które charakteryzują się wysoką wydajnością i niskim poborem energii – głównie ze względu na to, że takie układy świetnie sprawdzą się np. w urządzeniach przenośnych, gdzie liczy się każdy miliamper! Co więcej, chcieliśmy, aby kurs był oparty na nowszych układach, dzięki czemu kurs będzie aktualny przez długi czas. Wybór był więc prosty – kolejny kurs musiał dotyczyć rodziny STM32L4.

Gotowe zestawy do kursów Forbota

 Komplet elementów  Gwarancja pomocy  Wysyłka w 24h

Zamów zestaw elementów i wykonaj ćwiczenia z tego kursu! W komplecie płytka NUCLEO-L476RG oraz m.in. wyświetlacz graficzny, joystick, enkoder, czujniki (światła, temperatury, wysokości, odległości), pilot IR i wiele innych.

Zamów w Botland.com.pl »

Płytka uruchomieniowa NUCLEO-L476RG

Wszystkie przykłady opisywane w kursie bazują na dedykowanym zestawie elementów, w którego skład wchodzi oryginalna płytka NUCLEO-L476RG. Patrząc na nią od góry, zobaczymy oddzielną sekcję – jest to przejściówka USB<>UART oraz programator ST-LINK (z opcją debugowania, czyli analizowania tego, jak działa program wgrany do mikrokontrolera). Programator ten jest uniwersalny, można używać go do programowania innych układów STM32 (po wcześniejszym zdjęciu zworek CN2).

Górna część płytki NUCLEO-L476RG to uniwersalny programator

Górna część płytki NUCLEO-L476RG to uniwersalny programator

Pod programatorem rozpoczyna się sekcja z układem STM32L476RG, który będziemy programować. Na płytce oprócz mikrokontrolera znajdziemy wszystkie niezbędne elementy, aby mógł on poprawnie działać. Niektóre elementy na PCB nie są wlutowane – jest to zupełnie normalne. Wszystkie wolne miejsca zostały opisane w dokumentacji płytki. Pozwalają one na wprowadzanie pewnych modyfikacji w działaniu układu (np. dodanie innego źródła taktowania). Podczas tego kursu lutownica będzie zbędna – wszystkie ćwiczenia wykonamy na domyślnej wersji płytki.

Dolna część płytki NUCLEO-L476RG to mikrokontroler, który będziemy programować

Dolna część płytki NUCLEO-L476RG to mikrokontroler, który będziemy programować

Na płytce znajdziemy 2 przyciski: niebieski, który będziemy mogli wykorzystać w naszych programach, oraz czarny, który pozwala na ręczne zresetowanie układu. Oprócz tego na Nucleo znajduje się również dioda opisana jako LD2 – jest ona podłączona do jednego z wyprowadzeń mikrokontrolera, będziemy mogli wykorzystać ją w naszym programie (i zrobimy to w kolejnej części kursu). 

Dwa przyciski i dioda LD2 na NUCLEO-L476RG

Dwa przyciski i dioda LD2 na NUCLEO-L476RG

Praktycznie wszystkie nóżki układu STM32L476RG zostały wyprowadzone na złącza. Na płytkach z serii Nucleo znajdziemy dwa rodzaje złącz: długie goldpiny, do których możemy podłączyć się od góry i od dołu, oraz żeńskie złącza, charakterystyczne dla płytek Arduino. Dzięki nim do Nucleo można podłączać różnego rodzaju shieldy (płytki rozszerzeń dla Arduino).

Opis wyprowadzeń płytki NUCLEO-L476RG

Opis wyprowadzeń płytki NUCLEO-L476RG

Mikrokontroler STM32L476RG

Głównym bohaterem kursu jest 32-bitowy mikrokontroler STM32L476RG, który dedykowany jest do zadań wymagających wysokiej wydajności przy jednoczesnym niskim poborze prądu. Układ posiada 1 MiB pamięci flash oraz 128 KiB pamięci RAM. To dużo jak na mikrokontroler, a pamięć flash i tak możemy jeszcze rozszerzyć (za pomocą dodatkowych modułów QSPI).

Układ taktowany jest z częstotliwością do aż 80 MHz (w porównaniu z 16 MHz na Arduino UNO). Co ważne, mikrokontroler ten zasilany jest z 3,3 V. Większość jego wejść toleruje 5 V, ale w stanie wysokim na wyjściu otrzymamy 3,3 V, a nie 5 V – to zupełnie normalne i standardowe napięcie, z jakim pracują bardziej zaawansowane układy, ale trzeba o tym pamiętać.

Co najważniejsze, mikrokontroler ten został wyposażony w liczne peryferia – tutaj widać największą zaletę względem prostych układów 8-bitowych. Wewnątrz tego układu znajdziemy m.in.:

  • 3 × SPI, 1 × QSPI, 3 × I2C, 1 × CAN, 5 × USART, 1 × ULP UART,
  • aż 16 liczników (timerów),
  • 3 × 12-bitowe przetworniki ADC (24 zewnętrzne kanały ADC),
  • 51 × GPIO (do 114 w innych wersjach układu),
  • 2 × komparatory analogowe,
  • 2 × wzmacniacze operacyjne,
  • 1 × czujnik temperatury,
  • DMA (ang. direct memory access) – bezpośrednio dostęp do pamięci,
  • TRNG (ang. true random number generator) – sprzętowy generator liczb losowych,
  • FPU (ang. floating-point unit) – koprocesor arytmetyczny, jednostka zmiennoprzecinkowa,
  • oraz znacznie, znacznie więcej.

Istnieje możliwość, że wiele osób czytających ten kurs nie zna wielu z powyższych skrótów. To nic złego, jeśli nie wiesz, co tutaj wymieniliśmy (i dlaczego to takie fajne), ale spokojnie – o wszystkim przekonasz się w dalszych częściach kursu. Większość tych rzeczy zostanie pokazana przy prezentacji kolejnych przykładów, a inne będziesz mógł sprawdzić samodzielnie, gdy poznasz STM32CubeIDE.

Dokumentacja techniczna dla STM32L4

Produkty firmy STMicroelectronics posiadają bardzo obszerną dokumentację – to naprawdę ogromna zaleta. Nie ma potrzeby, aby w tej chwili czytać wszystkie pliki (które mają łącznie tysiące stron). Warto jednak wiedzieć, gdzie szukać odpowiednich dokumentów i jak się nazywają.

Dokumentacja płytki Nucleo

W przypadku płytki NUCLEO-L476RG dostępny jest tzw. user manual, który tak naprawdę opisuje wiele płytek z serii Nucleo. Z dokumentu, który ma ponad 60 stron, dowiemy się, co (i gdzie) znajduje się na płytce, jakie są jej wymiary itd. Będą tam też informacje na tematy specyficzne dla tych płytek. Dokument ten znajdziemy na stronie produktu NUCLEO-L476RG.

Tzw. user manual, który opisuje wiele płytek Nucleo

Tzw. user manual, który opisuje wiele płytek Nucleo

Dokumentacja mikrokontrolera STM32L476RG

W przypadku samego mikrokontrolera musimy mieć świadomość, że pod hasłem „dokumentacja” kryją się minimum trzy pliki, które znajdziemy na stronie mikrokontrolera STM32L476RG:

  • datasheet (w kategorii product specifications),
  • reference manual,
  • errata.

Datasheet (około 270 stron) zawiera informację o charakterystyce układu – znajdziemy tam np. opis wyprowadzeń. Reference manual (ponad 1900 stron) to dokument, w którym omówiono wszystkie moduły mikrokontrolera. Podczas programowania będziemy korzystać z wygodnych bibliotek, które dostarcza producent układu, więc nie musimy znać każdego rejestru. Jednak warto wiedzieć, że w razie problemów szczegółowy opis peryferiów mikrokontrolera znajduje się właśnie w tym dokumencie.

Datasheet, czyli nota katalogowa naszego mikrokontrolera

Datasheet, czyli nota katalogowa naszego mikrokontrolera

Ostatni dokument to errata (ponad 60 stron). Każdemu zdarzają się błędy, również producentom mikrokontrolerów. Najczęściej, jeśli coś źle działa, to dlatego, że źle napisaliśmy program albo coś źle zlutowaliśmy, ale same mikrokontrolery też nie są idealne. Ewentualne informacje na temat błędów, które popełnił producent, znajdziemy właśnie w erracie.

Dokumentacja bibliotek i programów

Płytka Nucleo i mikrokontroler to jednak nie wszystko. Producent przygotował też osobne dokumenty, które opisują tzw. STM32Cube, czyli zestaw narzędzi programistycznych, których będziemy używać podczas tworzenia programów na nasz mikrokontroler. Wiele plików, które opisują konkretne aspekty od strony programistycznej, znaleźć można na tej stronie.

Programistyczne składniki ekosystemu STM32

Programistyczne składniki ekosystemu STM32

Instalacja środowiska STM32CubeIDE

Wstęp teoretyczny za nami – możemy teraz przejść do najważniejszego, czyli do praktyki. Zaczniemy od instalacji środowiska, krótkiej konfiguracji oraz kompilacji pierwszego programu. Środowisko, którego będziemy używać w kursie L4, to STM32CubeIDE. Jest to oficjalne IDE, za którego rozwój odpowiada firma STMicroelectronics, dzięki czemu program ten jest szyty na miarę pod układy STM32.

W celu pobrania STM32CubeIDE wchodzimy na stronę producenta i w sekcji z plikami do pobrania wybieramy wersję odpowiednią dla naszego systemu operacyjnego (m.in. Windows, Linux, macOS). Po akceptacji licencji konieczne będzie zalogowanie się na stronie ST. Oczywiście w tym miejscu możliwe jest również szybkie utworzenie darmowego konta.

Gdy przejdziemy przez wszystkie formalności, natychmiast rozpocznie się pobieranie instalatora. Archiwum, zależnie od wersji IDE, może ważyć ponad 700 MB. Sam program będzie potrzebował później ponad 2 GB wolnego miejsca na dysku.

Pobrane archiwum rozpakowujemy i uruchamiamy standardowy instalator. Warto tylko zwrócić uwagę na dwa etapy instalacji. Pierwszy to wybór lokalizacji docelowej. Najlepiej zostawić domyślną ścieżkę, jednak jeśli chcemy ją zmienić, to trzeba unikać spacji, polskich znaków oraz innych dysków niż C.

Wybór lokalizacji docelowej dla środowiska STM32CubeIDE

Wybór lokalizacji docelowej dla środowiska STM32CubeIDE

Drugim ważnym krokiem podczas instalacji jest wybór sterowników dla programatorów, które mają zostać zainstalowane razem z IDE. W naszym przypadku konieczna będzie obsługa ST-LINK, warto jednak od razu zainstalować sterowniki do wszystkich dostępnych programatorów.

Wybór sterowników dla programatorów

Wybór sterowników dla programatorów

Potem naciskamy przycisk Install i cierpliwie czekamy, bo instalacja środowiska może zająć nawet do kilku minut. Na koniec powinniśmy zobaczyć standardowy komunikat o poprawnej instalacji oraz opcję utworzenia skrótu na pulpicie.

Standardowa instalacja STM32CubeIDE

Standardowa instalacja STM32CubeIDE

Wstępna konfiguracja STM32CubeIDE

Po instalacji środowiska przechodzimy do stworzenia pierwszego projektu – dzięki temu sprawdzimy, czy wszystko przebiegło zgodnie z planem. Uruchamiamy STM32CubeIDE. Przed startem właściwego IDE zostaniemy poproszeni o wybranie lokalizacji, w której będą się znajdować nasze projekty – jest to tzw. przestrzeń robocza (ang. workspace).

Wybór przestrzeni roboczej podczas pierwszego uruchomienia STM32CubeIDE

Wybór przestrzeni roboczej podczas pierwszego uruchomienia STM32CubeIDE

Możemy mieć wiele przestrzeni, w każdej z nich możemy trzymać różne projekty np. związane z nauką, i pracą. Jeśli nie chcemy, aby program pytał nas przy każdym uruchomieniu o tę lokalizację to możemy zaznaczyć opcję Use this as the default and do not ask again – wtedy automatycznie otwierana będzie zawsze ta przestrzeń robocza, z której poprzednio korzystaliśmy.

Podczas wybierania lokalizacji przestrzeni roboczej warto kierować się tymi samymi zasadami co przy instalacji środowiska – unikamy ścieżek ze spacjami, polskimi znakami i innymi niestandardowymi symbolami. Taka ścieżka to wręcz „gwarancja” późniejszych problemów.

Niezależnie od tego, czy pozostawimy domyślną ścieżkę, czy ustawimy jakąś niestandardową, klikamy następnie przycisk Launch. Dopiero teraz uruchomi się właściwie środowisko STM32CubeIDE. W trakcie pierwszego uruchomienia mogą pojawić się jeszcze dodatkowe komunikaty (takie jak np. pytanie o to, czy pliki z danym rozszerzeniem mają być automatycznie otwierane w tym IDE, zgoda na zbieranie danych statystycznych itd).

Uwaga: interfejsy graficzne mogą się zmieniać!

Programy z ładnymi interfejsami graficznymi mają wiele zalet. Klikanie w dobrze opisane przyciski lub wybieranie opcji z rozwijanych menu sprawia, że korzystanie z programów jest szybkie i wygodne. Nie inaczej jest w przypadku STM32CubeIDE.

Jest jednak jedna wada programów z interfejsami graficznymi, szczególnie ważna dla osób początkujących. Czasami zdarza się tak, że producenci wraz z kolejnymi wersjami programów zmieniają ich wygląd. To, że w momencie pisania tego kursu dany ekran STM32CubeIDE wyglądał właśnie w taki sposób, nie znaczy, że zawsze będzie wyglądał identycznie.

Pierwsze uruchomienie STM32CubeIDE

Pierwsze uruchomienie STM32CubeIDE

Dlatego podczas tworzenia tego kursu staraliśmy się opisywać wszystkie wykonywane operacje w taki sposób, aby możliwe było ich odtworzenie, nawet jeśli z czasem wygląd tego IDE zostanie zmieniony. Nie martw się więc, jeśli program na Twoim komputerze wygląda trochę inaczej niż na zrzutach z kursu – możliwe, że jest to związane z aktualizacją STM32CubeIDE.

Pierwszy projekt w STM32CubeIDE

Pora, aby nareszcie utworzyć pierwszy projekt. Z menu wybieramy opcję: File > New > STM32 Project. Uruchomiony zostanie kreator, dzięki któremu skonfigurujemy nowy projekt. Pierwszy krok to wybór mikrokontrolera, na który będziemy pisać kod. Dzięki temu nasze IDE załaduje odpowiednie biblioteki.

Za pomocą filtrów (po lewej stronie) możemy łatwo odnaleźć mikrokontroler, który będzie idealny do naszego projektu. Możemy wskazać, jaki interesuje nas rdzeń, jakie peryferia powinny być na pokładzie tego układu itd. W naszym przypadku wybór jest prosty, bo wiemy, że przykłady z tego kursu będą bazowały na STM32L476RG – taką nazwę wpisujemy więc w pole Part Number.

Wybór mikrokontrolera STM32L476RG

Wybór mikrokontrolera STM32L476RG

Natychmiast po wpisaniu symbolu zobaczymy skrót informacji na temat wybranego mikrokontrolera, jego cenę (dla zamówień hurtowych) oraz informację o płytce rozwojowej, na której go znajdziemy. W oknie tym od razu mamy też dostęp do dokumentów, które powiązane są z tym układem.

Po wybraniu odpowiedniego układu naciskamy przycisk Next. W kolejnym oknie zostaniemy zapytani o nazwę projektu. Wpisujemy np. „projekt1”, pozostałe opcje pozostawiamy bez zmian i klikamy Next.

Nazwa nowego projektu

Nazwa nowego projektu

Teraz widzimy podsumowanie naszego nowego projektu. Warto upewnić się tutaj, że zaznaczona jest opcja Copy only the necessary library files. Następnie naciskamy przycisk Finish. Podczas tworzenia pierwszego projektu mogą pojawić się jeszcze jakieś dodatkowe pytania (związane z konfiguracją IDE) – wszędzie najlepiej zgadzać się na domyślne propozycje.

Ustawienia pierwszego projektu

Ustawienia pierwszego projektu

W tym momencie STM32CubeIDE zacznie pobierać obszerne biblioteki. Na szczęście ta czynność jest wykonywana tylko raz, a mówiąc precyzyjniej: raz dla danej rodziny (np. STM32L4) i raz do czasu, aż pojawi się ich aktualizacja. Musimy się tutaj szykować na kolejne 700 MB danych (lub więcej).

Pierwsze pobieranie bibliotek

Pierwsze pobieranie bibliotek

Co więcej, domyślnie wszystkie biblioteki będą zainstalowane na dysku oznaczonym literą C. Nawet jeśli wybierzemy inną lokalizację, to po pojawieniu się nowszej wersji IDE i tak wszystko prawdopodobnie wróci na domyślny dysk. Po pobraniu i przetworzeniu bibliotek zobaczymy okno, w którym pojawi się graficzne przedstawienie naszego mikrokontrolera. Warto jednak poświęcić chwilę na poznanie samego środowiska, a konkretnie tego, jakie są dostępne perspektywy.

Czym są widoki i perspektywy w STM32CubeIDE?

Zanim przejdziemy dalej, konieczne jest omówienie podstawowych części interfejsu STM32CubeIDE. Używane są tutaj często dwa określenia: widok (ang. view) oraz perspektywa (ang. perspective). Widok to po prostu okienko, np. z kodem naszego programu czy eksploratorem plików. Natomiast perspektywa to określony układ widoków (okienek) i pasków narzędzi, między którymi można się szybko przełączać. 

W trakcie tworzenia programu na tak rozbudowany mikrokontroler musimy mieć dostęp do różnych „okienek”. Jedne opcje będą potrzebne podczas konfiguracji sprzętu, inne podczas pisania kodu, a jeszcze inne podczas debugowania programów. Na szczęście nie musimy za każdym razem ręcznie wywoływać każdego okienka osobno – możemy szybko przełączać się za pomocą perspektyw.

Najważniejsze perspektywy, z których będziemy korzystać, to:

  • Device Configuration Tool – do konfiguracji sprzętu mikrokontrolera,
  • C/C++ – do edycji kodu źródłowego programu,
  • Debug – do wgrywania i uruchamiania programu oraz do szukania błędów.

Teraz przejdziemy przez wszystkie perspektywy – od razu omówimy kilka ważnych pojęć i problemów, które mogą pojawić się podczas tworzenia pierwszego projektu. Nie ignoruj więc poniższego opisu!

Perspektywa Device Configuration Tool

Zacznijmy od omówienia perspektywy Device Configuration Tool (nazywanej też CubeMX), z której będziemy korzystać podczas konfigurowania układu. Przy bardzo prostych układach, które nie mają  rozbudowanych peryferiów, konfiguracje sprzętu pisze się często ręcznie – wystarczy kilka linijek kodu.

Przy mikrokontrolerach, które są dużo bardziej rozbudowane (tak jak używany w kursie układ STM32 z rodziny L4), „ręczne” napisanie takiej konfiguracji byłoby wyzwaniem (i to nawet dla doświadczonych programistów). Oczywiście jest to możliwe i są osoby, które upierają się, że to bajecznie proste – jasne, jeśli ktoś chce przeczytać np. 600 stron dokumentacji, aby uruchamiać układ ręcznie, to może tak robić.

Domyślny widok – perspektywa Device Configuration Tool

Domyślny widok – perspektywa Device Configuration Tool

Jednak bazując na naszym doświadczeniu z mikrokontrolerami (i z pisaniem kursów), możemy śmiało zaryzykować stwierdzenie, że ręczne konfigurowanie peryferiów w takich układach (z punktu widzenia osoby początkującej) byłoby bardzo trudne. Dlatego w tym kursie będziemy korzystać z CubeMX, czyli narzędzia przygotowanego przez producenta mikrokontrolerów STM32. Narzędzie to powstało właśnie po to, aby ułatwić życie programistom (hobbystom i profesjonalistom), bo dzięki niemu można bardzo szybko dosłownie „wyklikać” wszystkie ustawienia układu (i to nawet te najbardziej skomplikowane).

Jeśli nasze IDE jest uruchomione w perspektywie Device Configuration Tool, to po lewej stronie okna zobaczymy tzw. widok eksploatatora projektów. Są tam widoczne wszystkie pliki związane z danym projektem. Prawa strona okna z widokiem mikrokontrolera to właściwy interfejs CubeMX.

Ikony do przełączania perspektyw

Ikony do przełączania perspektyw

Na samej górze programu widoczny jest standardowy pasek z narzędziami, które są przydatne podczas korzystania z tej perspektywy. Ikonki dostępne w tym miejscu mogą się zmieniać zależnie od tego, co aktualnie będziemy robić. Po jego prawej stronie (pod przyciskiem do zamykania programu) widoczne są przyciski, które służą do przełączania się między perspektywami (Device Configuration Tool oraz C/C++, nie będzie tam widocznej perspektywy Debug – pojawi się automatycznie później).

Perspektywa C/C++ w STM32CubeIDE

W ramach zapoznania się ze środowiskiem i strukturą projektu warto rozwinąć katalog Core > Src, który dostępny jest z poziomu eksploatatora projektów (po lewej stronie okna). Następnie klikamy dwa razy w plik main.c – środowisko automatycznie zaproponuje przełączenie na perspektywę C/C++. Zgadzamy się na to, a po chwili ujrzymy kod źródłowy naszego programu.

Plik z głównym kodem naszego programu

Plik z głównym kodem naszego programu

Jeszcze nic nie napisaliśmy ani nie skonfigurowaliśmy, a plik ten jest już długi. Najbardziej zwracają na siebie uwagę „dziwne” komentarze – jest ich bardzo dużo. Osoby, które miały już kiedyś styczność z programowaniem, przyzwyczajone są pewnie do tego, że komentarze są „dla programisty”. Nie ma w tym przypadku – te komentarze są dla narzędzia CubeMX. Dzięki nim używane przez nas IDE może automatycznie umieszczać w odpowiednich miejscach kody, które będą np. coś konfigurowały.

Nasz kod możemy pisać tylko w konkretnych miejscach, czyli pomiędzy np. takimi komentarzami:

Wszystkie zmiany, które wprowadzimy poza tak oznaczonymi blokami, zostaną usunięte podczas najbliższej zmiany dokonanej w CubeMX. Musimy więc bardzo uważać i przyzwyczaić się do takiego działania narzędzia. Taka forma pracy z kodem ma swoje wady i zalety. Każdy ma też swoje preferencje, trzeba jednak przyznać, że idąc na takie ustępstwo, zyskujemy jako programiści dużą wygodę na etapie konfiguracji mikrokontrolera – będzie to widoczne już w kolejnej części kursu.

Na razie jednak się tym nie przejmujemy. Nasz program jeszcze nic nie robi – to tylko „pusty” szkielet. Możemy go jednak skompilować i wgrać na Nucleo, aby upewnić się, że wszystko działa poprawnie.

Kompilowanie programu w STM32CubeIDE

Zacznijmy od tego, że w STM32CubeIDE domyślnie włączona jest opcja automatycznej kompilacji projektów. Na początku warto ją wyłączyć – wystarczy odznaczyć opcję Build Automatically, która dostępna jest w menu Project. Od teraz kompilacja będzie wykonywana tylko na nasze wyraźne polecenie. W tym celu możemy kliknąć na pasku narzędzi ikonę z młotkiem, możemy też wybrać opcję Build All z menu Project.

Wybieramy więc jedną z tych opcji i chwilę czekamy. Po ukończeniu kompilacji w dolnej części okna zobaczymy podsumowanie. W oknie Console wyświetlona jest m.in. informacja o tym, ile zajmuje nasz pierwszy program. Po prawej stronie, w oknie Build Analyzer, dane te zostały przedstawione w znacznie bardziej czytelnej formie. Jak widzimy, użyliśmy dopiero 1,61% pamięci RAM oraz 0,47% pamięci flash. 

Podgląd informacji na temat skompilowanego programu

Podgląd informacji na temat skompilowanego programu

Uważni czytelnicy zauważą, że Build Analyzer pokazał 96 KiB pamięci RAM oraz 32 KiB pamięci RAM2. Mikrokontroler ma łącznie 128 KiB pamięci RAM, ale są one podzielona na dwa osobne obszary. Nasze programy domyślnie korzystają z tego pierwszego (większego) obszaru. Korzystanie z RAM2 to trochę bardziej zawiły temat, którego na ten moment nie będziemy poruszać (bo 96 KiB to i tak bardzo dużo).

Perspektywa Debug w STM32CubeIDE

Program nic ciekawego jeszcze nie robi, ale możemy już go uruchomić, czyli wgrać na mikrokontroler. Podłączamy więc płytkę Nucleo do komputera za pomocą przewodu USB. Nie musimy nic więcej robić z samym sprzętem. Pora wgrać program do mikrokontrolera – w tym celu z menu Run wybieramy opcję Debug lub klikamy w pasku narzędzi przycisk z ikonką zielonego robaka.

Za pierwszym razem wyświetli się w tym momencie okno z konfiguracjami, w którym nie musimy nic zmieniać. Zostawiamy domyślne ustawienia i klikamy przycisk OK.

Domyślna konfiguracja projektu

Domyślna konfiguracja projektu

Następnie możliwe są trzy scenariusze:

  1. Wyświetli się komunikat o tym, że nie wykryto programatora.
  2. Wyświetli się komunikat o tym, że można zaktualizować programator.
  3. Wszystko przebiegnie poprawnie i przejdziemy do perspektywy Debug.

Błąd: nie wykryto programatora

W przypadku komunikatu o braku programatora oczywiście upewniamy się, że został on podłączony do komputera za pomocą przewodu USB. Jeśli świecą się na nim jakieś diody, to znak, że jest zasilany, więc wszystko powinno działać dobrze. Sprawdzamy zatem ustawienie zworek na płytce, upewniamy się, że nie powodujemy jakiegoś zwarcia (np. stawiając Nucleo na metalowej powierzchni). Na koniec pozostaje nam restart komputera (w końcu instalowaliśmy nowe sterowniki).

Komunikat o braku programatora

Komunikat o braku programatora

Przeważnie te kroki wystarczą, natomiast w przypadku dalszych problemów warto sprawdzić, czy programator z płytki Nucleo jest poprawnie widoczny w menedżerze urządzeń systemu Windows. Powinien widnieć w sekcji z portami COM, np. jako: STMicroelectronics STLink Virtual COM Port.

Widoczność programatora jako portu COM

Widoczność programatora jako portu COM

Informacja: możliwość aktualizacji programatora

Inna opcja, którą możemy zobaczyć podczas pierwszej próby wgrania programu, to informacja o tym, że producent przygotował nową wersję oprogramowania. Oczywiście chętnie z tej opcji korzystamy. W nowym oknie klikamy Open in update mode, a następnie Upgrade. Po kilku sekundach programator powinien być zaktualizowany – możemy wtedy iść dalej.

Opcja aktualizacji programatora

Opcja aktualizacji programatora

Sukces: przejście do perspektywy Debug

Środowisko od razu zaproponuje nam automatyczne przełączenie do perspektywy Debug, dzięki której będzie operować na wgranych programach (bo w przeciwieństwie np. do popularnego Arduino tutaj mamy wpływ na to, jak wykonuje się program, mamy też podgląd na to, co dzieje się wewnątrz układu).

Widok nowej perspektywy – Debug

Widok nowej perspektywy – Debug

Po przejściu do nowej perspektywy program powinien zostać od razu wgrany do pamięci flash układu. Powinien też od razu się uruchomić – będzie to widoczne w okienku Console.

Może jednak zdarzyć się sytuacja, w której program antywirusowy na PC zacznie w tej chwili blokować jeden ze składników środowiska – trzeba dodać go wtedy do wyjątków.

Ostrzeżenie od Zapory Windows Defender

Ostrzeżenie od Zapory Windows Defender

Gdy pokonamy wszystkie przeszkody, możemy przyjrzeć się bliżej aktualnej perspektywie. W części z programem (na początku funkcji main) widoczna będzie tzw. pułapka (ang. breakpoint). Konkretnie znajdziemy ją w pierwszej linii zawierającej jakiś kod, który można wykonać. W tym przypadku nasz program zatrzyma się na funkcji HAL_Init() (wskazuje na to niebieska strzałka obok numeru linii).

Tzw. pułapka w linii numer 72

Tzw. pułapka w linii numer 72

Do pracy z debuggerem jeszcze wrócimy, ale mówiąc w skrócie, dzięki tej opcji sprawiliśmy, że program po wgraniu do mikrokontrolera uruchomił się, ale natychmiast został zatrzymany w miejscu, w którym znajduje się breakpoint. Aby kontynuować działanie programu, naciskamy F8 albo przycisk na pasku narzędziowym opisany jako Resume (zielony trójkąt).

Brawo! Nasz program już działa – w praktyce nie zaobserwujemy żadnych efektów, bo wgraliśmy pusty program, ale to miał być tylko test, dzięki któremu upewniliśmy się, że komunikacja środowiska z płytką działa poprawnie. W kolejnej części kursu stworzymy pierwsze programy, dzięki którym od razu będzie widać, że kod faktycznie działa na mikrokontrolerze.

Dla formalności warto dodać, że gdy program jest już uruchomiony na mikrokontrolerze, możemy go wstrzymać przyciskiem z paska narzędzi opisanym jako Suspend lub też całkiem zatrzymać za pomocą przycisku Terminate – wrócimy wtedy do perspektywy C/C++. 

Przyciski sterujące pracą debuggera

Przyciski sterujące pracą debuggera

Zadania domowe

To dopiero początek kursu, więc zaczynamy od prostych zadań domowych (na rozgrzewkę):

  1. Wykorzystaj kreator nowego projektu do tego, aby sprawdzić, jakie inne warianty naszego mikrokontrolera są dostępne w sprzedaży. Podpowiedź: podczas wyszukiwania układu wpisz tylko część jego nazwy: „STM32L476”.
  2. Zapoznaj się z dokumentacją mikrokontrolera – oczywiście nie musisz jej czytać. Przejrzyj jednak dokumenty, aby wiedzieć, czego można się w nich spodziewać.
  3. Daj nam znać w komentarzu, czy udało Ci się poprawnie wgrać program na płytkę. Zrzuty ekranu i zdjęcia płytek Nucleo mile widziane!

Podsumowanie – co powinieneś zapamiętać?

Za nami szybkie omówienie mikrokontrolera, płytki Nucleo oraz STM32CubeIDE. Tym razem najwięcej zajęło opisanie środowiska. W kolejnych częściach kursu nie będziemy aż tyle miejsca poświęcać na takie tematy. Po lekturze tej części musisz więc wiedzieć, jak samodzielnie tworzyć nowy projekt, jak przełączać się między perspektywami i jak wgrywać programy na płytkę.

Czy wpis był pomocny? Oceń go:

Średnia ocena 5 / 5. Głosów łącznie: 46

Nikt jeszcze nie głosował, bądź pierwszy!

Artykuł nie był pomocny? Jak możemy go poprawić? Wpisz swoje sugestie poniżej. Jeśli masz pytanie to zadaj je w komentarzu - ten formularz jest anonimowy, nie będziemy mogli Ci odpowiedzieć!

W kolejnej części kursu skupimy się na poznaniu podstawowych informacji na temat najważniejszych peryferiów, czyli uniwersalnych pinów GPIO, do których będziemy podłączać przeróżne elementy. Przy okazji omówimy też wiele informacji związanych z samym mikrokontrolerem oraz środowiskiem. Jeśli masz jakieś pytania związane z tą częścią kursu, to śmiało pytaj w komentarzach – mile widziane również informacje, że wszystko przebiegło zgodnie z planem!

Nawigacja kursu

Główny autor kursu: Piotr Bugalski
Współautor: Damian Szymański, ilustracje: Piotr Adamczyk
Oficjalnym partnerem tego kursu jest firma STMicroelectronics
Zakaz kopiowania treści kursów oraz grafik bez zgody FORBOT.pl

debug, ide, kursSTM32L4, perspektywy, stm32, STM32CubeIDE, stm32l4

Trwa ładowanie komentarzy...