Program sterujący
Cała magia emulatora czujnika temperatury DS1820 dzieje się w oprogramowaniu urządzenia. Jak wiemy, każda operacja mająca miejsce na magistrali 1-Wire inicjowana jest przez układ Master poprzez ściągnięcie tejże magistrali do logicznego „0” (przez czas 1…5 μs). W związku z tym naturalnym sposobem na obsłużenie protokołu ze strony układu Slave jest wykorzystanie przerwania zewnętrznego (np. INT0) skonfigurowanego w ten sposób aby zachodziło przy opadającym zboczu sygnału. Użycie przerwania zewnętrznego jest o tyle niezbędne, że magistrala 1-Wire wymusza dość rygorystyczne wymogi czasowe, więc zastosowanie typowego portu I/O i tzw. pollingu jest niewystarczająca w przypadku, gdyby układ Slave miał wykonywać jeszcze inne czasowo istotne operacje niezwiązane z obsługą magistrali. Wykorzystanie przerwania zewnętrznego niesie za sobą tą dodatkową zaletę, że cała obsługa protokołu zostanie zamknięta w ramach jednej funkcji ISR a program główny może realizować inną, niezbędną z punktu widzenia konkretnej aplikacji, funkcjonalność.
Zadeklarujmy, zatem kilka podstawowych zmiennych globalnych: numer seryjny naszego urządzenia Slave, scratchpad (pamięć termometru), zmienną przechowującą aktualny stan procedury obsługi układu Slave oraz zmienną odpowiedzialną za żądanie pomiaru temperatury. Jak wiemy, zmienne globalne to w dużym uproszczeniu zło (z przymrużeniem oka), gdyż utrudniają optymalizację kodu, lecz w przypadku styku na poziomie program główny/funkcje narzędziowe a funkcje obsługi przerwań systemowych są niezbędną koniecznością.
W związku z tym, że obsługa protokołu odbywa się w całości w ramach procedury obsługi przerwania INT0 (oraz jak się okaże, przerwania Timera0) funkcja główna naszego programu obsługi ogranicza się wyłącznie do konfiguracji niezbędnych peryferiów mikrokontrolera i wykonywania pomiaru temperatury na żądanie użytkownika. Jak widać, i o czym nie wspomniano wcześniej, w programie obsługi używany jest także timer sprzętowy (w tym przypadku 8-bitowy Timer0) jak i przerwanie od jego przepełnienia (TIMER0_OVF_vect). Użycie tego peryferium konieczne jest w przypadku, gdyby układ Master z jakiś powodów wysłał niepełną sekwencję sygnałów sterujących (np. tylko sygnał Reset bez jakichkolwiek dalszych komend) co spowodowałoby zmianę stanu procedury obsługi magistrali 1-Wire na predefiniowaną wcześniej wartość STATUS_WAITING_FOR_CMD i oczekiwanie na rozkaz sterujący uniemożliwiając tym samym dalsze, poprawne funkcjonowanie algorytmu obsługi. Timer ten każdorazowo ustawiany jest w taki sposób aby po upłynięciu zadanego czasu (zależnego od oczekiwanych operacji po stronie układu Master) przywrócić spoczynkowy stan procedury obsługi (STATUS_IDLE) w przypadku błędów po stronie układu nadrzędnego.
Przejdźmy zatem do właściwego programu obsługi układu Slave magistrali 1-Wire. Jak wspomniano wcześniej, stanem spoczynkowym układu Slave jest oczekiwanie na sygnał Reset a po jego wykryciu, wystawienie sygnału Presence i oczekiwanie na rozkaz sterujący. Tą część algorytmu programu obsługi pokazana na listingu (o wykonaniu poszczególnych części programu obsługi decyduje wartość zmiennej Status). Po wykonaniu tych czynności, układ Slave oczekuje (przez czas 2 ms) na odebranie komendy sterującej i w zależności od jej rodzaju realizuje pozostałe funkcje typowe dla emulowanego układu typu DS1820.