Trochę teorii o I2C
Interfejs I2C został opracowany przez firmę Philips. Głównym zastosowaniem tego interfejsu jest komunikacja z różnymi czujnikami, układami pamięci, zegarami czasu rzeczywistego, cyfrowymi przełącznikami, wyświetlaczami LCD, itp. W I2C urządzenia posiadają swój unikalny adres ustawiany przez producenta, lecz przeważnie dla projektanta systemu wyprowadzonych jest kilka pinów, umożliwiających konfigurowanie adresu na wypadek, gdyby urządzenia posiadały identyczny adres. Maksymalna prędkość transmisji danych dochodzi do 3,4 Mb/s w trybie szybkim, jednakże przeważnie wynosi 100 kb/s.
Połącznie interfejsu I2C realizowane jest przez dwie linie sygnałowe: SDA odpowiadająca za przesyłanie danych, a SCL odpowiadająca za taktowanie zegarowe. Obydwie linie mają charakter otwartego kolektora, dlatego w celu poprawnej komunikacji, należy połączyć je z napięciem zasilania rezystorami (R1 i R2) o wartościach w celu osiągnięcia na liniach odpowiedniego poziomu napięcia. Do magistrali można teoretycznie podłączyć nieograniczoną liczbę urządzeń, jednakże należy pamiętać, że pasożytnicza sumaryczna pojemność nie może zostać przekroczona, w przeciwnym razie nie będzie możliwe korzystanie z maksymalnej szybkości wymiany informacji. Układy mają możliwość działania w jednym z dwóch trybów mistrz, bądź niewolnik. Mistrz i niewolnik w ogólnie przyjętej nomenklaturze związanej z interfejsami komunikacyjnymi noszą nazwy master i slave, dlatego w dalszej części wpisu będę posługiwał się tymi wyrazami. Układy typu master przejmują kontrolę nad magistralą, zarządzając transmisją danych, czyli inicjalizują połączenie, kończą je oraz ustalają taktowanie. Układy typu slave są wybierane przez mastera. Warto zaznaczyć, że do magistrali I2C można dołączyć kilka układów typu master oraz slave. W czasie wymiany informacji tylko jeden układ master jest aktywny, lecz w przypadku, kiedy w tym samym czasie oba takie układy rozpoczną nadawanie, dostęp rozstrzygany jest na zasadzie arbitrażu. Typowe połączenie urządzeń z interfejsem I2C przedstawiłem na poniższym rysunku.
Transmisja danych jest inicjalizowana przez urządzenie pracujące w trybie master. Sekwencja rozpoczęcia komunikacji polega na zmianie stanu linii SDA z wysokiego na niski w momencie, kiedy linia SCL jest ustawiona w stan wysoki. Zakończenie transmisji działa na podobnej zasadzie. Linia SCL musi być ustawiona w stan wysoki, lecz stan linii SDA jest zmieniany z niskiego na wysoki. Logiczna “1” występuje w przypadku kiedy linia SDA ma stan wysoki, a linia SCL w tym czasie zmieni swój stan z niskiego na wysoki oraz z wysokiego na niski. Logiczne “0” występuje w przypadku kiedy linia SDA ma stan niski, a linia SCL w tym czasie zmieni swój stan z niskiego na wysoki oraz z wysokiego na niski. Opisane stany przedstawiłem graficznie na poniższym rysunku.
Długość ramki danych wynosi 8 bitów. Po odebraniu bajtu układ odbiornika wysyła potwierdzenie (ACK). Transmisja danych nie musi zakończyć się po wysłaniu jednego bajtu, lecz może być cały czas kontynuowana, aż do momentu zakończenia transmisji przez układ master. Podczas wymiany informacji transmisja może zostać wstrzymana, poprzez ustawienie linii SCL w stan niski. Ponowne wznowienie komunikacji polega na wznowieniu sygnału zegarowego. Tak jak wspomniano wcześniej, urządzenia posiadają swój własny adres, który jest generowany na linii SDA tuż po pojawianiu się sygnału rozpoczęcia transmisji. Adresy urządzeń interfejsu I2C składają się z 7 bitów. Po nadaniu adresu, ósmym bitem jest informacja, czy układ slave ma odbierać (stan niski linii SDA), czy nadawać (stan wysoki linii SDA). Typowe ramki danych interfejsu I2C zamieściłem poniżej.