Mikrokomputer CA80
układ czasowo-licznikowy Z80-CTC

generowanie PWM dla diody RGB


charakterystyka i informacje ogólne
książki / dokumentacja (literatura)
ulotki i broszurki MIK (literatura)
skany artykułów z prasy (literatura)
programator EPROM (aplikacje)
dwupunktowy termometr (aplikacje)
licznik-timer Z80-CTC i dioda RGB (aplikacje)
Direct Memory Loader - ładowarka do pamięci (akcesoria)
próbnik stanów logicznych MIK03C (akcesoria)
zdalnie sterowana klawiatura (akcesoria)
przegląd procedur systemowych (programowanie)

☘☘☘☘☘☘☘☘☘

Kostka Z80-CTC nie jest w systemie CA80 jakoś specjalnie eksploatowana. Wykorzystują ją wprawdzie przystawki częstościomierza oraz pozytywki programu Monitor CA88, ale poza tymi aplikacjami układ tylko wcina prąd chyba odrobinę się nudząc. Spróbuję zatem przedstawić proste zastosowanie układu licznikowego do generowana sygnałów sterujących dioda RGB. Zagadnienie wygląda na niezbyt skomplikowane, co zaraz zobaczymy, ale najpierw...

Z80-CTC - układ czasowo-licznikowy

Przedstawiamy bohatera odcinka - układ Z80-CTC i aby nie powielać ogólnie dostępnych treści odsyłam do linku z firmową dokumentacją Zilog: ⇨ Z80 Family CPU Peripherals Drugie opracowanie jest równie ciekawe, stanowi o wewnętrznej budowie układu. Wiedza ta, może nie do końca przydatna jest na co dzień, ale warto zerknąć, ogrom pracy badawczej robi wrażenie ⇨ Product Evaluation Of The Zilog Z80-CTC Układ CTC widzimy na fotografii poniżej, jak i całe ich stado obok. Ot była okazja capnąć listwę układów CTC i PIO ☺ Moje kostki pochodzą z roku 84, widać „stare” ładnie stylizowane Z, potem logo Ziloga jakoś spaskudniało.



W systemie CA80 kostka Z80-CTC zamieszkuje pod adresem bazowym $F8 przestrzeni I/O procesora, kolejne kanały układu są dostępne w lokalizacjach, odpowiednio:
  • $F8 – CTC_CH0
  • $F9 – CTC_CH1
  • $FA – CTC_CH2
  • $FB – CTC_CH3
    Aha i nie należy na widok czterech kanałów popadać w orgastyczne rozanielenie – w pełni funkcjonalne (mające pełną obsadę wejść i wyjść) są tylko kanały 0,1,2. Kanał 3 nie ma wyjścia ZC/TO ponieważ…zabrakło dla niego pinu w obudowie DIP28. Serio, bez kitu. Tak więc trzy kanały mamy do wykorzystania w rozwiązaniach sprzętowych, czwarty ma tylko wejście liczące. Pierwszy, prymitywny programik do sprawdzenia działania kanału CTC w trybie licznik widzimy na listingu poniżej:

    ;demo_ctc_1.asm
            .cr Z80
            .tf demo_ctc_1.hex,INT
            .lf demo_ctc_1.lst
            .in ca80.inc        
            
    CTC_CH0 .eq     $F8     
            .sm     CODE            
            .or     $C000       
    demo1:  
            ld      A, %01010101
            out     (CTC_CH0),A
            ld      A,10
            out     (CTC_CH0),A        
            jp      $
            ;
    

    W pierwszym kroku do rejestru kanału wpisujemy słowo sterujące, w drugim – inicjalną wartość stałej służącej do ładowania licznika po przepełnieniu. Budowa słowa naszego konkretnego ($55) słowa sterującego jest taka:
  • D7 - 0 - wyłączone przerwania
  • D6 - 1 - tryb licznik
  • D5 - 0 – nieistotne dla trybu COUNTER
  • D4 – 1 – zliczanie narastających zboczy na wejściu CLK
  • D3 – 0 - nieistotne dla trybu COUNTER
  • D2 – 1 – następnym zapisem będzie podana stała dla licznika
  • D1 – 0 – praca ciągła
  • D0 - 1 – zawsze ☺

    Podajemy na wejście CLK/TGR0 przebieg prostokątny o częstotliwości 2kHz i jak łatwo przeliczyć - kolejne narastające zbocza tego przebiegu będą pojawiały się co 500us. Do rejestru CTC wpisaliśmy stałą 10, zatem należy oczekiwać, że po odliczeniu tychże dziesięciu impulsów kostka CTC wygeneruje impulsik na wyjściu ZC/TO0 i ponownie rozpocznie zliczanie. No i proszę – na ekranie oscyloskopu mamy szpilki co 5ms (czyli oczekiwany 10x okres przebiegu wejściowego). Warto przypatrzeć się takiemu pojedynczemu impulsowi – jak widać ma on w naszym przypadku niecałe 400ns, czyli jest naprawdę króciutki. To specyfika układu CTC, z przebiegów w dokumentacji kostki wynika, że impuls ten trwa około jednego taktu zegara systemowego podawanego na wejście Φ układu CTC.



    generator PWM

    Skoro wiemy już, jak generować na wyjściach CTC impulsy z zadanym podziałem czasu to spróbujmy zastosować to wyprodukowania sygnału PWM (pulse width modulation). Potrzebne nam będą do tego: dwa liczniki – kanały CTC raz kawałek prostej logiki. Jeden licznik (channel 0) będzie odpowiedzialny za częstotliwość przebiegu wyjściowego, sygnał przezeń generowany będzie miał okres N razy dłuższy niż okres sygnału napędzającego zabawkę (fwej). Impulsy z kanału głównego ustawiają przerzutnik zbudowany z dwóch bramek NOR. Tu wyjaśnienie – model kleciłam z tego co pod ręką, więc w roli pary NOR dwie, trójwejściowe bramki z układu 7427, zbędne końcówki oczywiście do masy. A tak w ogóle to bramki NOR dlatego, że z nich zbudowany flip-flop jest ustawiany i kasowany wysokim stanem logicznym, co mi tu akurat odpowiada. Przerzutnik z NAND byłby kasowany stanem niskim. Drugi licznik (channel 1) jest odpowiedzialny za kontrolę długości impulsu wyjściowego. Jego wejście jest warunkowo zasilane sygnałem o fwej, licznik pracuje tylko do czasu odliczenia zadanej ilości impulsów, generując impuls na ZC/TO1 zmienia stan przerzutnika (kasuje) jednocześnie odcinając się od źródła sygnału. Mamy zatem sytuację, że w punkcie pomiarowym CH1 pojawia się 1 logiczne i trwa przez N1(channel 1) impulsów, potem aż do czasu wyznaczonego przez N0(channel 0) na wyjściu jest 0. Wypełnienie przebiegu określa iloraz stałych licznikowych kanału 1 do kanału 0.



    Realizacja powyższego w formie pająka:



    A tu prosty program konfigurujący oba kanały:

    ;demo_ctc_2.asm
            .cr Z80
            .tf demo_ctc_2.hex,INT
            .lf demo_ctc_2.lst
            .in ca80.inc        
            
    CTC_CH0 .eq     $F8     
    CTC_CH1 .eq     $F9     
            .sm     CODE            
            .or     $4000       
    demo1:  
            ld      A, %01010101
            out     (CTC_CH0),A
            ld      A,30
            out     (CTC_CH0),A        
            ld      A, %01010101
            out     (CTC_CH1),A
            ld      A,10
            out     (CTC_CH1),A        
            jp      $
            ;        
    

    Jak widać górny licznik (channel 0) zlicza do 30 i wtenczas generuje impuls dla przerzutnika, dolny liczy tylko do 10, kasując przerzutnik sprowadza sygnał wyjściowy do stanu L. Powyższe wywody odzwierciedlają oscylogramy na rysunku, przy okazji widzimy wyliczony przez Analog Discovery współczynnik duty przebiegu na poziomie ~33%



    generator pod kontrolą

    Następny krok to dobudowanie do zabawki prostego interfejsu użytkownika, programik sprawdza klawiaturę, zależnie czy wciśnięto klawisz [0] czy [1] modyfikuje parametr DUTY, który jest następnie przepisywany jako stała do licznika channel 1. Zdjęcia poniżej to przykładowe wartości i odpowiadające im oscylogramy, cały program dostępny tu: ⇨ demo_ctc_3.asm







    Oczywiście całość bardziej na żywo na filmiku. Zwróćmy uwagę na zachowanie układu podczas manipulowania częstotliwością sygnału wejściowego. Ponieważ generowanie PWM odbywa się w sposób czysto sprzętowy (programowalny jest tylko współczynnik wypełnienia) instalacja jest sterowalna i pracuje poprawnie do częstotliwości taktującej około 1MHz, to niezły wynik, ponieważ przy podziale jak w moim modelu (przez 100) daje to częstotliwość wyjściowego PWM na poziomie 10kHz.




    cyfrowe kolory - dioda RGB

    Naturalną konsekwencją tych wszystkich poczynań jest ewolucja układu do prostego ale wdzięcznego do obserwacji sterownika diody RGB, schemat widzimy poniżej:



    Zasada działania, już bardziej szczegółowo jest następująca: źródłem sygnału taktującego całość jest prymitywny generator z wykorzystaniem bramki NAND z wejściami Schmidta (U1A), dla wartości elementów jak na schemacie generator produkuje sygnał o częstotliwości około 6kHz.Sygnał ten jest podawany na dzielnik częstotliwości /100, to dwa znane układy 7490 podłączone w kaskadę. Na wyjściu Q3 kostki U3 mamy częstotliwość około 60Hz i to właśnie będzie częstotliwość naszego sygnału PWM. Problem z nim jest tylko taki, że czas trwania stanu H na wyjściu Q3 licznika U3 jest nieakceptowanie długi (choć taka uroda tej kostki) i zaburza pracę układu. Powinna być taka cienka szpileczka jak widzieliśmy po raz pierwszy na wyjściu ZC/TO ponieważ ma służyć do przestawienia stanu przerzutnika z nie zaduszenia na dłużej w stanie set. Potrzeba zatem układu formującego króciutki impuls dla narastającego zbocza, czyli w chwili przejścia L↗H. To daje nam prosty układ RC widoczny przed bramką U5A, dioda na wejściu przycina ujemną szpilkę z kondensatora co znieczula całość na opadające zbocza sygnału z wyjścia Q3. Drugi NOR (U5B) stanowi prosty negator, finalnie dając na wyjściu pozytywne szpilki, które z powodzeniem nadają się do ustawiania przerzutnika z bramek NOR.
    Wspomniany sygnał 6kHz podawany jest także na wejście bramki NAND (U1B) zarządzającej w ten sposób dopływem impulsów do wejścia zliczającego CLK/TRG układu Z80-CTC. Po odliczeniu zadanej w programie ilości impulsów Z80-CTC wygeneruje na wyjściu ZC/TO szpileczkę kasującą przerzutnik, co odetnie licznik w CTC od źródła sygnału a jednocześnie zmieni stan wyjścia sterującego jedną z diod składowych RGB. Sztuka działa identycznie dla trzech zestawów – licznik CTC + bramka + przerzutnik dając finalnie sterowanie wypełnieniem dla trzech kolorów składowych.

    Poniżej kilka zdjęć wykonanych podczas wstępnych testów układu.



    Oczywiście program sterujący - tym razem na ekraniku mamy wartości trzech składowych R, G i B. Dodałam niewielkie zabezpieczenia przed zawinięciem się wartości współczynnika wypełnienia – program zadaje liczby z zakresu 1..99.
    Oto cały kod: ⇨ demo_ctc_20_rgb.asm





    Filmik z testów kolorystycznych diory RGB mamy poniżej, dają się niestety we znaki uroki współczesnych tanich kolorowych diodek - aby uzyskać konkretny kolor, trzeba się nieco nagimnastykować ustawiając średni prąd płynący przez elementy struktury. Zauważmy, że nawet dla PWM na poziomie 1% (DUTY=1/100) dioda nieco się tli, co odrobinę psuje finalny efekt z barwami.



    I na koniec zdjęcia z kolejnych programowo wyizolowanych składowych R, G oraz B. Zwróćmy przy okazji uwagę na efekt działania układu formującego impulsy sterujące przerzutnikiem - widać, że stan H z wyjścia licznika jest całkiem długi, ale po przepuszczeniu przez układ D+R+C i dwie bramki - na przerzutnik wchodzi ładny, zwinny impulsik automatycznie wyznaczając minimalny czas stanu wysokiego dla generowanej fali PWM.







    ostatnie takty CLK

    Jak widać, oswojenie Z80-CTC i zagonienie do takich dość nieskomplikowanych zadań jak PWM nie stanowi problemu, układ jest sympatyczny w implementacji i programowaniu. Oczywiście, klecąc elektronikę mruczałam pod nosem na brak bramki sterującej (jak to dał Intel z kostkach 8253 czy 8254), ale te niedogodności są akceptowalne, z dołożeniem zewnętrznej logiki (przerzutników) liczyłam się wcześniej - to dzisiejsze nowobogackie MCU mają jednostki PWM, w średniowieczu robiono to na piechotę, jak wyżej. No i układ CTC Ziloga jest szybki, jest naprawdę cholernie szybki. Moja wersja to Z80A-CTC, ona przestała współpracować przy sygnale 1MHz, a mamy jeszcze edycję B i C! Tak więc jak na mikroelektronikę retro to osiągi są co najmniej zadowalające. Nieporadnie dość wyszło z brakiem wyjścia dla channel 3, ale jak domniemywam projektanci musieli podjąć decyzję - albo pełna integracja z priorytetowym system przerwań Z80 (który daje naprawdę wielkie możliwości) albo obsadzone wszystkie sygnały robocze. Stanęło na pierwszym i...słusznie ☺

    #slowanawiatr, marzec 2019

  • Natasza Biecek 2004-2019/~, e-mail