logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Atmega32][I2C] - I2C - dwa układy o tym samym adresie

lukhol2 27 Lis 2016 22:57 2685 34
  • #1 16090440
    lukhol2
    Poziom 7  
    Chciał bym wykorzystać sprzętowe porty w Atmedze do komunikacji z dwoma różnymi urządzeniami po I2C. Oba urządzenia będą podłączone zgodnie z założeniami I2C, czyli równolegle, ale niestety problem pojawia się w adresowaniu. Oba układy, których chcę użyć mają ten sam adres. W przypadku układu pierwszego czyli RTC DS1307 o ile dobrze zrozumiałem z noty katalogowej nie ma możliwości zmiany adresu. Natomiast w przypadku drugiego układu czyli L3G4200D jest taka możliwość poprzez podłączenie pinu SDO do GND lub VCC. W moim przypadku używam płytki od KAMAMI (opis w załączniku). Tutaj pojawiają się następujące pytania:
    1. Układ ma wyjścia CON1 - CON6, wyjścia od CON3 do CON5 służą do komunikacji przy pomocy I2C i nie występuje tam pin SDO. W jaki sposób w takim razie go zmienić?
    2. Czy mogę połączyć się z układem przy pomocy wyjścia CON3, a pinu SDO użyc z innego złącza?
  • Pomocny post
    #2 16090584
    krzysiek_krm
    Poziom 40  
    Witam,
    Piotrus_999 napisał:
    A schematu nie widzisz? Jakie ma znaczenie czy się do nóżki scalaka podłączasz z jakiegokolwiek złącza. Czy to wg Ciebie zmienia przewodzenie ścieżek na płytce?$

    bardzo przepraszam, ale myślę sobie, że zamiast wypisywać te uszczypliwe mądrości ludowe, warto albo nieco głębiej wniknąć w sprawę, albo taktownie milczeć, najlepiej we wszystkich znanych językach.

    Ale do rzeczy.
    Z dokumentacji:
    http://www.st.com/content/ccc/resource/techni...df/jcr:content/translations/en.CD00265057.pdf
    (tabela 2 na stronie 8) wynika, że:
    - pin 5 (CS) ma być ustawiony na 1 (SPI idle mode / I2C communication enabled)
    - pin 4 (SDO / SA0) jest najmłodszym bitem adresu (I2C least significant bit of the device address SA0)
    Ze schematu z załączonego przez Ciebie dokumentu wynika, że:
    - pin 5 (CS) jest podciągnięty do zasilania za pomocą R1 więc jest "1"
    - pin 4 (SDO / SA0) jest podciągnięty do zasilania za pomocą R4 więc jest "1"
    Ponieważ RTC ma najmłodszy bit adresu równy "0" więc "przygotowana" na płytce kombinacja:
    - CS = 1
    - A0 = 1
    jest akurat taka, jaka jest Ci potrzebna.
    Nie musisz zatem nic łączyć bo płytka jest przygotowana do komunikacji I2C z adresem, który nie wywoła konfliktu z RTC.

    Pozdrawiam
  • #3 16092622
    lukhol2
    Poziom 7  
    Zrozumiałem sposób podłączenia, ale pojawił mi się problem z odczytywaniem danych z żyroskopu. Podłączyłem ten moduł do Atmegi328p do nóżek 27 i 28, czyli SCL i SDA. Podłączyłem bez rezystorów zewnętrznych do pullup ponieważ są one wbudowane na płytce. Korzystam z obsługi I2c, którą opisał Mirek w swojej niebieskiej książce, a dokładniej:
    TWI.h
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    TWI.c
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Obsługa żyroskopu:
    GYRO_L3G4200D.h
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    GYRO_L3G4200D.c
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    To jest dopiero początek, ale włączyłem go dla przetestowania tego co napisałem. Program odczytuje jedną daną, a następnie się zawiesza. W pliku TWI.c w funkcji TWI_read() zakomentownie wyjścia z pętli while zacina program. Wydaje mi się, że problem jest po stronie TWI, a nie samego sposób odczytu z żyroskopu, ale niestety nie wiem co z tym zrobić.
  • #4 16092644
    Konto nie istnieje
    Konto nie istnieje  
  • #5 16092654
    lukhol2
    Poziom 7  
    Piotrus_999 napisał:
    Wez sobie bibliotekę Petera Fleury. Funkcje kol Kardasia, które nie zwracają np statusów operacji - czyli nie wiesz czy się powiodły czy nie - dyskwalifikują się same.

    Przejrzałem sobie tą bibliotekę, którą poleciłeś i patrząc na jej zawartość prawdopodobnie będzie zacinać się ona dokładnie w tym samym momencie. W oby przypadkach jest pętla, z której nie ma wyjścia jeżeli nie zostanie spełniony warunek !(TWCR & (1<<TWINT)). Zaczynam podejrzewać, że problem może być po stronie podłączenia układu, a nie samej programowej obsługi I2C. Może tak być czy się mylę? Dziś już nie jestem w stanie przetestować działania biblioteki, którą poleciłeś, ale zrobię to jutro z samego rana.
  • #6 16092699
    Konto nie istnieje
    Konto nie istnieje  
  • #7 16092958
    lukhol2
    Poziom 7  
    Schemat wygląda tak: [Atmega32][I2C] - I2C - dwa układy o tym samym adresie . Niestety nie posiadam biblioteki z modułem, którego używam więc na schemacie zastąpiony jest on DS1307 z odpowiednim opisem. Schemat układu, którego używam jest w moim pierwszym poście w pdf. Reszta jest zgodna z tym co podłączyłem na płytce stykowej. To odnośnie przypadku, w którym coś źle podłączyłem. EDIT: na schemacie napisałem, ze podłączylem do con3, a podłączone jest do con4, mój błąd.
  • #8 16092982
    Konto nie istnieje
    Konto nie istnieje  
  • #9 16093065
    lukhol2
    Poziom 7  
    Nie jestem w posiadaniu takich rezystorów aktualnie. Czekam na zamówienie, które powinno przyjść już parę dni temu więc narazie nie mogę tego sprawdzić. Układ podłączyłem bez tych rezystorów ponieważ zgodnie ze schematem płytki linie SCL i SDA idą do vcc przez rezystor 10k.
  • #10 16093087
    Konto nie istnieje
    Konto nie istnieje  
  • #11 16093104
    lukhol2
    Poziom 7  
    Są na płytce i nawet widać ścieżki do pinów.
  • #12 16093147
    Konto nie istnieje
    Konto nie istnieje  
  • #13 16093151
    lukhol2
    Poziom 7  
    Piotrus_999 napisał:
    Masz jakiś debuger czy tak na oko sprawdzasz. Na czym staje dokładnie?

    Niestety nie mam debugera więc sprawdzam tylko na oko.
  • #14 16093173
    Konto nie istnieje
    Konto nie istnieje  
  • #15 16093183
    lukhol2
    Poziom 7  
    Narazie jestem zmuszony na pozostanie przy najtańszym programatorze. Ogólnie komunikacja po I2C jest ponieważ inicjalizacja przebiega pomyślnie, następnie odczytuję jedną lub 2 dane i program zacina się w miejscu, które wskazałem: [Atmega32][I2C] - I2C - dwa układy o tym samym adresie . W przypadku gdy nie mam wyjścia z pętli nie następuje nawet inicjalizacja. W przypadku dodania wyjścia z pętli inicjalizacja przebiega pomyślnie, pobiera 1 lub 2 dane i więcej już nie chce pobrać.
  • #16 16093190
    Konto nie istnieje
    Konto nie istnieje  
  • #17 16093228
    lukhol2
    Poziom 7  
    Piotrus_999 napisał:
    lukhol2 napisał:
    Ogólnie komunikacja po I2C jest ponieważ inicjalizacja przebiega pomyślnie, następnie odczytuję jedną lub 2 dane i program zacina się w miejscu, które wskazałem:

    Bardzo odważny wniosek. Nie wprowadzaj takich dziwnych konstrukcji bo to nie o to chodzi.
    po start zobacz jaki jest status operacji. Po wysłaniu adresu też. Choćby poprzez zapalenie diody.

    Piotrus_999 napisał:
    Narazie jestem zmuszony na pozostanie przy najtańszym programatorze.

    To zamiast drogieko kakami trzeba było płytke protowypową i np GY-80 z aliego za 20zł - gdzie sensorów masz o wiele więcej.


    Płytkę kamami otrzymałem za darmo, dlatego z niej korzystam. Zapalanie diody działa do momentu próby odebrania danych funkcją L3G4200D_GetDataRaw. Czyli tak jak mówiłem inicjalizacja przebiega pomyślnie, a problem pojawia się przy odczycie danych. Postaram się dokładniej zlokalizować problem.

    EDIT: Dodałem test z diodą. Do funkcji odczytującej dane czyli L3G4200D_GetDataRaw dodałem zmienną static, która po 500 wykonaniach tej funkcji zapala mi poprawnie diodę. To wszystko było wykonane przy dodanym wyjściu z pętli while w funkcji TWI_read().

    W przypadku gdy usunę z funkcji TWI_read() wyjście z pętli while dioda nie zapala się po odczycie pierwszej danej. Zapala się natomiast po inicjalizacji.
  • #18 16093289
    lukhol2
    Poziom 7  
    Piotrus_999 napisał:
    lukhol2 napisał:
    while (len--) *buf++ = TWI_read( len ? ACK : NACK );


    Tu jest błąd.

    Zmień na while (len--) *buf++ = TWI_read( len == 1 ? ACK : NACK );


    Nic to nie zmienia niestety. Dodatkowo wg. mnie zmiana tej linii na taką jak podałeś mija się z celem. W takim przypadku odbiorę tylko 1 daną, a nie tablicę ponieważ już po odebraniu pierwszej danej wyślę do TWI_read argument 0. W każdym razie już próbie odbioru pierwszej danej TWI zacina się.

    Zmieniłem funkcję odczytującą na taką:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Jak widać problem jest w odczycie danych czyli nigdy nie spełniam warunku wyjścia z pętli while w funkcji:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #19 16093291
    Konto nie istnieje
    Konto nie istnieje  
  • #20 16093300
    lukhol2
    Poziom 7  
    Piotrus_999 napisał:
    moj bład sorki - tak to jest jak się pisze i rozmawia przez telefon na raz :)

    Edytowałem poprzedni post, dodałem końcówkę.
  • Pomocny post
    #21 16093474
    Konto nie istnieje
    Konto nie istnieje  
  • #22 16094860
    lukhol2
    Poziom 7  
    Jutro od rana będę dalej walczył w lokalizacji błędu, ale zastanawia mnie na teraz czy:
    1. Rezystory pullup 10k mogą zbytnio spowalniać transmisje i powodować błąd?
    2. Czy winą może być np. niewłaściwe filtrowanie zasilania?
    3. Moja Atmega ustawiona jest na 1MHz, a zgodnie z datasheetem żeby korzystać z I2C muszę wpisać do TWBR jakaś wartość. Jest na to wzór w datasheecie i wg. niego jeżeli chcę transmitować z prędkością 100kHz muszę wpisać tam liczbę ujemną. Może w tym jest problem?

    Inicjalizacja - wartości rejestru TWSR po kolejno (wartosci w HEX):
    START - 0x8
    WRITE SLA ADRESS - 0x20
    WRITE ADRESS (dla danych) - 0x30
    WRITE DATA - 0x30
    STOP 0xF8

    Dla odczytu danych
    START - 0x8
    WRITE SLA ADRESS - 0x20
    WRITE ADRESS - 0x30
    START - 0x10
    WRITE SLA+1 ADRESS - 0x48
    READ NACK/ACK - 0x0
    STOP - 0x0

    Zrobiłem również prowizoryczny error log na wyświetlaczu LCD, w którym właśnie przy próbie odczytu otrzymuję błąd, sprawdzam to następującym warunkiem:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Dla STARTU, STOPU, READ itd. są inne warunki zgodne z notą i tam błędów żadnych nie sygnalizuje.

    EDIT:
    Nie wychodzi ze sprawdzania warunku while w funkcji TWI_read(0), a wewnątrz tego while ustawia status TWSR = 0x48, czyli "SLA+R has been transmitte; NOT ACK has been received". Dokładnie to samo dzieje się dla TWI_read(1), a nie powinno ze względu na zmiane bitu ACK/NACK. Kompletnie przestaje rozumieć o co tu chodzi.
  • Pomocny post
    #23 16095570
    Konto nie istnieje
    Konto nie istnieje  
  • #24 16095571
    lukhol2
    Poziom 7  
    Piotrus_999 napisał:
    nigdy nie pisz dziesietnie wartosci w takich przypadkach bo to jest nieczytelne


    ok, poprawiam na hexa
    Dodano po 1 [minuty]:
    Piotrus_999 napisał:
    nigdy nie pisz dziesietnie wartosci w takich przypadkach bo to jest nieczytelne

    0x48 oznacza ze slave odmówił transmisji - albo zle ustawiłeś rejestry w nim albo masz bład adresu slave. Ile masz na raz podłaczonych urzadzeń?


    Aktualnie tylko jedno.

    O ile dobrze patrzę w dokumentację to:
    [Atmega32][I2C] - I2C - dwa układy o tym samym adresie
    0x48 oznacza "SLA+R has been transmitted"
  • Pomocny post
    #25 16095582
    Konto nie istnieje
    Konto nie istnieje  
  • #26 16095588
    lukhol2
    Poziom 7  
    Piotrus_999 napisał:
    kod 20 oznacza ze wyłał adres ale nic nie odpowiedziało czyli masz zły adres urzadzenia.


    Przeglądam dokumentację i z niej wynika coś innego. Zapomniałem dodać, ze zmieniłem na Atmegę32A ponieważ tamta Atmega328p była tylko przyjściowo. Docelowo wszystko będę robił na Atmedze 32A. Podłączenia analogicznie, wszystko sprawdziłem na płytce pare razy.
  • #27 16095589
    Konto nie istnieje
    Konto nie istnieje  
  • #28 16095597
    lukhol2
    Poziom 7  
    lukhol2 napisał:
    lukhol2 napisał:
    Przeglądam dokumentację i z niej wynika coś innego.

    Skoro wiesz lepiej to ja się odłączam od dyskusji.


    przejedź sobie po adresach i zobacz na którym dostaniesz prawidłową odpowiedź (0x18)

    Przeglądając dokumentację i widzę coś innego, ale nie mówię, ze patrzę w odpowiednim miejscu więc spokojnie :D
  • #29 16095611
    Konto nie istnieje
    Konto nie istnieje  
  • #30 16095614
    lukhol2
    Poziom 7  
    Piotrus_999 napisał:
    w cytacie nie Piotrus_999 napisał tylko lukhol2
    Dodano po 2 [minuty]:
    lukhol2 napisał:
    Przeglądając dokumentację i widzę coś innego

    To kontynuuj tak jak uważasz. Jak pisałem się odłączam na takie dictum

    Nie wiem czemu tak jest, ale pierwsza wypowiedz jest moja. Sprawdziłem możliwe adresy wynikające z dokumentacji i żaden nie odpowiada 0x18, wszystkie odpowiadają 0x20.
REKLAMA