Pamiętam jak wiele lat temu zmorą dla mnie było multipleksowanie matrycy diod. Jeny… jak ja to źle przeżywałem. Z dzisiejszej perspektywy zupełnie nie rozumiem siebie z tamtych lat. Przecież to wcale nie jest aż takie trudne jak mi się wtedy wydawało. Dzisiaj jest jeszcze prościej! Mamy specjalizowane układy multipleksujące stworzone z myślą o wyświetlaczach LED i to jest piękne. Lecimy z koksem!

Kompletny cykl wpisów:

Nigdy więcej multipleksowania na GPIO! MAX7219 w akcji cz.1

Nigdy więcej multipleksowania na GPIO! MAX7219 w akcji cz.2

Nigdy więcej multipleksowania na GPIO! MAX7219 w akcji cz.3

MAX7219

Jednym z takich układów jest MAX7129 ( MAX7219-MAX7221 Datasheet.pdf) który dzisiaj omawiam. Jest to układ, który potrafi kontrolować wyświetlacze diodowe o wspólnej katodzie. Potrafi obsłużyć 8 wyświetlaczy 7-segmentowych + kropkę, czyli łącznie 64 diod. Niekoniecznie muszą to być wyświetlacze segmentowe. Mogą to też być matryce 8×8, o czym przekonasz się później. Co ciekawe, posiada wbudowany dekoder BCD który może ułatwić pracę z układem. Do pamiętania tego co ma wyświetlić używa wbudowanej pamięci RAM.

Z układem możemy porozmawiać przez interfejs SPI. Układ wspiera połączenie kaskadowe, co pozwala na łączenie kostek w długie łańcuchy. Jest to ficzer który pozwala uzyskać spore rozmiary matryc LED.

Dalekowschodni przyjaciele produkują moduły z MAX7219 w wersji z wyświetlaczem 7-segmentowym oraz z matrycami 8×8.

Schemat i Cube

Moduły dostarczane przez chińczyków są bardzo proste w podłączeniu. Płytka posiada piny z dwóch stron. Jedna strona to wejście, druga to wyjście dla połączenia kaskadowego. Jako, że nie możemy nic czytać z ukłądu, połączenie i konfiguracja SPI będzie w trybie Master Transmit Only. Dzisiaj na mój blat trafił STM32L476RG zamontowany w płytkę Nucleo.

Zegar główny MCU jak zwykle ustawiam na tyle, ile fabryka pozwala – 80 MHz. Do testowania pojedynczych układów jest to całkiem wygodne. Preskaler SPI początkowo będzie miał wartość 64, co wynikowo daje 1,25 MHz na zegarze interfejsu szeregowego. Pin CS może być skonfigurowany jako Software lub Hardware. Obsłużymy obydwa przypadki.

Kodzimy, kodzimy, kodzimy!

MAX7219 udostępnia kilka rejestrów konfiguracyjnych.

Co możemy dzięki nim zrobić? Oprócz oczywistych rejestrów Digit X, pozostałe pozwalają na:

  • Przejście w tryb Shutdown – wyłączenie oscylatora, wygaszenie diod
  • Zmianę jasności diod przez ustawienie wypełnienia podawanego sygnału
  • Zakres skanowania cyfr – ograniczenie wyświetlania do i-tej cyfry
  • Włączenie testu – wszystkie diody świecą z maksymalną jasnością

Wszystkie te manewry są obsługiwane w mojej bibliotece przez wygodne enumy.

1
2
3
</p>
<p>MAX7219_STATUS MAX7219_SetDecodeMode(uint8_t DeviceNumber, MAX7219_DecodeMode DecodeMode);<br>MAX7219_STATUS MAX7219_SetIntensity(uint8_t DeviceNumber, uint8_t Intensity);<br>MAX7219_STATUS MAX7219_SetScanLimit(uint8_t DeviceNumber, MAX7219_ScanLimit Limit);<br>MAX7219_STATUS MAX7219_Shutdown(uint8_t DeviceNumber, MAX7219_ShutdownMode Shutdown);<br>MAX7219_STATUS MAX7219_SetDisplayTest(uint8_t DeviceNumber, MAX7219_TestMode Enable);</p>
<p>

Podstawowa konfiguracja wykonywana jest podczas inicjalizacji do której już klasycznie u mnie należy przekazać wskaźnik do SPI.

1
2
3
</p>
<p>MAX7219_STATUS MAX7219_Init(SPI_HandleTypeDef *hspi);</p>
<p>

No dobra, ale jest jescze taki ‘rejestr’ jak No-Op. Jak sama nazwa wskazuje, przesłanie tego do układu powoduje brak operacji. Na co to? Służy to do trybu kaskadowego, gdzie dane podawane na DIN przekazywane są później na DOUT.

MAX7219 działa jak rejestr przesuwny. Dane wpisane do niego są zatrzaskiwane w momencie powrotu sygnału CS do stanu wysokiego. Wtedy ostatnie 16 bitów, które trafiły do rejestru są tymi, które determinują wykonywaną operację. Opiszę to dokładniej, gdy dotrzemy do kaskady.

Ustawienie cyfry dla pojedynczego układu jest łatwe. Wystarczy wysłać do układu pod odpowiedni rejestr wybraną wartośc. Należy mieć na uwadzę jakie ustawienie kodowania jest wybrane. Jeśli MAX7219 ma sam dekodować BCD na odpowiednie segmenty, wystarczy wysłać liczbę z zakresu 0÷9.

Ja jednak namawiam do nie używania dekodera BCD. Dlaczego? Bo można zdefiniować więcej znaków na wyświetlaczu. Przygotowałem listę liter, które przyszły mi do głowy i da się je zrealizować na 7-segmentach. Nic nie stoi na przeszkodzie, aby dodać własne.

Do ustawiania pojedynczych cyfer służy funkcja

1
2
3
</p>
<p>MAX7219_STATUS MAX7219_SetDigit(uint8_t DeviceNumber, uint8_t Digit, uint8_t Value, uint8_t Dot);</p>
<p>

Zwróć uwagę, że numerowanie Digit zaczyna się jakby od końca. Cyfra zerowa jest z prawej strony, a siódma z lewej. Jest do dla nas mało naturalne, ale wyświetlacz jest tak fizycznie podłączony do pinów scalaka.

Printowanie

Jednak czy wysyłanie pojedynczych znaków jest wygodne? No nie. O wiele lepiej użyc czegoś w rodzaju printf’a. W tym celu powołałem kilka pomocnych funkcji.

1
2
3
</p>
<p>MAX7219_STATUS MAX7219_PutString(int Start, char *String);<br>MAX7219_STATUS MAX7219_PutStringRightAdjust(char *String);<br>MAX7219_STATUS MAX7219_PutStringLeftAdjust(char *String);<br>MAX7219_STATUS MAX7219_PutStringCenterAdjust(char *String);</p>
<p>

Pierwsza z góry służy do wypisania ciągu znaków zaczynając od pozycji Start. W tym miejscu naprawiłem nieludzkie ułożenie cyfr w całym wyświetlaczu i zerowa pozycja jest z lewej strony. Funkcja łyka wszystkie znaki ASCII które zdefiniowałem pod ich prawdziwymi kodami. Łatwo jest więc wpisać po prostu co się chce. Znaki których nie ma w zdefiniowanej tablicy pomija.

No dobra, ale co z kropką?! Przecież na wyświetlaczach 7-segmentowych jest ona integralną częścią cyfry! Zgadza się i przygotowałem się na taki zarzut. Otóż printowanie obsługuje kropki. Gdy kropka znajdzie się jako znak w stringu, jest ona doklejana do cyfry. Sprawdź sam jak to działa.

Pozostałe 3 funkcje to taki bajer. Mają one za zadanie wyrównać wprowadzany napis odpowiednio do prawej, do lewej oraz wycentrować. Taki bajer jak w edytorach teskstów.

Wszystkie te funkcje obsługują połączenie kaskadowe, które omówię w kolejnej części wpisu.

Działanie

Jeszcze szybki rzut na to jak to działa. Sprawdźmy najpierw ile czasu zajmuje wyświetlenie wszystkich ośmiu cyfr.

SCK 1,25 MHz

SCK 2,5 MHz

SCK 5 MHz

SCK 10 MHz

Wyniki są następujące:

  • 1,25 MHz – 176 µs
  • 2,5 MHz – 118 µs
  • 5 MHz – 88 µs
  • 10 MHz – 73 µs

Układ niestety nie współpracuje jeśli chodzi o overclocking. Powyżej 10 MHz zaczyna pokazywać śmieci, więc wartość w dokumentacji jest już na prawdę maksymalną.

Podsumowanie

Jak widzisz można uznać, że multipleksowanie na GPIO odchodzi do lamusa. Komu teraz będzie chciało się robić to ręcznie? Byc może w aplikacjach, gdzie cena jednostkowa urządzenia musi być wyśrubowana do granic możliwości. Jednak wtedy też należy przemyśleć czy aby na pewno zaoszczędzenie na scalaku bedzie korzystniejsze niż oszczędność czasu potrzebnego na implementacje multipleksowania.

W kolejnej części omówię budowanie kaskady z układów MAX7219.

Jeżeli spodobał Ci się opisywany dzisiaj moduł z wyświetlaczami 7-segmentowymi, możesz nabyć go u mnie w sklepie.

Pełny projekt wraz z biblioteką znajdziesz jak zwykle na moim GitHubie: link

Jeśli zauważyłeś jakiś błąd, nie zgadzasz się z czymś, chciałbyś coś dodać istotnego lub po prostu uważasz, że chciałbyś podystkutować w tym temacie, napisz komentarz. Pamiętaj, że dyskusja ma być kulturalna i zgodna z zasadami języka polskiego.


Raz na jakiś czas wyślę Ci też e-mail z ciekawymi rzeczami które znalazłem


Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Serwis wykorzystuje pliki cookies. Korzystając ze strony wyrażasz zgodę na wykorzystywanie plików cookies. Więcej informacji znajdziesz na stronie Polityka Prywatności

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close