Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450

p.kaczmarek2 11 Nov 2021 02:44 1557 3
IGE-XAO
  • Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Witajcie moi drodzy.
    Zapraszam na kolejną część mojego tutoriala PIC18F2550 i kompilatora SDCC.
    W tej części poznamy sterownik wyświetlacza LED MM5450, połączymy go z PIC18F2550 i napiszemy od 0 implementację ich komunikacji. Docelowo użyjemy MM5450 do wysterowania wyświetlacza LED 5 na 5.
    Cały proces powstawania układu na płytce stykowej oraz programu na PICa przedstawię krok po kroku, w każdym kroku będę wprowadzać dodawać dodatkową funkcjonalność i opisywać co zmieniłem.
    Zacznę od prostych rzeczy, a potem będą bardziej zaawansowane.

    Spis części (osobnych tematów) tutoriala
    Tutorial podzielony jest na osobne tematy i tutaj znajdują się do nich linki.
    Część 1 - Konfiguracja środowiska pracy
    https://www.elektroda.pl/rtvforum/viewtopic.php?p=18304424#18304424
    Część 2 - Hello world, piny IO, cyfrowe wejścia i wyjścia
    https://www.elektroda.pl/rtvforum/topic3647884.html
    Część 3 - Ustawienia oscylatora. Oscylator wewnętrzny, zewnętrzny, rezonator kwarcowy, PLL
    https://www.elektroda.pl/rtvforum/topic3657704.html
    Część 4 - Timery, przerwania
    https://www.elektroda.pl/rtvforum/viewtopic.php?p=18580858#18580858
    Część 5 - Obsługa wyświetlacza siedmiosegmentowego
    https://www.elektroda.pl/rtvforum/viewtopic.php?p=18580877#18580877
    Spis treści będzie uzupełniany wraz z pisaniem przeze mnie kolejnych części.

    UWAGA - język C
    W temacie zakładam, że użytkownik ma jakieś podstawowe pojęcie o programowaniu w języku C lub podobnym. Niezbyt mam tu możliwość tłumaczy czym jest zmienna, funkcja, czy tam tablica. Tu będzie też nieco trudniej niż wcześniej, użyję preprocesora, zaawansowanych operacji na bitach, bitowych przesunięć...
    Zakładam też, że czytelnik wie czym jest bajt, bit, że bajt ma 8 bitów, itp.

    Krótko o MM5450
    MM5450 to sterownik wyświetlacza LED produkcji Microchip (a właściwie przejętego przez niego Micrel).
    MM5450 pozwala sterować aż do 35 (w wersji z pinem Enable do 34) segmentów LED poprzez tylko dwa piny - zegar (clock) i dane (data).
    MM5450 pozwala wygodnie kontrolować jasność całego wyświetlacza poprzez potencjometr, sam zarządza prądem segmentów i eliminuje konieczność użycia rezystorów.
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    MM5450 pracuje na napięciach aż do 12V.
    MM5450 nie wymaga ciągłego odświeżania pamięci czy tam multipleksowania, do układu wysyłamy dane raz z mikrokontrolera i potem on pamięta które segmenty świecą. Pozwala to odciążyć mikrokontroler, bo normalnie pewnie byśmy sterowali wyświetlaczem w przerwaniu...
    Przykładowa aplikacja:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450

    1. Punkt startowy
    Zaczynamy od minimalnego układu wymaganego dla PIC18F2550 (tutaj PIC18LF2550, ale bez różnicy, wersja z L może pracować również na niższych napięciach - Low voltages), dodatkowo z diodą LED:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450 Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Rozpoczęcie prac od sprawnego blink (migania diodą) jest ważne gdyż daje nam pewność że mikrokontroler działa i jest poprawnie zasilany. Często byłem świadkiem sytuacji, gdzie ktoś próbował uruchamiać jakiś układ lub kod i dziwił się, czemu on nie chce mu działać, a w rzeczywistości nawet samo programowanie się nie powodziło...

    2. Podstawowe połączenie
    MM5450 umieścimy na drugiej płytce stykowej. Ten typ płytek można razem łączyć na zaczepy, jest to bardzo wygodne:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Zaczniemy od zasilania i komunikacji:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Układ zasilamy z 5V tak jak PICa.
    DATA IN podłączamy do dowolnego pinu, wybrałem jeden z portu C. Zegar (Clock) podobnie.
    Enable tutaj mamy z kreseczką, czyli z negacją. Czyli to jest pin "not enabled". Jeśli damy na niego stan wysoki, to "not enabled" jest prawdą (1, true), i układ jest wyłączony. Chcemy go włączyć, więc zwieramy ten pin do masy.
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Jeszcze układ do regulacji jasności:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Gotowe:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Kondensator 100nF jest tu w celu usunięcia zakłóceń przy regulacji jasności.


    3. Pierwszy test
    Na próbę podłączyłem jedną diodę LED. Sprawdziłem regulację jasności - okazało się, że już działa:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450 Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Przez przypadek też udało mi się zwizualizować czemu zostawianie pinów "w powietrzu" jest złe. Każdy pin jest anteną! Tutaj zbierają zakłócenia z palca i dotyk zmienia stan LEDów:

    Oczywiście nie radzę Wam tak eksperymentować, bo przy odrobinie niefartu dotykanie układów scalonych skończy się ich uszkodzeniem poprzez wyładowania ESD.

    4. Sterowanie z poziomu mikrokontrolera - teoria
    Teraz musimy przeanalizować co trzeba zrobić by skomunikować PIC z MM5450.
    Informacje są w nocie katalogowej:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Najważniejsze fragmenty:
    Quote:

    Data is transferred serially via two signals: clock and
    serial data. Data transfer without the added
    inconvenience of an external load signal is
    accomplished by using a format of a leading “1”
    followed by the allowed 35 data bits. These 35 data bits
    are latched after the 36th has been transferred

    Dane wysyłane są poprzez dwa sygnały - clock (zegar) i dane (data). Najpierw wysyłamy zawsze bit 1 (true), potem 35 bitów danych (stany LEDów). Informacje są zapisane i wyświetlone po tym jak 36-ty bit zostanie przesłany.
    Quote:

    There must be a complete set of 36 clocks or the shift registers will not clear.

    Zegar musi przejść pełne 36 cykli.
    Mamy też wizualizację sygnałów:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Widać tu kilka rzeczy:
    - najpierw wchodzi pierwszy bit gdy zegar jest na stanie niskim (bit START, zawsze 1)
    - potem robi cykl zegar (pierwszy z 36)
    - potem bit pierwszej diody LED
    - potem znów zegar
    - i tak dalej...
    Tutaj też widzimy, kiedy zmienia się zegar a kiedy bit danych:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Czyli w pseudokodzie to będzie:
    1. ustaw bit danych na 1 (bit START)
    2. zrób puls zegara
    3. Wykonaj 35 razy (pętla for)
    3.1 ustaw bit danych na wartość danej diody LED
    3.2 zrób puls zegara
    W sumie 36 cykli zegara.
    Zasadniczo tyle. Jeszcze trzeba pamiętać, że w trakcie tej operacji pin Enable nie może blokować MM5450.

    5. Sterowanie z poziomu mikrokontrolera - praktyka
    Do ułatwienia implementacji użyję preprocesora C. Tu należy zachować ostrożność i wiedzieć że preprocesor zamieniany jest na kod w czasie kompilacji, ale sam język C jest nieco poza zakresem tego tutorialu.
    Kolejno, potrzebujemy określić indeksy i porty pinów sygnałowych:
    Code: c
    Log in, to see the code

    (te nazwy sobie całkiem dowolnie dobrałem, po prostu używam angielskiego nazewnictwa w kodzie)
    Potem możemy zrobić dyrektywy ustawiające i czyszczące dany bit portu:
    Code: c
    Log in, to see the code

    Potem zrobić ich skróty dla naszych sygnałów - zegar i dane:
    Code: c
    Log in, to see the code

    Na koniec skrócik dla pulsu zegara, ale uwaga - jeśli nasz mikrokontroler jest zbyt szybki to układ docelowy może nie "załapać" zegara. Tu tego problemu nie ma, MM5450 pracuje do 0.5MHz, ale warto pamiętać...
    Code: c
    Log in, to see the code

    Przypominam kod blinka. Musimy go zmodyfikować... ale mamy już pseudokod z poprzedniego akapitu.
    Tylko jeszcze pojawia się pytanie skąd wziąć stany diod LED do wysłania?
    Proponuje wysłać ciąg: 010101010101 lub podobny.
    Można go wytworzyć poprzez operację modulo 2 - sprawdzenie parzystości liczby - dla indeksu wyświetlanego bitu.
    Code: c
    Log in, to see the code

    Dopisujemy. Oczywiście też pamiętamy by ustawić port w trybie wyjścia (TRISC=0):
    Code: c
    Log in, to see the code

    Rezultat:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450

    6. Sterowanie z poziomu mikrokontrolera - rozwinięcie
    Sama komunikacja jest gotowa, ale w takiej postaci nie możemy nic wygodnie wysłać.
    Proponuję wydzielić komunikację do osobnej funkcji.
    Trzeba też skądś wczytywać dane.
    Kuszące pewnie byłoby zrobienie czegoś w stylu tablica integerów o rozmiarze 35, jakieś int arr[35], ale to byłoby bez sensu. My potrzebujemy zasadniczo 35 bitów, a nie bajtów czy tam zależy ile ma int na tej platformie.
    35 bitów daje nam niecałe 5 bajtów (5*8 = 40). Tak też zrobimy.
    W tym kompilatorze nie ma zdefiniowanego typu byte, zdefiniujmy go samemu dla wygody:
    Code: c
    Log in, to see the code

    Pojedynczy bajt bez znaku, 8 bitów. Typ char na tej platformie ma 8 bitów. Ale uwaga - warto przed użyciem typu sprawdzać czy na pewno ma taki rozmiar jakiego oczekujemy. Np. typ int może mieć w zależności od platformy 2 bajty albo 4, itp. Warto do sprawdzenia użyć sizeof.
    Teraz nasza tablica...
    Code: c
    Log in, to see the code

    W pętli zwiększajmy tylko pierwszy bajt, z każdą iteracją o jeden. Tak będzie wygodniej testować:
    Code: c
    Log in, to see the code

    Zostało zrobić funkcję display...
    Funkcja ta powinna brać 5 bajtów (a dokładniej wskaźnik na pierwszy element tablicy pięciu bajtów, a dokładniej o nieznanym rozmiarze, ale to nie kurs C) i po kolei "wyłuskiwać" kolejny bit z każdego bajtu, badać jego wartość i wysyłać do MM5450.
    Do sprawdzenia bitu użyjemy operacji AND - &.
    Aby móc zrobić AND i sprawdzić zapalenie bitu, musimy zamienić indeks bitu na maskę, tzn. zamienić np. numer 5 (dziesiętnie) na 10000 (binarnie) (zapalony piąty bit). Robimy to przesunięciem bitowym o i-pozycji. Przesuwamy jeden, w ten sposób: 1 << i
    Jeszcze jest problem z tym, że 1 << i w przypadku bajtów ma sens tylko dla wartości od 0 do 8, a my mamy aż 35 bitów do obsłużenia...
    W tym celu zamieniamy bezwzględy indeks bitu (od 0 do 35) na indeks względny bitu (od 0 do 8) oraz indeks bajtu z którego on pochodzi (od 0 do 4). Do tego starczy nam dzielenie (16/8 = 2, mówi nam że 16-ty bit to bajt numer 2) i modulo: (16%8 = 0, mówimy nam ze 16-bit to lokalnie bit zerowy danego bajtu).
    Poniżej gotowiec, mam nadzieje, że troszkę się wyjaśni...
    Code: c
    Log in, to see the code

    Tak napisany kod działa i generuje nam "zegar binarny", czyli kolejno widzimy jak zapalają się bity, tzn:
    0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 1
    0 0 0 0 0 0 1 0
    0 0 0 0 0 0 1 1
    0 0 0 0 0 1 0 0
    0 0 0 0 0 1 0 1
    Itd, itp.
    Rezultat na filmiku:


    7. Nieco lepsza macierz
    Pora zlutować sobie jakiś lepszy wyświetlacz. Oczywiście są takie też do kupienia, ale myślę, że warto pokazać iż taki wyświetlacz to nie jest jakaś magiczna czarna skrzynka, tylko po prostu odpowiednio połączone diody LED.
    Chcemy by nasze diody LED miały wspólną nóżkę do zasilania, czyli anodę (ta dłuższa).
    Robimy zatem własny common anode led display.
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Niestety standardowe diody są nieco za grube by je wygodnie ułożyć obok siebie, musiałem im spiłować boczki:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Chcę wyświetlacz kwadratowy, 6 na 6 to za dużo, zdecydowałem się na 5 na 5.
    Początek prac:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Przy lutowaniu do takiej płytki trzeba uważać by nie przegrzać padów. Na początku miałem za dużą temperaturę na grocie lutownicy i jeden mi odpadł:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Postęp prac:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450 Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450 Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Gotowe. Wyświetlacz podłączyłem do pinów MM5450 zachowując kolejność, a dokładniej numerując LEDy wedle wierszy, tj:
    1 2 3 4 5
    6 7 8 9 10
    11 12 itd. itp.
    To bardzo ważne, jak sobie ponumerujemy chaotycznie to potem się w tym nie odnajdziemy!
    A musimy też móc wygodnie liczyć bezwzględny indeks komórki LED z jej numeru wiersza i kolumny....

    8. Trik z unią
    W zasadzie to nie jest to konieczne, ale lubię czasem wprowadzić jakąś ciekawostkę.
    Na ten moment rozwiązanie z tablicą wymusza na nas wpisanie osobno 5 bajtów.
    A co jeśli byśmy chcieli wpisać typ 4 bajtowy, np. long int?
    Można by wykonywać rzutowanie, np:
    Code: c
    Log in, to see the code

    taka operacja wpisze na wartość komórek pamięci 'ar' wartość podaną jako long int, ale jest też inna, bardziej nietypowa metoda.
    Można stworzyć unię, która będzie zawierać dwa pola o różnych typach, znajdujące się pod tym samym adresem w pamięci.
    Code: c
    Log in, to see the code

    Teraz możemy wpisywać do tej uni dane też w ten sposób:
    Code: c
    Log in, to see the code

    Albo, wpisywanie systemem binarnym:
    Code: c
    Log in, to see the code

    Możemy też w pętli inkrementować ten long int i zrobić w ten sposób odliczanie lepsze niż wcześniej, bo na 4 bajtach a nie na jednym:
    Code: c
    Log in, to see the code

    Pora zobaczyć powyższy kod w akcji (z nieco zmniejszonym czasem oczekiwania w pętli):


    9. Sposób wpisywania znaków graficznych do kodu
    Nasz wyświetlacz może wyświetlić dowolny znak lub symbol.
    Tylko jak te symbole wpisywać do kodu?
    Możemy przygotować sobie taki szablon:
    XKolumna 1Kolumna 2Kolumna 3Kolumna 4 Kolumna 5
    Wiersz 1 b0 b1 b2 b3 b4
    Wiersz 2 b5 b6 b7 b8 b9
    Wiersz 3 b10 b11 b12 b13 b14
    Wiersz 4 b15 b16 b17 b18 b19
    Wiersz 5 b20 b21 b22 b23 b24

    UWAGA: jeśli inaczej podłączyliście wyświetlacz to oczywiście ten szablon Wam nie zadziała.
    Jeśli będziemy chcieli narysować jakiś znak, to "wypełniamy" komórki które mają być wyświetlone jedynkami, a te zgaszone zerami. Przykładowo:
    XKolumna 1Kolumna 2Kolumna 3Kolumna 4 Kolumna 5
    Wiersz 1 1 0 0 0 1
    Wiersz 2 0 1 0 1 0
    Wiersz 3 0 0 1 0 0
    Wiersz 4 0 1 0 1 0
    Wiersz 5 1 0 0 0 1

    Spisujemy wierszami zera (z przeglądarki można zaznaczyć i się ustawiaja liniami po kolei):
    0b1000101010001000101010001
    Dopisane 0b jest dla kompilatora, by wiedział, że to notacja binarna.
    To tak jak liczby w systemie szesnastkowym wpisujemy jako (np) 0xFAFA, tak binarne wpisujemy jako 0b1010.
    Wpiszmy ją do kodu:
    Code: c
    Log in, to see the code

    Rezultat:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450

    10. Sposób przechowywania znaków w kodzie
    Wiemy już jak stworzyć własną czcionkę, ale nie wiemy jak ją przechować.
    Kusiłoby tu nas zrobić tablicę czterobajtowych liczb (long int) i w zasadzie by to zadziałało, choć byłoby ryzykowne bo kod oczekuje 35 bitów i wychodziłby poza jej zakres. Można by na jej koniec dać dodatkowy element by upewnić się że nie odczytujemy wartości całkiem losowych z pamięci, ale i tak nie byłoby przyszłościowe rozwiązanie, bo co jeśli będziemy mieć więcej niż te 25 LEDów? Nie warto ograniczać się do 32 sztuk, jak scalak wspiera 35.
    W związku z tym zrobimy tablicę, ale tablicę znaków.
    Najpierw zdefiniujmy sobie typ znaku:
    Code: c
    Log in, to see the code

    A potem ich tablicę...
    Code: c
    Log in, to see the code

    UWAGA: proszę zwrócić uwagę w jaki sposób przepisałem tu wartość 0b1000101010001000101010001! Gdzie trafia jaki bit - najmłodszy bit jest po prawej, a nie po lewej stronie.
    Analogicznie możemy zrobić więcej znaków... zasadniczo możemy narysować co chcemy na naszej matrycy 5x5.
    Teraz dla wygody możemy wpisać do tablicy znaki w ten sposób, by ich indeksy w tablicy im odpowiadały - czyli kolejno, grafiki dla cyfry 0, 1, 2, 3, itp.
    Oczywiście można też zrobić litery, A, B:
    Code: c
    Log in, to see the code

    Nie zrobiłem wszystkich liter, ale rozmieszczenie pikseli zależy w pełni od nas.
    Poniżej zdjęcia rezultatu:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450 Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450 Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450 Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450 Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450

    11. Inna metoda tworzenia grafik. Ustawianie pikseli na pozycji X Y
    Wyświetlaną grafikę można też generować proceduralnie. Przedstawię tu jak możemy to zaimplementować.
    Na początek stworzymy osobny 'znak', który będzie naszym wyświetlanym buforem, powiedzmy, ekranem:
    Code: c
    Log in, to see the code

    Teraz potrzebne są funkcje, które będą na nim operować. Najwygodniej jest zrobić edycję per-pixel. Potrzebna jest funkcja która stawia piksel na miejscu o danej pozycji X Y.
    Załóżmy, że X to numer wiersza a Y to numer kolumny.
    W takim razie indeks bitu liczymy jako X * W + Y, gdzie W to rozmiar wiersza.
    Code: c
    Log in, to see the code

    Zostaje jeszcze ustawić bit o indeksie 'idx' na wartość z 'px' (zero lub jeden).
    Tu znów jest problem, że musimy umieć indeksować dowolną ilość bajtów, nie tylko jeden.
    Zgodnie z tym co pisałem wcześniej:
    Code: c
    Log in, to see the code

    Usunięcie bitu jest równoznaczne z wykonaniem AND z jego negacją. Zapalenie to wykonanie OR. Operator << to przesunięcie bitowe i on zamienia numer bitu na jego maskę.
    Sprawdźmy działanie:
    Code: c
    Log in, to see the code

    Rezultat:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450

    12. Ruchomy pixel X Y
    Możemy teraz troszkę ożywić naszą grafikę, nadać jej animację.
    Chociaż przyda się jeszcze funkcja czyszcząca ekran:
    Code: c
    Log in, to see the code

    W #define trzymam ilość bajtów używaną do reprezentacji znaku/grafiki by można było ją wygodnie zmienić w jednym miejscu i tym samym zaktualizować resztę kodu.
    UWAGA: CHAR_BYTES to nie jest to samo u mnie co SCREEN_SIZE. Ilość bajtów w jednym "znaku" wyświetlanym na ekranie (znaku graficznym) to CHAR_BYTES, inaczej ilość znaków w naszej "bitmapie". Z kolei "SCREEN_SIZE" to wymiar boku ekranu, szerokość i wysokość bo ekran jest kwadratowy. Wartości tych zmiennych są takie same przez przypadek..
    Code: c
    Log in, to see the code

    Funkcja ustawiająca ekran na daną wartość musi pamiętać, że "1" nie jest równe 255 (inaczej 0xff, wszystkie bity zapalone), z tego też powodu dla pewności zamienia podaną wartość właśnie na 0 lub 0xff. Zapis z '?' w jednej linii to odpowiednik if.
    Teraz jeszcze ruchomy piksel. Pozycja i wektor przesunięcia (byśmy wiedzieli, w którą stronę się porusza):
    Code: c
    Log in, to see the code

    Kod wyświetlania (czyści ekran, nanosi piksel):
    Code: c
    Log in, to see the code

    'Fizyka' (odbijanie od ścianek):
    Code: c
    Log in, to see the code

    Cały kod:
    Code: c
    Log in, to see the code

    I końcowy efekt:

    Wyglądałoby to lepiej na większej planszy, algorytm nie patrzy na jej rozmiar, nawet przy wymiarach 100 na 100 by się odbijał "poprawnie" piksel, można tak zrobić np. grę Arkanoid.


    13. Negatyw
    Efekt bardzo prosty do zrobienia, a całkiem ładnie wygląda.
    Code: c
    Log in, to see the code

    Jedyne co trzeba tu pamiętać to to, że chcemy negację dla każdego bitu, a nie tylko per bajt, więc używamy ~ a nie !.
    Zrobimy negatyw naszej czcionki, tyle, że nie możemy robić tej operacji na samym buforze ze znakami graficznymi (bo je popsujemy), musimy je najpierw kopiować do bufora ekranu, którego używałem już wcześniej.
    Funkcja kopiująca grafikę:
    Code: c
    Log in, to see the code

    Przykład użycia:
    Code: c
    Log in, to see the code

    Rezultaty:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450 Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450 Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450


    Dodatek - większe rozmiary macierzy LED
    Ktoś mógłby pomyśleć, że jesteśmy ograniczeni tylko do tych 35 segmentów przy jednym MM5450. Nic bardziej mylnego.
    Sprytne użycie tego układu pozwala obsłużyć znacznie więcej LEDów. Przykładowo 8 cyfr po 7 segmentów, czyli 8*7 = 56 segmentów. Tylko wtedy już trzeba korzystać z multipleksingu:
    Tutorial PIC18F2550 + SDCC - Część 6 - Sterownik wyświetlacza LED MM5450
    Na schemacie powyżej piny 18 i 17 mają specjalną rolę - wybierają one który fragment wyświetlacza w danym momencie świeci. Pozostałe piny wtedy obsługują ten właśnie fragment. Potem szybko następuje zmiana i obsługujemy drugi zestaw cyfr. Jeśli będziemy robić to dostatecznie szybko, to ludzkie oko nie wychwyci nawet migania i użytkownik odniesie wrażenie, że wszystkie cyfry po prostu normalnie świecą.
    UWAGA: ale wtedy musimy już na bieżąco odświeżać stany wyjść MM5450, a w przypadku normalnego go użycia możemy raz ustawić segmenty a potem "zapomnieć" aż do następnego odświeżenia np. po paru minutach.
    UWAGA2: oczywiście można tez użyć dwóch MM5450, np. poprzez pin enable lub przez całkiem osobne data/clock.


    Podsumowanie
    Komunikacja z MM5450 wcale nie jest taka trudna. Całość można zrealizować na dowolnych dwóch pinach cyfrowych w trybie wyjścia a wszystkie potrzebne informacje są w nocie katalogowej MM5450.
    MM5450 wyjątkowo mi się spodobał - układ ten mocno odciąża mikrokontroler, można mu wysłać raz bieżący stan naszych segmentów a potem nic nie trzeba odświeżać, układ wszystko pamięta i co więcej nawet pozwala regulować nam jasność wyświetlacza potencjometrem. Zero ghostingu i zabaw z przerwaniami!
    Oprócz samych podstaw komunikacji pokazałem tu też nieco bardziej zaawansowane rzeczy które oczywiście są niezależne od SDCC i PICów, mam nadzieję, że jest to jasne. Przedstawione tu kody można portować i uruchamiać pod Arduino i na całkiem innych platformach. Ogólne schematy postępowania są tam te same, więc myślę, że nawet osoby niezainteresowane PICami mogą skorzystać.
    Załączam ostateczną wersję projektu SDCC oraz pliku .bat do kompilacji:

    Cool? Ranking DIY
    Can you write similar article? Send message to me and you will get SD card 64GB.
    About Author
    p.kaczmarek2
    Level 26  
    Offline 
  • IGE-XAO
  • IGE-XAO
  • #4
    p.kaczmarek2
    Level 26  
    @piottr242 zwróć uwagę, że oferuję on też regulacje jasności.
    Ale ogólnie... dobry pomysł z tym 74595 . Też postaram się go zaprezentować w tutorialu.