Sygnały zegarowe STM32F1 Connectivity Line

Wraz z pojawieniem się na rynku mikrokontrolerów STM32 należących do komunikacyjnego segmentu connectivity line, pojawiło się wiele pytań o poprawną konfigurację sygnałów zegarowych. W odpowiedzi na te pytania publikujemy artykuł ukazujący sposób konfiguracji zaawansowanego systemu kontroli sygnałów zegarowych w układach STM32F107.

Każdy synchroniczny system cyfrowy, a do takich z pewnością należą układy mikroprocesorowe, wymaga do poprawnej pracy odpowiednich sygnałów zegarowych. W najprostszym przypadku cały system jest taktowany z jednego źródła tą samą częstotliwością.

Wraz ze wzrostem poziomu skomplikowania, a co ważniejsze, ze wzrostem skali integracji, istnieje potrzeba generowania w układach mikroprocesorowych sygnałów zegarowych o różnych częstotliwościach, determinowanych przez rodzaj stosowanych układów peryferyjnych.

Mikrokontrolery STM32 należące od rodziny connectivity line są wyposażone w imponującą liczbę peryferiów komunikacyjnych, m. in. Ethernet MAC (opcjonalnie), USB OTG, I2S. Na rys. 1 przedstawiono schemat blokowy obrazujący mnogość dostępnych peryferiów układów connectivity line. Tak duża liczba elementów o różnorodnym przeznaczeniu sprawia ,że konieczne staje się generowania jednocześnie wielu przebiegów zegarowych, o różnych częstotliwościach. W artykule przedstawiona została konfiguracja sygnałów zegarowych dla aplikacji korzystającej z USB i Ethernet.

 

Rys. 1. Wyposażenie segmentu connectivity line [źródło: STMicroelectronics]

Rys. 1. Wyposażenie segmentu connectivity line [źródło: STMicroelectronics]

 

Układy warstwy fizycznej PHY Ethernet wymagają zazwyczaj taktowania częstotliwością 25MHz, w przypadku stosowania interfejsu MII (Media Independence Interface), lub 50MHz, jeżeli wykorzystano interfejs RMII (Reduced MII). Najczęściej mikrokontrolery z wbudowanym sterownikiem Ethernet wymagają pracy z zewnętrznym źródłem sygnału zegarowego (np. rezonator kwarcowy) o częstotliwości 25 MHz. Konstruktorzy, którzy zdecydowali się na stosowanie układu z rodziny STM32 nie są jednak skazani na stosowanie w swoich aplikacjach ethernetowych „kwarców” tylko o tej częstotliwości. Jak pokażemy w dalszej części artykułu, architektura mikrokontrolerów firmy STMicroelectronics pozwala na odstępstwa od tej reguły.

Kontroler magistrali USB do poprawnej pracy wymaga taktowania z częstotliwością 48MHz. Jeśli tylko aplikacja nie ma zbyt dużych wymagań i nie korzysta z urządzeń peryferyjnych wymagających specyficznych częstotliwości pracy, to wtedy można cały system mikroprocesorowy taktować zegarem 48 MHz. A co, jeśli owe 48 MHz to za mało dla naszej aplikacji? W takim przypadku na ratunek przychodzi możliwość taktowania rdzenia mikrokontrolera z innego źródła sygnału zegarowego.

Taktowanie w STM32

Mikrokontrolery STM32F107, czyli należące do szerszej rodziny connectiviy line, mają wbudowane aż trzy układy PLL, które umożliwiają mnożenie wejściowego sygnału przez wiele współczynników. Do dyspozycji są również dwa układy wstępnego dzielenia sygnału oraz liczne multipleksery sygnałów zegarowych. Budowa bloku kontroli zegarów została przedstawiona na rysunku poniżej.

 

Rys. 2. Schemat RCC (Reset and Clock Control) [źródło: STMicroelectronics]

Rys. 2. Schemat RCC (Reset and Clock Control) [źródło: STMicroelectronics]

 

Mikrokontrolery connectivity line mogą pracować z rezonatorami o częstotliwościach z przedziału od 3 MHz do 25 MHz. Dokumentacje dostarczane przez firmę ST podają, że celem rozszerzenia górnej granicy do 25 MHz było osiągnięci możliwości pracy wszystkich interfejsów komunikacyjnych po podłączeniu tylko jednego źródła sygnału zegarowego. Pokażemy, że niezwykła elastyczność układu taktowania tej podrodziny mikrokontrolerów STM32 pozwala na wykorzystanie również rezonatorów o innych częstotliwościach. Przedstawiona zostanie konfiguracja dla rezonatora 10 MHz z przeznaczeniem dla aplikacji z obsługą Ethernet i USB.

Obsługa obu interfejsów: Ethernet i USB wymaga uzyskania dwóch różnych sygnałów zegarowych, odpowiednio 25 MHz i 48 MHz. Jeśli mikrokontroler STM32 ma dodatkowo wykorzystywać pełnię swoich możliwości, to należy odpowiednio skonfigurować sygnał zegarowy dla rdzenia mikrokontrolera, tak by uzyskał on 72 MHz. Na rys. 3 przedstawiono konfigurację dla poszczególnych bloków, tak by każdy z peryferiów pracował z optymalną częstotliwością. Jak widać droga do zamierzonego celu wydaje się dość kręta, jednak jak zaraz przekonamy się, nie jest aż tak źle.

 

Rys. 3. Konfiguracja sygnałów zegarowych dla rdzenia, USB i Ethernet, przy oscylatorze 10MHz

Rys. 3. Konfiguracja sygnałów zegarowych dla rdzenia, USB i Ethernet, przy oscylatorze 10MHz

 

Wszystkie czynności związane z konfiguracją sygnałów zegarowych mogą zostać zgrupowane do postaci jednej funkcji. W przedstawianym przykładzie funkcję nazwano RCC_Configuration(), listing funkcji zamieszczono poniżej.

 

Listing 1. Konfiguracja bloku RCC (Reset and Clock Control)

 

Domyślnie po włączeniu zasilania mikrokontroler używa do pracy wewnętrzny generator RC o częstotliwości około 8 MHz. Szybki oscylator zewnętrzny (HSE – High Speed External), zanim zostanie użyty, musi zostać włączony. Działanie to realizuje wywołanie funkcji RCC_HSE_Config. Następnie w pętli sprawdzany jest stan flagi, która informującej o tym, czy HSE został poprawnie uruchomiony. Oczekiwanie na poprawne włączenie się oscylatora trwa do 1280 (szesnastkowo 0x0500) wywołań pętli. Wartość ta jest określona przez definicję HSEStartUp_TimeOut. Ograniczenie liczby wywołań pętli służy zabezpieczeniu przed zablokowaniem się w przypadku braku poprawnej inicjalizacji HSE. W bibliotece API dostarczanej przez firmę STMicroelectronics dyrektywy preprocesora umieszczone są w pliku stm32f10x.h.

Jeśli flaga HSERDY po przekroczeniu czasu wyznaczonego przez pętlę jest nadal wyzerowana, to wtedy instrukcja warunkowa zapisuje do zmiennej statusu HSEStatus wartość ERROR. Wystąpienie takiej sytuacji skutkuje przerwaniem procesu konfiguracji sygnałów zegarowych, włączane jest jedynie taktowanie dla portów wejścia/wyjścia. W przypadku poprawnego startu HSE rozpoczyna się właściwy proces konfiguracji RCC. W ramach ,którego ustawiane są m. in. mnożniki i dzielniki sygnałów zegarowych.

Pamięć FLASH wbudowana w mikrokontrolery STM32 serii F1 może pracować z maksymalną częstotliwością 24 MHz, w związku z czym należy ustawić dla niej tzw. „wait state”, czyli opóźnienie.

Dalej konfiguracja odbywa się jakby od końca. Najpierw ustalane są częstotliwości sygnałów wyznaczanych na podstawie zegara systemowego SYSCLK, a więc taktowanie wszystkiego, co jest podłączone do magistrali AHB (patrz rys. 2). Wybierane jest źródło sygnału zegarowego m. in. dla: rdzenia mikrokontrolera, magistral APB1 (PCLK1) i APB2 (PCLK2), opcjonalnie również taktowanie przetworników A/C, liczników itd.. Dodać tu należy, że magistrala APB1 może być taktowana sygnałem o maksymalnej częstotliwości 36 MHz, natomiast dla magistrali APB2 jest to wartość 72 MHz.

Gdy fragment bloku RCC podłączony do magistrali AHB ma ustalone swoje parametry pracy, należy przystąpić do właściwej konfiguracji układów PLL, multiplekserów i dzielników.

W naszym przypadku sygnał z zewnętrznego oscylatora HSE jest dzielony przez 2 w drugim bloku wstępnego dzielenia sygnału PREDIV2, w ten sposób uzyskiwany jest sygnał o częstotliwości 5 MHz. W następnym kroku włączany jest układ PLL3 z mnożnikiem x10. Wyjście PLL3 może być podłączone przez multiplekser do wyprowadzenia MCO (Microcontroller Clock Output), ale sygnał z PLL3 może być również dzielony przez 2 zanim zostanie doprowadzony do MCO. Właśnie ta druga opcja została wykorzystana w przedstawionym przykładzie, zatem na wyprowadzeniu MCO układu będzie sygnał o częstotliwości 25 MHz, czyli tyle, ile wymaga interfejs MII, który jest stosowany do podłączenia warstwy fizycznej Ethernet.

W założeniach zaznaczono, że rdzeń mikrokontrolera powinien pracować z zegarem 72 MHz. Aby to osiągnąć konfigurowany jest układ PLL2 z mnożnikiem x8, by uzyskane w ten sposób 40 MHz. Następnie częstotliwość dzielona jest przez 5 w bloku PREDIV1, dzięki temu na wejście układu PLL dostarczany jest przebieg o częstotliwości 8 MHz. Teraz wystarczy już tylko ustawić mnożnik PLL na 9, by uzyskać oczekiwane 72 MHz.

Brakuje jeszcze sygnału zegarowego dla interfejsu USB. Częstotliwość przebiegu na wyjściu PLLVCO układu PLL jest w omawianym przypadku powielana 18 razy. W efekcie uzyskuje się 144 MHz, co jest poprawną wartością (maksymalną) dla wyjścia PLLVCO. Ostatecznie sygnał ten dzielony jest przez 3 w preskalerze USB, w wyniku czego uzyskiwane jest wymagane 48 MHz.

Ostatni etap konfiguracji bloku RCC to włączenie układów peryferyjnych: USB, Ethernet i portów wejścia/wyjścia.

Z jaką częstotliwością pracuje mój mikrokontroler?

Pracując z tak zaawansowanym systemem sygnałów zegarowych może niekiedy dochodzić do stanu, że wszystko powinno działać, ale układ wydaje się nie pracować z wymaganą częstotliwością. Bezpośrednią i zarazem najprostszą metodą sprawdzenia szybkości pracy zegara systemowego jest jego wyprowadzenie na zewnątrz. Metoda ta posiada dwa ograniczenia. Pierwsze dotyczy wymogu posiadania miernika częstotliwości o dość dużym zakresie. Drugie ograniczenie daje o sobie znać przy częstotliwościach będących rzędu wielu dziesiątek megaherców. Tutaj ograniczeniem są możliwości układów sterujących wyjściami mikrokontrolera. W przypadku układów STM32, maksymalna częstotliwość przełączania wyprowadzenia MCO wynosi 50 MHz. Z odsieczą przychodzą jednak pośrednie sposoby wyznaczenia częstotliwości pracy jednostki centralnej.

Mikrokontrolery STM32 są wyposażone w systemowy timer SYSTICK. Jest to 24-bitowy układ licznikowy, liczący w dół. Może on być taktowany z taką samą częstotliwością jak rdzeń, lub ośmiokrotnie mniejszą. Pomiar prędkości pracy MCU polega na podzieleniu częstotliwości systemowej za pomocą SYSTICK i zmianie stanu wyprowadzenia w przerwaniu. W ten sposób można uzyskać na wyprowadzeniu sygnał rzędu np. kilku, kilkunastu kHz, a taką wartość można już zmierzyć zwykłym multimetrem posiadającym opcję pomiaru częstotliwości, lub też drugim mikrokontrolerem, który pracuje ze znaną częstotliwością. Jest oczywistym, że taki pomiar nie będzie dokładny, ale pozwala rozstrzygnąć, czy wszystkie dzielniki i mnożniki sygnału zegarowego zostały ustawione w poprawny sposób oraz czy rezonator kwarcowy uruchomił się na odpowiedniej częstotliwości.

Konfiguracja timera SysTICK nie jest zbyt wyrafinowana, wymaga jedynie dwóch linii kodu. Funkcję ustawiającą parametry licznika przedstawiono na listingu 2 Również funkcja obsługi przerwania od timera nie jest skomplikowana, zamieszczono ją na listingu 3. To jeszcze nie wszystko. Wyprowadzenie pomiarowe, w zasadzie dowolne, przykładowo niech będzie to GPIOE7 powinno zostać skonfigurowane, a dla portu GPIOE należy włączyć taktowanie. Wspomniane zadania wykonuje funkcja z listingu 4.

 

Listing 2. Funkcja konfiguracji licznika SysTick

 

Listing 3. Obsługa przerwania od licznika SysTick

 

Listing 4. Funkcja konfigurująca wyprowadzenie GPIOE7