Dodatki‎ > ‎

SPI Flash

Na płytce przewidziane zostało miejsce na pamięć typu serial flash o pojemności 16 megabitów (czyli 2 MiB do dyspozycji). 
To pozwala np. na gromadzenie danych wtedy, gdy układ działa bez połączenia z PC jako samodzielne urządzenie. 
W tej pamięci mogą być też przechowywane ikony i czcionki, jeśli zamierzasz używać wyświetlaczy graficznych. 
Główna trudność to właściwe skonfigurowanie komponentu SPI, bo właśnie za pomocą szeregowego, synchronicznego interfejsu odbywa się wymiana danych między tą pamięcią a mikrokontrolerem. W załączniku spi-dla-flash.png jest sprawdzona, działająca konfiguracja SPI do współpracy z pamięcią EN25Q16.

Zwróć uwagę na to, że karta pamięci microSD oraz pamięć Flash są podłączone do wyjść SPI2, a nie SPI1.

Sygnał #ChipSelect jest sterowany programowo ze względu na specyfikę układu pamięci, fizycznie w mikrokontrolerze jest to wyprowadzenie PTE3, a odpowiedni komponent w postaci zrzutu ekranu zamieściłem w załącznikach.
Uwaga! polaryzacja tego sygnału jest odwrócona, tzn. wpisanie wartości 0 aktywuje układ pamięci! Ten fakt jest zresztą zaznaczony w samej nazwie sygnału - symbol # lub mała litera 'n' przed nazwą sygnału oznaczają właśnie że jest on aktywny w stanie niskim.
Wartością początkową sygnału nCS (po resecie) powinno być 1, i najlepiej ustawić to od razu w komponencie - tak jak to widać na zrzucie ekranu. Wartość 0 wystawiana jest tylko na czas komunikacji z pamięcią.

flash_CS_PutVal(0); //wybór układu pamięci flash (rozpoczęcie komunikacji)
  //wysyłanie komend
  //odbieranie danych przez SPI
  //...
flash_CS_PutVal(1); //koniec komunikacji 

W realizacjach układów SPI charakterystyczne jest to, że zapisanie (wysłanie) jakiejś porcji danych (typowo 8 lub 16 bitów) ZAWSZE jest związane z odczytaniem takiej samej liczby bitów. Jest to poglądowo przedstawiane jako rejestr przesuwny. Najczęściej wysyłanie danych rozpoczyna się od najstarszego bitu (MSB first).
Rozważmy hipotetyczny przypadek: chcemy co pewien czas odczytać 8 bitów informacji z urządzenia podrzędnego (ang. slave). W tym celu musimy poprzedzać każdy odczyt wysłaniem 8 bitów danych. Zwykle jest tak, że w takiej sytuacji wysyła się cokolwiek (np. 0x00 albo 0xFF). W literaturze taki "dowolny" bajt danych określany jest jako dummy. Precyzyjniejsze byłoby stwierdzenie, że w czasie jednego transferu SPI jednocześnie ma miejsce odbieranie i wysyłanie danych. Zarówno nadawanie jak i odbiór są synchronizowane jednym wspólnym zegarem.

W uC CFV1 młodsze (ang. Low) 8 bitów rejestru danych SPI2 ma oznaczenie: SPI2DL.
Użycie komendy SPI2DL = 0x00; spowoduje włączenie nadajnika i wygenerowanie 8 cykli zegarowych, przy czym w każdym z nich wysłany zostanie bit o wartości 0 na wyjście MOSI. Jednocześnie odbiornik SPI pilnie nasłuchuje i pobiera z pinu MISO kolejne bity danych z układu slave
Efekt końcowy będzie taki, że układ slave ma w swoim rejestrze danych SPI to, co mu wysłaliśmy (w tym przypadku 0x00), natomiast w naszym rejestrze danych (układu master) znajduje się to, co w międzyczasie przesłał nam układ podrzędny.
Możemy teraz te dane odczytać instrukcją: byte data = SPI2DL; Ta instrukcja  - w odróżnieniu od instrukcji zapisu do rejestru - nie wywołuje aktywności na liniach SPI. Jest to tylko odczytanie z pamięci układu odebranej wcześniej paczki danych.
Podsumowując: aby coś odebrać z SPI, urządzenie master musi w tym celu cokolwiek wysłać, tylko wtedy włączy się zegar synchronizujący wymianę danych. Wysyłanie i odbiór są w SPI ściśle ze sobą związane. Jedno z urządzeń jest nadrzędne (master) i odpowiada za sterowanie transmisją danych (m.in. generuje sygnał zegarowy).

Jest to zupełnie inny mechanizm niż ten spotykany np. w UART, gdzie nadawanie i odbiór danych są od siebie zupełnie niezależne, a żadna ze stron nie musi być traktowana jako nadrzędna (tj. sterująca przebiegiem transmisji znaków).

Typowo transmisja jednej porcji danych przez SPI jest związana z zerowaniem, a następnie ustawianiem sygnału nCS po każdej porcji danych. W takim wypadku zwykle wybiera się sprzętową obsługę tego sygnału przez moduł SPI.
Dla odmiany, w układach pamięci Flash lub w kartach SD sygnał nCS musi mieć niski stan przez cały czas trwania transmisji. Wygodniej wtedy tym sygnałem sterować z poziomu oprogramowania jak zwykłym wyjściem GPIO (tak jak w przykładzie kilka akapitów wyżej).

c.d.n.
ą
Krzysztof Urbański,
19 lut 2012, 13:37
ą
Krzysztof Urbański,
19 lut 2012, 13:40