STM32: rozstań się z 8-bitowcami! Taktowanie w STM32

Ceny mikrokontrolerów STM32 osiągnęły poziom pozwalający traktować je jako alternatywę dla wszelkiej maści 8-bitowców. Jeśli wziąć pod uwagę jeszcze ich wydajność, wyposażenie i realne możliwości, pozostawanie w świecie 8 bitów całkiem traci racjonalne podstawy…

32-bitowe mikrokontrolery są postrzegane przez konstruktorów jako elementy do bardziej wymagających zadań. Ta opinia jest ugruntowywana przez wyposażenie w stosunkowo duże pamięci programu Flash i pamięci danych, oraz w zaawansowane układy peryferyjne. Duża wydajność i znakomite wyposażenie logicznie łączyło się z wyższą ceną w porównaniu z prostszymi mikrokontrolerami 8-bitowymi czy nawet 16-bitowymi. Wynika to miedzy innymi z tego, że skomplikowany 32-bitowy rdzeń zajmuje dużą powierzchnię na płytce krzemowej i jest droższy w produkcji. Jednak nowa generacja rdzeni Cortex-M zaprojektowana przez firmę ARM specjalnie do układów sterowania została znacząco uproszczona. Uproszczenie spowodowało, że zadania stawiane w układach wbudowanych mogą być wykonywane szybciej, przy zmniejszonym poborze energii, ale jednoczenie implementacja w krzemie ma mniejsze wymiary i przez to jest tańsza. Z tych powodów mogły się pojawić mikrokontrolery z wydajnym 32-bitowym rdzeniem w cenie 8-bitowych jednostek. Wykorzystali to oczywiście producenci wietrząc w tym możliwość udziału w olbrzymim rynku prostszych aplikacji opanowanym przez mikrokontrolery 8-bitowe.

 

 

Posiadanie dobrego produktu to jedno, a sprzedanie go inna sprawa. Oprócz ceny bardzo ważną rzeczą jest przyzwyczajenie konstruktorów. Jeżeli ktoś swoje urządzenie potrafi zrobić bez problemu na „atmelku” czy „picku” to dlaczego nagle ma zacząć korzystać z zupełnie innej architektury, narzędzi i rezygnować z wszystkich swoich przyzwyczajeń? Tym bardziej, że producenci 8-bitowców również nie próżnują i ich wyroby są coraz lepiej wyposażone i dzięki nowym technologiom wytwarzania mogą być taktowane szybszymi zegarami i wydajanie oszczędzać energię. Żeby sprzedać nowe rozwiązania trzeba użytkownika jakoś przekonać. Może to być łatwość w kupieniu elementu, dostępne, tanie i łatwe w zdobyciu płytki ewaluacyjne, dostępne i tanie lub bezpłatne narzędzia typu kompilator C i środowisko IDE. Ważnym elementem kampanii reklamowych jest propagowanie nowych rozwiązań w szkołach i uczelniach, tak by nowo wykształceni konstruktorzy je znali i używali.

 

 

 

Ja postanowiłem przekonać jak wygląda przejście z architektury 8-bitowej na 32-bitową z perspektywy kogoś kto to robi pierwszy raz. Załóżmy, że do docelowego projektu szukamy taniego mikrokontrolera 32-bitowego z rdzeniem Cortex. Wybór padł na rodzinę STM32F100 produkowaną przez firmę STM i nazywana przez nią Value Line. Mikrokontrolery Value Line mają rdzeń Cortex–M3 taktowany z maksymalną częstotliwością 24 MHz. Pamięć programu Flash może mieć maksymalną pojemność 512 kB, a pamięć danych RAM 32 kB.

 

Tani początek

Najprostszą i wbrew pozorom najtańszą metodą na szybkie i bezproblemowe rozpoczęcie pracy z nowym mikrokontrolerem jest zakup gotowego zestawu ewaluacyjnego. Jeżeli chcemy wstępnie sprawdzić czy mikrokontroler rzeczywiście spełni nasze wymagania, to poszukamy modułu taniego, ale odpowiednio wyposażonego. Przez to wyposażenie rozumiem minimum 2 elementy: wbudowany programator/emulator i wyprowadzenie linii portów do złącz, które można łatwo wykorzystać. Programator w tanim module znacznie obniża koszty, bo wciąż nie wiemy czy nowy element spełni oczekiwania i wydatek na drogi programator/emulator jest ryzykowny. Dostępne wyprowadzenia mikrokontrolera znacznie ułatwiają pracę, bo znam tanie moduły z nietypowym złączem do których trzeba dokupić bardzo drogę płytkę rozszerzenia, by cokolwiek z nim zrobić.

 

STM32: rozstań się z 8-bitowcami! Taktowanie w STM32

Fot. 1. Wygląd i wyposażenie zestawu STM32VLDISCOVERY (dostępny w KAMAMI.pl)

 

Dla mikrokontrolerów STM32 atrakcyjną propozycją jest STM32VLDISCOVERY (fotografia 1), który charakteryzuje się dobrym wyposażeniem (w tym pokładowym programatorem-debuggerem JTAG) i niską ceną (ok. 60 PLN brutto).

Zestaw STM32VLDISCOVERY składa się z dwóch 2 części:

  • programatora/emulatora zgodnego z ST-Link. To dobra wiadomość, bo jest to narzędzie wspierane przez najpopularniejsze środowiska IDE. ST Link jest sterowany i zasilany ze złącza USB co dodatkowo upraszcza jego używanie. Programator wbudowany w płytkę ma wyprowadzone sygnały magistrali programującej i można go wykorzystać jako zewnętrzny programator we własnych konstrukcjach po zakończeniu prób. Bardzo rozsądne rozwiązanie za niewielkie pieniądze,
  • części ewaluacyjnej z mikrokontrolerem STM32F100RBT6. Jego wyprowadzenia GPIO połączono z dwoma listwami goldpinów, które są umieszczone na krawędzi płytki. Każde z wyprowadzeń jest czytelnie opisane.

Bardzo mi się takie rozwiązanie spodobało, bo bez żadnych problemów można się dołączyć do linii portów na przykład za pomocą przewodów zakończonych wtyczkami pasującymi do goldpinów. Oprócz mikrokontrolera na płytce umieszczono jeszcze 2 rezonatory kwarcowe: 8-MHz i 32kHz („zegarkowy”), 2 diody LED: zieloną i niebieską, połączone z liniami portów oraz 2 przyciski: jeden do zerowania mikrokontrolera (RST), a drugi połączony z linią portów (USER). Spartańskie wyposażenie modułu tłumaczy jego niską cenę. Jednak prostota jest w tym przypadku zdecydowaną zaletą.

 

IDE: środowisko programistyczne i kompilator

Mamy już moduł z programatorem i dużo zapału do pracy. Potrzebujemy teraz środowiska IDE, w którym będzie można pisać programy, potem je kompilować, uruchamiać i na koniec programować pamięć mikrokontrolera. W dokumentacji modułu są polecane trzy pakiety programistyczne:

  • uVision 4 (ARM-MDK) produkowane przez firmę Keil,
  •  Embedded Workbench for ARM produkowany przez firmę IAR,
  • TrueSTUDIO produkowana przez firmę Atollic.

Ponieważ należy się spodziewać, że każde z tych środowisk będzie dobre, wybrałem najpopularniejszy w Polsce pakiet ARM-DMK z IDE o nazwie uVision firmy Keil. Wybrany pakiet oprócz środowiska IDE zawiera też wersję ewaluacyjną kompilatora C dla rdzenia Cortex-M3. Bezpłatna wersja kompilatora dostarczana wraz z pakietem IDE ma ograniczenie kodu do 64kB i do celów eksperymentów na pewno wystarczy. Jednak w tym miejscu musimy sobie przypomnieć, że naszym celem jest sprawdzenie czy można bezboleśnie przejść ze stosowania mikrokontrolerów 8-bitowych na 32-bitowe Corteksy. Dla 8-bitowców Atmela jest do dyspozycji bezpłatny kompilator GCC bez ograniczenia kodu czy innych ograniczeń. Użytkownicy Microchipa mają ewaluacyjne wersje kompilatorów wszystkich rodzin łącznie z 32-bitowymi PIC32. Ograniczeniem jest tylko brak silnej optymalizacji kodu, przez co pamięć programu zapełnia się szybciej niż mogłaby. W przypadku STM32-mamy do dyspozycji „darmowe ”64 kB: tylko 64 kB czy też aż 64 kB. Nie mając za sobą kilku praktycznych projektów, które zastępują projekty z 8-bitowcami trudno powiedzieć czy to wystarczy, ale na pewno to ograniczenie da o sobie znać prędzej czy później. Być może znajdzie się inne legalne rozwiązanie, bo kupienie drogiego kompilatora tylko po to by zmienić rodzinę na pewno nie wchodzi w grę.

Pakiet uVision4 można prac po uprzednim wypełnieniu ankiety na stronie ww.keil.com. Instalacja przebiega tak jak podobne programy tego typu i nie wymaga komentarza. Po zakupie płytki i zainstalowaniu IDE mamy już wszystko co potrzebne by zacząć próby.

Płytka ewaluacyjna zapewnia programowanie, zasilanie i taktowanie mikrokontrolera. Spróbujemy napisać najprostszy program zapalający i gaszący diodę LED umieszczoną na STM32VLDISCOVERY. Żeby nawet taki prosty program mógł zadziałać trzeba zadbać o odpowiednie taktowanie peryferiów mikrokontrolera. Mamy na płytce rezonator kwarcowy i wydaje się, że nie będzie z tym problemu.

W historycznie pierwszych mikrokontrolerach źródłem sygnału zegarowego był wyłącznie oscylator kwarcowy z zewnętrznym oscylatorem, tzw. „kwarcem”. Żeby mikrokontroler mógł działać trzeba było dołączyć do niego taki rezonator i ewentualnie kondensatory ceramiczne o pojemności 10…50pF, zależnie od wymagań układu. Tak było w intelowskich 8048 i 8051. Częstotliwość taktowania klasycznego 8051 zawierała się w granicach 1,2…12 MHz i inaczej nie można było. W mikrokontrolerach PIC16 wprowadzono konfigurację generatora taktującego rdzeń za pomocą bitów konfiguracyjnych umieszczonych w pamięci Flash i programowanych programatorem razem z pamięcią programu. To już był duży postęp, bo mikrokontroler można było taktować małymi częstotliwościami np. 32 kHz lub stosować generator RC z zewnętrznymi elementami RC. Wraz z rozwojem technologii zaczęto stosować wewnętrzne generatory RC o wysokiej częstotliwości do taktowania rdzenia i generatory RC małej częstotliwości do celów pomocniczych np. do taktowania wewnętrznego watchdoga. Wbrew pozorom to dość ważny krok w technice taktowania. Wewnętrzny generator RC ma zalety: nie wymaga elementów zewnętrznych i przede wszystkim bardzo szybko startuje po włączeniu zasilania, czego nie można powiedzieć o generatorach kwarcowych. Jest idealny w aplikacjach, które nie wymagają dużej stabilności generowanej częstotliwości, czyli tam, gdzie nie wymagane jest dokładne odliczanie czasu, lub stosowania transmisji asynchronicznej typu UART (RS232). Wewnętrzny RC jest chętnie stosowany w popularnych 8-bitowcach Atmela i Microchipa, ale oczywiście jako równoległa możliwość razem z oscylatorem kwarcowym.

Zatem w mikrokontrolerach 8-bitowych najpopularniejszy generator sygnału taktującego to generator kwarcowy o programowanym zakresie częstotliwości, lub wewnętrzny generator RC o częstotliwości 4MHz lub 8MHz. Taktowanie jest programowane bitami konfiguracyjnymi tak zwanymi fuse’ami. Oprócz tego stosuje się wewnętrzne dzielniki dzielące częstotliwość generatora (głównie wewnętrznego RC) tak by można było taktować mikrokontroler z częstotliwościami niższymi jeżeli to konieczne. Dzielnik można programować w trakcie pracy mikrokontrolera i dynamicznie zmieniając taktowanie zależnie od potrzeb. Sprawa jest stosunkowo prosta. Zobaczy teraz jak to jest w przypadku naszego mikrokontrolera. Wiemy już, że rdzeń może być taktowany maksymalną częstotliwością 24 MHz. Podobnie jak w mikrokontrolerach 8-bitowych źródłem sygnału może być generator kwarcowy nazwany HSE i wewnętrzny oscylator RC nazwany HSI.

Generator HSE wymaga zewnętrznego oscylatora kwarcowego o częstotliwości z zakresu 4…24 MHz. na pierwszy rzut oka wydaje się, że ten zakres w zupełności wystarczy. Rdzeń może być taktowany z fmax = 24 MHz i wystarczy dobrać odpowiednia częstotliwość rezonatora do wymagań. W naszej płytce ewaluacyjnej kwarc ma częstotliwość 8 MHz. Czyżby producent płytki zamierzał taktować rdzeń tylko z 1/3 maksymalnej prędkości ? Wybór tej częstotliwości jest w pewien sposób związany z rozbudowanym blokiem generowania sygnału zegarowego. W STM32F100 częstotliwość sygnału z generatora może być dzielona ale tez może być powielana w układach PLL – rysunek 2.

 

Rys. 2. Schemat blokowy modułu generatora sygnału zegarowego w STM32F1

Rys. 2. Schemat blokowy modułu generatora sygnału zegarowego w STM32F1

 

Ponieważ wewnętrzny generator RC HSI ma również częstotliwość 8 MHz, to można używać go zamiennie z HSE bez konieczności przeprogramowywania dzielników i układów PLL. Trzeba tez wiedzieć, że po włączeniu zasilania mikrokontroler staruje z generatorem wewnętrznym i dopiero w wykonywanym programie można się przełączyć na generator kwarcowy. Ponadto przy problemach z generatorem kwarcowym mikrokontroler przełącza się automatycznie na wewnętrzny RC , To jeszcze jeden argument za tym by częstotliwość HSE była równa częstotliwości HSI. Jeżeli się przypatrzymy dokładnie rysunkowi 2 to widać, że jest możliwe ustawienie różnych częstotliwości taktowania rdzenia i taktowania magistral układów peryferyjnych. Zaprogramowanie układu generowania zegara z jednej strony jest bardziej skomplikowane niż w 8-bitowych mikrokontrolerach, ale jednocześnie jest bardziej elastyczne – coś za coś.

Ważne jest to, że zegar nie jest programowany bitami konfiguracyjnymi i musimy o jego konfigurację zadbać w programie, najlepiej na jego samym początku. Jak to zrobić? Mamy dwie możliwości: albo na podstawie dokumentacji mikrokontrolera zapiszemy wszystkie konieczne rejestry konfiguracyjne (co nie jest w końcu takie trudne, ale pracochłonne), albo skorzystamy z gotowych procedur standardowej biblioteki Standard Peripherial Library. Obie metody są dobre, ale na początek dobrze jest zobaczyć jak robią to doświadczeni użytkownicy. Dlatego skorzystamy z gotowych bibliotek. Zazwyczaj producent mikrokontrolerów lub modułów ewaluacyjnych stara się dostarczyć przykładowe programy. Wykorzystamy to analizując przykład SysTick pokazujący jak skonfigurować i wykorzystać licznik SysTick i zgłaszane przez niego przerwanie.

Przykładowe procedury STM32VLDISCOVERY Firmware Package (AN3268) można pobrać ze strony producenta www.st.com/stm32. Po rozpakowaniu trzeba otworzyć gotowy projekt SysTick dla uVison4 z katalogu an3268/stm32vldiscovery/Project/examples/SysTick/MDK_ARM. Struktura plików i katalogów projektu jest pokazana na rysunku 3.

 

Rys. 3. Struktura katalogu przykładowego projektu SysTick

Rys. 3. Struktura katalogu przykładowego projektu SysTick

 

Projekt jest dość mocno rozbudowany jak na funkcje, która ma wykonywać. Przypomnijmy: konfigurujemy zegar systemowy, linie portów, licznik SysTick i obsługujemy przerwanie od jego przepełnienia. Można sobie zadać pytanie: po co tyle plików, katalogów skoro dla mikrokontrolera 8-bitowego podobny projekt można napisać w kilkunastu – kilkudziesięciu linijkach w jednym pliku?

Jest to naturalna konsekwencja wyboru gotowych bibliotek i pewnego stylu programowania. Po nabyciu wprawy takie podejście jest o wiele bardziej efektywne niż pisanie za każdym razem wszystkiego od nowa. Trzeba tez pamiętać, że mikrokontrolery STM32-są jednak bardziej rozbudowane niż 8-bitowe jednostki i wymagają szerszej inicjalizacji. Decydując się na ewentualna zamianę trzeba to uwzględnić. Jak już wiemy jedną z początkowych czynności jest konfiguracja modułu taktowania.

Głównym plikiem projektu jest main.c i tam rozpoczniemy szukanie konfiguracji zegara. Jednak na początku funkcji void main(void) umieszczona jest informacja, że konfigurację zegara umieszczono w procedurze SystemInit() wywoływanej przez procedury startowe startup. Procedury startowe są napisane w asemblerze i mogą być automatycznie dodawane do projektu przez IDE uVision4 w trakcie jego tworzenia. Procedurę SystemInit() umieszczono w pliku system_stm32f10x.c. Po jej odnalezieniu okazuje się, że wywołuje kolejna funkcję SetSysClock()listing 1.

List. 1

Jej działanie jest powiązane z definicjami pokazanymi na listingu 2.

List. 2

Dlaczego piszę o tym tak dokładnie? Bo ustalenie źródła i częstotliwości zegara taktującego rdzeń jest bardzo istotne dla poprawnego działania programu. Przy pierwszym kontakcie z mikrokontrolerem sposób ustalenia jak taktować i z jaka częstotliwością uznałem za jedna z najważniejszych czynności. Tutaj mamy możliwość wyboru 2 predefiniowanych częstotliwości: częstotliwości zegara HSE (generatora kwarcowego) lub częstotliwości 24 MHz. W tym drugim przypadku jest to częstotliwość 8 MHz pomnożona przez 3 w układzie PLL. W pliku system_stm32f10x.c korzystamy z definicji:

i powinniśmy taktować rdzeń z częstotliwością 24 MHz, czyli maksymalnie jak na to pozwala rodzina STM32F100. Dla porządku pokażę na poniższym listingu jak wygląda firmowa procedura ustawiania zegara systemowego dla 24 MHz – listing 3.

List. 3

Wystarczy spojrzeć na powyższy listing by stwierdzić, że wybór bibliotek firmowych zamiast samodzielnej konfiguracji zegara był właściwy. Zaoszczędziło nam to wiele pracy i w sumie stało się tak proste jak konfiguracja taktowania w popularnych mikrokontrolerach 8-bitowych. Musimy pamiętać, że po opanowaniu podstawowych czynności związanych z konfiguracją zegara warto się zapoznać z mechanizmami zabezpieczeń przed zakłóceniami sygnału zegara Clock Security System. Możemy zobaczyć na listingu 3, że już w trakcie konfigurowania zegara wykonywane jest sprawdzanie poprawności generowania sygnału przez HSE. Clock Security System potrafi zdiagnozować problemy z generatorem zewnętrznym, wysłać sygnał przerwania informujący o problemie i przełączyć się na wewnętrzny generator HSI o częstotliwości 8 MHz. Podobne rozwiązania są stosowane w mikrokontrolerach 8-bitowych na przykład w rodzinie PIC18F i są bardzo cenione w aplikacjach obsługujących krytyczne algorytmy sterowania, gdzie niestabilność taktowania wiąże się z poważnymi problemami.

Tomasz Jabłoński

Autor: