logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Analizujemy i uruchamiamy moduł 48 LED na rejestrach przesuwnych z Arduino - HC164A

p.kaczmarek2 01 Lis 2024 20:28 1320 1
REKLAMA
  • Płytka z diodami LED w różnych kolorach
    Jak działa rejestr przesuwny? Jak można kaskadować rejestry przesuwne tak, aby uruchomić 48 diod LED za pomocą jedynie dwóch linii - zegara i danych? Tutaj postaram się to zademonstrować na przykładzie płytki z elektrośmieci, którą też najpierw przeanalizuję.

    Rozpoczynamy zwiad. Na płytce jest 6 układów HC164A oraz jeden 74AHC14D:
    Płytka drukowana z układami scalonymi i diodami LED
    Zielona płytka drukowana z widocznymi ścieżkami i złączem na końcu.
    Zdjęcie płytki PCB z kilkoma układami scalonymi HC164A Płytka drukowana z układami scalonymi HC164A i komponentami elektronicznymi Płytka elektroniczna z układami HC164A i 74AHC14D
    Sprawdzamy noty układów, HC164A :
    Karta katalogowa układu MC74HC164A Onsemi
    Pierwszy to rejestr przesuwny. Wejście szeregowo, wyjścia równolegle.
    Schemat logiczny układu MC74HC164A
    Ten rejestr przesuwny ma 8 wyjść a tylko 3 wejścia. Podając odpowiedni sygnał na wejścia, możemy ustawić wedle uznania wyjścia, więc zasadniczo pozwala nam uzyskać więcej pinów IO.
    Rejestr przesuwny pamięta to co mu raz ustawimy.
    W celu ustawienia jego wyjść podajemy mu sygnał zegara (CLK), zbocze narastające zegara sprawia że pamiętane wartości w rejestrze przesuwają się o miejsce dalej. W tym też momencie następuje pobrania kolejnej wartości (na pierwsze miejsce), stanowi ona rezultat iloczynu logicznego na wejściach A1 i A2.
    W uproszczonym zastosowaniu A2 można ustawić na poziom wysoki, wtedy manipulujemy tylko A1 i zegarem (CLK), i w ten sposób wpisujemy dane na kolejne piny wyjściowe rejestru.
    Zegar po prostu wykonuje kolejne cykle (ustawiamy na poziom niski, potem na wysoki, itd), a na A1 wystawiamy wedle uznania wartość którą chcemy wpisać na dane miejsce (1 lub 0).
    W kodzie będzie to nieco jaśniejsze.
    Drugi układ to tylko bramki realizujące funkcję NOT:
    Fragment dokumentacji układu scalonego 74AHC14
    W jego środku jest tych bramek kilka, każda na wyjście podaje przeciwny stan logiczny do tego na wejściu:
    Schemat układu 74AHC14 z opisem pinów i funkcji
    Teraz trzeba zbadać piny wyprowadzenia.
    Odlutowałem złącze:
    Zbliżenie na płytkę drukowaną z lutowanymi pinami
    Najłatwiej jest określić VDD i GND - mamy przecież wyprowadzenia układów. Dodatkowo masa to najczęściej miedziana wylewka na płytce, zasilanie też często może być taką wylewką.
    Ustawiamy multimetr w test ciągłości ("pikacz") i badamy, dokąd prowadzi każdy pad, czy przypadkiem nie trafia on do któregoś z pinów układów oznaczonych w nocie katalogowej VDD bądź GND.
    W ten sposób zostają zatem tylko 3 sygnały, których podłączenie też zbadałem multimetrem, umieszczając obserwacje na zdjęciu:
    Zdjęcie płytki z układami HC164A i 74AHC14D, schematycznie zaznaczone połączenia.
    Wnioski są następujące, mamy tu trzy sygnały:
    - wspólny CLK - prowadzi on do 74AHC14D, który jest w roli bufora, a potem rozwidla się na połączone wspólne zegarowe wejścia układów po prawej i lewej stronie
    - wspólny A2 - tak jak zegar, prowadzi do 74AHC14D, który jest w roli bufora, a potem się rozwidla...
    - kaskadowy A1 - prowadzi on do A1 pierwszego rejestru przesuwnego
    Kolejne piny A1 są podłączane do wyjść QH poprzednich rejestrów przesuwnych, dzięki temu przy kolejno "wsuwamy" bity to ostatni bit, który jest "na wyjściu" nie jest gubiony, tylko przechodzi do kolejnego rejestru.
    To co tu mamy, to jest zasadniczo zrobiony "jeden długi rejestr przesuwny" zbudowany z kilku zwykłych rejestrów.
    Zostaje jeszcze pytanie po co bramka NOT - pewnie by się obyło i bez niej, podejrzewam, że jest ona tu tylko w roli bufora, by była odpowiednia wydajność prądowa do wysterowania wejść rejestrów. Zresztą, te sygnały przechodzą przez nią dwa razy, więc nie są po tym zanegowane (negacja neguje negację).

    Uruchomienie
    Zatem szykujemy Arduino, lutujemy kabelki:
    Zbliżenie na płytkę drukowaną z przylutowanymi kablami
    Zaglądamy jeszcze do noty katalogowej rejestru, by wiedzieć co wysyłać:
    Diagram czasowy rejestru przesuwnego
    Uprościmy sobie sytuację - te dodatkowe, wspólne wejście ustawimy na stałe na stan wysoki. Operować będziemy tylko zegarem oraz pinem do wpisywania danych.
    Wpisujemy nasze piny w kod, tak jak podłączyliśmy:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Ustawiamy je jako wyjścia cyfrowe, ENA na stałe na stan wysoki:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    I teraz najważniejsze - wysyłanie danych.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Na razie wysyłam 32-bitową liczbę, w tym przypadku -1, która w reprezentacji bitowej to 0xFFFFFFFF, czyli same zapalone bity, a potem wysyłam same bity zgaszone. Chcę, by coś pomrugało.



    Niby coś działa, ale czemu na przemian?
    A wiem już, bo przecież te LEDy tam są dwukolorowe... więc tam jest ich w sumie 24*2 = 48 bitów, a ja wysyłam tylko 32 bity. Dodatkowo nie resetuję nic, więc zasadniczo wysyłam najpierw bity [0,31], potem [32, 47] i od nowa [0, 15], i tak się zapętla..
    Zbyt pochopnie zrobiłem tę pierwszą próbę, ale już wiem co jest nie tak.

    To teraz druga próba. 48 bitów to może być 6 bajtów, więc zrobiłem tablicę. Trochę kusiło też by użyć typu 64-bitowego, ale tablica się przyda do demonstracji. Teraz wysyłam konkretnie 48 bitów, więc liczę, że każda nowa transakcja będzie wpisywać nową osobną kolejkę stanów diod LED.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Jeszcze potrzeba to przetestować - na razie jedna dioda:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Testujemy:



    Działa!

    Pora na ambitniejszy test. Określiłem eksperymentalnie, że kolory LEDów są na przemian...
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Teraz zapalam kolejno czwórki LEDów wedle ich koloru:





    To teraz zostało dodać obsługę pojedynczych LEDów... bity powinny być po kolei, trzeba jedynie dopisać ich ustawianie. Pamiętajmy, że to tablica:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Kod demonstracyjny:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Efekt:



    I to tyle... teraz można się bawić, wyświetlać jakieś stany urządzenia, itd, bo na "knight rider" tu bym się nie pokusił ze względu na "ghosting", o tym zaraz.

    Podsumowanie
    Wszystko udało się uruchomić, choć początkowo myślałem, że będą tu 24 LEDy a nie 48, dopiero potem się zorientowałem, że byłby to absurd... mamy 6 rejestrów, każdy po 8 bitów, więc w sumie wychodzi 48 bitów.
    Oprócz tego poszło sprawnie.
    Rejestry są podłączone kaskadowo ale z punktu widzenia kodu nawet nie musimy o tym pamiętać, one się z automatu zachowują jako jeden duży rejestr.
    Chyba jedyny większy problem tutaj jest z tym, że ten konkretny rejestr nie posiada przełącznika "output enable" który by włączał/wyłączał wyjścia, więc jak mu "wsuwamy" bity to przez bardzo krótki okres czasu stany są widoczne na nieodpowiednich diodach. Psuje to efekt animacji i wymaga dodatkowych zabiegów, by to wyglądało dobrze.
    Przykładem rejestru przesuwnego z taką funkcją może być 74HC595, w jego przypadku można łatwiej uniknąć potencjalnego "ghostingu" segmentów.
    Teraz tylko pojawia się pytanie, do czego wykorzystać ten moduł? Może jakiś wskaźnik, ale co z "ghostingiem"?
    PS: To nie było już nasze pierwsze starcie z takim rejestrem, uruchamiałem już w oparciu o niego wyświetlacz 7-segmentowy:
    Wyświetlacz 7 segmentowy tunera, uruchomienie z Arduino, rejestr przesuwny
    EDIT: Pewnie pojawią się pytania o schemat, więc znalazłem w sieci coś pasującego:
    Schemat połączeń rejestrów przesuwnych i wyświetlaczy LED
    Tyle, że u mnie wszystkie "B" są razem i ja podaję na nie stan wysoki.
    Źródło: https://www.amobbs.com/thread-3278926-1-1.html

    Fajne? Ranking DIY
    Pomogłem? Kup mi kawę.
    O autorze
    p.kaczmarek2
    Moderator Smart Home
    Offline 
  • REKLAMA
  • #2 21289265
    austin007
    Poziom 17  
    Na schemacie jest błąd. Wyjście CA jest podłączone do szyny opisanej jako GND. Powinno być Vcc. Zatrzaskiwanie stanu i wyświetlanie dopiero po załadowaniu docelowych stanów zrealizowałbym od biedy poprzez właśnie wygaszanie montując w obwodzie CA klucz P-Mosfet/PNP. Jeśli zegar będzie dość szybki, wygaszenie nie będzie uciążliwe. Jeśli byłoby wolniej, można pokusić się o ściemnienie PWM tym kluczem , załadowanie, rozjaśnienie. Przy bardzo szybkim taktowaniu stany nieustalone nie będą zauważone. Zdecydowanie lepiej stosować rejestr z zatrzaskiem lub multipleksować przy wyświetlaczu i dla odciążenia procesora użyć gotowe multipleksery. Taka linijka led to juz chyba pierwszy świąteczny projekt zgodnie z wielkopowierzchniową, komercyjną, pogańską tradycją. Po Wszystkich Świętych w hipermarketach wjeżdżają ozdoby świąteczne.
REKLAMA