[015] Magistrala I2C

[015] Magistrala I2C

Zamiast całej rozprawki, którą można by z pewnością napisać na temat magistral, ogólne informacje sprowadzę do jednego zdania: magistrale to połączenia między różnymi blokami urządzenia bądź różnymi urządzeniami, którymi przepływają informacje, czyli dane.


No i tyle wystarczy, gdyż informacji na ten temat w sieci można znaleźć tak dużo, że musiałbym się tylko powtarzać. Magistrale mogą być bardzo różne, powstawały od początku czasów elektroniki i powstają nadal. Jedną z najczęściej stosowanych obecnie jest magistrala o nazwie I2C. Cóż to za dziwna nazwa? Nie ma się co dziwić, trzeba się przyzwyczaić, dziwnych nazw w elektronice spotyka się sporo. To jedna z wielu magistral szeregowych średniej szybkości, początkowo mająca w założeniach zastąpić połączenia równoległe między podzespołami, a więc uprościć przede wszystkim okablowanie wewnątrz urządzeń. Początki sięgają jeszcze lat osiemdziesiątych, a twórcą założeń był Philips. Obecnie standard przeszedł kilka modyfikacji i stanowi jedną z najbardziej popularnych magistral.

Specyfikację łatwo znaleźć w wielu miejscach, więc tylko ogólnie: magistrala korzysta z dwóch linii: danych i zegara, i może łączyć ze sobą wiele urządzeń, korzystając z puli 128 lub 1024 adresów. W danej chwili jedno z nich musi być nadrzędne, ale ten przywilej nie jest zastrzeżony na stałe do wybranego elementu.

Wśród peryferiów można znaleźć wiele układów różnych producentów: od zegarów, pamięci nieulotnych, przetworników analogowo-cyfrowych i na odwrót, po porty równoległe, które z racji powiększania ilości wejść bądź wyjść w systemie, zwie się ekspanderami. I takiemu układowi przyjrzymy się tutaj, a przy okazji poznamy zasady pracy z magistralą I2C w Arduino.

Na płytce edukacyjnej TME znajdują się dwa układy ekspanderów MCP23008 firmy Microchip. Ekspanderów – czyli układów oferujących dodatkowe piny, mogące być portami wejściowymi lub wyjściowymi. Układ może dużo, jak na dość prosty w założeniach zespół ośmiu uniwersalnych portów. Oprócz możliwości definiowania każdego z nich jako wejście lub wyjście, w przypadku wejść można aktywować wstępną polaryzację rezystorem o wartości 100 kΩ, a także korzystać z rozbudowanego systemu generowania przerwań. Na deser dostajemy możliwość sprzętowego wyboru jednego z ośmiu adresów, co umożliwia pracę ośmiu takich układów na jednej szynie I2C.

Układ pracuje przy napięciu od 1,8 do 5 woltów i pozwala obciążać wyjścia prądem 25 mA. Dość popularne stały się moduły wykorzystujące ten ekspander w formie interfejsu ograniczającego zużycie linii: jak na przykład szesnastoprzyciskowe klawiatury czy wyświetlacze LCD. W pierwszym przypadku oszczędność wynosi sześć portów, w drugim – cztery, przy czym magistrala nie jest wykorzystana na wyłączność.

Jak to połączyć? Nóżka pierwsza to zegar, druga – dane. Ze względu na wymagania biblioteki, o której zaraz opowiem, łączymy je kolejno z portami A5 i A4 Arduino.

Nóżki 3, 4 i 5 umożliwiają wybór adresu układu. Mają wpływ na najmłodsze bity rejestru adresu, w którym pozostałe bity ustawiono na stałe. Zatem adres może należeć do puli od 32 do 39. Na mojej płytce ma on wartość 36, co wynika z działania: 32 – bo tyle stanowi niezmienny adres bazowy + 1*4 – bo mamy wysoki stan na wejściu A2 + 0*2 + 0*1 – bo mamy niskie stany na wejściach A1 i A0. Drugi układ znajdujący się na płytce ma adres 32, ale o nim w tym artykule mówić nie będę.

Nóżka 6 to reset, aktywowany poziomem niskim. Nie chcąc go używać, należy go podłączyć do poziomu wysokiego. Nóżka 8 daje sygnał przerwania. Tym razem nie będziemy z niego korzystać.

Zasilanie należy podać na nóżki 18 – plus oraz 9 – minus. W końcu na nóżkach od 10 do 17 mamy porty, które możemy wykorzystać według własnego widzimisię.

Układ zawiera 11 rejestrów konfiguracyjnych i oczywiście współpracując z nim, można odwoływać się do nich wprost. Ale to zostawiam dociekliwym. Jak każde chyba peryferium, także to posiada kilka bibliotek, które znakomicie wszystko upraszczają i w oparciu o nie pokażę, jak można sterować tym ekspanderem. Na początek – coś bardzo prostego. Spróbujemy analizować wejście znajdujące się na nóżce 10 i w zależności od jego stanu sterować diodą świecącą wbudowaną w Arduino.

A tak przy okazji: dlaczego zaczynam od takich, wydawałoby się, głupot? Otóż jest zasada: przymierzając się do pierwszych kroków z dotychczas nieznaną materią, a taką jest tutaj magistrala I2C, jak i ten konkretny ekspander, należy zacząć od rzeczy najprostszej. Jeśli zadziała – wyeliminujemy wszelkie sprzętowe problemy na etapie porozumiewania się mikrokontrolera z tym urządzeniem, zarówno w zakresie magistrali jak i jego samego.

#include <Adafruit_MCP23008.h>  // Dołącz bibliotekę sterującą układem MCP23008
Adafruit_MCP23008 ekspander;    // Nadaj układowi nazwę "ekspander"

const byte LED = 13;  // Adres portu sterującego diodą świecącą.

void setup() {
  pinMode(LED, OUTPUT);  // Port diody świecącej deklaruj jako wyjście.

  ekspander.begin(36);          // Inicjuj bibliotekę sterującą układem MCP23008 pod adresem 0x4
  ekspander.pinMode(0, INPUT);  // Zadeklaruj port zerowy ekspandera jako wejście.
  ekspander.pullUp(0, HIGH);    // Dołącz rezystor podciągający.
}

void loop() {
  digitalWrite(LED, ekspander.digitalRead(0));  // Przekaż na port diody świecącej stan portu zerowego ekspandera.
}

Program jest bardzo prosty. Jak zwykle na początku dokładamy bibliotekę. Jest ich kilka, ta, którą wybrałem, jest dość prosta i przejrzysta. Specyfika wymaga nadania nazwy układowi, co też czynię tutaj:

Adafruit_MCP23008 ekspander;    // Nadaj układowi nazwę "ekspander"

Do sprawdzenia działania wykorzystam arduinową diodę świecącą, jak już wiemy, umieszczoną na porcie 13. W związku z tym port ten należy zadeklarować jako wyjście. Teraz nastąpią deklaracje związane z ekspanderem. Zaczynamy od inicjacji układu, odnosząc się do niego bezpośrednio za pomocą adresu:

ekspander.begin(36);          // Inicjuj bibliotekę sterującą układem MCP23008 pod adresem 0x4

Teraz trzeba zdefiniować zerowy port jako wejście.

ekspander.pinMode(0, INPUT);  // Zadeklaruj port zerowy ekspandera jako wejście.

Na koniec trzeba jeszcze podłączyć do niego rezystor podciągający, chyba że polaryzację wymusimy z zewnątrz.

ekspander.pullUp(0, HIGH);    // Dołącz rezystor podciągający.

W pętli głównej będzie tylko jedna instrukcja: stan zerowego portu będzie sterował diodą świecącą. Po wysłaniu programu do mikrokontrolera dioda będzie świecić albo nie, w zależności od tego, czy nóżka portu zerowego będzie zwierana do masy, czy będzie wisiała w powietrzu, a więc będzie zwierana do wysokiego poziomu dołączonym powyższą instrukcją rezystorem.

Jak mówiłem, program jest nudny, ale pozwala upewnić się, że komunikacja z ekspanderem pracuje i wszystko działa jak powinno. Oczywiście znajdziemy mnóstwo zastosowań takiej funkcjonalności układu, gdzie potrzebne są po prostu wejścia dwustanowe. Ciekawsze zastosowanie ekspandera omówię w kolejnym artykule.

Płytka edukacyjna TME-EDU-ARD-2Płytka edukacyjna TME-EDU-ARD-2Sprawdź tutaj

Przeczytaj również

Nasi partnerzy

TMETech Master EventTME EducationPoweredby
Copyright © 2024 arduino.pl