I2C i automatyczne przydzielanie adresu

Mar 17, 2008 9 Replies

Mam pewien układ, złożony z modułu głównego i wielu mniejszych komunikujących się z głównym przez I2C (wszystko na AVR). Jako że układ z założenia ma mieć możliwość podpinania kolejnych modułów (także kilku tego samego typu), istnieje potrzeba wyboru adresu I2C dla każdego z nich. Najprościej byłoby użyć np zadajnika kodu HEX i kilku portów procka na każdym module. Problemem jednak jest:



- brak wolnych pinów



- marnowanie wolnych adresów (trzeba by np rezerwować pulę adresów na każdy rodzaj modułu i mimo że np byłby taki jeden w systemie, zajęte byłoby 16 adresów) Macie jakieś pomysły, żeby nadać te adresy programowo? Na razie chodzi mi jakaś niejasna koncepcja z wykrywaniem urządzeń o adresie np 0 (czyli nieprzydzielonym, od którego startowałyby wszystkie Slave). Jeśli Master wykryłby urządzenie o takim adresie, wysyłałby do niego nowy adres, jeśli nie, to kończyłby enumerację. O ile pamiętam, to w przypadku konfliktu adresów, dane przesyłane są tylko do jednego ze Slave, więc mogłoby zadziałać, ale poprawcie mnie jeśli się mylę, lub są w tym jakieś haczyki.



Dariusz Żołna


Dariusz Zolna pisze:

Jak będzie konflikt adresów to dane otrzymują wszyscy pod tym adresem.

wersja A: wpinać tylko po jednym nieprzydzielonym module jednocześnie, to kolizji nie będzie. Jak master już przydzieli nowemu adres, to można kolejnego nowego dołożyć.

wersja B: każde urządzenie niezainicjowane losuje se długą sekwencję bitów (np. tworząc ją z najmniejszego bitu kolejnych odczytów wiszącej lub zaszumionej nogi ADC). Master robi odczyt tej sekwencji z adresu 0, czyli wszyscy potencjalni niezainicjowani się chwalą swoją sekwencją. Sekwencje są losowe, więc najprawdopodobniej się różnią, przy odpowiedniej długości sekwencji można to uznać za aksjomat. No i wszyscy jednocześnie wystawiają te swoje bity, prędzej czy później będzie konflikt - jedni chcą zera, inni jedynkę. Ci z jedynką przegrają, dowiedzą się że nie są jedynymi i odpadają z tego okrążenia (arbitration lost w atmega). Ci z zerami idą dalej po kolejnych bitach, na każdym kolejnym konflikcie ktoś odpada. Po wysłaniu wszystkich do mety powinien dobiec tylko jeden, chyba że wylosowane kody się powtarzają. A wtedy master wysyła do wszystkich niezaicjowanych: "ty, który do końca wytrwałeś, od teraz nazywasz się xxx". I kolejna runda, aż się skończą niezainicjowani.

wersja C: wpisać adres do EEPROMa modułu przed wpięciem do systemu.

W

Zobacz jak dzialalo PnP na ISA. Mimo wszystko wolalbym chyba na przelaczniku ..

Wypadaloby jeszcze wprowadzic indywidualny numer w kazdym z modulow ..

J.

Dariusz Zolna pisze:

Wiesz, jak działa arbitraż w I2C?? jeśli mamy 2 urządzenia o tym samym adresie i zaczną one nadawać jednocześnie, to co się stanie?? Otóż układ nadając cały czas sprawdza stan linii SDA. Urządzenie, jak nadaje "1", a na linii ma "0", to wie, że jest konflikt - i się wyłącza :)... no i to będzie podstawa :)... musisz każdemu urządzeniu nadać numer seryjny - niepowtarzalny!! Z tym, że może on być dowolnie długi :)... teraz tak, host wysyła na domyślny adres komendę "przedstaw się" (tzn. podaj numer seryjny). Teraz wszyscy zaczynają nadawać swój numer seryjny, ale wszyscy (poza jednym) odpadają. Zostaje ten o najmniejszym numerze seryjnym. Dlaczego?? Patrz zasada arbitrażu :)... każdy nadaje swoją sewkencję, jak chce nadać "1" i widzi, że jest "0" (wymuszone przez inne urządzenie) to się wyłącza... i tyle... po wysłaniu numeru seryjnego host nadaje urządzeniu adres i powtarza całą czynność do momentu, w którym na komendę "przedstaw się" pod adresem domyślnym nic nie odpowie (czyli odbierze same "1" :).. Zalety tej metody są takie:

-sposób "arbitrażu" jest zgodny z I2C

-możesz sobie wymyślić dowolnie długi kod seryjny i w ten sposób obsługiwać dowolną ilość urządzeń (tzn. nie naraz ;))

-pomimo długiego kodu ustalenie adresu nie trwa długo

-adres może być krótki pomimo długiego kodu seryjnego

-możesz ustalić u "hosta" na stałe pewne adresy dla pewnych urządzeń (może być tu przydatna funkcja alternatywnego "wzywania" układów - nie przez adres a przez numer seryjny)

Inna metoda, jaka mi do głowy przychodzi to taka, że urządzenie SAMODZIELNIE zmieni swój adres gdy wykryje konflikt... ale nie wiem, czy da się to zrealizować w jakiś sensowny sposób - poza tym, host nie wiedziałby o tym... a chyba po to nadajesz adresy, żeby host mógłby te urządzenia rozróżnić ;)....

Pozdrawiam Konop

Tak ci to nie zadziala, bo w przypadku konfliktu jak ci napisano odpowiedza wszystkie urzadzenia. Ale to nie problem. Mozesz to zrobic na kilka sposobow jak podano, ze swojej strony dorzucilbym kolejny - rozwiazywanie konfliktow tak jak w sieci ethernet, masz konflikt pomiedzy dwoma urzadzeniami o tym samym adresie (zero w tym przypadku), kazde z urzadzen w przypadku stwierdzenia konfliktu losuje sobie czas nieaktywnosci w ktorym nie odpowiada na zapytania. Poniewaz jest nieprawdopodobne, zeby za kazdym razem dla wszystkich urzadzen ten czas byl identyczny wiec w ten sposob pojedynczo jestes w stanie inicjalizowac urzadzenia.

T.M.F. pisze:

Dzięki! Ta metoda wygląda na najłatwiejszą w realizacji na AVR. Z arbitrażem jaki podawano mi w innych postach mogą być pewne problemy przy korzystaniu ze sprzętowego interfejsu.

Pozdrawiam, Dariusz Żołna

Wojciech Piechowski pisze:

Tak, masz rację.

Ale trzeba dorzucić dodatkową linię albo odcinać zasilanie, co też komplikuje układ.

I to w sumie jest zgodne ze standardem (dzięki słowu kluczowemu "arbitraż" doszukałem się stosownych dokumentów), jednak mam pewne obawy co do implementacji tej metody przy użyciu sprzętowego interfejsu w AVR.

To też jest jakieś wyjście, bo i tak każdy procek musi być zaprogramowany. Skorzystam jednak z podpowiedzi kolegi T.M.F.

Pozdrawiam, Dariusz Żołna

J.F. pisze:

Kolega T.M.F podsunął już ciekawy pomysł.

Owszem, będzie taki, niezależnie od tego jak problem rozwiążę.

Pozdrawiam, Dariusz Żołna

Konop pisze:

Teraz już wiem :)

Wszystko się zgadza, tylko nie wiem czy uda się zrobić sprzętowo na AVR.

Gdyby tylko Slave potrafił nadać sobie nieprzydzielony adres, to nie ma problemu, bo brak odpowiedzi od Slave o zadanym adresie wykrywa się łatwo, więc wystarczy "przelecieć" przez 128 adresów.

Pozdrawiam, Dariusz Żołna

Owszem, tylko wymaga "wykrycia kolizji".

Co moze byc dosc trudne .. a w PnP to opanowali.

Ale to jednak pewne utrudnienie w masowej produkcji ..

J.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required