Sterowanie portami Amigi
Otrzymałem wiele listów dotyczących sterowania urządzeniami podłączonymi do portów Amigi. W większości wypadków chodzi o sterowania kilkoma urządzeniami z portu PAR. Na początek opiszę budowę portu PAR, sposób podłączenia do niego urządzeń oraz przykładowe programy w kilku językach sterujące portem. W następnej kolejności opiszę praktyczne urządzenia podłączone do portu wraz z programem je obsługującym. Jeśli temat wzbudzi zainteresowanie pojawi się opis sterowania przez port SER.
Artykuł (mam nadzieję że cykl artykułów) rozpocznę od rzeczy trochę nudnych, ale bardzo przydatnych. Omówię budowę wewnętrzną portu 8520 zastosowanego w Amidze, a właściwie sposobu sterowania pojedyńczą linią.
Na
Poke $BFE301,255 : Rem Ustawienie portu jako wyjście Poke $BFE101,0 : Rem Wpisanie zera na bit 0 portu Print "Stan portu";Peek($BFE101) : Rem Odczyt i wyświetlenie stanu portuPo uruchomieniu programu na ekranie ujżymy: Stan portu 0 a dioda led zgaśnie. Po wpisaniu i uruchomieniu programu (listing 2):
Poke $BFE301,255 : Rem Ustawienie portu jako wyjście Poke $BFE101,1 : Rem Wpisanie jedynki na bit 0 portu Print "Stan portu";Peek($BFE101) : Rem Odczyt i wyświetlenie stanu portuna ekranie ujżymy: Stan portu 1 a dioda led zaświeci. Wykonajmy teraz układ z
Poke $BFE301,255 : Rem Ustawienie portu jako wyjście Poke $BFE101,1 : Rem Wpisanie jedynki na bit 0 portu Bset 7,$BFE101 : Rem Wpisanie jedynki na bit 7 portu Print "Stan portu";Peek($BFE101) : Rem Odczyt i wyświetlenie stanu portuna ekranie ujżymy: Stan portu 128 binarnie %10000000, zamiast %10000001. Podobnie byłoby gdybyśmy użyli rozkazu "Or". Wszystko dla tego, że asemblerowy rozkaz "Bset 7,$BFE101" wykonuje operację odczyt-modyfikacja-zapis. Możnaby to porównać do sekwencji rozkazów:
MOVE.B $BFE101,D0 OR.B #7,D0 MOVE.B D0,$BFE101Dlatego rozkazy: Bset, Bclr, Btst, Bchg tak samo jak And, Or zadziałają błędnie! Także rozkazy Add, Sub, Ror, Rol, Cmp i inne wykonane bezpośrednio na rejestrach portów będą działać błędnie! Zajmniemi się teraz budową i sposobem sterowania portem CIA-A obsługującym gównie port równoległy.
Adres Nazwa Funkcja $bfe001 PRA rejestr danych zewnętrznych dla portu danych A $bfe101 PRB rejestr danych zewnętrznych dla portu danych B $bfe201 DDRA rejestr kierunku danych portu A $bfe301 DDRB rejestr kierunku danych portu B $bfe401 TALO młodszy bajt zegara A $bfe501 TAHI starszy bajt zegara A $bfe601 TBLO młodszy bajt zegara B $bfe701 TBHI starszy bajt zegara B $bfe801 TODLO młodszy bajt licznika TOD $bfe901 TODMID środkowy bajt licznika TOD $bfea01 TODHI starszy bajt licznika TOD $bfeb01 TODHR nie używany $bfec01 SDR rejestr danych szeregowych $bfed01 ICR rejestr kontroli przerwań $bfee01 CRA rejestr kontrolny A $bfef01 CRB rejestr kontrolny BRejestr DDRB ustala kierunek linii portu Parallel. Wpisanie jedynki na bit 0 rejestru DDRB spowoduje, że pin 2 portu parallel będzie linią wyjściową. Wpisanie 0 spowoduje, że pin 2 portu będzie linią wejściową. Bit 1 ustala kierunek linii 3 portu, bit 2 linii 4, itd do bitu 7 odpowiedzialnego za pin 9. Wpisanie liczby 255 ($ff) ustawi linie 2...9 jako wyjściowe, liczba 0 ustawi linie jako wejściowe.
Rejestr PRB służy do odczytu danych z linii 2...9 portu parallel, gdy port pracuje jako wejście, lub zapisu stanu na liniach 2..9 portu gdy pracuje jako wyjście. Warto omówić przypadek, gdy część linii będzie ustawione jako wejścia, a część jako wyjścia. Wpiszmy i uruchomijmy program z listingu 4:
Poke $BFE301,$F0 : Rem Ustawienie bitów 0...3 portu jako wejście, bitów 4...7 jako wyjście Poke $BFE101,%10101010 : Rem Zapisanie danych na port Print "Stan portu ";Bin$(Peek($BFE101)) : Rem Odczytanie i wyświetlenie stanu portuna ekranie ujżymy (zakładam, że do portu nie jest nic podłączone, a w szczególności drukarka lub inne urządzenie z dwukierunkowym interfejsem): Stan portu %10101111 Jak można wywnioskować dane daje się zapisać tylko na te linie portu PRB, na których w rejestrze DDRB znajdują się jedynki. Zapis do linii ustawionych jako wejścia zostaje zignorowany. To jest największa różnica portu 8520 w stosunku do portów pseudo-dwukierunkowych. Działanie portu 8520 jest takie samo jak portów w procesorach serii AVR. Warto jeszcze wspomnieć, że każdy zapis lub odczyt rejestru PRB powoduje pojawienie się ujemnego impulsu, o czasie trwania około 200ns, na linii 1 portu parallel. Dzięki temu po wpisaniu danej do PRB automatycznie jest generowany strob informujący drukarkę o tym, że dane na porcie są ustalone. Gdyby port pracował jako wejściowy, strob poinformuje urządzenie nadające, że dane zostały przyjęte i można wysłać kolejną daną. Na porcie parallel jest dostępnych więcej linii. Pin 10 portu jest wejściem i jego stanu nie można oczytać bezpośrednio. Na pin 14 wyprowadzono napięcie zasilające o wartości +5V przez rezystor 47R. Z wyprowadzenia tego można czerpać prąd o wartości około 10mA. Pin 16 podłączony jest do linii reset. Pojawi się tam ujemny impuls w czasie restartu komputera. Lniami podłączonymi do pinów 11...13 można dowolnie sterować. Są one podłączone do układu CIA-B. Oto adresy rejestrów układu:
Adres Nazwa Funkcja $bfd000 PRA rejestr danych zewnętrznych dla portu danych A $bfd100 PRB rejestr danych zewnętrznych dla portu danych B $bfd200 DDRA rejestr kierunku danych portu A $bfd300 DDRB rejestr kierunku danych portu B $bfd400 TALO młodszy bajt zegara A $bfd500 TAHI starszy bajt zegara A $bfd600 TBLO młodszy bajt zegara B $bfd700 TBHI starszy bajt zegara B $bfd800 TODLO młodszy bajt licznika TOD $bfd900 TODMID środkowy bajt licznika TOD $bfda00 TODHI starszy bajt licznika TOD $bfdb00 TODHR nie używany $bfdc00 SDR rejestr danych szeregowych $bfdd00 ICR rejestr kontroli przerwań $bfde00 CRA rejestr kontrolny A $bfdf00 CRB rejestr kontrolny BRejestr DDRA ustala kierunek linii portu parallel i serial:
bit 0 pin 11 bit1 pin 12 bit2 pin 13bity3...7 ustalają kierunek linii podłączonych do portu serial i nie należy modyfikować ich zawartości. Jak więc ustawić kierunek? Nic prostrzego, należy posłużyć się rozkazami "And", "Or" lub "Bset", "Bclr". Naprzykład, aby ustawić linie podłączone do pinów 11...13 portu jako wyjścia należy wydać rozkaz: Poke $BFD200,Peek($BFD200) Or %00000111 lub użyć sekwencji:
Bset 1,$BFD200 Bset 2,$BFD200 Bset 3,$BFD200Gdy linie 11...13 chcemy ustawić jako wejściowe należy wydać rozkaz: Poke $BFD200,Peek($BFD200) And %1111100 0 lub użyć sekwencji: Bclr 1,$BFD200 Bclr 2,$BFD200 Bclr 3,$BFD200 Rejestr PRA służy do odczytu danych z linii 11...13 portu parallel, gdy port pracuje jako wejście, lub zapisu stanu na liniach 11...13 portu gdy pracuje jako wyjście. Obowiązują te same zasady co dla rejestru PRB portu CIA-A, tzn zapis będzie skuteczny jeśli na odpowiednich bitach rejestru DDRA będą ustawione jedynki. Przy zapisie rejestru PRA należy pamiętać, aby nie zmieniać stanu bitów 3...7, natomiast przy odczycie ignorować stan tych bitów. Ustawianie/zerowanie linii najlepiej realizować rozkazami "Bset", "Bclr". Przy odczycie można posłużyć się rozkazem "Btst" lub zamaskować bity 3...7 rozkazem And, np:
Na koniec pierwszej części, na listingu 5, przedstawiam prosty program generujący na efekt tzw "węża świetlnego":
Poke $BFE301,255 : Rem Port jako wyjście Restore : Rem Ustaw dane na początek Cls: Rem Czyść ekran Do Read A : Rem Czytaj daną do wyświetlenia If A<0 : Rem Jeśli koniec danych to: Restore : Rem Ustaw dane na początek Read A : Rem Czytaj pierwszą daną End If Poke $BFE101,A : Rem Zapisz dane do portu Home : Rem Kursor w lewy górny róg ekranu A$=Bin$(A)-"%" : Rem Wyświetl dane na ekranie A$="00000000"+A$ Print Right$(A$,8) Wait 10 : Rem Czekaj If Inkey$<>"" Then Exit : Rem Jeśli naciśnięto jakikolwiek klawisz to wyjdź Loop Data 1,2,4,8,16,32,64,128,64,32,16,8,4,2 Data -1:Rem Koniec danychDo wyjścia portu można podłączyć układ
AVT-2047 "Programowany sterownik do zabawek i modeli" EdW 6/96 AVT-2061 "Monitor interfejsu CENTRONICS" Edw 9/97 AVT-2097 "Moduł wykonawczy dużej mocy na triakach" EdW 10/97 AVT-2098 "Moduł wykonawczy dużej mocy do sterownika AVT2047" EdW 9/96 AVT-2099 "Moduł wykonawczy do sterownika AVT2047" EdW 8/96 AVT-2099+AVT-110 "Zestaw oświetlenia dyskotekowego-Moduł wykonawczy" EP 2/96 po małych modyfikacjach można podłączyć: AVT342 "Komputerowa strzelnica sportowa" EP 6/97W niektórych przypadkach konieczne może być zastosowanie rozkazu "Xor" przed wysłaniem danych na port. Spowodowane jest to negowaniem danych przez interfejs. W programie z Listingu 5 przed linią: Poke $BFE101,A : Rem Zapisz dane do portu należałoby wstawić:
Często 11 linii wejścia-wyjścia okazuje się zbyt małą liczbą, aby sterować bardziej skomplikowanymi urządzeniami. W kolejnej części zajmniemy się więc sposobem zwiększenia liczby wejść/wyjść portu równoległego. Instnieją dwa zasadnicze sposoby realizacji tego zadania: - sposób szeregowy: prosta realizacja sprzętowa, bardziej skomplikowany program sterujący, mała szybkość transmisji, - sposób równoległy: bardziej somplikowana budowa sprzętowa, prostrzy program, duża prędkość transmisji.
Na początek opiszę sposób zwiększenia liczby wyjść sposobem szeregowym. Na
Teraz zajmniemy się zwiększeniem liczby wejść sposobem szregowym. Przykładowy sposób realizacji widzimy na
Przejdźmy do kolejnego etapu, zwiększanie liczby wyjść sposobem równoległym. Przykładowe rozwiązanie można znaleźć na
Następnie wysyłamy dane na port. Impuls strobu z pinu 1 portu równoległego pojawia się na jednym z wyjść dekodera 74138. Układy 74574 reagują na narastające (tylne) zbocze sygnału strobu, dlatego nie można zamiast nich wykorzystać rejestrów 74573. Przepisują one dane na wyjście w chwili gdy na wejściu sterującym jest poziom H, natomiast aktywnym poziomem dla 74138 jest poziom "L". Jeśli komuś bardzo zależy na wykorzystaniu układów 74573 musi wymienić dekoder na 4028 lub 4514 dla którego aktywnym poziomem jest "H" . Przykładowy program obsługujący max 8 rejestrów widzimy na listingu 11. >>> Umieścić listing 11 <<<
Zwiększenie liczby wejść sposobem równoległym przedstawiono na
Zwiększenie liczby wejść-wyjść sposobem równoległym.
Jeśli chcemy zwiększyć zarówno liczbę wejść jak i wyjść proponuję układ z
Adres | Typ | funkcja portu | portu | bramki| dla podłączonych wejśę| | +-------+-------+-------+ | | D | CD | BCD | --------+-------+-------+-------+-------+ 0 | AND |In |In |In | 1 | AND |In |In |In | 2 | AND |In |In |In | 3 | AND |In |In |In | 4 | AND |In |In |In | 5 | AND |In |In |In | 6 | AND |In |In |In | 7 | AND |In |In |In | 8 | AND |Out |In |In | 9 | AND |Out |In |In | 10 | AND |Out |In |In | 11 | AND |Out |In |In | 12 | AND |Out |Out |In | 13 | AND |Out |Out |In | 14 | AND |Out |Out |Out | 15 | AND |Out |Out |Out | 0 | OR |in |In |In | 1 | OR |In |In |In | 2 | OR |In |In |Out | 3 | OR |In |In |Out | 4 | OR |In |Out |Out | 5 | OR |In |Out |Out | 6 | OR |In |Out |Out | 7 | OR |In |Out |Out | 8 | OR |Out |Out |Out | 9 | OR |Out |Out |Out | 10 | OR |Out |Out |Out | 11 | OR |Out |Out |Out | 12 | OR |Out |Out |Out | 13 | OR |Out |Out |Out | 14 | OR |Out |Out |Out | 15 | OR |Out |Out |Out | --------+-------+-------+-------+-------+
Pliki do probrania:
Listingi i programy
Sławomir Skrzyński
slawomir.skrzynski@ep.com.pl