W przypadku budowy odmiennego wariantu (przykładowo inny zestaw modułów pomiarowych, gdyż koncepcja całego systemu jest bardzo elastyczna) należy odpowiednio „poinformować” procesor komunikacyjny o rzeczywistym zestawie przyłączonych modułów.
Zbudowany procesor komunikacyjny będący sterownikiem zarządzającym komunikacją na magistrali RS485 wymaga odpowiedniej konfiguracji, czyli zdefiniowania właściwych identyfikatorów podłączanych modułów po stronie interfejsu RS232 oraz całej gamy modułów przyłączonych do interfejsu RS485. W tym celu należy przyłączyć go do komputera i skorzystać z dowolnego emulatora terminalu (używając złącza przeznaczonego do RS232). Wymaga to starannego wpisywania poleceń – nie można używać klawisza Backspace, gdyż oprogramowanie modułu nie realizuje tej funkcjonalności.
Innym rozwiązaniem jest utworzenie dla komputera PC specjalizowanego programu, który ułatwi realizację tej czynności. Program ten powstał na bazie środowiska narzędziowego LAZARUS. Jest to wolne, niekomercyjne oprogramowanie pozwalające tworzyć oprogramowanie graficzne uruchamiane w środowisku WINDOWS oraz LINUX (raz napisany kod programu może być kompilowany na różne platformy docelowe).
Oprogramowanie LAZARUS jest bardzo zbliżone do koncepcji komercyjnego narzędzia DELPHI, toteż każdy użytkownik, który posługuje się narzędziem DELPHI, nie będzie miał problemów z używaniem oprogramowania LAZARUS. W Internecie jest wystarczająco dużo dokumentacji opisującej możliwości LAZARUS.
Po uruchomieniu programu do konfiguracji dostępne są następujące funkcje (rysunek 1), gdzie istnieje możliwość wyboru portu komunikacyjnego po kliknięciu na „szufladę” z nazwami dostępnych portów (rysunek 2).
Po wyborze portu przeznaczonego do komunikacji z przyłączonym modułem należy użyć przycisku „Otwórz port”. To zaowocuje zaświeceniem zielonej lampki symbolizującej otwarcie portu i aktywację pozostałych przycisków. W dalszej kolejności można w odpowiednie pole wpisać polecenie, przykładowo HELLO. Przyciskiem „Wyślij polecenie” jest ono wysyłane za pośrednictwem portu do przyłączonego modułu. Wysyłane polecenia są wyświetlane w okienku „Wysłane”. Odebrane z portu szeregowego dane są wyświetlane w okienku „Odebrane” (rysunek 3).
Prowadząc z modułem dialog konfiguracyjny, w pierwszej kolejności musimy przejść do odpowiedniego trybu pracy dopuszczającej funkcjonalność związaną z konfiguracją (polecenie CONNECT). W kolejnych krokach należy zmienić jego własny identyfikator, dodać identyfikator serwera www, do którego będą wysyłane dane (identyfikator jest elementem mającym istotne znaczenie w filtrowaniu danych przesyłanych do serwera i jest on wkompilowany w kod jego programu), dodać identyfikatory modułów po stronie SLAVE będących kolejnymi elementami budowanej instalacji.
Po wprowadzeniu danych trzeba je zapisać w pamięci nieulotnej i się rozłączyć. Warto zauważyć, że po zmianie identyfikatora w procesorze komunikacyjnym zmienił się symbol urządzenia będącego źródłem przesyłanych danych (w okienku „Odebrane” na rysunku 3). Kolejny element jaki daje się zauważyć, to zaczyna migać w odpowiednim tempie lampka LED sygnalizująca transmisję w interfejsie RS485.
Po utworzeniu kilkuelementowej listy urządzeń SLAVE skonfigurowany kontroler zaczyna realizować swoją funkcję w zakresie dystrybucji żetonów (zezwoleń na zwrotną transmisję od modułu SLAVE do modułu MASTER), jednak chwilowo nie docierają one do adresatów, gdyż do urządzenia MASTER nic nie jest przyłączone. Konfiguracja i sprawdzenie działania jest wykonywane według tabeli 1 (dostępna w Elportalu)
O ile konfiguracja procesora komunikacyjnego nie stanowi większego problemu technicznego (moduł dysponuje portem w standardzie RS232), o tyle w przypadku innych modułów (które zostaną opisane w kolejnych częściach) wymaga zastosowania odpowiedniego modułu pośredniczącego. Wynika to z tego, że moduły będące elementami typu SLAVE (czyli posiłkujące się transmisją półdupleksową z wykorzystaniem interfejsów RS485) nie mogą być bezpośrednio przyłączone do komputera PC.
Niezbędny jest moduł, który odbierze dane w standardzie RS232 i prześle je dalej jako RS485. Zakładając, że po stronie RS485 jest przyłączony jeden konfigurowany moduł, wystarczy jedynie właściwe sterowanie kierunkiem transmisji bez konieczności „rozdawania żetonów”. Taką funkcjonalność sprzętową przykładowo spełnia opisany wcześniej procesor komunikacyjny, dla którego należałoby przygotować odpowiednią wersję oprogramowania. Jednak do tego celu skonstruowałem dedykowany moduł – procesor konfiguracyjny. Jego jednostkę centralną pokazuje rysunek 4.
Większość rozwiązań sprzętowych jest identycznych jak w dotychczasowych konstrukcjach. W tym wypadku został zastosowany mikrokontroler ATmega8515, który ma w swoich zasobach jeden kontroler transmisji szeregowej. Ten wewnętrzny zespół zostaje skierowany do interfejsu RS485, łącznie z linią sterującą kierunkiem transmisji układu SN75176 (rysunek 4 i 7).
Brakujący kontroler zostaje uzupełniony zewnętrznym specjalizowanym układem do obsługi asynchronicznej transmisji szeregowej UART (U201, TL16C450). Układ ten jest przyłączony do mikrokontrolera jako zewnętrzna pamięć, gdyż ten umożliwia dodanie zewnętrznej pamięci RAM do istniejącej wewnątrz struktury mikrokontrolera. Taka pamięć jest standardowo używana przez oprogramowanie, jej użycie niczym się nie różni od pamięci wbudowanej.
Do obsługi pamięci rozszerzenia niezbędne jest wykorzystanie dedykowanych do tego celu wyprowadzeń mikrokontrolera. Szyną danych (8-bitową) staje się PORTA, który jest współdzielony z młodszą częścią 16-bitowej szyny adresowej. Funkcję starszej części szyny adresowej pełni PORTC. Do obsługi tej pamięci niezbędne są jeszcze dwa sygnały sterujące: sygnał żądania zapisu lub odczytu generowany przez mikrokontroler.
W tej roli występują dwa wyprowadzenia PORTD oznaczone jako /WR (strob zapisu) i /RD (strob odczytu). Odpowiedni sygnał strobu w stanie aktywnym przyjmuje wartość logicznego zera. Uwzględniając to oraz dodatkowo stan wybranej linii adresowej (A15), z bramek NAND zbudowany jest odpowiedni układ kombinacyjny generujący sygnał aktywacji pamięci (U102, rysunek 4). W typowym rozwiązaniu sprzętowym stosowanym do obsługi zewnętrznej pamięci wykorzystywany jest 8-bitowy zatrzask aktywowany sygnałem ALE (wyprowadzenie mikrokontrolera).
Procesor, chcąc zapisać coś do zewnętrznej pamięci, wystawia na liniach PORTA młodszą część szyny adresowej i generuje impuls na wyjściu ALE, który zapisuje do rejestru zatrzasku stan PORTA. Jednocześnie na PORTC wystawiona jest starsza część szyny adresowej (kompletna przestrzeń adresowa pamięci RAM tego mikrokontrolera wymaga 16-bitowego adresu i procesor taki adres udostępnia na zewnątrz).
Po zapisaniu części adresu PORTA przejmuje rolę przewidzianą dla szyny danych, toteż przy operacji zapisu pojawią się tam dane (przy operacji odczytu procesor pobierze stamtąd dane). Jednocześnie generowany jest impuls na wyjściu /WR albo /RD, dając sygnał aktywujący pamięć do realizacji operacji dostępu.
Jednak w stosunku do typowego rozwiązania przyłączenia zewnętrznej pamięci w tym przypadku wystąpiły znaczące uproszczenia. W roli pamięci występuje kontroler transmisji szeregowej (rysunek 5).
Pomimo że nie jest to pamięć, sposób obsługi układu jest identyczny. Kontroler TL16C450 jest widziany w przestrzeni adresowej jako osiem komórek, co wymaga jedynie trzech bitów adresowych. Pozwala to na redukcję o rejestr zatrzasku (równocześnie staje się bezużyteczne wyjście ALE), a wymagana przez TL16C450 szyna adresowa zostaje przyłączona do wybranych linii w starszej części szyny. Implikuje to wykorzystanie jedynie PORTC do roli szyny adresowej.
Dodając linię adresową A15 do zespołu kombinacyjnego (U102), determinuje to ściśle określone położenie rejestrów wewnętrznych układu TL16C450 w przestrzeni adresowej mikrokontrolera. To znaczące uproszczenie sprzętowe ma swoje konsekwencje w oprogramowaniu w takim znaczeniu, że kolejne komórki układu TL16C450 są specyficznie rozrzucone w przestrzeni adresowej mikrokontrolera i nie stanowią ciągłego obszaru (nie występują one jako kolejne adresy w pamięci).
Pracujący kontroler transmisji szeregowej (U201, rysunek 5) sygnałem INT informuje o wykonaniu swojej pracy. Jest to sygnał przerwania, który jest doprowadzony do mikrokontrolera do wejścia przeznaczonego na sygnały przerwań z zewnątrz. Stanem aktywnym linii INT jest logiczna jedynka, toteż w torze tego sygnału znajduje się negator logiczny zbudowany z jednej bramki 74HC00. Właściwie to mikrokontroler jest w stanie zareagować na sygnał INT generowany przez TL16C450 bez negacji, ale jak widać siła przyzwyczajenia do rozwiązań z czasów popularności procesora Z80 jest duża, gdzie stanem aktywnym sygnału przerwania jest logiczne zero.
Zastosowany układ TL16C450 ma wbudowany generator sygnału taktującego i wymagane jest jedynie przyłączenie rezonatora kwarcowego. Częstotliwość 1,8432MHz pozwala na realizację każdej standardowej prędkości transmisji. Sam układ zawiera w sobie programowalny dzielnik częstotliwości determinujący wymaganą prędkość transmisji. Jego szyna danych, szyna adresowa i odpowiednie sygnały sterujące są połączone z odpowiednimi wyprowadzeniami mikrokontrolera. Sygnał reset układu TL16C450 jest przyłączony do wybranego wyprowadzenia w PORTD.
W programie będzie musiała być zawarta operacja generująca właściwy sygnał reset (poziomy aktywne sygnału reset mikrokontrolera oraz układu TL16C450 są odmienne, co implikuje, że nie jest możliwe bezpośrednie ich połączenie). Transmitowane dane, już w postaci szeregowej, oraz wybrane linie modemowe są poprzez popularny układ interfejsu RS232 (MAX232) wyprowadzone na odpowiednie złącze.
Sygnalizacja stanu pracy całego urządzenia jest zrealizowana z wykorzystaniem LED-ów (rysunek 6). Sygnalizują one niezależnie nadawanie oraz odbieranie danych szeregowych w obu interfejsach. Rozwiązanie interfejsu RS485 jest identyczne jak w dotychczasowych modułach (rysunek 7). Ponieważ moduł konfiguracyjny stanowi funkcjonalnie odpowiednik procesora komunikacyjnego, zawiera na wyjściu układu U401 (SN75C176) rezystory (R403, R404 i R405) determinujące stan pasywny na liniach komunikacyjnych.
Całość zamyka stabilizator dostarczający do układów właściwe napięcie zasilające (rysunek 8). Moduł nie jest przewidziany do pracy ciągłej (straty cieplne nie są istotne), więc zastosowane rozwiązanie jest najprostsze z możliwych. Do schematu została opracowana płytka drukowana, której widok pokazują rysunki 9 i 10. Zbudowane i uruchomione urządzenie widać na fotografii 1.
Większość aspektów oprogramowania jest identyczna jak w opisanych dotychczas modułach. Właściwego komentarza wymaga jedynie obsługa zewnętrznego układu UART. Jego sposób przyłączenia implikuje kilka rozwiązań w oprogramowaniu. W sensie adresowym (umiejscowienie rejestrów układu TL16C450) w przestrzeni adresowej przedstawia listing 1 (Uwaga, wszystkie listingi dostępne są w Elportalu wśród materiałów dodatkowych do tego numeru). Osiem rejestrów tego układu będzie znajdować się na odpowiednich, różnych adresach (jak widać, nie stanowią one ciągłego obszaru, są rozrzucone w przestrzeni jako pojedyncze bajty).
Tu warto zwrócić uwagę, że nie są to jedyne możliwe lokacje w przestrzeni. Jak było opisane wcześniej, interfejs adresowy pomiędzy mikrokontrolerem a układem TL16C450 jest mocno zredukowany, nie jest brana pod uwagę przykładowo młodsza część adresu, a to oznacza, że każdy adres z zakresu od 8000 hex do adresu 80FF hex będzie prowadził do tej samej komórki. Również w starszej części adresowej występują swoiste dziury.
Analizując schemat przyłączenia, można zauważyć, że przykładowo linia adresowa A14 (jak też kilka innych) nie jest wykorzystana, toteż układ nie jest wrażliwy na stan tej linii i może ona przyjmować wartość dowolną. Sygnał przerwania generowany przez układ TL16C450 jest przyłączony do mikrokontrolera jako sygnał INT0 (zewnętrzne przerwanie). Implikuje to, że przerwanie generowane przez ten układ jest w oprogramowaniu widziane jako przerwanie INT0, więc musi być skojarzone z odpowiednim wektorem przerwania w programie. Pokazuje to listing 2.
Do tej funkcji trafia każde wygenerowane przez układ przerwanie. By rozpoznać powód, dla jakiego zostało ono wygenerowane, należy odczytać odpowiedni rejestr zawarty w TL16C450 (rejestr identyfikowany adresem InterruptIdRegister). Na odpowiednich bitach jest zawarta szczegółowa informacja pozwalająca poznać powód, dla którego zostało wygenerowane przerwanie. W zależności od stanu tych bitów realizowana jest właściwa funkcjonalność (przerwanie od nadajnika czy przerwanie od odbiornika).
Zapis Port = ( uint8_t * ) LineControlRegister ; oznacza, że po wykonaniu instrukcji zmienna będzie zawierać wskazanie (adres) do komórki w pamięci RAM (w tym przypadku będzie to zewnętrzna pamięć RAM). Z kolei zapis * Port = 0x080 ; (ze znakiem gwiazdki przed nazwą zmiennej) oznacza, że podstawiane dane zostaną przesłane do miejsca, na które wskazuje zmienna Port, czyli pod odpowiednie miejsce w przestrzeni adresowej.
Układy sprzętowe obsługi dostępu do pamięci zawarte w strukturze mikrokontrolera „zauważą”, że operacja dotyczy pamięci zewnętrznej i zrealizują niezbędne działania, by taka operacja zaistniała (na wyprowadzeniach PORTA i PORTC zostanie wystawiony adres, zaistnieje odpowiedni impuls na wyprowadzeniu ALE itd.). Przez zmianę zawartości zmiennej Port dokonuje się zapis (lub odczyt) pozostałych rejestrów układu TL16C450. Do poszczególnych rejestrów zostają zapisane odpowiednie dane, z innych zrealizowany jest odczyt.
Dodatkowego wyjaśnienia wymaga zapis stałej będącej podzielnikiem w układzie generowania sygnału taktującego transmisją szeregową. Jej częstotliwość jest determinowana parametrami rezonatora kwarcowego i jest wewnętrznie dzielona przez 16 oraz przez programowalny dzielnik. W przestrzeni rejestrów układu TL16C450 nie ma jawnie występującego rejestru (takiego odpowiednika rejestru UBRR w przypadku mikrokontrolerów AVR). By wykonać zapis stałej do dzielenia częstotliwości taktującej, należy zapisać do rejestru LineControl wartość z ustawionym najbardziej znaczącym bitem (przykładowo 0x80).
Po tej operacji należy zrobić dwa zapisy: pierwszy do rejestru nadawanych danych (DataRegister) oraz drugi do rejestru kontrolującego generowanie przerwań (InterruptEnRegister). Żadne te zapisy nie są interpretowane jako wysłanie szeregowe danych ani konfiguracja systemu przerwań, a dotyczą ukrytego odpowiednika AVR-owego rejestru UBRR. Dalszy zapis do rejestru LineControl dotyczy już rzeczywistego wpisania trybu pracy (w zapisywanych danych nie jest ustawiony najstarszy bit).
Na zakończenie programowania kontrolera zapisany jest rejestr InterruptEnRegister. Zapis ten informuje układ TL16C450, by generował sygnał przerwania w wyniku odebrania oraz wysłania szeregowych danych.
Zaprogramowanie zewnętrznego układu do transmisji danych pokazuje listing 3. Algorytm zawiera zapis odpowiednich wartości do poszczególnych rejestrów układu. Lokalna zmienna Port jest wskaźnikiem (zmienną zawierającą adres) do obszaru o wielkości jednego bajta, czyli w pamięci zajmuje dwa bajty (identycznie jak wyżej opisana funkcja obsługi przerwania) i wskazuje na strukturę jednobajtową w pamięci.
By powyższe operacje związane z obsługą zewnętrznej pamięci RAM były możliwe, konieczna jest aktywacja odpowiednich zespołów zawartych w strukturze AVR (listing 4). Należy ustawić w rejestrze AVR oznaczonym jako MCUCR bit SRE (aktywacja obsługi zewnętrznej pamięci RAM), SRW10 (każdy dostęp do zewnętrznej pamięci będzie realizowany z dodatkowym cyklem oczekiwania) oraz ISC01 (przerwanie zgłaszane przez układ TL16C450 jako przerwanie zewnętrzne INT0 będzie reagować na opadające zbocze sygnału przerywającego).
Przed zaprogramowaniem mikrokontrolera ATMEGA 8515 należy zmodyfikować w bitach konfiguracyjnych (FUSES) źródło sygnału taktującego mikrokontroler (ustawić opcje określające przyłączenie zewnętrznego rezonatora kwarcowego).
Opisany moduł przeznaczony do konfiguracji stanowi elementarny składnik środowiska diagnostycznego (fotografia 2). Zawiera ono niewielką magistralę RS485 (zbudowaną na bazie kostek zaciskowych) oraz opisany wyżej procesor konfiguracyjny. Do magistrali przyłączony jest zestaw przewodów zakończonych wszystkimi rodzajami używanych wtyków (fotografia 3). Pozwala ono na konfigurację kolejnych modułów wchodzących w skład całego systemu oraz stanowi istotne wsparcie w trakcie tworzenia ich oprogramowania.
W kolejnej części zostanie opisany moduł sterowania oświetleniem.