Książki o elektronice i programowaniu w promocji 2 za 1 (tańsza za 0 zł)! Sprawdź listę tytułów »

Kurs STM32 F4 – #10 – Obsługa SPI, wyświetlacz OLED

Kurs STM32 F4 – #10 – Obsługa SPI, wyświetlacz OLED

Jednym z podstawowych zagadnień w świecie elektroniki jest komunikacja pomiędzy układami scalonymi.

W kolejnym artykule z serii o STM32 F4 zajmiemy się wyświetlaczem graficznym OLED. Wcześniej zapoznamy się z interfejsem SPI, który używany jest do komunikacji ze sterownikiem wyświetlacza.

Interfejs SPI

SPI (ang. Serial Peripheral Interface), to szeregowy, synchroniczny interfejs komunikacyjny służący do transmisji danych pomiędzy układami scalonymi. SPI w odróżnieniu od interfejsu I2C do przesyłania danych wykorzystuje 3 linie transmisyjne, co pozwala na komunikację full-duplex.

Zastosowanie poszczególnych linii danych:

  • MISO (Master Input Slave Output) - transmisja do urządzenia master.
  • MOSI (Master Output Single Output) - transmisja do urządzeń slave.
  • SCLK (Serial Clock) - sygnał zegarowy generowany przez urządzenie master.
Połączenie interfejsu SPI pomiędzy urządzeniem slave i master.

Połączenie interfejsu SPI pomiędzy urządzeniem slave i master.

Dodatkowo do każdego urządzenia typu slave musi zostać podłączona linia SS (Slave Select).

Jest to przydatne, gdy do magistrali podłączonych jest wiele urządzeń, z którymi komunikuje się urządzenie master. Można dzięki temu uprościć ramki danych o adresy układów, do których wysyłane są informacje.

Podłączenie wielu urządzeń slave do SPI.

Podłączenie wielu urządzeń slave do SPI.

Przy większej ilości urządzeń staje się to jednak problematyczne, ponieważ trzeba prowadzić osobną linię do każdego układu, z którym chcemy się komunikować.

Transmisja danych przez SPI

Urządzenie master odpowiada za generowanie sygnału zegarowego na linii SCLK. Dane transmitowane są do podłączonego urządzenia za pomocą linii MOSI. Urządzenie może odpowiadać na linii MISO. Mamy tu więc do czynienia z komunikacją full-duplex.

W przeciwieństwie do I2C, nie jest tu nam potrzebna wiedza na temat ramki danych. Musimy znać jednak kilka szczegółów, którymi cechuje się transmisja SPI.

Polaryzacja sygnału zegarowego

Polaryzację sygnału zegarowego (parametr transmisji CPOL) można skonfigurować na 2 sposoby:

  • CPOL = 0  - oznacza to, że linia zegarowa w stanie bezczynności (Idle) przyjmuje stan niski (zazwyczaj 0V). W stanie aktywnym przyjmuje stan wysoki, odpowiadający logicznej "jedynce" w systemie (w naszym przypadku - 3V).
  • CPOL = 1 - odwrotność przypadku poprzedniego.
Tryby polaryzacji sygnału zegarowego w transmisji SPI

Tryby polaryzacji sygnału zegarowego w transmisji SPI.

Przesunięcie w fazie odbierania/wysyłania danych

Drugim z parametrów transmisji, z którym spotkamy się w SPI jest określenie, na którym zboczu zegara następuje odbieranie danych, a na którym transmisja. Odpowiada za to parametr CPHA.

  • CPHA = 1 - dane są transmitowane na zboczu active⇒idle (przejście ze stanu aktywnego do stanu jałowego). Odbiór danych następuje na zboczu przeciwnym, a więc idle⇒active. Dla parametru CPOL = 0, transmisja danych odbywać się będzie na zboczu opadającym (3V ⇒ 0V), a odbiór danych na zboczu narastającym (0V⇒3V).
  • CPHA = 0 - odwrotnie do sytuacji poprzedniej.

Informacje te przydadzą nam się w praktyce, ponieważ musimy być w stanie rozróżnić w jakim trybie pracuje urządzenie, z którym zamierzamy się komunikować.

Zestaw elementów do kursu

 999+ pozytywnych opinii  Gwarancja pomocy  Wysyłka w 24h

Zestaw elementów do przeprowadzenia wszystkich ćwiczeń z kursu STM32 F4 można nabyć u naszego dystrybutora! Zestaw zawiera m.in. płytkę Discovery, wyświetlacz OLED, joystick oraz enkoder.

Zamów w Botland.com.pl »

Wyświetlacz OLED

Aby wykorzystać interfejs SPI w praktyce, użyjemy graficznego wyświetlacza OLED. Można go znaleźć w zestawie elementów stworzonym specjalnie na potrzeby tego kursu. Sprzęt z którym będziemy pracować, to kolorowy wyświetlacz o przekątnej ekranu 0,95" wyprodukowany w technologii OLED. Rozdzielczość ekranu, to 96x64 piksele.

Moduł małego wyświetlacza OLED.

Moduł małego wyświetlacza OLED.

Jako sterownik wyświetlacza wykorzystano układ SSD1331. Przed przystąpieniem do konfiguracji warto przyjrzeć się krótkiej instrukcji użytkownika omawianego wyświetlacza. Na ostatniej stronie znajdziemy rysunek przedstawiający schemat transferu danych

Schemat odbierania danych przez sterownik SSD1331 za pomocą interfejsu SPI

Schemat odbierania danych przez sterownik SSD1331 za pomocą interfejsu SPI.

Z powyższego rysunku możemy wyciągnąć dwa istotne wnioski. Po pierwsze, dane transmitowane są od bitu najstarszego, a więc od MSB (Most Significant Bit). Po drugie, próbkowanie odbywa się na zboczu narastającym. Oznacza to, że transmisja danych z mikrokontrolera musi się odbywać również na zboczu narastającym!

Wyprowadzenia wyświetlacza

Z boku wyświetlacza znajdują się piny, dzięki którym można się z nim komunikować. Przyjrzyjmy się wszystkim po kolei:

  • VCC - zasilanie układu. Wyświetlacz można zasilać z 3 lub 5V.
  • GND - masa układu.
  • NC (Not Connected) - pin niepodłączony.
  • DIN (Data In/Device In) - inna nazwa na MOSI (Master Output Slave Input). Wejście danych.
  • CLK (Clock) - linia zegarowa.
  • CS (Chip Select) - inna nazwa linii SS (Slave Select). Stan niski aktywuje nasłuchiwanie w urządzeniu, do którego mają być przesyłane dane.
  • D/C (Data/Command) - stan niski na tej linii powoduje, że odbierane dane odczytywane są jako komendy do sterownika. W przeciwnym wypadku, jako zwykłe dane.
  • RES (Reset) - stan niski na tej linii powoduje zresetowanie wyświetlacza.

Konfiguracja mikrokontrolera

Spróbujemy teraz skonfigurować SPI tak, aby można było przesyłać dane do wyświetlacza.

Krok 1. Tworzymy nowy projekt i konfigurujemy zegary.

Krok 2. Uruchamiamy SPI1 na panelu z lewej strony. Normalnie skonfigurowalibyśmy go w trybie Full-Duplex, jednak jak już wcześniej zauważyliśmy, komunikacja z wyświetlaczem jest tylko jednostronna. Będziemy korzystać z jednej linii transmisyjnej, a konkretnie MOSI. Wystarczy w takim razie, jeśli skonfigurujemy SPI w trybie "Transmit Only Master".

Konfiguracja SPI w trybie Transmit Master Only

Konfiguracja SPI w trybie Transmit Master Only.

Krok 3. Konfigurujemy 3 dodatkowe wyprowadzenia na linie CS, DC oraz RESET w trybie GPIO_Output. Aby ułatwić sobie później podłączanie wyświetlacza, warto również dodać etykiety do linii zegara oraz danych, tak jak na poniższym obrazku.

Konfiguracja mikrokontrolera do współpracy ze sterownikiem SSD1331

Konfiguracja mikrokontrolera do współpracy ze sterownikiem SSD1331.

 Krok 4. Przechodzimy do panelu konfiguracyjnego SPI.

Panel konfiguracyjny SPI

Panel konfiguracyjny SPI.

  • Frame Format - typ ramki danych. Praktycznie zawsze jest to format Motoroli.
  • Data Size - szerokość ramki danych. SPI pozwala na przesyłanie ramek o szerokości 8 lub 16 bitów. Pozostawiamy domyślną wartość 8 Bits.
  • First Bit - stanowi o stronie, od której zaczyna się transmisja bajtu. MSB (Most Significant Bit) - od najważniejszego bitu, a więc od bitu [7]. LSB (Least Significant Bit), od bitu [0]. Jak wiemy z dokumentacji, do sterownika wyświetlacza dane należy wysyłać w trybie MSB.
  • Prescaler - dzielnik zegara taktującego SPI.
  • Baud Rate - prędkość transmisji w bitach na sekundę.
  • Clock Polarity (CPOL) - opisane na początku artykułu.
  • Clock Phase (CPHA) - opisane na początku artykułu.

Krok 5. Generujemy projekt pod nazwą 07_SPI_OLED.

Uruchomienie wyświetlacza OLED

Teraz musimy skomunikować się z wyświetlaczem, aby wyświetlić pożądane grafiki.

Bibliotekę do obsługi wyświetlacza można znaleźć na stronie producenta. Nie jest ona jednak napisana pod biblioteki HAL i przystosowanie jej do naszych zastosowań wymaga wyodrębnienia kluczowych plików oraz dokonania drobnych zmian w kodzie.

Dołączenie biblioteki

W bibliotece znajdują się 2 foldery - inc oraz src. Należy przekopiować ich zawartości do odpowiadających katalogów w głównym folderze projektu. Zawartość inc przekopiujemy więc do folderu .../07_SPI_OLED/Inc, a zawartość src do folderu .../07_SPI_OLED/Src. Następnie musimy dołączyć pliki nagłówkowe do projektu. Można to zrobić na dwa sposoby.

Dodawanie biblioteki - sposób 1

W drzewku projektu klikamy prawym przyciskiem myszy na folder User i wybieramy Import.

Importowanie plików do projektu

Importowanie plików do projektu.

Następnie zaznaczamy General > File System i klikamy Next.

Dodawanie plików do projektu

Dodawanie plików do projektu.

Naszym oczom ukaże się panel importowania plików. W celu sprecyzowania położenia plików, które mają być dodane, wybieramy Browse i odszukujemy położenie folderu .../07_SPI_OLED/Src. W moim przypadku jest to:

D:\Biblioteki\Documents\Studia\Forbot\kurs-stm32f4\Programy\07_SPI_OLED\Src

Dodawanie plików do projektu

Dodawanie plików do projektu.

Po sprecyzowaniu odpowiedniej ścieżki do plików wybieramy te, które mają być dodane (Fonts.c i SSD1331.c) i klikamy Finish.

Dodawanie plików do projektu

Dodawanie plików do projektu.

Jeżeli wszystko wykonaliśmy poprawnie, w drzewku projektu powinny się pokazać dwa dodane przed chwilą pliki:

Drzewko projektu z dodanymi plikami do obsługi wyświetlacza

Drzewko projektu z dodanymi plikami do obsługi wyświetlacza.

Dodawanie biblioteki - sposób 2

W eksploratorze plików należy zaznaczyć pliki do zaimportowania, a następnie przeciągnąć je w odpowiednie miejsce w drzewku projektu.

Importowanie plików do projektu

Importowanie plików do projektu.

Używanie biblioteki do wyświetlacza OLED

Biblioteka jest już w pełni gotowa do użycia. Aby z niej skorzystać, należy dołączyć główny plik nagłówkowy, a więc SSD1331.h do pliku main.c

Rozmiary czcionek

Pierwszą istotną rzeczą jaką tam znajdziemy są rozmiary czcionek zdefiniowane dla tej biblioteki. Rozmiary podane są w pikselach.

Kolory

Kolejną istotną rzeczą są wstępnie zdefiniowane kolory. Na listingu poniżej widzimy sposób definiowania każdego z nich. Na tej podstawie jesteśmy w stanie wygenerować nowe - wystarczy tylko znać odpowiedni "przepis" na dany kolor, będący mieszanką trzech składowoych RGB.

Funkcje rysujące

Ostatnią sekcją w omawianym pliku są prototypy funkcji, z których będziemy korzystać w celu obsługi wyświetlacza. Chcąc narysować prostokąt, linię czy okrąg, wystarczy udać się w to miejsce i zbadać składnię wywołania danej funkcji. 

Podłączenie wyświetlacza

Ostatnią rzeczą, którą musimy zrobić przed rozpoczęciem pisania kodu jest fizyczne podłączenie wyświetlacza do płytki Discovery. Na początku artykułu przygotowaliśmy sobie ładne oznaczenia w STMStudio, więc nie powinno być problemu z odnalezieniem gdzie co należy podłączyć:

  • DiscoveryF4 - Wyświetlacz OLED
  • 3V lub 5V - VCC
  • GNG - GND
  • PA5 - CLK
  • PA7 - DIN
  • PC5 - CS
  • PB1 - DC
  • PE7 - RES

Pierwszy program - Hello World

Czas napisać nasz pierwszy program wykorzystujący wyświetlacz OLED!

Krok 1. Prawie każde urządzenie przed rozpoczęciem pracy należy zainicjalizować. Odpowiednią funkcję znajdziemy w pliku SSD1331.h

Krok 2. Następnie warto wyczyścić cały ekran, żeby mieć puste pole do rysowania.

Krok 3. Kiedy wyświetlacz jest już przygotowany, możemy spróbować wyświetlić dane:

Funkcja display_string w pierwszych dwóch argumentach przyjmuje pozycję piksela (x,y), od którego ma zacząć rysować. Kolejnym parametrem wywołania jest napis do wyświetlenia - w naszym wypadku "Hello World". Ostatnie dwa parametry, to rozmiar oraz kolor napisu.

Krok 4.  Możemy zbudować i wgrać program na mikrokontroler. Finalną wersję podstawowego Hello World przedstawia poniższy listing.

Jeżeli poprawnie skonfigurowaliśmy SPI, zaimportowaliśmy bibliotekę, dobrze podłączyliśmy kabelki i napisaliśmy kod bez błędów, po wgraniu i uruchomieniu programu na ekranie powinniśmy zobaczyć nasze pierwsze na tym wyświetlaczu Hello World.

Działający wyświetlacz OLED.

Działający wyświetlacz OLED.

Gdzie tu jest SPI?

Jak na razie w kodzie zajmowaliśmy się głównie wyświetlaczem, którego podobno obsługujemy przez SPI. Nie wywołaliśmy żadnej funkcji odpowiadającej za komunikację poprzez SPI, a jednak wyświetlacz działa. To dlatego, że w dołączonej bibliotece dodane są już odpowiednie wywołania. Można je znaleźć w pliku LIB_Config.h.

Ich analizę pozostawiam dla chętnych. Na tym etapie programowania nie trzeba zagłębiać się dalej. To, co najważniejsze, czyli wykorzystanie wyświetlacza LCD w praktyce można otrzymać bazując na opisanych do tej pory operacjach,

Podsumowanie

W tym odcinku nauczyliśmy się obsługiwać wyświetlacz OLED. Poznaliśmy również podstawy komunikacji za pomocą interfejsu SPI.

W następnym artykule zajmiemy się kolejnym sposobem przesyłania danych. Tym razem będzie to USB, czyli jeden z najczęściej używanych standardów komunikacji. To tyle na dziś. Jeżeli macie problemy lub uwagi, to piszcie w komentarzach!

Nawigacja kursu

Autor kursu: Bartek (Popeye) Kurosz
Redakcja: Damian (Treker) Szymański

Załączniki

Kurs STM32 F4 OLED (zip, 4 MB)

Paczka plików z projektem tworzonym podczas artykułu oraz biblioteki do wyświetlacza.

F4, kurs, kursSTM32F4, OLED, programowanie, SPI, stm32, wyświetlacz

Trwa ładowanie komentarzy...