RSMPX - rozdzielacz RS232

Projekty użytkowników forum zarówno sprzętowe, jak i związane z programowaniem w dowolnym języku.
Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

RSMPX - rozdzielacz RS232

Postautor: gaweł » wtorek 21 maja 2019, 00:10

SUMATOR RS232

rsmpx4_00.jpg


Wątek poboczny od tematu PINTOOL.

Inna „antyczna” konstrukcja rodem z XX wieku (na PCB widnieje data 2003 rok, ale na schematach jest data 1999). W tamtej starożytności powszechnie dostępne były procki z rodziny C51, więc nie należy się dziwić, że rozwiązanie jest jakie jest. Koncepcja urządzenia dotyczy „rozszycia” kanału RS232 wychodzącego z kompa na kilka urządzeń typu emulator EPROM czy PINTOOL. Ujmując najprościej, chodzi o przekierowanie strumienia RS232 z kompa do jednego wybranego urządzenia.
Wiadomo, że sygnałów w standardzie RS232 nie daje się „sumować na drucie” (jak w przypadku RS485). Nie znaczy, że takiej operacji nie da się wykonać, tylko trzeba zmienić do tego podejście. Sumę logiczną w standardach TTL daje się dobić robić bez najmniejszych problemów. W ofercie układów logicznych jest wiele takich, które by do tego się nadawały. Rozpatrzmy taką konstrukcję (obróbka czterech kanałów RS232 do jednego).
Zacznijmy od ogólnego poglądu na sprawę:
RSMPX4_0.PNG
W szczegółach, mamy jednostkę centralną opartą na procku z rodziny C51. Jego aplikacja nie należy do „dziwnych”. Mamy klasyczne rozwiązanie z pamięcią programu w EPROM. Dodatkowo występuje trochę ośmiobitowych portów rozrzuconych tu i ówdzie w przestrzeni adresowej XRAM.
RSMPX4_1.PNG
Przyłącze do kompa to nieskomplikowane rozwiązanie. Stosowane układy interfejsów to MC1488 (4 nadajniki) i MC1489 (4 odbiorniki), więc niejako w gratisie powstał dodatkowy kanał do podsłuchiwania innych (i tak zostały jeszcze wolne kanały w interfejsach) → złącze P202.
RSMPX4_2.PNG
Sama logika „sumacyjna” to poniższe rozwiązanie.
RSMPX4_3.PNG
Wiadomo, że stanem pasywnym w transmisji szeregowej po stronie TTL jest logiczna jedynka, więc podanie na jedną z nóżek bramek OR jedynki logicznej skutecznie wyłącza dany kanał. Właściwie, tak na upartego, to możliwe jest jednoczesne włączenie wszystkich kanałów (co technicznie jest możliwe) tylko to musi być ujęte w oprogramowaniu urządzeń korzystających w powyższego diwajsa (konieczna jest realizacja transmisji w trybie półdupleksowym, ale to jako efekt uboczny). Przy okazji z linii komunikacyjnych można wydzielić przez mpx 74LS151 jedną i przekierować dodatkowo do kanału podsłuchowego. Tak patrzę sobie teraz na to rozwiązanie i za chorobę nie mogę sobie przypomnieć dlaczego mpx przełączający de facto dwie linie dostaje do wysterowania dwa druty, choć wystarczy jeden. Chyba wymyśliłem, pamięć choć zawodna, powoli wraca. W rzeczywistości istotne są trzy stany: podsłuch linii TXD, podsłuch linii RXD oraz żadnej, czyli na wyjściu 74LS151 ma być logiczna jedynka, dlatego pozostałe wejścia w mpx są ujedynkowane.
Wyjście w drugą stronę to również banalne rozwiązanie:
RSMPX4_4.PNG
Jeszcze została tylko sygnalizacja, co się dzieje w diwajsie z elementarną obsługą małej klawiatury.
RSMPX4_5.PNG
I odpowiada to płytce frontpanelu.
RSMPX4_6.PNG
Na koniec jest zasilacz. Daje trzy napięcia: +5V, +12V i -12V (takich wymagają układy MC1488 i MC1489) no i sam procek z okoliczną cyfrówką (+5V).
RSMPX4_7.PNG
By uzyskać takie napięcia najprościej jest użyć trafo z odczepem na środku.
Do tego jest PCB (skoro jest fizyczna konstrukcja, to musi być rzecz jasna PCB, jedno bez drugiego nie istnieje :D ).
Strona TOP, BOTTOM i rozłożenie elementów.
RSMPX4_topv.png
RSMPX4_botv.png
RSMPX4_topm.png
PCB wykonane metodą chałupniczą (sitodruk) i zmontowane urządzenie to:
rsmpx4_01.jpg
rsmpx4_02.jpg
Soft do urządzenia, co nie dziwne, nigdy nie powstał :) , ale mam jakieś przeczucie, że chyba wkrótce powstanie.
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Ostatnio zmieniony wtorek 21 maja 2019, 11:20 przez gaweł, łącznie zmieniany 1 raz.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: RSMPX - rozdzielacz RS232

Postautor: gaweł » wtorek 21 maja 2019, 01:08

Inny wariant
Obróbka 8 kanałów RS232


Godziny przeglądania płytek CD z dawnych czasów. Jest schemat, nie znalazłem projektu PCB, być może nigdy nie powstał, a z pewnością nie miał fizycznej realizacji. Schemat jest datowany na rok 1998. Jak widać, w stosunku do wyżej opisanego wariantu 4-kanałowego, ten jest dosyć ubogi.
RSSUM8.PNG
RSSUM8_1.PNG
RSSUM8_2.PNG
RSSUM8_3.PNG
RSSUM8_4.PNG
RSSUM8_5.PNG
RSSUM8_6.PNG
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1321
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: RSMPX - rozdzielacz RS232

Postautor: gaweł » sobota 25 maja 2019, 02:40

PANEL KOMUNIKACYJNY

Toksyczna muzahttps://www.youtube.com/watch?v=qRX5Enk51k4

Przeglądając archiwalne CD'ki, natrafiłem na konstrukcję panelu komunikacyjnego. Rozwiązanie, wg dokumentacji, jest datowane na przełom 2002/2003 roku, więc jest trochę wiekowe a sam niewiele pamiętam. Nawet dokumentacja jest kompletna, to znaczy są schematy, jest PCB, jest soft dla AVR'a oraz zawartość użytych układów CPLD. Cóż czasami tak bywa, że pamięć ulatuje, ale jak natrafimy na coś z przeszłości, to są szanse, że wróci. Nie pamiętam co stało się z owym panelem, bo go nie mam u siebie (zapewne poszedł w ludzi). Pamiętam, że takie urządzenie zostało zbudowane i było przez jakiś czas w użyciu. Jedyna pamiątka, jaka po nim pozostała (oprócz dokumentacji na płycie CD), to garść układów scalonych (CPLD), które zostały zastosowane w konstrukcji. W sumie to fajne układy (bo +5V'owe, więc nie istnieją żadne problemy wynikające z konwersji napięć) i przez jakiś czas zastanawiałem się, co z nich można zrobić i … tak przeleżały sobie w pudełeczku do dzisiejszych czasów. Nadal oczekują z nadzieją na swoją szansę.
panko_01.jpg
Jego zadaniem było... przekierowywanie strumienia transmisji szeregowej (po RS232) na określone podkanały. Trudno tu mówić o jakiejś komutacji kanałów komunikacyjnych. Raczej sprowadzało się do rozszycia portu szeregowego na kilka kanałów (również RS232), chociaż w tej konstrukcji została przewidziana możliwość przejścia na RS485 (tak na zapas, a może kiedyś do czegoś się przyda). W sumie mi się nie przydała, ale komuś... niewykluczone. W tamtych czasach miałem już kilka urządzeń z automatyki domowej, które jakoś należało zintegrować.
No więc wygląda to tak:
panko_02.png
Centralny procek (ATMEGA161, dzisiaj już chyba jest nieosiągalny) ma typową aplikację. Jego wybór został podyktowany tym, że można do niego „doczepić” dodatkowe porty jako komórki pamięci RAM (procek może obsługiwać zewnętrzną RAM). Z tego powodu zbudowany jest dekoder adresowy do generowania sygnałów typu chip select (klasyczne rozwiązanie na bazie 74HC138). Do procka przypięty jest kanał szeregowy, który jest używany do konfiguracji tej całej maszynerii.
panko_03.png
Wlot szeregowy do panelu jest zbudowany na bazie standardowych układów 16C450. Są zastosowane dwa (dlaczego? nie mogę sobie przypomnieć). Przejście z sygnałów logicznych na standardy RS232 jest zrealizowane na bazie pełnomodemowych układów typu 75232 (niestety wymagają 3 napięć zasilających). Te kontrolery transmisji są obsługiwane w przerwaniach, ich przerwania są doczepione do procka jako przerwania zewnętrzne.
panko_04.png
Cała „magia” przetwarzania zaszyta jest w układzie CPLD ispLSI1032 (od Lattice). W tym układzie zaimplementowanych jest ileś rejestrów sterujących widzianych jako komórki pamięci zewnętrznej (czyli dochodzi szyna danych od procka i parę sygnałów sterujących) plus logika związana z obróbką sygnałów transmisji szeregowej.
panko_05.png
panko_06.png
By było widać, co się dzieje w panelu, jest cała banda lampek LED, które są sterowane z proca (poprzez wpis do rejestrów 74HCT574). O kurczę... 40 LED'ów, to prawie choinka na Boże Narodzenie. Sygnały wychodzą na złącze GOLDPIN, by kabelkiem płaskim przejść na frontpanel.
Sam frontpanel to praktycznie diody LED plus fajny klawisz monostabilny. Pamiętam, był ładny, z podświetleniem LED. Jego naciśnięcie oznaczało wejście do trybu konfiguracyjnego by dokonać wymaganych zmian (połączyć się via lokalny, ten w procku ATM161, kanał szeregowy z dowolnego emulatora terminala i poprzez odpowiednie menu dokonać zmian).
panko_07.png
Wyjście panelu komunikacyjnego to cała banda złączek DB9 w standardzie RS232
panko_08.png
i dwa w standardzie RS485 (oba jako dwuparowe).
panko_09.png
Zasilacz panelu jest „bardzo skomplikowany”, to tylko złącze (+5V, +12V i -12V).
panko_10.png
Skoro było urządzenie, to jest PCB. Elementy generalnie są na stronie TOP, ale część jest na stronie BOTTOM.
panko_11.png
panko_12.png
Tak patrzę na to PCB i dochodzę do wniosku, że było przewidziane na technologią chałupniczą, bo nie ma podejść lutowniczych do miejsc niedostępnych (jak złączki DB9 po stronie TOP). Więcej, PAD'y pod złączki są jednostronne.
Zawartość układu PLD została wysmarowana w VHLD'u. Właśnie wtedy zaprzyjaźniłem się z VHLD'em i tak jakoś zostało do dzisiaj. Wcześniej próbowałem rysować schematy na zawartość układów CPLD. Niestety na studiach mnie nie uczyli tego języka, więc jakoś trzeba było sobie radzić. Zaczynałem od rysowania schematów, cóż każdy orze jak może. Z pewnej perspektywy to były fajne czasy, bo pokonywało się jakieś bariery, z drugiej strony wymagało to sporej pracy, bo nie było nawet z kim pogadać o napotykanych problemach (nikt ze znajomych nie wchodził w układy PLD). Ale, jak widać, problemy są do pokonania...

Kod: Zaznacz cały

--
-- ******************************************************************************
-- ******************************************************************************
-- **                                                                          **
-- **                 Logika panelu komunikacyjnego                            **
-- **                      Uklad ispLSI1032E                                   **
-- **                                                                          **
-- **                         Wersja: 1.00                                     **
-- **                    Bialystok, 2003.01.08                                 **
-- **                                                                          **
-- ******************************************************************************
-- ******************************************************************************

library ieee ;
use ieee.std_logic_1164.all ;

entity panelcom is
  port ( Clock            : in std_logic ;                              -- sygnal zegarowy
         DataBus          : inout std_logic_vector ( 7 downto 0 ) ;     -- szyna danych mikrokontrolera
         NotRd            : in std_logic ;                              -- sygnal odczytu, szyna sterowania mikrokontrolera
         NotWr            : in std_logic ;                              -- sygnal zapisu, szyna sterowania mikrokontrolera
         ChipSelect       : in std_logic ;                              -- sygnal wyboru
         Address          : in std_logic_vector ( 1 downto 0 ) ;        -- szyna adresowa mikrokontrolera
         Enable           : out std_logic_vector ( 9 downto 0 ) ;       -- sterowanie liniami modemowymi poszczegolnych kanalow RS232
         GlobalTXD        : in std_logic ;                              -- sumaryczny sygnal TXD
         GlobalRXD        : out std_logic ;                             -- sumaryczny sygnal RXD
         TXD              : out std_logic_vector ( 9 downto 0 ) ;       -- sygnaly TXD dla poszczegolnych kanalow jako wyjscie RS232
         RXD              : in std_logic_vector ( 9 downto 0 ) ;        -- sygnaly RXD dla poszczegolnych kanalow jako wejscie RS232
         TXD485           : out std_logic_vector ( 9 downto 8 ) ;       -- sygnaly TXD dla poszczegolnych kanalow jako wyjscie RS485
         RXD485           : in std_logic_vector ( 9 downto 8 ) ;        -- sygnaly RXD dla poszczegolnych kanalow jako wejscie RS485
         Test1            : out std_logic ;
         Test2            : out std_logic ) ;
end panelcom ;

-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-- ::                                                                     ::
-- :: Adresy i znaczenie rejestrow dla zapisu:                            ::
-- :: A0,A1 = 00                                                          ::
-- ::        D7 .. D0 => Enable Register ( 7 .. 0 )                       ::
-- :: A0,A1 = 01                                                          ::
-- ::        D1 .. D0 => Enable Register ( 9 .. 8 )                       ::
-- :: A0,A1 = 10                                                          ::
-- ::        D1       => Mode485 kanalu 9                                 ::
-- ::        D0       => Mode485 kanalu 8                                 ::
-- :: A0,A1 = 11                                                          ::
-- ::                 => zerowanie rejestru statusow                      ::
-- ::                                                                     ::
-- :: Adresy i znaczenie rejestrow dla pdczytu:                           ::
-- :: A0,A1 = 00                                                          ::
-- ::        D7 .. D0 <= Enable Register ( 7 .. 0 )                       ::
-- :: A0,A1 = 01                                                          ::
-- ::        D1 .. D0 <= Enable Register ( 9 .. 8 )                       ::
-- ::        D2       <= Mode485 kanalu 8                                 ::
-- ::        D3       <= Mode485 kanalu 9                                 ::
-- :: A0,A1 = 10                                                          ::
-- ::        D7 .. D0 <= Status register ( 7 .. 0 )                       ::
-- :: A0,A1 = 11                                                          ::
-- ::        D1 .. D0 <= Status register ( 9 .. 8 )                       ::
-- ::                                                                     ::
-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

architecture behavioral of panelcom is

  component DifSensor
    port ( DClock        : in std_logic ;
           SetReg        : in std_logic ;
           DOutput       : out std_logic ) ;
  end component ;

  signal WriteEnableRegisterL : std_logic ;
  signal WriteEnableRegisterH : std_logic ;
  signal WriteModeStrobe      : std_logic ;
  signal ClearStatusStrobe    : std_logic ;
  signal Clock2               : std_logic ;
  signal EnableRegister       : std_logic_vector ( 9 downto 0 ) ;
  signal Mode485              : std_logic_vector ( 9 downto 8 ) ;
  signal InternalRXD          : std_logic_vector ( 9 downto 0 ) ;
  signal RxdStatus            : std_logic_vector ( 9 downto 0 ) ;
  signal LastLine             : std_logic_vector ( 9 downto 0 ) ;
  signal InternalData         : std_logic_vector ( 7 downto 0 ) ;
  signal DifSensClock         : std_logic_vector ( 9 downto 0 ) ;

begin
  Test1 <= '1' when (LastLine(0) /= InternalRXD(0)) else '0' ;
  Test2 <= DifSensClock(0) or DifSensClock(1) or DifSensClock(2) or DifSensClock(3) or DifSensClock(4) or
           DifSensClock(5) or DifSensClock(6) or DifSensClock(7) or DifSensClock(8) or DifSensClock(9) ;

  WriteEnableRegisterL <= '1' when ((Address="00") and (NotWr='0') and (ChipSelect='0')) else '0' ;
  WriteEnableRegisterH <= '1' when ((Address="01") and (NotWr='0') and (ChipSelect='0')) else '0' ;
  WriteModeStrobe <= '1' when ((Address="10") and (NotWr='0') and (ChipSelect='0')) else '0' ;
  ClearStatusStrobe <= '1' when ((Address="11") and (NotWr='0') and (ChipSelect='0')) else '0' ;

  DifSens0 : DifSensor port map ( DClock => DifSensClock ( 0 ) ,
                                  SetReg => ClearStatusStrobe ,
                                  DOutput => RxdStatus ( 0 ) ) ;
  DifSens1 : DifSensor port map ( DClock => DifSensClock ( 1 ) ,
                                  SetReg => ClearStatusStrobe ,
                                  DOutput => RxdStatus ( 1 ) ) ;
  DifSens2 : DifSensor port map ( DClock => DifSensClock ( 2 ) ,
                                  SetReg => ClearStatusStrobe ,
                                  DOutput => RxdStatus ( 2 ) ) ;
  DifSens3 : DifSensor port map ( DClock => DifSensClock ( 3 ) ,
                                  SetReg => ClearStatusStrobe ,
                                  DOutput => RxdStatus ( 3 ) ) ;
  DifSens4 : DifSensor port map ( DClock => DifSensClock ( 4 ) ,
                                  SetReg => ClearStatusStrobe ,
                                  DOutput => RxdStatus ( 4 ) ) ;
  DifSens5 : DifSensor port map ( DClock => DifSensClock ( 5 ) ,
                                  SetReg => ClearStatusStrobe ,
                                  DOutput => RxdStatus ( 5 ) ) ;
  DifSens6 : DifSensor port map ( DClock => DifSensClock ( 6 ) ,
                                  SetReg => ClearStatusStrobe ,
                                  DOutput => RxdStatus ( 6 ) ) ;
  DifSens7 : DifSensor port map ( DClock => DifSensClock ( 7 ) ,
                                  SetReg => ClearStatusStrobe ,
                                  DOutput => RxdStatus ( 7 ) ) ;
  DifSens8 : DifSensor port map ( DClock => DifSensClock ( 8 ) ,
                                  SetReg => ClearStatusStrobe ,
                                  DOutput => RxdStatus ( 8 ) ) ;
  DifSens9 : DifSensor port map ( DClock => DifSensClock ( 9 ) ,
                                  SetReg => ClearStatusStrobe ,
                                  DOutput => RxdStatus ( 9 ) ) ;

  ClockDivider : process ( Clock )
  begin
    if rising_edge ( Clock ) then
      Clock2 <= not Clock2 ;
    end if ;
  end process ;

  StoreEnLProcess : process ( WriteEnableRegisterL )
  begin
    if rising_edge ( WriteEnableRegisterL ) then
      EnableRegister ( 7 downto 0 ) <= DataBus ( 7 downto 0 ) ;
    end if ;
  end process ;

  StoreEnHProcess : process ( WriteEnableRegisterH )
  begin
    if rising_edge ( WriteEnableRegisterH ) then
      EnableRegister ( 9 ) <= DataBus ( 1 ) ;
      EnableRegister ( 8 ) <= DataBus ( 0 ) ;
    end if ;
  end process ;

  StoreModeProcess : process ( WriteModeStrobe )
  begin
    if rising_edge ( WriteModeStrobe ) then
      Mode485 ( 9 ) <= DataBus ( 1 ) ;
      Mode485 ( 8 ) <= DataBus ( 0 ) ;
    end if ;
  end process ;

  with ChipSelect & NotRd & Address select
    InternalData <= EnableRegister ( 7 downto 0 )             when "0000" ,
                    "111111" & EnableRegister ( 9 downto 8 )  when "0001" ,
                    RxdStatus ( 7 downto 0 )                  when "0010" ,
                    "111111" & RxdStatus ( 9 downto 8 )       when "0011" ,
                    "11111111"                                when others ;

  DataBus <= InternalData when ( ( NotRd = '0' ) and ( ChipSelect = '0' ) ) else "ZZZZZZZZ" ;

  TXD ( 0 ) <= GlobalTXD or EnableRegister ( 0 ) ;
  TXD ( 1 ) <= GlobalTXD or EnableRegister ( 1 ) ;
  TXD ( 2 ) <= GlobalTXD or EnableRegister ( 2 ) ;
  TXD ( 3 ) <= GlobalTXD or EnableRegister ( 3 ) ;
  TXD ( 4 ) <= GlobalTXD or EnableRegister ( 4 ) ;
  TXD ( 5 ) <= GlobalTXD or EnableRegister ( 5 ) ;
  TXD ( 6 ) <= GlobalTXD or EnableRegister ( 6 ) ;
  TXD ( 7 ) <= GlobalTXD or EnableRegister ( 7 ) ;
  TXD ( 8 ) <= GlobalTXD or EnableRegister ( 8 ) when Mode485 ( 8 ) = '0' else '1' ;
  TXD ( 9 ) <= GlobalTXD or EnableRegister ( 9 ) when Mode485 ( 9 ) = '0' else '1' ;
  TXD485 ( 8 ) <= GlobalTXD or EnableRegister ( 8 ) when Mode485 ( 8 ) = '1' else '1' ;
  TXD485 ( 9 ) <= GlobalTXD or EnableRegister ( 9 ) when Mode485 ( 9 ) = '1' else '1' ;

  InternalRXD ( 0 ) <= EnableRegister ( 0 ) or RXD ( 0 ) ;
  InternalRXD ( 1 ) <= EnableRegister ( 1 ) or RXD ( 1 ) ;
  InternalRXD ( 2 ) <= EnableRegister ( 2 ) or RXD ( 2 ) ;
  InternalRXD ( 3 ) <= EnableRegister ( 3 ) or RXD ( 3 ) ;
  InternalRXD ( 4 ) <= EnableRegister ( 4 ) or RXD ( 4 ) ;
  InternalRXD ( 5 ) <= EnableRegister ( 5 ) or RXD ( 5 ) ;
  InternalRXD ( 6 ) <= EnableRegister ( 6 ) or RXD ( 6 ) ;
  InternalRXD ( 7 ) <= EnableRegister ( 7 ) or RXD ( 7 ) ;
  InternalRXD ( 8 ) <= EnableRegister ( 8 ) or RXD ( 8 ) when Mode485 ( 8 ) = '0' else
                       EnableRegister ( 8 ) or RXD485 ( 8 ) ;
  InternalRXD ( 9 ) <= EnableRegister ( 9 ) or RXD ( 9 ) when Mode485 ( 9 ) = '0' else
                       EnableRegister ( 9 ) or RXD485 ( 9 ) ;

  StoreLines : process ( Clock )
  begin
    if rising_edge ( Clock ) then
      LastLine ( 9 downto 0 ) <= InternalRXD ( 9 downto 0 ) ;
    end if ;
  end process ;

  GlobalRXD <= InternalRXD(0) and InternalRXD(1) and InternalRXD(2) and InternalRXD(3) and
               InternalRXD(4) and InternalRXD(5) and InternalRXD(6) and InternalRXD(7) and
               InternalRXD(8) and InternalRXD(9) ;

  Enable ( 7 downto 0 ) <= EnableRegister ( 7 downto 0 ) ;
  Enable ( 8 ) <= EnableRegister ( 8 ) or Mode485 ( 8 ) ;
  Enable ( 9 ) <= EnableRegister ( 9 ) or Mode485 ( 9 ) ;

  DifSensClock ( 0 ) <= '1' when ( LastLine ( 0 ) /= InternalRXD ( 0 ) ) else '0' ;
  DifSensClock ( 1 ) <= '1' when ( LastLine ( 1 ) /= InternalRXD ( 1 ) ) else '0' ;
  DifSensClock ( 2 ) <= '1' when ( LastLine ( 2 ) /= InternalRXD ( 2 ) ) else '0' ;
  DifSensClock ( 3 ) <= '1' when ( LastLine ( 3 ) /= InternalRXD ( 3 ) ) else '0' ;
  DifSensClock ( 4 ) <= '1' when ( LastLine ( 4 ) /= InternalRXD ( 4 ) ) else '0' ;
  DifSensClock ( 5 ) <= '1' when ( LastLine ( 5 ) /= InternalRXD ( 5 ) ) else '0' ;
  DifSensClock ( 6 ) <= '1' when ( LastLine ( 6 ) /= InternalRXD ( 6 ) ) else '0' ;
  DifSensClock ( 7 ) <= '1' when ( LastLine ( 7 ) /= InternalRXD ( 7 ) ) else '0' ;
  DifSensClock ( 8 ) <= '1' when ( LastLine ( 8 ) /= InternalRXD ( 8 ) ) else '0' ;
  DifSensClock ( 9 ) <= '1' when ( LastLine ( 9 ) /= InternalRXD ( 9 ) ) else '0' ;

end behavioral ;
Soft (napisany w ASM), nie jest jakiś specjalnie złożony. W sumie obróbkę transmitowanych sygnałów zapewnia układ CPLD. Najbardziej złożoną funkcjonalnością programu jest obsługa konfiguracji. Program robił to w ten sposób, że „drukował” na ekran terminala odpowiedni menus, z którego użytkownik wybierał określoną opcję (takie jednoznakowe polecenie). W zależności od wczytanego znaku coś tam robił. Z grubsza wygląda to tak:

Kod: Zaznacz cały

ServiceActive   :                         ;PROCEDURE ServiceActive ( ) : BOOLEAN ;
;****************                      ;BEGIN (* ServiceActive *)
             sbic   PINB,SrvKey        ; IF ServKey = 0 THEN
             rjmp   SrvA_0             ;
             call   Delay              ;  Delay ( ) ;
             sbic   PINB,SrvKey        ;  IF ServKey = 0 THEN
             rjmp   SrvA_1             ;
             sec                       ;   RETURN TRUE ;
             ret                       ;
SrvA_1       :                         ;  END (* IF *) ;
SrvA_0       :                         ; END (* IF *) ;
             clc                       ; RETURN FALSE ;
             ret                       ;END ServiceActive ;
;-----------------------------------------------------------------------------
ServiceMenu :       .db   "KONFIGURACJA PANELU KOMUNIKACYJNEGO ",Cr,Lf
                    .db   "   0) identyfikacja ",Cr,Lf
                    .db   "   1) wlaczenie kanalow ",Cr,Lf
                    .db   "   2) wylaczenie kanalow",Cr,Lf
                    .db   "   3) parametry transmisji do kanalu podstawowego ",Cr,Lf
                    .db   "   4) parametry transmisji do kanalu alternatywnego ",Cr,Lf
                    .db   "   5) parametry transmisji do urzadzen",Cr,Lf
                    .db   "   6) parametry transmisji serwisowej ",Cr,Lf
                    .db   "   7) rodzaj wyjscia kanalow 9 i 10 ",Cr,Lf
                    .db   "   8) czas powrotu do kan. podstawowego ",Cr,Lf
                    .db   "   9) parametry fabryczne ",Cr,Lf
                    .db   "   #) koniec konfiguracji ",Cr,Lf,Cr,Lf,0,0
KeyService   :                         ;PROCEDURE KeyService ( ) ;
;****************                      ;BEGIN (* KeyService *)
             cli                       ; DI ( ) ;
             call   ResetLocalSerial   ; ResetLocalSerial ( ) ;
             się                       ; EI ( ) ;
             clr    acc                ; ConfigFlag := FALSE ;
             sts    ConfigFlag,acc     ;
             ldz    ServiceMenu<<1     ; LocSendRSTxt ( ServiceMenu ) ;
             call   LocSendRSTxt       ;
             call   InputKeyWithTimeUp ; acc := InputKeyWithTimeUp ( ) ;
             or     acc,acc            ; IF acc = 0 THEN
             brne   KeSe_13            ;
             ldz    ServiceAutoExit<<1 ;  LocSendRSTxt ( ServiceAutoExit ) ;
             call   LocSendRSTxt       ;
             ret                       ;  RETURN ;
KeSe_13      :                         ; END (* IF *) ;
(. . )
             ret                       ;END KeyService ;
;-----------------------------------------------------------------------------
SetupService :                         ;PROCEDURE SetupService ( ) ;
;****************                      ;BEGIN (* SetupService *)
             call   StartKeyService    ; StartKeyService ( ) ;
             call   KeyService         ; KeyService ( ) ;
             call   StopKeyService     ; StopKeyService ( ) ;
( . . )
             ret                       ;END SetupService ;
;-----------------------------------------------------------------------------
Main :                                 ;BEGIN (* Main *)
             call   ClearRAM           ; ClearRAM ( ) ;
             call   ClearRegs          ; ClearRegs ( ) ;
             call   HardwareInit       ; HardwareInit ( ) ;
             call   EnvirInit          ; EnvirInit ( ) ;
( . . )
             call   ServiceActive      ;  IF ServiceActive ( ) THEN
             brcc   Main_1             ;
( . . )
             call   SetupService       ;   SetupService ( ) ;
( . . )
Main_1       :                         ;  END (* IF *) ;
( . . )
Halt         :                         ;
             rjmp   Halt               ;
                                       ;END Main ;
;-----------------------------------------------------------------------------
gdzie poszczególne opcje rozwijają się na kolejne. Mniej więcej są takie:

Kod: Zaznacz cały

OnOffMenuTxt :    .db   "  1) kanal 1",Cr,Lf
                  .db   "  2) kanal 2",Cr,Lf
                  .db   "  3) kanal 3",Cr,Lf
                  .db   "  4) kanal 4",Cr,Lf
                  .db   "  5) kanal 5",Cr,Lf
                  .db   "  6) kanal 6",Cr,Lf
                  .db   "  7) kanal 7",Cr,Lf
                  .db   "  8) kanal 8",Cr,Lf
                  .db   "  9) kanal 9",Cr,Lf
                  .db   "  0) kanal 10 ",Cr,Lf
                  .db   "  #) zakoncz",Cr,Lf,0,0
Cmm7SubMenu :     .db   " 1) kanal 9 jako RS232",Cr,Lf
                  .db   " 2) kanal 9 jako RS485",Cr,Lf
                  .db   " 3) kanal 10 jako RS232 ",Cr,Lf
                  .db   " 4) kanal 10 jako RS485 ",Cr,Lf
                  .db   " #) zaniechaj ",Cr,Lf,0,0
AddQuestionTxt :  .db   "  0) nie",Cr,Lf
                  .db   "  1) tak",Cr,Lf,0,0
SelFunctionTxt :  .db   "Zmiana dotyczy :",Cr,Lf
                  .db   " 0) trybu transmisji",Cr,Lf
                  .db   " 1) predkosci transmisji",Cr,Lf
                  .db   " #) zaniechaj ",Cr,Lf,0,0
ExtUARTSpeedMenuTxt :   .db   "Wybierz predkosc transmisji ",Cr,Lf
                  .db   "  0) 600",Cr,Lf
                  .db   "  1) 1200 ",Cr,Lf
                  .db   "  2) 2400 ",Cr,Lf
                  .db   "  3) 3600 ",Cr,Lf
                  .db   "  4) 4800 ",Cr,Lf
                  .db   "  5) 7200 ",Cr,Lf
                  .db   "  6) 9600 ",Cr,Lf
                  .db   "  7) 14400",Cr,Lf
                  .db   "  8) 19200",Cr,Lf
                  .db   "  9) 28800",Cr,Lf
                  .db   "  A) 38400",Cr,Lf
                  .db   "  B) 57600",Cr,Lf
                  .db   "  C) 115200 ",Cr,Lf
                  .db   "  #) zaniechaj",Cr,Lf,0,0
IntUARTSpeedMenuTxt :   .db   "Wybierz predkosc transmisji ",Cr,Lf
                  .db   "  0) 2400 ",Cr,Lf
                  .db   "  1) 4800 ",Cr,Lf
                  .db   "  2) 9600 ",Cr,Lf
                  .db   "  3) 14400",Cr,Lf
                  .db   "  4) 19200",Cr,Lf
                  .db   "  5) 28800",Cr,Lf
                  .db   "  6) 38400",Cr,Lf
                  .db   "  7) 57600",Cr,Lf
                  .db   "  8) 76800",Cr,Lf
                  .db   "  9) 115200 ",Cr,Lf
                  .db   "  #) zaniechaj",Cr,Lf,0,0
WLMenu :          .db   "Dlugosc slowa ",Cr,Lf
                  .db   "  0) 5 bitow",Cr,Lf
                  .db   "  1) 6 bitow",Cr,Lf
                  .db   "  2) 7 bitow",Cr,Lf
                  .db   "  3) 8 bitow",Cr,Lf
                  .db   "  #) zaniechaj",Cr,Lf,0,0
PmodeMenu :       .db   "Parzystosc",Cr,Lf
                  .db   "  0) bez parzystosci",Cr,Lf
                  .db   "  1) z parzystoscia ",Cr,Lf
                  .db   "  2) z nieparzystoscia",Cr,Lf
                  .db   "  #) zaniechaj",Cr,Lf,0,0
StBitsMenu :      .db   "Liczba bitow stopu",Cr,Lf
                  .db   "  0) 1 bit",Cr,Lf
                  .db   "  1) 2 bity ",Cr,Lf
                  .db   "  #) zaniechaj",Cr,Lf,0,0


I tak to było.
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse


Wróć do „DIY”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 12 gości