W coraz bardziej skomplikowanych układach sterowanych mikrokontrolerami konieczne stało się wytworzenie magistrali komunikacyjnej pomiędzy nimi a sterowanymi przez nie układami. Wychodząc na przeciw potrzebom firma Philips opracowała i opublikowała w roku 1981 specyfikacje takiej magistrali. Została ona nazwa I2C. Stosunkowo niewielka liczba zmian oraz dobre przyjęcie świadczy o dobrych założeniach i wykonaniu. Nowy sposób komunikacji zaadaptowano do wielu układów. W systemach mikroprocesorowych budowanych w oparciu o mikrokontrolery jednoukładowe bardzo często zachodzi potrzeba dołączenia układów peryferyjnych, które nie wymagają częstej komunikacji z CPU. Przykładami takich układów mogą być:
• pamięć EEPROM zawierająca nastawy początkowe urządzenia, współczynniki kalibracyjne przyrządu pomiarowego itp.,
• zegar czasu rzeczywistego,
• sterownik wyświetlacza LED lub LCD,
• kontroler klawiatury,
• specjalizowane układy analogowe o programowo zmienianych parametrach pracy np. syntezer częstotliwości, cyfrowo przestrajany filtr,
• wzmacniacz itp.
Rzadka wymiana informacji między mikrokontrolerem, a takimi układami pozwala na jej realizację za pomocą interfejsu szeregowego. Przesyłanie informacji przy użyciu interfejsu szeregowego następuje przy użyciu niewielkiej liczby linii sygnałowych (rys. 1). Jest też możliwy dostęp dwóch mikrokontrolerów do jednego zasobu urządzeń (rys. 2). Stosowanie interfejsu szeregowego ma, w porównaniu do interfejsu równoległego, szereg zalet:
• Jeśli wszystkie układy peryferyjne wykorzystujące interfejs równoległy zostaną zastąpione układami z interfejsem szeregowym, to wyprowadzenia mikrokontrolera służącego do komunikacji z obszarem zewnętrznej pamięci danych (linie portów P0 i P2, wyprowadzenia sygnałów WR i RD) mogą być wykorzystane do innych celów .
• Zmniejszenie liczby linii sygnałowych prowadzi do zredukowania liczby wyprowadzeń układów peryferyjnych, a w konsekwencji do zmniejszenia kosztu tych elementów (tańsze obudowy) i całego układu (mniejsza płytka).
• Upraszcza się istotnie projekt płytki drukowanej (prowadzone są tylko 2 - 3 linie sygnałowe zamiast kilkunastu), zwłaszcza w przypadku wielu układów wykorzystujących tę samą szynę interfejsu. Możliwe jest łatwe i tanie sprzęganie układów umieszczonych na różnych płytkach (typowym przykładem jest tu oddzielna płytka wyświetlacza) . Niski koszt wynika głównie ze stosowania małych złącz (pojedyncze linie sygnałowe) oraz braku buforów (przy małych prędkościach transmisji pojemności montażowe mają znikomy wpływ na pracę interfejsu).
• Właściwość wymieniona w punkcie poprzednim powoduje, że przy minimalnym nakładzie środków dodatkowych szyna może być wykorzystana do celów diagnostycznych, czyli do testowania i uruchamiania urządzenia.
Nie każdy interfejs szeregowy będzie jednak dobrze spełniał rolę wspólnej szyny służącej do sterowania wewnętrznych (w sensie urządzenia, a nie mikrokontrolera) układów peryferyjnych. Standardowe łącze szeregowe występujące w mikrokontrolerach rodziny 51 doskonale nadaje się np.: do realizacji komunikacji wieloprocesorowej ale nie ma ono mechanizmów, które pozwoliłyby na łatwe przystosowanie go do roli interfejsu w układach peryferyjnych nie posiadających wbudowanej inteligencji (w postaci mikrokontrolera). Rodzajem interfejsu szeregowego dobrze funkcjonującego w takich zastosowaniach jest natomiast szyna I2C.
Ogólne założenia interfejsu I2C
Szyna I2C posiada następujące cechy charakterystyczne :
• transmisja odbywa się za pomocą dwóch linii sygnałowych: SDA - linii danych i SCL - linii sygnału taktującego,
• możliwe jest przesyłanie informacji między wieloma urządzeniami wykorzystującymi wspólną szynę,
• transmisja danych jest dwukierunkowa (nadawanie i odbiór),
• każdy z układów dołączonych do szyny posiada niepowtarzalny (jedyny w całym systemie) adres, umożliwiający jednoznaczne zaadresowanie danego urządzenia do nadawania lub odbioru,
• przesyłaniem danych steruje układ nadrzędny, przy czym w systemie może występować więcej niż jeden układ nadrzędny,
• w przypadku jednoczesnego rozpoczęcia nadawania przez kilka urządzeń nadrzędnych, mechanizm arbitrażu nie dopuszcza do utraty, ani przekłamania przesyłanych danych,
• synchronizacja transmisji za pomocą sygnału taktującego umożliwia komunikację między urządzeniami stosującymi różne prędkości przesyłania danych,
• maksymalna prędkość transmisji danych po szynie I2C wynosi 100 kbodów w standardowym trybie pracy szyny i 400 kbodów w trybie szybkim,
• wszystkie układy posiadające interfejs I2C wyposażone są w układy filtracji zakłóceń (w postaci szpilek napięciowych mogących występować na liniach SDA i SCL), istotnie podwyższające niezawodność pracy interfejsu,
• liczba układów podłączonych do szyny ograniczona jest wyłącznie maksymalną pojemnością szyny równą 400 pF.
Łatwa i tania implementacja interfejsu I2C w układach peryferyjnych jest możliwa dzięki jednej z podstawowych cech szyny I2C, a mianowicie podziału urządzeń dołączonych do szyny na nadrzędne i podrzędne. Urządzenie nadrzędne jest układem inicjalizującym transmisję po szynie, generującym sygnał taktujący , adresującym urządzenia podrzędne, określającym rodzaj transmisji (nadawanie odbiór danych) itp. Urządzenie podrzędne musi zaś jedynie stwierdzić, czy zostało ono zaadresowane (porównać adres przesłany po szynie z własnym adresem urządzenia) oraz, w takt sygnału generowanego przez urządzenie nadrzędne, wysłać lub odebrać dane. Dzięki takiemu rozwiązaniu inteligencję musi posiadać jedynie urządzenie nadrzędne (rolę tę pełni zwykle mikrokontroler), podczas gdy interfejs urządzenia podrzędnego może być zrealizowany jako prosty automat o niewielkiej liczbie stanów. Z punktu widzenia konstruktora, interfejs I2C posiada wiele zalet wynikających bezpośrednio ze sposobu funkcjonowania szyny. Najistotniejszą z nich jest chyba to, że te same układy wyposażone w interfejs I2C mogą być wykorzystywane w wielu różnych urządzeniach, a ich sterowanie zawsze będzie identyczne. Dzięki temu raz utworzone moduły biblioteczne mogą być wykorzystywane wielokrotnie, skracając poważnie czas opracowywania nowych konstrukcji. Ułatwione jest też opracowywanie wariantów tego samego urządzenia, ponieważ w wielu przypadkach będzie się ono sprowadzało do usunięcia, zamiany lub dołączenia nowego układu do istniejącej już szyny.
Przesyłanie informacji po szynie I2C
Liniami sygnałowymi interfejsu I2C są linie SDA i SCL (rys. 1 i 2). Są to linie dwukierunkowe podłączone do dodatniego napięcia zasilania za pośrednictwem rezystorów podciągających. (Rys 3) Jeśli szyna jest zwolniona (brak transmisji), obie linie znajdują się w stanie wysokim. Wszystkie układy podłączone do szyny muszą mieć stopnie końcowe (linii SDA i SCL) typu otwarty kolektor lub otwarty dren - umożliwia to realizację funkcji AND typu wspólny kolektor (wspólny dren), wykorzystywanej m-in. przez mechanizm arbitrażu szyny. Ze względu na możliwość dołączania do szyny układów wykonanych w różnych technologiach (CMOS, NMOS, układy bipolarne) przedziały napięć odpowiadające poziomom logicznego zera (stan niski) i jedynki (stan wysoki) nie muszą być sztywno ustalone i mogą zależeć od wartości napięcia zasilania. do którego dołączone są rezystory podciągające linii SDA i SCL. Podczas transmisji danych, impulsy taktujące na szynie SCL wysyłane są w ilości jeden impuls na każdy bit przesyłanych danych. Podczas wysokiego stanu na linii SCL stan linii SDA musi być stabilny - stan tej linii może ulegać zmianie tylko podczas niskiego stanu linii SCL. (rys 4) Wyjątkiem od tej reguły są sygnały START i STOP wysyłane przez urządzenie nadrzędne (rys. 5). Wysłanie sygnału START polega na wymuszeniu opadającego zbocza na linii SDA podczas trwania wysokiego stanu na linii SCL. Sygnał START służy do identyfikacji początku transmisji. Po pojawieniu się tego sygnału szyna uważana jest za zajętą aż do momentu wystąpienia sygnału STOP , identyfikującego koniec transmisji. W rzeczywistości szyna uważana jest za zwolnioną dopiero po pewnym czasie od wykrycia sygnału STOP, czyli po stwierdzeniu pojawienia się narastającego zbocza na linii SDA przy wysokim stanie linii SCL. Pełny algorytm przesłania bitu danych dla standardowego trybu pracy zawiera rys 6. Każdy bajt danych przesyłanych po szynie I2C musi składać się z 8 bitów, przy czym dane nadawane są począwszy od bitu najbardziej znaczącego (rys. 7). Liczba bajtów danych przesyłanych w ramach danej transmisji nie jest ograniczona. Każda operacja przesłania bajtu danych powinna zakończyć się bitem potwierdzenia (rys. 8). Impuls taktujący związany z bitem potwierdzenia jest generowany przez urządzenie nadrzędne. Urządzenie nadające dane musi na czas bitu potwierdzenia zwolnić linię SDA (umożliwić jej przyjęcie stanu wysokiego), zaś urządzenie odbierające na czas trwania wysokiego stanu na linii SCL (oczywiście z uwzględnieniem stanów przejściowych) winno wymusić stan niski na linii SDA. Jeśli zaadresowane urządzenie podrzędne nie jest w stanie potwierdzić swojego adresu, musi pozostawić ono linię SDA w stanie wysokim. Wówczas urządzenie nadrzędne może wysłać sygnał STOP i tym samym przerwać transmisję. Analogiczna sytuacja ma miejsce, gdy urządzenie podrzędne potwierdzi swój adres, ale nie jest w stanie odebrać jednego z następnych bajtów danych i chce wymusić przerwanie transmisji ze strony urządzenia nadrzędnego. Urządzenie podrzędne powinno wówczas wysłać sygnał braku potwierdzenia (czyli po prostu pozostawić linię SDA w stanie wysokim na czas trwania bitu potwierdzenia). W odpowiedzi urządzenie nadrzędne wyśle sygnał STOP i zakończy transmisję danych. Jeśli dane są odbierane przez urządzenie nadrzędne, to wysłanie przez to urządzenie bitu braku potwierdzenia jest informacją dla urządzenia podrzędnego (nadającego dane), że zakończono właśnie transmisję ostatniego bajtu danych. Urządzenie podrzędne musi w takim przypadku zwolnić linię danych (SDA), by umożliwić urządzeniu nadrzędnemu wysłanie sygnału STOP. Jeśli urządzenie odbierające dane nie może z pewnych względów rozpocząć odbioru następnego bajtu, to może ono przeciągnąć niski stan na linii SCL i wymusić w ten sposób na urządzeniu nadającym przejście w stan oczekiwania. Transmisja danych będzie w takim przypadku kontynuowana po zwolnieniu linii SCL przez urządzenie odbierające dane.
Sterowniki interfejsu I2C w mikrokontrolerach rodziny 51
W obecnie produkowanych mikrokontrolerach rodziny 51 spotyka się trzy odmiany sterowników interfejsu I2C. Najczęściej spotykany jest układ, jaki pierwotnie zastosowano w mikrokontrolerze C552. Sterownik ten stosowany jest też (czasem z nieznacznymi modyfikacjami) w innych mikrokontrolerach - CL410, CE558, CE559, CL580, C652, C654, CL781, CL782 itp. Omawiany interfejs obsługuje transmisję pełnych bajtów danych. Inny rodzaj sterownika interfejsu I2C - umożliwiający sterowanie transmisją na poziomie bitowym - można znaleźć w mikrokontrolerach C524 i C528. Bitowy interfejs I2C (innego typu) występuje też w mikrokontrolerach C751 i C752. Wszystkie układy interfejsu I2C występujące w mikrokontrolerach rodziny 51 mogą pracować zarówno w trybie urządzeń nadrzędnych, jak i podrzędnych. Mikrokontrolerami rodziny 51 wyposażonymi w interfejs I2C umożliwiający pracę w trybie szybkim są układy CE558 i CE559. Niektóre z pozostałych układów teoretycznie pozwalają również na uzyskiwanie prędkości transmisji powyżej 100 kbodów , jednakże producent gwarantuje ich poprawną pracę jedynie w zakresie standardowych prędkości transmisji (do 100 kbodów).