magistrala Inter-Integrated Circuit (I2C) jest mechanizmem komunikacji szeregowej na poziomie układów scalonych, który działa tylko na dwóch przewodach. Niektórzy programiści wymawiają nazwę autobusu eye-two-see, inni eye-squared-see, ale obaj odnoszą się do tego samego. Opracowany przez Philips na początku 1980 roku, I2C został ustanowiony w celu standaryzacji komunikacji między chipami firmy, ale od tego czasu stał się de facto standardem obsługiwanym przez wiele urządzeń mikrokontrolerów z płyt Arduino do Raspberry Pi i, oczywiście, imps.,

fizyczna Szyna

I2C składa się z dwóch przewodów. Jedna linia I2C przesyła dane, druga sygnały zegarowe, które synchronizują rozmowę między urządzeniami. Linia danych nazywa się „SDA”, linia zegara „SCL”.

zazwyczaj zarówno SDA, jak i SCL są podłączane do linii zasilającej 3,3 lub 5 V przez pojedynczy rezystor „pull-up”, po jednym na każdej linii. Jest to konieczne, ponieważ połączenia SDA i SCL urządzeń są liniami „open drain”: mogą wymusić napięcie na linii do 0V lub „low”, ale nie mogą podnieść go do 3,3 V lub „high”., Wysokie i niskie to elektryczne reprezentacje 1s i 0s, które są podstawowymi składnikami informacji cyfrowej. Dodanie tych dwóch rezystorów — a magistrala potrzebuje tylko dwóch, bez względu na to, ile urządzeń jest do niej podłączonych-zapewnia wzrost napięcia z powrotem do 3,3 V bez zwarcia.

urządzenia I2C mają otwarte przewody spustowe, aby zapewnić, że wysokie prądy nie będą mogły płynąć, gdy dwa urządzenia spróbują jednocześnie sygnalizować.

w większości przypadków należy się spodziewać samodzielnego dodania tych rezystorów, ale niektóre urządzenia, zazwyczaj te, które działają na 3.,3V, dołącz je, aby były kompatybilne z urządzeniami zasilającymi 5V. pamiętaj, że potrzebujesz tylko pary rezystorów pull-up na magistralę, więc może być konieczne wyjęcie rezystorów pull-up dołączonych do innych urządzeń na magistrali. Chociaż imp ma wewnętrzne Rezystory pull-up własnych, są one zbyt słabe, aby być przydatne dla I2C i tak są one automatycznie wyłączone, gdy jego piny są ustawione do obsługi sygnałów I2C.

kontrolery i urządzenia peryferyjne

magistrala I2C dzieli urządzenia na 'kontrolery' i 'urządzenia peryferyjne'., Tylko jedno urządzenie może wysyłać impulsy czasowe na linii SCL na raz, a to jest ten wybrany jako kontroler. Wszystkie pozostałe synchronizują swoje timingi ze sterownikiem i dlatego są uważane za Urządzenia peryferyjne. Kontroler-zazwyczaj imp – i jego urządzenia peryferyjne mogą Wszystkie transmitować i odbierać dane, ale tylko kontroler może powiedzieć obwodowi, kiedy przesyłać dane z powrotem.

adresowanie

aby jedno urządzenie I2C mogło komunikować się z drugim na zasadzie jeden do jednego, oba urządzenia muszą być jednoznacznie zidentyfikowane. Ta tożsamość to adres I2C urządzenia., Adresy I2C są zwykle numerami 7-bitowymi, więc szyna może zawierać maksymalnie 127 urządzeń. Bajt składa się z ośmiu bitów; dodatkowy bit jest używany do wskazania, czy sygnał jest wysyłany przez kontroler do obwodów – „zapisu” — czy w przeciwnym kierunku — „odczytu”. Ten ósmy bit jest w rzeczywistości bitem zerowym w bajcie adresu wysłanym do magistrali. Adres 7-bitowy jest umieszczany w bitach od jednego do siedmiu bajtu adresu.

zgodnie z tym formatem, imp API przyjmuje adresy I2C jako wartość 8-bitową., Dostawcy urządzeń zazwyczaj podają adresy swoich produktów jako numer 7-bitowy, dlatego konieczna jest konwersja adresu z siedmiu bitów na osiem. Jest to operator <<, który przesuwa poszczególne wartości bitowe liczby w lewo. Proces ten jest równoznaczny z mnożeniem przez dwa. W kodzie proces ten wygląda tak:

local sevenBitAddress = 0x39;local eightBitAddress = sevenBitAddress << 1;

Squirrel automatycznie ustawia bit zero na poprawną wartość zdefiniowaną przez I2C: 0 dla operacji zapisu, 1 dla odczytu., Teraz you 're ready to use one of the imp' s I2C methods to write data to the bus:

i2c.write(eightBitAddress, dataInStringForm);

7-bitowy adres urządzenia, do którego chcesz, aby twój imp komunikował się z zostanie dostarczony przez producenta komponentu i wymieniony w arkuszu danych urządzenia. Może nie być stały, ale wybierany z zakresu adresów zgodnie z napięciem przyłożonym do innego pinu urządzenia., Na przykład czujnik światła TAOS TSL2561 ma trzy możliwe adresy: 0x29, 0x49 lub 0x39, w zależności od tego, czy jego pin ADDR jest ustawiony na 0V, 3.3 V lub „pływający” między nimi. Mówimy, że wartość jest zmienna, ponieważ nie została aktywnie wybrana do pracy pod określonym napięciem; może to być cokolwiek od 0 do 3,3 V włącznie.

kontroler magistrali I2C wykorzystuje 7-bitowy adres urządzenia peryferyjnego do identyfikacji komponentu, z którym chce rozmawiać., W rzeczywistości, sygnalizacja jest bardziej skomplikowane niż, ale na szczęście wszystkie szczegóły są obsługiwane przez imp tak, że trzeba tylko dostarczyć adres jako 8-bitowa wartość.

Jeśli piszesz do urządzenia peryferyjnego, musisz również podać dane do zapisu, które często zawierają wartości rejestru, które instruują Urządzenie peryferyjne, co ma zrobić z danymi. Dokumentacja imp API odnosi się do tych rejestrów jako 'pod-adresy':

i2c.write(eightBitAddress, dataString);

write() wymaga danych w postaci ciągu znaków. W związku z tym może być konieczna Konwersja wartości przechowywanej w innych typach zmiennych do postaci łańcuchowej.,

Odczyt informacji z urządzenia może wymagać polecenia, aby powiedzieć urządzeniu, które dane należy pobrać. Informowanie imp do odczytu danych z magistrali I2C wymaga również dostarczenia trzeciego parametru, liczby bajtów, których oczekujesz:

i2c.read(eightBitAddress, controlDataString, numberOfBytesToRead);

za tymi operacjami są sygnały elektryczne I2C, stosowane do linii SDA zsynchronizowane z impulsami czasowymi zastosowanymi do linii SCL. Zapis do magistrali wymaga znacznika startu: spadek SDA do 0V, podczas gdy SCL wynosi 3,3 V. zmiana napięcia SDA, gdy napięcie SCL jest wysokie, definiuje znaczniki startu i zatrzymania., Jeśli napięcie SDA nie zmieni się, gdy SCL jest wysoki, urządzenia I2C wiedzą, że dane, a nie znaczniki, są wysyłane.

SDA teraz idzie w górę lub w dół, aby wysłać każdy bit bajtu adresu: 7-bitowy adres urządzenia, a następnie bit odczytu / zapisu. Bity bajtu są wysyłane z lewej-najbardziej bit — „najbardziej znaczący bit” — pierwszy, z SDA będzie wysoki, jeśli wartość bitu wynosi 1 lub niski, jeśli jest zero. Docelowy peryferyjny będzie teraz wyciągał SDA low, aby sygnalizować potwierdzenie odbioru danych, a następnie wychodzi osiem bitów informacji sterujących lub danych, a następnie więcej danych, jeśli to konieczne., Na SDA pomiędzy każdym wysłanym ośmioma bitami występuje pauza potwierdzająca „ack”, czasowana na dziewiąty impuls SCL. Jeśli urządzenie peryferyjne nie potwierdzi odbioru w ten sposób, kontroler wykryje, że SDA pozostał wysoki i zasygnalizuje błąd.,

gdy dane przepływają z urządzenia peryferyjnego do kontrolera, ten ostatni również uznaje odbiór ośmiu bitów, ciągnąc SDA low na dziewiątym impulsie SCL, chyba że jest to ostatni bajt partii, w którym to przypadku kontroler nie ciągnie SDA low — wytwarza sygnał ” nak ” lub „no acknowledgement” — w celu poinformowania peryferyjnego o zakończeniu.

kiedy skończymy, SDA idzie wysoko jako znacznik stopu.,


początek transmisji jest sygnalizowany spadkiem SDA z Wysokiego na niskie napięcie (prostokąt po lewej),
stop przez odwrotną (prostokąt po prawej). SCL musi być wysoki, gdy ma to miejsce

Timing

standardowa Prędkość zegara dla komunikacji I2C wynosi 100KHz — 100 000 impulsów SCL na sekundę. Jest to możliwe, aby przejść szybciej, do 400kHz. Niektóre urządzenia mogą nie być w stanie obsługiwać tę prędkość; sprawdź Arkusz danych, który towarzyszy urządzeniu, które chcesz podłączyć do imp., Jednak wiele powolnych urządzeń używa techniki zwanej „rozciąganiem Zegara”, aby zmusić szybsze urządzenia do pracy z ich prędkością. Imp obsługuje urządzenia, które wykorzystują tę technikę. Zasadniczo, trzymają SCL nisko, podczas gdy są one pobieranie danych, które chcesz je wysłać do imp. Imp wykrywa to, uwalnia linię SCL i czeka, aż SCL ponownie wzrośnie przed kontynuowaniem.

jednak może być konieczne obniżenie prędkości I2C samodzielnie, jeśli charakterystyka elektryczna Twojej konfiguracji spowalnia prędkość przejścia między 0V a 3,3 V, zwany „czasem narastania”., Często jest to spowodowane długimi przewodami, które zwiększają pojemność obwodu. Aby urządzenia z powodzeniem wykryły transmisję każdego bitu, magistrala musi działać wolniej. Uszkodzenie danych lub nieoczekiwane wyniki To wskazówki, na które powinieneś zwrócić uwagę. Zmniejsz prędkość magistrali I2C do momentu pomyślnego odczytu danych.

imp API obecnie dostarcza cztery predefiniowane wartości zegara: 10, 50 100 i 400kHz., Są one wybierane przez przekazanie stałej do metody konfiguracji I2C jako parametru:

i2c.configure(speedConstant);

gdzie wartość speedConstant jest jedną z

  • CLOCK_SPEED_10_KHZ
  • CLOCK_SPEED_50_KHz
  • CLOCK_SPEED_100_KHZ
  • clock_speed_400_khz

konfigurowanie IMP dla I2C

obiekt I2C w przykładowych liniach kodu podanych powyżej nie jest dostarczany bezpośrednio przez Imp, ale wybrany przez Ciebie zgodnie z którym z wybranych przez Ciebie pinów IMP będziesz używać do komunikacji I2C., Każdy typ imp ma wiele autobusów I2C, wszystkie udostępnione przy starcie. Check out the pin mux for the type of imp you are using to see which I2C objects are available to you. Zakładamy, że używasz imp001. Imp001 w dwa I2C autobusy są na piny 1 i 2, i piny 8 i 9, odpowiednio instance jako właściwości i2c12 i i2c89 hardware object gdy imp uruchamia się. Piny 1 i 8 są przypisane do SCL, 2 i 9 do SDA.,

powszechne jest odwoływanie się do wyboru za pomocą zmiennej globalnej:

i2c <- hardware.i2c12;i2c.configure(CLOCK_SPEED_100_KHZ);

przykładowy kod

poniższy kod działa z czujnikiem światła widzialnego i podczerwieni Taos TSL2561, urządzeniem 3,3 V, które wykorzystuje I2C do komunikacji z mikrokontrolerem hosta. Kartę danych Chipa można pobrać ze strony internetowej Adafruit. Adafruit sprzedaje chip na niedrogiej płycie breakout, która zawiera odpowiednie Rezystory pull-up na pinu zasilania, VCC. Oznacza to, że jest gotowy do podłączenia bezpośrednio do szpilek I2C imp.,


Adafruit ' s TSL2561 breakout board

Uwaga Po napisaniu tego artykułu Adafruit zaktualizował swoją płytę czujnika TSL2561. Nowa wersja działa z bieżącym kodem.

oto kod, dla agenta, a następnie urządzenia:

co robi Kod

kod agenta odpowiada na przychodzące żądanie HTTP, powiadamiając urządzenie, że wymaga odczytu. Dla uproszczenia odczyt jest po prostu wyświetlany w dzienniku.

Kod urządzenia odczytuje czujnik i oblicza wartość lux zgodnie z math ustawioną w arkuszu danych TSL2561., Pierwsza część programu ustawia stałe dla rejestrów i ustawień klucza TSL2561, w tym Opcje adresów I2C. Inne stałe są używane w procesie konwersji jasności.


okablowanie imp

w punkcie startowym programu, kod aliasuje jeden z Imp ' s I2C pin ustawiony jako zmienna globalna, konfiguruje prędkość magistrali do 100KHz, a następnie przesuwa adres I2C TSL2561 jeden bit w lewo, więc jest gotowy do użycia z funkcjami imp I2C. Następnie ustawia czujnik., Aby sprawdzić, czy to działa, odczytujemy rejestr kontrolny: wartość zwracana powinna wynosić 3, Jeśli TSL2561 właśnie się uruchomił, lub 51, jeśli urządzenie jest już włączone.

następnie kod ustawia rozdzielczość ADC czujnika przez rejestr czasu TSL2561, a następnie ustawia wzmocnienie sygnału na wysoki.

na koniec informujemy imp, jak reagować na"sense" powiadomienia od agenta. Wywołuje to funkcję, która odczytuje dwa czujniki światła TSL2561, których wartości cyfrowe są przechowywane w czterech 8-bitowych rejestrach ADC układu., Dwie pierwsze dają 16-bitowy połączony odczyt optyczny i podczerwieni, druga para 16-bitową wartość tylko IR. Funkcje readSensorAdc0 () i readSensorAdc1() zamieniają poszczególne wartości rejestru na liczby 16-bitowe przez pomnożenie najbardziej znaczącego bajtu przez 256 i dodanie wartości najmniej znaczącego bajtu. Mnożenie odbywa się poprzez przesunięcie bitów ośmiobitowej liczby o osiem miejsc z operatorem <<.,

kod przekazuje oba te odczyty trzeciej funkcji, aby obliczyć ostateczną jasność, wartość „lux”.

Czytaj dalej

  • błędy I2C — jak debugować problemy z odczytem i zapisem I2C

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *