Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[Atmega32][C] - komunikacja z akcelerometrem LIS3DH po SPI

Fifa_X 05 Sie 2017 22:20 810 21
  • #1 05 Sie 2017 22:20
    Fifa_X
    Poziom 4  

    Cześć!

    Zabrałem się za projekt którego celem jest zbieranie danych o przyśpieszeniu z akcelerometru LIS3DH i wyświetlenie ich na wyświetlaczu LCD/ Napotkałem jednak problem z komunikacją pomiędzy moim mikrokontrolerem a LIS'em poprzez SPI. Napisany kod wydaje mi się poprawny i zgodny z dokumentacją a mimo to nie mogę ruszyć dalej. Problem wygląda następująco, gdy próbuję odczytać rejestr WHO_AM_I z akcelerometru otrzymuję wartość 0 na wyświetlaczu która moim zdaniem jest błędna. Przy próbie odczytania jakiegokolwiek innego rejestru nie dostaję nic.

    Kod mojego programu:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    W funkcji SPI_masterinit() inicjuję moją Atmegę jako MASTER układu oraz definiuje odpowiednie piny jako wyjścia. W funkcji spi_transmit() ustawiam wartość pinu CS na 0 co oznacza zgodnie z dokumentacją rozpoczęcie transmisji poprzez SPI. Następnie program oczekuje na flagę potwierdzenia zakończenia transmisji i wtedy CS wskakuje na 1. Wynik wyświetlam za pomocą odpowiedniej biblioteki dla LCD. Rozwiązania szukalem już po utworzonych wątkach jednak niec co by mi pomogło nie znalazłem. Czy ktoś wie w czym może tkwić problem albo co robię nie tak? Poniżej załączam schemat połączenia mojego układu oraz dokumentację do akcelerometru.
    [Atmega32][C] - komunikacja z akcelerometrem LIS3DH po SPI

  • #2 05 Sie 2017 22:59
    excray
    Poziom 38  

    Ustaw PB4 (SS) jako wyjście. Poza tym Twoja komunikacja jest błędna:
    [Atmega32][C] - komunikacja z akcelerometrem LIS3DH po SPI
    Dane się odczytuje dopiero przy transmisji 2-go bajtu.

  • #3 05 Sie 2017 23:14
    JarekC
    Poziom 27  

    Wysłałeś po SPI rozkaz ale nie odczytałeś danej, przed ustawieniem CS=1 musisz wykonać jeszcze jedną transmisje (np bajtu 0xFF, tzw dummy byte) aby odczytana dana pojawiła się w rejestrze SPDR.
    Patrz rysunek nr 6 z karty katalogowej.

    JarekC

  • #4 06 Sie 2017 11:07
    Fifa_X
    Poziom 4  

    Ustawiłem pin SS jako wyjście i po wysłaniu komendy wysłałem jeszcze dummy byte jednak dalej nie dostaję żadnej wartości na wyświetlacz ;/
    Czy przy odczytywaniu danych powinienem zmienić wartość pierwszego bitu komendy na 1? Chodzi mi o bit RW z rysunku 6.

  • #5 06 Sie 2017 11:18
    excray
    Poziom 38  

    Po każdej poprawce wklejaj aktualnie używany kod.

  • #6 06 Sie 2017 11:24
    Fifa_X
    Poziom 4  

    Próbowałem zrobić to na dwa sposoby:
    W pierwszym zmodyfikowałem tyko funkcję spi_transmit();

    Kod: c
    Zaloguj się, aby zobaczyć kod


    W drugim rozbiłem to na dwie funkcje:
    Kod: c
    Zaloguj się, aby zobaczyć kod

  • #7 06 Sie 2017 11:27
    excray
    Poziom 38  

    A gdzie masz inicjalizację SPI? Jak to może działać, skoro nie inicjalizujesz SPI? Poza tym, skoro chcesz odczytać rejestr 0x0F to musisz zaznaczyć to w transmisji - ustawić bit R/!W. Czyli powinieneś wysłać (0x0F | 0x80)

  • #8 06 Sie 2017 12:18
    Marek_Skalski
    Poziom 33  

    Jaki to ma sens?

    Kod: C
    Zaloguj się, aby zobaczyć kod

    Wracasz z funkcji, a później deaktywujesz układ przypięty do SPI? Wszystko poniżej return jest pomijane.
    Masz pewność, że SPIF ustawiony po wysłaniu pierwszego bajtu nie będzie ustawiony kiedy wysyłasz drugi bajt? Może trzeba skasować flagę? Najpierw należy sprawdzić czy można wykonać zapis do rejestru SPDR. Później sprawdzasz czy transfer został zakończony = czy odebrano kolejny bajt.

  • #9 06 Sie 2017 17:48
    Fifa_X
    Poziom 4  

    SPI jest zainicjowane w funkcji spi_masterinit():

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Wyzerowałem flagę i dla sprawdzenia przy wchodzeniu do pierwszej i drugiej pętli "while" dodałem mrugającą diodę. Program wchodzi do pętli nr 1 zapala diodę, gasi jak wyjdzie, tak samo z drugą i wszystko się zgadza tylko pod koniec zamiast wypluć wartość rejestru o który pytam podaje mi wartość 0. Widać że transmisja działa bo odpytuje akcelerometr cały czas.

    Kod: c
    Zaloguj się, aby zobaczyć kod

  • #10 06 Sie 2017 19:05
    excray
    Poziom 38  

    Załączaj cały kod, a nie jakieś wydzielone kawałki. Chyba, że Ty lepiej wiesz gdzie popełniłeś błąd, tylko po co wtedy cały ten wątek? W inicjalizacji ustaw linię CS. POL i PHA ustaw na 0.

  • #11 06 Sie 2017 20:00
    Fifa_X
    Poziom 4  

    Cały kod wygląda następująco:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Wydaje mi się że mikrokontroler przeprowadza transmisję poprzez SPI, wysyła komendę oraz dummy byte, natomiast nie otrzymuje odpowiedzi od LIS'a w efekcie czego dostaję 0 na wyświetlaczu, pytanie dlaczego tak się dzieje.

  • #12 06 Sie 2017 20:04
    excray
    Poziom 38  

    Z inicjalizacji zupełnie wywal tą linijkę: "SPCR = ~(1 << CPOL) | ~(1 << CPHA); //CPOL i CPHA na 0".

  • #13 06 Sie 2017 20:09
    Fifa_X
    Poziom 4  

    Niestety dalej 0 na wyświetlaczu ;/

  • #14 06 Sie 2017 20:22
    Marek_Skalski
    Poziom 33  

    Ten program chyba nie robi dokładnie tego co chciałbyś. Pomyśl jak się zachowają linie SPI, przypięte do portu B, kiedy wykonujesz taki zestaw instrukcji:

    Kod: C
    Zaloguj się, aby zobaczyć kod

    Poza tym, musisz jednoznacznie zdefiniować stany na wyjściach SPI, w tym NCS przed rozpoczęciem transmisji, a tego nie ma w Twoim programie. Sygnał NCS jest używany do synchronizacji odbiornika. Podłącz oscyloskop albo analizator stanów logicznych i zobacz co jest wysyłane, albo co jest odbierane przez układ docelowy.
    Może SPI nadaje ze zbyt wysoką prędkością? Może przewody są zbyt długie? A może coś nie jest podłączone? Sprawdziłeś to wszystko? A może brakuje pull-up na wejściu MISO?
    Jesteś pewien, że AVCC (pin 30) powinien być przypięty do GND? Tak masz na schemacie i polemizowałbym czy to prawidłowo.

  • #15 06 Sie 2017 20:52
    Fifa_X
    Poziom 4  

    Tę diodę wrzucilem tylko dla sprawdzenia czy program faktycznie wchodzi w te pętle.
    Nie mam niestety dostępu w domu do oscyloskopu więc tego nie sprawdzę. Przewody mają 20 cm myślę jednak że to nie o to chodzi. podciągnięcie napięcia (pull - up) na wejściu jest ponieważ po sprawdzeniu miernikiem na linii MISO mam ~4,5 V. Od strony akcelerometru nie mam podłączonego napięcia 3Vo bo nie mogę znaleźć w nocie katalogowej jakie napięcia tam podać i co zasila ten pin. Co do AVCC zgoda mój błąd w dokumentacji atmegi pisze że należy podać tam napięcie.

    Edit. Pin 3V0 to wyjście z regulatora napięcia.

  • #16 06 Sie 2017 21:01
    Marek_Skalski
    Poziom 33  

    Nie wiem co to za linia 3V0. Powiedz jeszcze do czego podłączyłeś pin #1 układu LIS3DH? To jest zasilanie linii interfejsu komunikacyjnego. Bez tego układ nie zagada.

  • #17 06 Sie 2017 21:12
    Fifa_X
    Poziom 4  

    Zasilanie Vin ( w nocie katalogowej Vdd_IO) podpiąłem do stabilizatora napięcia i mam tam 2,5 V. Reszta pinów jest podpięta tak jak w SPI należy więc MISO -> SDO, MOSI -> SDA, SCK -> SCL, CS -> PA0

  • #18 06 Sie 2017 21:31
    Marek_Skalski
    Poziom 33  

    Czyli układ zasilany napięciem 2,5V, który toleruje maksymalnie 3,6V, a na liniach komunikacyjnych może przyjąć maksymalnie Vdd+0,1V (czyli 2,6V) podałeś 5V. Nawet jeżeli układ żyje, to nie ma możliwości uzyskania poziomu rozpoznanego jako wysoki przez uC.
    Optymalnie, jest zasilać wszystko w układzie napięciem 3,0V-3,3V. Wtedy nie ma problemu z dopasowaniem poziomów. Być może układ jeszcze żyje. Spróbuj obniżyć napięcie zasilania uC.
    Pin #10 LIS3DH też musi być podłączony do GND.
    Dodaj aktualny schemat, proszę.

  • #19 06 Sie 2017 21:40
    Fifa_X
    Poziom 4  

    Schemat jest taki jak w pierwszym poście. Zmierzyłem dokładnie teraz napięcie zasilania i było to 2,9 V. Co do pinów o które pytasz w tym PIN#10 nie mogę go podłączyć nigdzie gdyż ten akcelerometr wygląda tak:
    [Atmega32][C] - komunikacja z akcelerometrem LIS3DH po SPI

    Dokumentacja do niego jest na pewno dobra jako że pobierałem ze strony producenta.

  • #20 06 Sie 2017 22:01
    Marek_Skalski
    Poziom 33  

    Gdybyś od samego początku pisał, że korzystasz z gotowego modułu, który ma translatory napięć, to nie marnowałbym czasu na pisanie postów i szukanie błędów sprzętowych. Pin #10 jest podłączony do GND i tutaj jest wszystko ok.
    Ale nadal są jakieś błędy, ponieważ wbudowany stabilizator powinien dać 3,3V, a linia danych wyjściowych ma wlutowany pull-down 10k. Nawet dokładając wewnętrzny pull-up atmegi (~47k), napięcie na wejściu powinno wynosić około 0,87V w stanie niskim, który odczytujesz w układzie (skoro w rejestrze jest 0x00). A Ty zmierzyłeś ~4,5V, więc gdzieś jest przerwa, a do tego konfiguracja portu jest gdzieś błędna, np. tutaj:

    Kod: C
    Zaloguj się, aby zobaczyć kod

    I popraw definicje związane z NCS. Ustawiasz PB4 jako wyjście, ale sterujesz portem PA0. Zdefiniuj jednoznacznie każdy pin: kierunek i stan.

  • #21 06 Sie 2017 22:12
    Fifa_X
    Poziom 4  

    Wybacz proszę że nie napisałem wcześniej że to gotowy moduł. Można powiedzieć że jestem początkującym w kwestii zabawy z mikrokontrolerami.

    Konfigurację portów już poprawiłem, widać to w poście#11. Zatem problem może być sprzętowy a nie programowy skoro na liniach MISO i SCK dostaję ok. 4,5V tak?

  • #22 06 Sie 2017 23:29
    excray
    Poziom 38  

    Marek_Skalski napisał:
    I popraw definicje związane z NCS. Ustawiasz PB4 jako wyjście, ale sterujesz portem PA0

    I tak ma być. Aby SPI działało w trybie Master pin SS (PB4) musi być ustawiony jako wyjście (stan nieważny). Niemniej linię CS można podpiąć pod dowolny inny pin - tak jak tutaj PA0.

 Szukaj w ofercie
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME