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

ATmega128 Problem z SPI (16-bit, master-recieve itp.)

kris_jr 10 Maj 2010 10:52 3291 11
REKLAMA
  • #1 8057857
    kris_jr
    Poziom 10  
    Witam,
    Chciałem połączyć stosunkowo szybki przetwornik (lub przetworniki) AC z procesorem ATmega128 poprzez interfejs SPI. Napotkałem jednak kilka problemów do rozważenia. Jako, że jestem początkujący to być może dla wielu z Was te zagadnienia okażą się łatwe i będziecie w stanie mi pomóc, za co oczywiście z góry dziękuję.

    Problemy są następujące:

    1. Przetwornik wysyła dane w formie 16-bitowej i nie jestem pewien jak powinienem odebrać te dane, gdyż ATmega ma SPI 8-bitowy. Oczywiście można by odbierać po 8-bitów gdyby tylko przetwornik tak mógł wysyłać, ale nie może :( Nie wiem natomiast czy dwukrotne odebranie po 8-bitów pod rząd jest wykonalne na ATmedze. Dodam, że prędkość SPI ma być bardzo duża najlepiej fosc/2 = 8MHz, a w najgorszym razie fosc/4 = 4MHz. Jeżeli teraz po odebraniu 8-bitów musimy zorientować się o końcu transmisji, przepisać rejestr i znowu zacząć odbierać, to nie uda się chyba tego zrobić na tyle szybko aby nie stracić części nadchodzącej informacji.

    2. W ogóle nie jestem pewien jak to jest z tym odbieraniem bitów przez mastera. ATmega128 w tej sytuacji jest masterem, ale niczego nie wysyła tylko ma taktować transmisję, wybierać nadawcę i odbierać dane. Jak w ogóle to działa czy muszę wpisywać dane do rejestru wysyłkowego tak jakby procesor miał wysyłać dane żeby odebrać to co jest w rejestrze danych przychodzących? To jest dal mnie nieco niejasna część dokumentacji.

    3. Chciałbym aby oprócz zajmowania się komunikacją SPI procesor w tym czasie wykonywał jakieś inne operacje (obliczeniowe, ewentualna dalsza komunikacja z pamięcią lub komputerem przez RS232 itp.) Jak to w ogóle zrobić, bo jeżeli trzeba cały czas sprawdzać status flagi mówiącej o końcu transmisji, a dane mają z założenia napływać cały czas to procesor nic innego nie będzie robił. Wydawało mi się że skoro ta część (SPI) w ATmedze jest zautomatyzowana to wystarczy np. raz na kilkanaście/kilkadziesiąt cykli zegarowych zająć się danymi otrzymanymi i powrócić do wykonywania na nich operacji. Jak to ugryźć może ktoś z szanownych kolegów ma to już opanowane?

    Bardzo proszę o pomoc i dziękuję za poświęcony czas.

    Pozdrawiam
  • REKLAMA
  • #2 8057907
    tadzik85
    Poziom 38  
    W jakim języku chcesz to pisać?

    Po tym jakie pytania zadałeś myślę ze powinieneś zapoznać się z tematem przerwań.
    A odbiór 16bitowej danej przez SPI zrealizuj przez obiór 2x 8-bitów. CLK/2 będzie oznaczało ze kolejna zmienna pojawi się po 16 taktach procesora i w sumie obie zmienne można odebrać w jednym przerwaniu. 2 kwestią jest to jak często będzie odbierał te dane.
  • #3 8057948
    kris_jr
    Poziom 10  
    Dziękuję za odpowiedź.
    Nie wiem czy dobrze myślę, ale jeżeli mamy taktowanie SPI CLK/2 czyli 16MHz/2 co daje 8MHz to rzeczywiście 8-bitów "przeleci" przez linię danych po 16 taktach zegara, problem w tym że następny 9-ty bit pojawi się po 2 taktach i co się wtedy stanie? Bo nawet zakładając, że po otrzymaniu tych 8-bitów SPI zgłosi przerwanie które zostanie obsłużone to mamy na to chyba tylko 2 takty bo jak już mówiłem kolejny bit przyjdzie po dwóch taktach i nie wiem czy nie nadpisze bitów w rejestrze danych przychodzących jeśli nie zdążę w ciągu tych dwóch taktów przepisać tych danych.
    A jak już wspominałem dane przychodzą stale, z tym że pomiędzy 16-bitowymi paczkami teoretycznie mógłbym dać sobie trochę czasu przed przełączeniem na drugiego nadawcę, ale z założenia mają oni naprzemiennie nadawać bez przerwy (z dokładnością do kilku taktów)

    Dodano po 37 [sekundy]:

    A pisać to chcę oczywiście w Asemblerze
  • REKLAMA
  • Pomocny post
    #4 8057995
    tadzik85
    Poziom 38  
    Rejestr przesuwny nie jest tym samym co rejestr wyjściowy. Wobec czego masz 16 taktów na odczyt. Oczywiście przy tak dużej prędkości cale 16bitow musisz odebrać w jednym przerwaniu.
  • #5 8058111
    kris_jr
    Poziom 10  
    Nie wiem tylko czy istnieje jakiś sposób dostania się do rejestru przesuwnego, bo nie znalazłem takiego sposobu w dokumentacji procesora (mogłem coś przeoczyć).

    Jeżeli jednak dobrze zrozumiałem zasadę działania tego interfejsu to niezależnie czy wysyłamy czy odbieramy w trybie master musimy coś (bajt) wpisać do rejestru SPDR i wówczas jednocześnie w takt zegara jest wysyłany ten bajt do slave'a i odbierany bajt od niego po czym natychmiast po wysłaniu ostatniego bitu zatrzymywany jest zegar. Dobrze to zrozumiałem?
    Zastanawiam się zatem, czy można zrobić tak, że po uruchomieniu SPI robić sobie coś innego w oczekiwaniu na przerwanie, a po zakończeniu otrzymywania 8-bitów wejść do obsługi przerwania wywołanego końcem transmisji odebrać dane z rejestru i wpisać ponownie jakiś bajt do SPDR nie ruszając wyjścia SS (stan niski = zezwolenie na transmisję slave'a). Powinien znowu się uruchomić zegar i po kolejnych 8-bitach znowu powinien się ustawić bit SPIF (znacznik końca transmisji). Można teraz odebrać drugi bajt 16-bitowej danej i podnieść SS aby zasygnalizować koniec transmisji slave'owi i zsynchronizować się z nim. Dane powinny być otrzymane prawidłowo gdyż są taktowane zegarem z uP który w czasie obsługi przerwania jest zatrzymany więc nic nie ucieknie, a po wznowieniu będą leciec dalej od 9-bitu do 16-tego. Dobrze myślę?

    Dodano po 37 [minuty]:

    Pojawiła mi się jeszcze jedna wątpliwość. Przetwornik zewnętrzny ADC (tlc2552) jest po części taktowany tym zegarem z uP. Próbkowanie jest robione z wykorzystaniem tego zegara, bo sama konwersja już wykorzystuje wewnętrzny oscylator. Wynika z tego, że jeśli wcześniejsze rozważania są sensowne o odbiorze tych 16-bitów i wstrzymywaniu zegara, to podczas próbkowania zostałby na chwilę wstrzymany zegar no i instrukcja niestety nic nie mówi o takiej sytuacji. Dopuszczalne są różne częstotliwości tego zegara, ale nie ma mowy o ewentualnym wstrzymaniu i jaki może to mieć wpływ na poprawność próbkowania. Czy ktoś kto ma zdecydowanie większe ode mnie doświadczenie ma jakiś pomysł na to co może się w tej sytuacji stać? Być może moje obawy o poprawność działania przetwornika w takich warunkach są nieuzasadnione, ale nie mam dostatecznej wiedzy aby coś sensownego ustalić.
  • REKLAMA
  • #6 8062459
    kris_jr
    Poziom 10  
    Może spróbuję jeszcze nieco usystematyzować moje pytania.
    Zakładam, że w ATmedze jak ustawię SPI tak aby zgłaszał przerwanie to zgłosi przerwanie po wysłaniu ostatniego bitu (już się dowiedziałem, że aby odbierać coś na masterze to trzeba jednocześnie coś wysyłać) i w procedurze obsługi tego przerwania po skopiowaniu odebranych danych jeśli wpisze kolejny bajt do wysłania bez przerywania transmisji to wszystko zadziała prawidłowo.
    Pytania:
    1. Czy można najpierw wpisać kolejny bajt do wysyłki, zanim skopiujemy ten już otrzymany i potem w trakcie drugiej transmisji odczytać rejestr przychodzący bez ryzyka popsucia danych? Innymi słowy czy do tego rejestru (danych przychodzących) jest przepisywana wartość rejestru przesuwnego dopiero po jego wypełnieniu się, co dałoby czas ok 16 cykli zegarowych)
    2. Nie ma jakiegoś sprytnego sposobu na zautomatyzowanie tego (być może trzeba by przerobić coś SPI lub zrobić całkowicie programowy) aby przerwanie zgłaszane było dopiero po odebraniu 16-bitów które znajdą się w którymś podwójnym rejestrze?
    3. Jeżeli zegar SPI wyłącza się natychmiast po wysłaniu/odebraniu 8-bitów to może ktoś z Was wie jaki mogłoby to mieć wpływ na wspomniany przetwornik, który do próbkowania używa tego zegara.

    Dodano po 11 [minuty]:

    Aha z tym pytaniem 2 to chodzi o to czy istnieje ewentualny inny sposób który nie odciążałby procesora jeszcze bardziej, a wręcz mniej.
  • #7 8067763
    GienekS
    Poziom 32  
    A które urządzenie jest jako Master ? Bo jeżeli AVR to niema żadnych problemów, bo zegar wysyła master. Gdyby był jako Slave to przy 2 bajtach też nie powinno być problemu bo jak już ktoś wspomniał jest jeszcze rejestr przesuwny do którego dane są ładowane jak bufor jest jeszcze zajęty. Po odczytaniu danych z bufora dane z rejestru natychmiast przepisywane są do bufora.
  • REKLAMA
  • #8 8068437
    kris_jr
    Poziom 10  
    Ok, dzięki. ATmega będzie masterem, ale będzie odbierał dane. Oczywiście wysyłać też coś musi, żeby w ogóle SPI sprzętowe działało, ale te dane będą nieistotne.

    A co będzie z przetwornikiem? Bo jak wspominałem przetwornik jest taktowany zegarem z SPI, a ten zegar w ATmedze działa tylko wtedy gdy coś jest nadawane. Wynika z tego że uruchamia się podczas pierwszego bitu, a po ósmym automatycznie się wyłącza i trzeba wtedy obsłużyć przerwanie (co z pewnością zajmie kilka do kilkunastu cykli zegarowych) i wymusić na nim wysyłkę drugiego bajtu. Wtedy zegar znów ruszy. Przetwornik przez dwanaście cykli zegarowych (zegara z SPI) próbkuje czyli siłą rzeczy w trakcie tego próbkowania zegar się w pewnym momencie znacznie wydłuży (na czas zabawy z przerwaniem i wpisaniem drugiego bajtu do wysyłki).
    Jak może to wpłynąć na poprawność działania przetwornika? Oczywiście nawet ten wydłużony czas nie sprawi że kondensator podtrzymujący w przetworniku się rozładuje bo minimum na utrzymanie przyzwoitego ładunku jest zegar 10kHz. Ale czy takie nierówne działanie zegara nie wpłynie jakoś negatywnie na jakość próbkowania?
  • #9 8068605
    GienekS
    Poziom 32  
    A co na ten temat mówi dokumentacja przetwornika? Podaj może jego typ. Nie wydaje mi się żeby ten zegar był jednocześnie zegarem przetwornika. Nie spotkałem się jeszcze z takim rozwiązaniem.
  • #10 8068698
    kris_jr
    Poziom 10  
    Dokumentacja właśnie nic nie mówi, a typ podawałem wcześniej w opisie problemu. To jest tlc2552 ale może też być np. AD7921 lub podobny. Chyba, że ktoś zna jakiś stosunkowo niedrogi i dostępny przetwornik 12-bitowy dwukanałowy z próbkowaniem minimum 100 ksps na kanał z interfejsem RÓWNOLEGŁYM to by mi rozwiązało problem, bo mi nie zależy na ilości nóżek zajmowanych w procku (mam ich sporo wolnych) a zależy mi na szybkości i wygodzie zastosowania.
  • Pomocny post
    #11 8070048
    Maciekqbn
    Poziom 15  
    Popatrz na MCP3202. To przetwornik 12-bitowy 2 kanałowy.
    MCP3202

    Kiedyś robiłem projekt na MCP3201 (wersja jednokanałowa w/w przetwornika). Współpracowało to z ATtiny2313. Zegar był generowany "na piechotę" poprzez zmianę stanu na nodze kontrolera, odstępy czasowe odmierzane NOP'ami - i to działało bez problemów. Tym bardziej będzie działał ze sprzętowym SPI, zwłaszcza, że na str. 15 aplikacji jest stosowny opis (idea taka jak piszesz - 3 transfery 8 bitowe).

    W wybranym przez Ciebie przetworniku istotnie zegar SPI jest wykorzystywany do konwersji jak i próbkowania, wskazane by było zatem, by kolejne transfery 8 bitowe odbywały się bezpośrednio po sobie. Ponieważ (jak napisał wcześniej GienekS) SPI posiada dodatkowy bufor (rejestr), taki transfer powinien się udać. Pozostaje sprawdzić w praktyce.
  • #12 8071115
    kris_jr
    Poziom 10  
    Dzięki. Zaproponowany przez Ciebie przetwornik jest rzeczywiście bardzo fajny. Niestety jest trochę za wolny :( Ma 100 ksps łącznie przy dwóch kanałach, to na jeden kanał wyjdzie max 50 ksps bo są multipleksowane. Sytuacji też nie zmieni zastosowanie dwóch bo musiałbym mieć dwa oddzielne SPI żeby je odsługiwać jednocześnie :( Przeglądnąłem resztę oferty Microchipa i niestety nie mają 12-bitowych z 200 ksps. Ale gdyby nie to to byłby idealny.
REKLAMA