I2C i automatyczne przydzielanie adresu

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

Reply to
Dariusz Zolna
Loading thread data ...

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
Reply to
Wojciech Piechowski

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

Wypadaloby jeszcze wprowadzic indywidualny numer w kazdym z modulow ..

J.

Reply to
J.F.

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

Reply to
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.

Reply to
T.M.F.

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

Reply to
Dariusz Zolna

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

Reply to
Dariusz Zolna

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

Reply to
Dariusz Zolna

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

Reply to
Dariusz Zolna

Owszem, tylko wymaga "wykrycia kolizji".

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

Ale to jednak pewne utrudnienie w masowej produkcji ..

J.

Reply to
J.F.

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.