Jak czytać dane za pomocą Arduino SPI

w arkuszu danych jest stwierdzone, że powinienem zastosować 32 zegary szeregowe, aby uzyskać 32 bity danych. Jak można Programuję czy to Arduino?

Komentarze

  • Proponuję otworzyć przykłady biblioteki SPI i sprawdzić je. Tak czy inaczej kod powinien być byte result[4]; for (i = 0; i < 4; i++) result[i] = SPI.transfer(0x00);, a w result znajdziesz 32 bity, których potrzebujesz.
  • Już to zrobiłem. Ale układ energetyczny Używam STPM10 i sugeruje, że powinienem użyć synchronicznego SPI simplex, gdzie MOSI nie jest podłączony. Jest tylko diagram czasowy, aby przełączyć się z odczytu bajtów i zapisania bajtów.Gdy użyłem SPI.transfer (), dane nie są stabilny i myślę, że nie jest niezawodny
  • Jak mówisz, że to nie jest niezawodne? Urządzenie peryferyjne jest w trybie pełnego dupleksu i zgodnie ze sposobem, w jaki działa, jedynym sposobem na otrzymanie danych jest wysłanie fikcyjnych danych. Jeśli MOSI jest brak połączenia, cóż, to nie ' nie ma znaczenia ; zwróć jednak uwagę, że nie możesz ' t używać kodu PIN MOSI do innych zadań. Nawiasem mówiąc, czy pamiętałeś, aby poprawnie ustawić pin wyboru slave drugiego urządzenia peryferyjnego? Czy użyłeś pinezki SS na tablicy arduino, czy innej?

Odpowiedz

Dzwonisz do SPI.transfer() cztery razy, za każdym razem zapisując zwróconą wartość do zmiennej po odpowiednim przesunięciu bitów.

uint32_t val; val = SPI.transfer(0xff); //0xff is a dummy val |= (uint32_t)SPI.transfer(0xff) << 8; val |= (uint32_t)SPI.transfer(0xff) << 16; val |= (uint32_t)SPI.transfer(0xff) << 24; 

Zakładam, że najmniej znaczące bajt jest odbierany jako pierwszy. Upewnij się, że tryb SPI jest właściwy, jak wskazano w arkuszu danych.

Jeśli slave nie może obsłużyć cofnięcia asercji między bajtami (co jest tym, co SPI.transfer() zrobi na końcu transakcji), możesz spróbować sprzętowego SPI st2000 lub użyć bitbanged SPI z shiftIn().

Komentarze

  • Nie jestem pewien, czy to zadziała. Naprawdę musimy wiedzieć, jak działa slave SPI, zanim będziemy mogli założyć, jak zareaguje. Ponadto, jeśli linia Chip Select jest potwierdzana i cofana przy każdej 8-bitowej transakcji SPI, jak dobrze jest zaprojektowany podrzędny SPI? Oznacza to, że taki slave SPI może łatwo stracić synchronizację z masterem SPI. W szczególności, skąd masz pewność, który 8-bitowy bajt faktycznie czytasz?
  • @ st2000 OP uznał za stosowne podać zbyt mało szczegółów; Dopóki to się nie zmieni, można poczynić tylko założenia.
  • Wszystkie przykłady, które ' widziałem, używają SPI, transfer (0) do odczytu danych, a nie SPI.transfer (0xff). Używają również SPI.transfer do zapisu danych. Nadal nie ' nie wiem, co robi SPI z 0 lub 0xff, gdy faktycznie czytasz dane. Czy to jest wysyłane do slavea?
  • @ S.Imp ' ponownie bajty fałszywe. Możesz wysłać wszystko, co chcesz, urządzenie po drugiej stronie nadal je odrzuca, jeśli w ogóle zwraca uwagę na dane. Element SPI.transfer() jest zawsze używany częściowo z powodu nieodłącznej natury SPI w trybie pełnego dupleksu, a następnie (ze względu na pierwszy czynnik) częściowo ze względu na sposób, w jaki większość MCU implementuje swoje urządzenia peryferyjne SPI. Po uruchomieniu zegara w liniach MOSI i MISO zawsze pojawiają się ” dane „, czyli ' jest tylko do każdego uczestnika magistrali, czy może go przeczytać, czy nie, decydując na podstawie dowolnego wstępnie zdefiniowanego protokołu wyższej warstwy, jeśli ” dane ” ma znaczenie, czy nie.
  • Nie ' nie byłoby całkowicie błędne stwierdzenie, że można ' t naprawdę czytać bez pisania na magistrali SPI i odwrotnie. Dlatego ma sens po prostu zaprojektować urządzenie peryferyjne, które pobiera bajt w jednym rejestrze i 8 cykli później zwraca bajt w innym (lub nawet tym samym) rejestrze, tylko po to, aby uogólnić przypadki użycia. Następnie ' należy do aplikacji użytkownika ', aby zdecydować, czy ' re interesuje tylko bajt, który został zapisany w pierwszej kolejności (TX) lub ten, który został odczytany z powrotem (RX) lub oba (TX i RX). Stąd też niejednoznaczna nazwa transfer(), ponieważ służy zarówno do czytania, jak i do pisania.

Odpowiedź

Odpowiedź

Celem jest odczytanie 32 bitów za pomocą port SPI (nieznanego) urządzenia.

Jeśli urządzenie będzie tolerować aktywność linii SPI Chip Select (przechodząc od nieaktywnego do aktywnego do nieaktywnego po każdym odczytanym 8-bitowym bajcie), powinieneś być w stanie uzyskać żądane 32 bity danych wykonując 4 kolejne 8 czyta bit SPI.

Jednakże, jeśli urządzenie nie będzie tolerować powyższej aktywności linii SPI Chip Select (to znaczy, jeśli urządzenie wymaga, aby funkcja SPI Chip Select była aktywna dla całej 32-bitowej transakcji SPI), nie można rozdzielić 32-bitowej transakcji na 4 oddzielne 8-bitowe transakcje SPI bez kontrolowania linii SPI Chip Select. Poniższy przykład kodu ilustruje, jak to się robi:

void loop(){ //transfer 0x0F to the device on pin 10, keep the chip selected SPI.transfer(10, 0xF0, SPI_CONTINUE); //transfer 0x00 to the device on pin 10, keep the chip selected SPI.transfer(10, 0×00, SPI_CONTINUE); //transfer 0x00 to the device on pin 10, store byte received in response1, keep the chip selected byte response1 = SPI.transfer(10, 0×00, SPI_CONTINUE); //transfer 0x00 to the device on pin 10, store byte received in response2, deselect the chip byte response2 = SPI.transfer(10, 0×00); } 

Powyższy przykład pochodzi z biblioteki Arduino SPI strony internetowej i jest 16-bitowym (nie 32-bitowym) transferem. Aby zakodować 32-bitowy transfer, kontynuuj wywoływanie metody SPI.transfer za pomocą parametru SPI_CONTINUE.

dodane później …

Wygląda na to, że ludzie zniechęcają do korzystania z metod DueExtendedSPI . I SPISettings i SPI.beginTransaction () mają być używane? Jeśli tak, ta strona pokaż przykładowy kod, w którym kod wyraźnie kontroluje linię SPI Chip Select (poszukaj slaveAPin & slaveBPin). Zwróć uwagę, jak kod odczytuje 24 bity ze slave A i zapisuje 8 bitów do slave B. Aby odczytać 32 zamiast 24 bitów, musimy zmienić segment kodu (wraz z kilkoma innymi wspierającymi zmianami) w następujący sposób:

... SPI.beginTransaction(settingsA); digitalWrite (slaveAPin, LOW); // reading only, so data sent does not matter val0 = SPI.transfer(0); val1 = SPI.transfer(0); val2 = SPI.transfer(0); val3 = SPI.transfer(0); digitalWrite (slaveAPin, HIGH); SPI.endTransaction(); ... 

Komentarze

  • Naprawdę musimy zapoznać się ze specyfikacjami podrzędnego urządzenia SPI, aby skomponować więcej konkretna odpowiedź.
  • Używam płyty ewaluacyjnej STPM10. Połączenie jest synchronicznym SPI simplex, a MOSI Arduino nie jest do niczego podłączone. Istnieje diagram czasowy umożliwiający przełączanie z trybu tylko do odczytu i tylko do zapisu. Moje problemy polegają na tym, jak odczytać dane z rejestrów chipa. Użyłem SPI.transfer, ale nie ' uważam, że dane są wiarygodne.
  • Diagram czasowy STPM10 znajdujący się na stronie 11 ' specyfikacja nie wygląda na standardową transakcję SPI. Jestem skłonny powiedzieć, że nie możesz korzystać z biblioteki Arduino SPI. Zamiast tego może być konieczne całkowite rozwiązanie tego problemu w oprogramowaniu. Na przykład nie sądzę, aby w standardowej magistrali SPI była linia ” SYN „. I nie ' nie uważam, że linia Chip Select powinna iść wysoko przed końcem transakcji SPI.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *