piątek, 17 marca 2023

NUCLEO-G070RB - szablon projektu Bare Metal, nieblokujące miganie diodą LED.


W oczekiwaniu na produkcję i dostawę zaprojektowanej płytki rozszerzeń mikroBUS dla Nucleo, z którą zacznę robić bardziej koszerne rzeczy, zabawię się w klasyczne Hello World z płytką Nucleo-G070RB. Stworzę szablon projektu do programowania Bare Metal dla MCU STM32G070RBT i pokażę jak migać nieblokująco diodą LED znajdującą się na płytce Nucleo. Nauczmy się cieszyć z rzeczy prostych :). Wszystko będzie na rejestrach rzecz jasna. Z użyciem HAL byłoby to zbyt nudne i pozbawione emocji :).



 

Skupienie uwagi na seriach STM32G0 i STM32G4 jest dobrym i przyszłościowym posunięciem. Wszystko co STM32F... a przynajmniej część z tej serii będzie powoli odchodziło do lamusa i nie będzie rozwijane przez STM-a .

STM32G070 jest najprostszym i najtańszym MCU z całej serii STM32G0. Jest to bardzo dobry MCU na początek i do nauki.

Wszystko co będzie pokazane w tym artykule opiera się na płytce Nucleo-G070RB i STM32 CUBE IDE. Zacznę od stworzenia szablonu projektu dla programowania Bare Metal. Szablon będzie pozbawiony biblioteki HAL i wszystkich związanych z nią komponentów. Co otrzymamy w zamian ? : lekkość i całkowitą kontrolę nad tym co robimy. Oczywiście z HAL jest łatwiej i zawsze jest na kogo zrzucić winę jeśli coś nie działa zgodnie z oczekiwaniem :).

Uruchamiamy STM32 CUBE IDE. Pisałem już o tym w innym artykule jak stworzyć szablon projektu Bare Metal , większość rzeczy będzie powtórzona z tamtego artykułu ale będą też drobne zmiany.

Wybieramy z menu File -> New -> STM32 Project . W selektorze wyszukujemy i wybieramy MCU dla którego tworzymy projekt w moim przypadku to STM32G07RBT6


W kolejnym okienku podajemy nazwę projektu i zaznaczamy opcję Empty.


Zawartość wygenerowanego projektu wygląda jak poniżej :


Do wygenerowanego projektu musimy dołączyć dodatkowe pliki m.in CMSIS, pozyskamy je z projektu HAL, który sobie teraz stworzymy.

Tworzę zatem analogicznie projekt ale w okienku gdzie zaznaczyliśmy opcję Empty wybieramy opcję STM32Cube :


Zamykamy okno konfiguratora CUBE MX , które nam wyskoczy automatycznie. Otwieramy drzewo katalogów projektu HAL i za pomocą copy/paste przenosimy cały katalog Drivers z projektu HAL do naszego projektu bez HAL. Z przekopiowanego katalogu Drivers usuwamy katalog STM32G0xx_HAL_Driver. Cała struktura projektu bez HAL powinna wyglądać jak na obrazku poniżej :


Kopiujemy jeszcze z projektu HAL do naszego projektu bez HAL trzy dodatkowe pliki  : stmg0xx_it.c, stmg0xx_it.h i system_stm32g0xx.c. Miejsca docelowe dla tych plików jak poniżej :



Otwieramy plik stmg0xx_it.c i kasujemy wiersz : #include "main.h", schodzimy na sam koniec pliku do ciała funkcji  SysTick_Handler() i kasujemy wiersz z wywołaniem funkcji HAL_IncTick();
 
W pliku stmg0xx_it.c będziemy zamieszczać funkcje wywołujące przerwania m.in do obsługi SysTick-a etc.. Sprawdźmy jak wyglądać powinna struktura naszego szablonu na tę chwilę :



Kolejnym krokiem jest ustawienie ścieżek do skopiowanego katalogu Drivers , tak aby pliki w nim zawarte były widoczne w projekcie. Robimy to np. tak File -> Properties -> C/C++ General -> Paths and Symbols i dodajemy dwie ścieżki z katalogiem Drivers . Całość powinna wyglądać tak jak poniżej na obrazku :



Jeśli potem dodajemy do projektu jakieś swoje katalogi z plikami nagłówkowymi, to katalogi te należy również podać w ustawieniach projektu tak jak powyżej .

Wchodzimy ponownie do  File -> Properties -> C/C++ General -> Paths and Symbols i w zakładce Symbols dodajemy nazwę : STM32G070xx



Projekt HAL można już skasować nie będzie nam do niczego potrzebny. W pliku main.c podmieniamy zawartość na np. jak poniżej :


Kompilujemy projekt i jeśli wszystko zrobiliśmy jak opisałem , kompilator nie zgłosi żadnych błędów.


Od tej chwili mamy gotowy szablon do programowania Bare Metal dla STM32G070RBTx. Rozbudujmy nasz projekt o funkcje inicjalizujące warstwę sprzętową naszego MCU. Do tego celu będą nam potrzebne dwie funkcje, funkcja inicjalizująca zegar dla wybranych portów i funkcja inicjalizująca piny z których chcemy korzystać a w zasadzie jeden pin PA5 na którym znajduje się LED w NUCLEO-G070RB.
Warto nadmienić, że po starcie MCU pracuje na zegarze wewnętrznym 16MHz i nic tutaj nie musimy zmieniać. Pozostaje nam zatem tylko włączyć zegar dla portów , ja zwyczajowo włączam go dla wszystkich dostępnych portów. A wygląda to jak poniżej : 
 


Jak widzimy w projekcie przybył nam katalog MCU_peripheral_config, do którego wrzucam wszystko co jest związane z inicjalizacją sprzętową MCU. Ten katalog musimy dodać do ustawień projektu . Wchodzimy do  File -> Properties -> C/C++ General -> Paths and Symbols i dodajemy ścieżkę dostępu do naszego nowego katalogu :


Teraz zajmę się inicjalizacją pinu PA5 i stworzę dla niego wygodne makra. Najpierw definicja makr :


W podanych powyżej definicjach mamy dostęp atomowy do pinu PA5 to tak na marginesie. Teraz konfiguracja dla pinu PA5, najprościej jak tylko się da , ustawiamy pin jako wyjście  :


W projekcie posługuję się jedną zbiorczą funkcją inicjalizującą peryferia :


Funkcję tę odpalam w main.c :


W pliku main.c pojawia się prosta inicjalizacja SysTick-a, bazująca na funkcji "systemowej" znajdującej się w CMSIS. Przy zegarze 16 MHz przerwanie SysTick-a będzie wywoływane co ok 1ms. SysTick daje nam podstawę czasu, którą wykorzystam do migania diodą LED. Zakładam sobie, że LED będzie zmieniał stan co ok 500 ms co da nam okres 1 s. Zróbmy sobie teraz mechanizm "timera" programowego.

W pliku stmg0xx_it.h deklaruję zmienną ms_counter a w pliku  stmg0xx_it.c definjuję tą zmienną i dodaję  #include <stdint.h>



W pliku stmg0xx_it.c odnajduję funkcję obsługi dla SysTick-a i dodaje do niej kod obsługi dla naszego licznika milisekund (licznik odlicza w dół od zadanej wartości ms_counter) . Przerwanie wywoływane jest co 1ms .


Przechodzę do pliku main.c i w pętli głównej realizuję zmianę stanu diody LED co 500 ms :


Podłączam płytkę Nucleo i wgrywam wsad , z napięciem i wypiekami na twarzy :) wpatruję się w diodę LED :). Dioda LED jeszcze przed wgraniem wsadu napiernicza jak przecinak , jakiś kod "example" wgrany przez producenta ? pewnie tak . Jeszcze jakiś upgrade STLinka bo za stary mam w płytce i wreszcie wsad wgrany. Dioda LED niezwłocznie miga po mojemu :) juhuuu . Proste a cieszy :)


Pozdrawiam

PICmajster
picmajster.blog@gmail.com







Brak komentarzy:

Prześlij komentarz