Spis treści

 

Ad. 5
Kwestie techniczne już zostały przedstawione, pora zbudować układ elektroniczny, który tym wszystkim będzie zarządzał. Elektronika powstawała na płytce prototypowej równocześnie z rozwojem całego układu. Nie wyglądało to w ten sposób, że najpierw narysowałem schemat i później zacząłem go realizować w praktyce. Było dokładnie odwrotnie - najpierw krok po kroku łączyłem elementy na płytce stykowej a dopiero na samym końcu narysowałem schemat. Na potrzeby tego opracowania najpierw przedstawię Państwu schemat a następnie po kolei opiszę poszczególne jego elementy odnosząc niego (zdjęcie nr 20). Całość programu sterującego napisana została w środowisku Bascom.

Pierwsza kwestia to mikrokontroler - w prezentowanym układzie zastosowałem model ATmega16 firmy Atmel, choć i ten duży układ ma zbyt małą liczbę pinów do obsługi wszystkich elementów układu. Zastosowałem więc dodatkowy układ rozszerzający jego możliwości o nowe piny, który będzie sterował pracą diod LED w panelu sterującym. Układ ten to PCF 8574 jest to sterowany magistralą I2C 8-pinowy port.

Za jego pomocą możemy sterować niezależnie stanem każdego z pinów lub odczytywać ich stan. W układzie wykorzystałem go w funkcji sterowania podłączonymi do niego diodami LED. W ten sposób zajmujący tylko dwa piny mikrokontrolera na magistralę I2C zyskałem 6 dodatkowych pinów wyjściowych co rozwiązało problem braku wyjść mikrokontrolera. Sterowanie diodami podłączonymi do tego ekspandera jest również bardzo proste. Wystarczy w pętli głównej programu umieścić instrukcję wysyłającą bajt rejestru stanu diod - zwykłą zmienną, którą zadeklarujemy w programie:
I2csend &H40 , Diody - instrukcja odświerzająca stan diod LED.

Zmienna ta w każdym nowym cyklu będzie wysyłana do expandera bez względu na to czy zmieni się czy nie. Następnie, by w prosty sposób umożliwić sobie umieszczanie poleceń włączenia lub wyłączenia konkretnej diody w różnych miejscach programu można nazwać poszczególne bity zmiennej i używać w programie już tych przyjaznych nazw:

Dstop Alias Diody.0
Dtimer Alias Diody.1
Dtransmisja Alias Diody.2
Dprzeplywba Alias Diody.3
Dprzeplywab Alias Diody.4
Drejestrator Alias Diody.5
Dpomiar Alias Diody.6
Dpompa Alias Diody.7
Config Pina.7 = Output
Set Porta.7
Dstart Alias Porta.7


Dziewiąta dioda zastosowana w panelu będzie sterowana już bezpośrednio z portu mikrokontrolera.
Następny element układu elektronicznego, który zastosowałem to pamięć trwała. Pomiary ilości i przepływu gazu w badaniach biochemicznych czy innych podobnych zazwyczaj trwają dość długo, nawet kilka miesięcy. By możliwe było zobrazowanie produkcji gazu podczas całego badania, trzeba by mieć cały czas włączony komputer i na bieżąco odbierać dane. Postanowiłem więc wbudować w układ pamięć i zbudować rejestrator, który gromadził by dane a dopiero po skończonym badaniu można by je szybko przesłać przez port RS-232.


Fot. 20 Schemat ideowy płyty głównej miernika gazu (kliknij na zdjęcie by powiększyć).

Ponadto podczas tak długich badań należy się liczyć z możliwością jakiejś awarii bądź zaniku prądu, postanowiłem więc wykorzystać tę pamięć do podtrzymania informacji o sumarycznej ilości wyprodukowanego gazu. Po każdym włączeniu urządzenia algorytm najpierw odczytuje wartość zmiennej odpowiadającej za objętość a później inkrementuje ją i każdą zmienioną wartość cały czas zapisuje tak, by w razie nagłego wyłączenia jej nie stracić.

Zastanawiałem się jaką pamięć zastosować w układzie, na początku myślałem o trwałych pamięciach EEPROM, ale niestety mają ograniczoną liczbę zapisów a w moim układzie pamięć będzie zapisywana nawet kilkanaście razy na sekundę. Musiałem więc skorzystać z pamięci typu RAM, którą można zapisywać praktycznie w nieskończoność. Niestety po zaniku zasilania dane uległy by skasowaniu więc musiałem zapewnić takiej pamięci podtrzymanie bateryjne. Mój wybór padł na układ firmy Microchip o symbolu 23K256, jest to bardzo ciekawa pamięć RAM o pojemności 256 KB, którą w bardzo prosty sposób można zapisywać i odczytywać poprzez magistralę SPI.

Wada jej jest taka, że jej napięcie zasilania wynosi 3,6 V i do sterowania należy również wykorzystać takie poziomy napięć. Problem ten w prosty sposób rozwiązałem stosując dzielniki napięcia na wejściach SCK, MOSI i CS oraz konwerter napięcia zbudowany z tranzystora T1 i rezystora R6 na wyjściu MISO. Teraz czas na baterię, która podtrzyma zasilanie pamięci w momencie zaniku zasilania urządzenia. Zastosowałem baterię G1 o napięciu 3,6 V, którą zasiliłem przez dwie diody D1 i D2 ze źródła układu 5 V, spadki napięć na diodach obniżyły napięcie zasilania do 3,6 V a rezystor R2 ograniczał prąd ładowania baterii podczas normalnej pracy urządzenia. Ponadto diody zabezpieczały baterię przed wypływem prądu w kierunku zasilania po zaniku napięcia. Baterię połączyłem z układem pamięci RAM na płytce testowej a sam układ z mikrokontrolerem i rozpocząłem próby zapisów i odczytów. Zdęcie 21 przedstawia pomiar napięcia podczas pracy z sieci.

Fot. 21 Pomiar napięcia baterii w trakcie pracy z sieci.

Samej procedury i konfiguracji interfejsu SPI nie będę opisywał bo informacji na ten temat jest mnóstwo. Co natomiast zrobić by móc coś zapisać i odczytać z tej pamięci ?. Z pomocą przychodzi nam oczywiście karta katalogowa.

Fot. 22 Sekwencje na liniach sygnałowych podczas zapisu i odczytu pamięci.

Na zdjęciu nr 22 widzimy sekwencje na wszystkich 4 liniach sygnałowych łączących mikrokontroler z pamięcią. Pierwsza linia CS, którą obsługujemy bezpośrednio w mikrokontrolerze informuje pamięć, że mamy zamiar wykonać jakąś operację. Każda operacja na pamięci 23k256 musi się odbywać przy niskim stanie lini CS. Po ustawieniu linii w stan niski wysyłamy z mikrokontrolera poprzez interfejs SPI pierwszy bajt - jest to bajt instrukcji różny dla każdej czynności, którą mamy zamiar wykonać. Kolejne zdjęcie nr 23 przedstawia wartości tego bajtu dla możliwych czynności.

Fot. 23 Opis pierwszego bajtu instrukcji, jaki należy wysłąć do pamięci.

Oczywiście ten bajt może mieć jeszcze inne wartości dla różnych trybów pracy, ale tego nie będę opisywał w tym opracowaniu. Zainteresowanych odsyłam do karty katalogowej. Następne informacje jakie wysyłamy to dwa bajty adresu pod który mamy zamiar coś zapisać lub odczytać i wreszcie bajt zmiennej do zapisu lub odczytu. Teraz przedstawię fragmenty kodu, dzięki którym wreszcie będziemy mogli przeprowadzić na pamięci jakieś operacje. Po pierwsze wpisujemy informacje konfiguracyjne interfejsu SPI:

Config Pina.1 = Output
Set Porta.1
Cs Alias Porta.1
Config Spi = Hard , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Noss = 1
Spiinit


Następnie tworzymy zmienne zapis i odczyt (wcześniej je deklarując) i wpisujemy im wartości instrukcji odczytu i zapisu by się nie myliły i by łatwo można je było stosować:

Zapis = 2 Odczyt = 3

Teraz deklarujemy zmienną typu Word o nazwie adres i dzielimy ją na dwie zmienne typu byte bo niestety przez SPI możemy w jednej porcji przesłać tylko jeden bajt a adres jest dwubajtowy:

Dim Adres As Word
Dim Adresa As Byte At Adres Overlay
Dim Adresb As Byte At Adres + 1 Overlay


Sekwencja zapisu zmiennej bajtowej Test pod adresem 0 będzie wyglądała następująco:

Adres = 0
Cs = 1
Cs = 0
Spiout Zapis , 1
Spiout Adresa , 1
Spiout Adresb , 1
Spiout Test , 1
Cs = 1


Analogicznie jeśli tę zmienną chcemy odczytać spod adresu 0:

Adres = 0
Cs = 1
Cs = 0
Spiout Odczyt , 1
Spiout Adresa , 1
Spiout Adresb , 1
Spiin Test , 1
Cs = 1


W ten sposób do zmiennej test zaczytamy wartość zapisaną w pamięci pod adresem 0.