Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[Atmega32a][avr-gcc] - Komunikacja z HMC5883L po I2C - prośba o sprawdzenie kodu

Brooce 31 Paź 2014 00:42 1245 5
  • #1 31 Paź 2014 00:42
    Brooce
    Poziom 5  

    Witam wszystkich forumowiczów!

    Głupio mi zaczynać przygodę z forum od takiego tematu - prośby o znalezienie błędu w kodzie, lecz sam nie mogę rozgryźć dlaczego nie działa.


    // Ten problem już rozwiązałem, w ostatnim poście pytam czy dobrze przeprowadziłem self-test?




    Używając ATmegi32a chcę się połączyć z magnetometrem HMC5883L (moduł GY-271). Na razie próbuję odczytać zawartość dowolnego rejestru (np. Status Register), ale za każdym razem dostaję osiem "jedynek", więc coś jest nie tak. Ciekawostka: Po ośmiu bitach danych, magnetometr przesyła bit ACK w stanie niskim (co sprawdza mi warunek w funkcji I2C_ack()) - czyli potwierdzenie odbioru.

    Jeśli chodzi o połączenia elektryczne, to zakładam że w owym module są zawarte rezystory podciągające linię I2C, więc podłączyłem jedynie zasilanie oraz SCL + SDA. Chwilowo wszystko jest zasilane z programatora przez USB.


    Poniżej zamieszczam kody najważniejszych plików (oprócz tego jest obsługa wyświetlacza, ale to nieistotne).

    Main.c:

    Kod: c
    Zaloguj się, aby zobaczyć kod



    Oraz magnetometr.c:
    Kod: c
    Zaloguj się, aby zobaczyć kod




    Bardzo proszę o pomoc - sprawdzenie co jest nie tak przede wszystkim w funkcjach określających protokół I2C (myślę że w nich siedzi problem), na razie nie ma co patrzeć na polecenia związane z samym magnetometrem. Może wprawione oko od razu znajdzie coś, czego ja nie mogę...


    Edit:

    Uff, wreszcie udało mi się coś odczytać. Problemem było chyba coś z kolejnością funkcji przy korzystaniu z I2C. Teraz nie umiem powiedzieć dokładnie co, bo porównując poprawiony kod widzę, że na dobrą sprawę nic nie zmieniłem...

    0 5
  • #2 31 Paź 2014 06:42
    lukastoja
    Poziom 15  

    Witam

    Wyciąg z dokumentacji:
    External pull-up resistors are required to
    support these standard and fast speed modes.
    Na schematach również są zaznaczone rezystory więc są zapewne wymagane.

    No i zdaje się że przy odczycie powinieneś wysłać "adres" nie poda "MAG_address_w" tylko "_r"

    0
  • #3 31 Paź 2014 07:41
    voytaschec
    Poziom 24  

    Dodatkowo:
    Przesuwając liczbę ośmiobitową o siedem (dlaczego tylko siedem?) pozycji w lewo dostaniesz liczbę ośmiobitową z co najwyżej jedną jedynką na najstarszym bicie. Inna sprawa to taka, że nie kasujesz zmiennej "dane" tylko cały czas orujesz, co w dłuższej perspektywie da same jedynki (na młodszym bajcie).
    Powinno być:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #4 31 Paź 2014 08:56
    Brooce
    Poziom 5  

    lukastoja napisał:
    Wyciąg z dokumentacji:
    External pull-up resistors are required to

    Wiem że są potrzebne, ale jak pisałem - kupiłem moduł ( http://botland.com.pl/magnetometry/2722-hmc58...netometr-cyfrowy-i2c-33v-5v-modul-gy-271.html ), który te rezystory ma już posiadać.

    lukastoja napisał:
    No i zdaje się że przy odczycie powinieneś wysłać "adres" nie poda "MAG_address_w" tylko "_r"

    W pierwszej kolejności wysyłam adres "write", żeby wysłać adres rejestru który chcę odczytać. Później idzie już adres z bitem "read", a po nim odczyt.

    voytaschec napisał:
    Przesuwając liczbę ośmiobitową o siedem (dlaczego tylko siedem?) pozycji w lewo dostaniesz liczbę ośmiobitową z co najwyżej jedną jedynką na najstarszym bicie.

    Oczywiście powinno być przesunięcie o 8, już mi się zaczęło mieszać w głowie.

    Dzięki za poprawienie tej linijki, myślałem że nie jest potrzebne dodatkowe rzutowanie - program zrobi to automatycznie. Na to, że nie kasuję zmiennej, nawet nie zwróciłem uwagi.

    0
  • #5 02 Lis 2014 12:28
    Brooce
    Poziom 5  

    Dzięki za odzew Panowie, w końcu zadziałało. Problemem była prawdopodobnie niewłaściwa kolejność poleceń przy komunikacji przez I2C, m.in. nie można dawać "repeated start" przy zapisie danych do kolejnych rejestrów.

    Zapytałbym się jeszcze czy to normalne, że dane z rejestru dla jednej osi (np. x) reagują bardzo silnie przy odchylaniu magnetometru w dowolną stronę? Skąd wiemy wtedy wokół której osi obróciło się nasze urządzenie?

    0
  • #6 14 Lis 2014 12:24
    Brooce
    Poziom 5  

    Echh, szaleją mi te odczyty...


    Postanowiłem zrobić w końcu self-test urządzenia - i wychodzą strasznie małe wartości (58, -3 i -7 odpowiednio dla [x,y,z] przy "positive bias" i -57, -55, -50 przy ujemnym)! Chciałem sie poradzić czy na pewno dobrze go robię, mianowicie (kolejno): ustawiam odpowiednio rejestry CRA i CRB, przechodzę na "single-measurement mode" i - jednorazowo - odczytuję wartości rejestrów. Zakładam, że tam jest już gotowy wynik testu (tj. różnica dwóch pomiarów o których mowa w datasheecie), czy tak?

    0