[1] STM32CUBE w przykładach

Firma STMicroelectronics przygotowała zestaw bibliotek Hardware Abstraction Layer, umożliwiający programowanie mikrokontrolerów STM32 w bardzo prosty, wysokopoziomowy, sposób. Dzięki temu, nie ma konieczności zagłębiania się w obszerną specyfikację układu ani rdzenia ARM. Wraz z bibliotekami HAL, producent dostarcza również program STM32CubeMX. Jest to graficzny generator konfiguracji mikrokontrolera, pozwalający na skonfigurowanie wszystkich wyprowadzeń, interfejsów, liczników oraz taktowania całego układu, a następnie na wygenerowanie gotowego projektu dla różnych środowisk IDE. Wszystko to sprawia, że programowanie tak zaawansowanego mikrokontrolera jest niemal równie proste i intuicyjne, jak programowanie platformy Arduino.

W krótkim, kilkuodcinkowymkursie postaram się przedstawić w praktyczny sposób – podczas tworzenia prostych projektów, sposób programowania układów z rodziny STM32F4. Jest to pierwszy artykuł z serii. Przedstawione tutaj zostały narzędzie STM32CubeMX oraz środowisko programistyczne System Workbech for STM32. Podczas czytania artykułu oraz wykonywania przykładów, utworzymy pierwszy projekt – mikrokontrolerowe “Hello world!”. W kolejnych częściach omówione zostaną liczniki, przerwania, generowanie sygnału PWM, odczyt stanów pinów wejściowych, komunikacja z komputerem oraz innymi urządzeniami za pośrednictwem interfejsu UART, sterowanie adresowalnymi paskami diod LED, bazujących na chipie WS2812b. Dodamy także do naszego mikrokontrolera obsługę WiFi, dzięki zastosowaniu układu ESP8266, obsłużymy prosty wyświetlacz LCD i odbierzemy dane z różnych czujników.

Podczas tworzenia tego kursu, korzystałem z płytki rozwojowej Kamami KA-NUCLEO-F411CE bazującej na układzie STM32F411CEU6. Układ ten posiada interfejs USB 2.0 (do dyspozycji użytkownika), pięć interfejsów SPI, pięć magistral I2S, trzy magistrale I2C, trzy interfejsy USART/UART, sześć liczników 16-bitowych oraz dwa 32-bitowe i może być taktowany zegarem o maksymalnej częstotliwości 100 MHz. Na płytce oprócz właściwego mikrokontrolera, znajduje się również prostszy układ STM32F103C8U6, pełniący funkcję programatora ST-LINK z wyjściem USB. Płytka posiada wyprowadzenia pinów zgodne z Arduino, wbudowany przycisk do dyspozycji użytkownika oraz trójkolorową diodę LED RGB. Większość omawianych przykładów będzie możliwa do wykonania na dowolnej innej płytce rozwojowej z układem STM32F4, jednak zachęcam do zakupu tej konkretnej, posiadającej wymienione elementy.

Płytka rozwojowa KA-NUCLEO-F411CE

Witaj migająca diodo!

Naszym pierwszym projektem będzie mikrokontrolerowy odpowiednik, znanego z nauki różnych języków programowania, programu “Hello world!”, czyli program którego, w naszym przypadku, jedynym zadanie jest naprzemienne zapalanie i gaszenie diody znajdującej się na płytce rozwojowej. Podczas tworzenia tego prostego projektu przyjrzymy się podstawom korzystania z programu STM32CubeMX – konfiguracji funkcji pinów, sygnału taktującego rozchodzącego się po mikrokontrolerze oraz środowisku System Workbench for STM32, w którym to napiszemy kod naszej aplikacji, skompilujemy go i załadujemy na mikrokontroler.

Generowanie projektu w STM32CubeMX

Kreator wyboru mikrokontrolera w programie STM32CubeMX

 

Po uruchomieniu programu STM32CubeMX i utworzeniu w nim nowego projektu, klikając w przycisk “New project”, pierwszym oknem jaki ujrzymy będzie kreator wyboru mikrokontrolera. Możemy tutaj od razu wybrać z list rozwijanych model posiadanego przez nas układu oraz przejść dalej klikając “OK”. Na wykorzystywanej przeze mnie, podczas tworzenia tego kursu, płytce Kamami KA-NUCLEO-F411CE, znajduje się układ z serii STM32F411CEUx w obudowie UFQFPN48. Kreator ten przydatny jest jednak nie podczas tworzenia prostych projektów w trakcie nauki, a przy tworzeniu projektów do produkcji seryjnej. Z listy po lewej stronie, wybieramy wtedy wszystkie funkcje i interfejsy mikrokokontrolera, których potrzebuje do działania nasz projekt, a po prawej stronie okna, otrzymujemy listę wszystkich mikrokontrolerów z rodziny STM32, które spełniają nasze wymagania. Możemy w ten sposób wybrać najprostszy i najtańszy układ spełniający nasze oczekiwania. W podobny sposób, w drugiej zakładce, jesteśmy też w stanie wybrać płytkę rozwojową. Znajdują się tam jednak tylko płytki wyprodukowane przez producenta układów STM32 – firmę STMicroelectronics.

Ustawienia funkcji pinów w programie STM32CubeMX

 

Po wyborze mikrokontrolera przechodzimy do właściwego okna programu STM32CubeMX. W pierwszej zakładce widoczna jest obudowa mikrokontrolera wraz ze wszystkimi jego wyprowadzeniami oraz, na liście po lewej stronie, lista komponentów które możemy skonfigurować. Należą do nich wszystkie liczniki i interfejsy naszego mikrokontrolera, ale nie tylko. Zazwyczaj są to też funkcje alternatywne poszczególnych pinów. Z tego względu, większość rzeczy które możemy skonfigurować w tej zakładce, możemy ustawić na dwa sposoby – albo klikając prawym przyciskiem myszy na pin i wybierając jedną z jego funkcji – tj. wejście/wyjście GPIO, wejście konwertera ADC, czy wyjście interfejsu UART, albo ustawiając tą funkcję na liście po lewej stronie i przenosząc metodą przeciągnij-upuść odpowiednio ustawiony pin w inne miejsce.

To co powinniśmy ustawić w tej zakładce, to wejście zegara dostarczającego sygnał taktujący do mikrokontrolera, o ile taki znajduje się na naszej płytce. Mikrokontrolery STM32 posiadają również wbudowany układ taktujący. Nie jest on jednak zbyt stabilny i do poprawnej pracy zaleca się skorzystanie z zewnętrznego generatora. Na płytce KA-NUCLEO-F411CE znajdują się dwa oscylatory kwarcowe dostarczające sygnał taktujący do naszego układu – HSE (zegar wysokiej częstotliwości) i LSE (zegar niskiej częstotliwości). W tej chwili potrzebujemy ustawić jedynie pierwszy z nich. Będzie on źródłem sygnału taktującego dla całego układu. Drugi z nich – LSE wykorzystywany jest jako źródło częstotliwości dla układu odmierzającego czas rzeczywisty (RTC). Nie będziemy go jednak w tej chwili konfigurować.

Z listy po lewej stronie, rozwijamy kolejno “Peripherials” -> “RCC” i z listy rozwijanej w polu “High Speed Clock (HSE)” wybieramy pozycję “Crystal/Ceramic Resonator”. Spowoduje to ustawienie na dwóch pinach na schemacie, ich funkcji alternatywnych – do nich fizycznie przyłączony jest oscylator.

Kolejną rzeczą którą zrobimy, będzie ustawienie pinu do którego podłączona jest dioda w stan “GPIO_Output”, tak abyśmy mogli ją włączać i wyłączać. Wykorzystamy tutaj diodę RGB znajdującą na płytce KA-NUCLEO-F411CE, a konkretnie jej jedną część odpowiadającą za świecenie w kolorze niebieskim. Dioda ta podłączona jest do pinu PB13 (kolor czerwony i zielony to odpowiednio piny PB14 i PB15). Należy zwrócić uwagę, że dioda ta podłączona jest w kierunku zaporowym ze strony pinu mikrokontrolera do napięcia dodatniego (3.3V). Dioda będzie więc świecić gdy na pinie ustawimy stan niski – 0V oraz gasnąć gdy ustawimy stan wysoki – 3.3V. Piny w stan “GPIO_Output” ustawiamy klikając lewym przyciskiem myszy na pin i wybierając z listy, funkcję jaką ma pełnić – “GPIO_Output”. Dodatkowo możemy też kliknąć na pin prawym przyciskiem myszy, wybrać z menu “Enter User Label” i nadać mu nazwę – tutaj “RGB_BLUE”. Będziemy z niej później korzystać w programie odwołując się zarówno do portu do którego podłączona jest dioda “RGB_BLUE”, jak i do konkretnego pinu na tym porcie.

Konfiguracja pętli PLL

Konfiguracja pętli PLL w STM32CubeMX

 

Druga zakładka okna programu STM32CubeMX, pozwala na konfigurację sygnału taktowania dostarczanego do poszczególnych części układu mikrokontrolera. Schemat ten może wyglądać na pierwszy rzut oka dość skomplikowanie, jest on jednak bardzo prosty i szybki w konfiguracji, gdy tylko zrozumiemy podstawy działania zaznaczonych na schemacie układów. Jego konfiguracja sprowadza się najczęściej do przełączenia dwóch przełączników i wpisania oczekiwanej wartości taktowania. Wszystkie parametry potrzebne do uzyskania zadanej wartości taktowania zostaną wyliczone przez program w pełni automatycznie.

Na środku schematu, w niebieskiej sekcji oznaczonej podpisem “Main PLL”, znajduje się główna pętla PLL. Czym jednak jest ta pętla? Bez wdawania się w szczegóły techniczne jej działania, jest to układ który z sygnału taktującego o ustalonej częstotliwości, stosując sekcję dzielącą i mnożącą, pozwala uzyskać sygnał o innej (najczęściej wyższej) częstotliwości. Jako sygnał wejściowy na pętlę PLL możemy wybrać HSI, czyli wewnętrzny niestabilny oscylator lub HSE – zewnętrzne źródło taktowania, które skonfigurowaliśmy w poprzedniej zakładce. Klikamy więc na przełącznik HSE znajdujący się przed pętlą PLL. Potrzebujemy jeszcze zdefiniować jego częstotliwość. Na omawianej płytce rozwojowej, jej wartość to 8 MHz. Tą liczbę wpisujemy więc w niebieskie pole podpisane jako “Input frequency” znajdujące się zaraz przed blokiem “HSE”.

W sekcji “System Clock Mux” wybieramy źródło sygnału taktowania dla całego mikrokontrolera. Domyślnie jest to ponownie HSI, czyli wewnętrzny niestabilny oscylator. Przełączamy źródło na wyjście, dopiero co skonfigurowanej, pętli PLL. Możemy tutaj również wybrać jako źródło, bezpośrednio zewnętrzny oscylator HSE, pomijając pętlę PLL. W polu HCLK wpisujemy częstotliwość, w MHz, jaką chcemy uzyskać. Maksymalna jej wartość, obsługiwana przez nasz układ, podana jest pod tym polem. Po wpisaniu wartości i kliknięciu klawisza Enter lub kursorem myszy poza pole, program STM32CubeMX przeliczy pozostałe parametry i ustawi wartości dzielników i mnożników tak aby uzyskać zadaną wartość taktowania. Jeśli wybierzemy częstotliwość której nie możemy uzyskać w pętli PLL lub zbyt dużą, z poza zakresu obsługiwanego przez mikrokontroler, program poinformuje nas o błędzie.

Mikrokontroler znajdujący się na płytce rozwojowej KA-NUCLEO-F411CE wspiera maksymalną częstotliwość taktowania 100 MHz, spróbujmy ustawić tą wartość. W zastosowaniach produkcyjnych, częstotliwość pracy mikrokontrolera powinna być jak najniższa, aby tylko pozwolić na działanie naszemu programowi. Przekłada się to bezpośrednio na pobierany przez mikrokontroler prąd.

Sygnał taktujący następnie trafia kolejno na preskalery, czyli “dzielniki częstotliwości” oraz na magistrale doprowadzające taktowanie do poszczególnych peryferiali. “FCLK Cortex Clock” to częstotliwość taktowania rdzenia procesora ARM. W przypadku mikrokontrolerów z rodziny STM32F4, “APB1” to magistrala doprowadzająca taktowanie do interfejsów SPI2, SPI3, USART2, I2C1, I2C2, I2C3, I2S2, I2S3 oraz liczników TIM2, TIM3, TIM4 i TIM5. “APB2” to kolejna magistrala, dostarczająca sygnał taktowania do interfejsów SPI1, SPI4, SPI5, USART1, USART6, ADC1 oraz liczników TIM1, TIM9, TIM10, TIM11. Peryferiale znajdujące się na magistrali “APB1”, w przypadku omawianego układu, nie mogą być taktowane z częstotliwością wyższą niż 50 MHz. Dlatego program CubeMX podzielił tą częstotliwość przy pomocy preskalera, a następnie pomnożył ją, aby liczniki były taktowane częstotliwością 100 MHz.

Na schemacie znajdują są jeszcze inne źródła i układy korzystające z sygnału taktującego. Zaznaczono tutaj wejście drugiego oscylatora zewnętrznego – LSE, generującego sygnał o niskiej częstotliwości, wykorzystywany przez zegar czasu rzeczywistego. Z głównej pętli PLL mamy też dodatkowe wyjście na kolejną pętlę – PLLI2S. Jest ona wykorzystywana tylko gdy korzystamy z interfejsu I2S. Jej istnienie spowodowane jest koniecznością stosowania nietypowych częstotliwości podczas przesyłu danych przez ten interfejs. Powstał on w celu przesyłu cyfrowego sygnału audio o częstotliwości próbkowania 44.1 kHz. Jest obecnie wykorzystywany wszędzie tam gdzie potrzebujemy skorzystać z nietypowych częstotliwości, w taki sposób aby nie miało to wpływu na pracę pozostałych komponentów. Sygnałów tych na razie nie potrzebujemy konfigurować.