Serwis Edukacyjny
w I-LO w Tarnowie
obrazek

Materiały dla uczniów liceum

  Wyjście       Spis treści       Wstecz       Dalej  

obrazek

Autor artykułu: mgr Jerzy Wałaszek
Konsultacje: Wojciech Grodowski, mgr inż. Janusz Wałaszek

©2024 mgr Jerzy Wałaszek
I LO w Tarnowie

obrazek

Mikrokontrolery

ATmega32

Interfejs szeregowy – SPI

obrazek

Educational and Non-Profit Use of Copyrighted Material:

If you use Microchip copyrighted material solely for educational (non-profit) purposes falling under the “fair use” exception of the U.S. Copyright Act of 1976 then you do not need Microchip’s written permission. For example, Microchip’s permission is not required when using copyrighted material in: (1) an academic report, thesis, or dissertation; (2) classroom handouts or textbook; or (3) a presentation or article that is solely educational in nature (e.g., technical article published in a magazine).

https://www.microchip.com/about-us/legal-information/copyright-usage-guidelines

SPIS TREŚCI
Podrozdziały

obrazek

Cechy interfejsu SPI

Interfejs szeregowy (ang. Serial Peripheral Interface, SPI) pozwala na szybki przesył synchroniczny danych pomiędzy mikrokontrolerem ATmega32 a urządzeniami peryferyjnymi lub pomiędzy kilkoma układami AVR. ATmega32 SPI zawiera następujące cechy:

Na początek:  podrozdziału   strony 

Przegląd interfejsu SPI

Schemat blokowy modułu SPI jest przedstawiony na poniższym rysunku:

Połączenie pomiędzy układem Master a Slave pokazuje poniższy rysunek.

obrazek

System składa się z dwóch rejestrów przesuwających oraz generatora zegara Master. Układ SPI Master rozpoczyna cykl przesłania danych przez ustawienie w stan niski pożądanej końcówki SS wybierającej układ SPI Slave (ang. Slave Select). Układy Master i Slave przygotowują dane do przesłania w swoich rejestrach przesuwających, a układ Master generuje impulsy zegarowe na linii SCK do wymiany danych. Dane z układu Master do Slave są zawsze przesuwane linią MOSI (ang. Master Out – Slave In), a dane z układu Slave do Master przesuwane są po linii MISO (ang. Master In – Slave Out). Po każdym pakiecie danych układ Master synchronizuje układ Slave przez ustawienie w stan wysoki linii SS (ang. Slave Select, wybór układu Slave).

Po skonfigurowaniu jako Master interfejs SPI nie posiada żadnej automatycznej kontroli nad linią SS. Musi to być wykonywane przez program użytkownika, zanim będzie mogła rozpocząć się transmisja. Gdy zostanie to zrobione, zapis bajtu do rejestru danych SPI włącza generator zegara SPI i osiem bitów zostaje przesunięte sprzętowo do układu Slave. Po przesuwie jednego bajtu generator zegara SPI zatrzymuje się, ustawiając znacznik końca transmisji (SPIF). Jeśli bit włączający przerwania SPI (ang. SPI Interrupt Enable bit, SPIE) w rejestrze SPCR jest ustawiony na 1, to nastąpi żądanie przerwania. Układ Master może kontynuować przesuwanie następnego bajtu przez zapis do rejestru SPDR lub zasygnalizować koniec transmisji przez ustawienie w stan wysoki linii wyboru układu Slave SS. Ostatni odebrany bajt będzie przechowywany w rejestrze buforowym do późniejszego wykorzystania.

Gdy układ zostanie skonfigurowany jako Slave, interfejs SPI pozostaje w uśpieniu z linią MISO w stanie wysokiej impedancji tak długo, jak końcówka SS jest wysterowana stanem wysokim. W tym stanie oprogramowanie może uaktualniać rejestr danych SPI (ang. SPI Data Register, SPDR), lecz dane nie zostaną przesunięte na zewnątrz przez nadchodzące impulsy na końcówce SCK, aż końcówka SS nie zostanie wysterowana stanem niskim. Gdy jeden bajt został całkowicie przesunięty, ustawiany jest znacznik końca transmisji (ang. End of Transmission Flag, SPIF). Jeśli bit włączający przerwania SPI (ang. SPI Interrupt Enable bit, SPIE) w rejestrze SPCR jest ustawiony na 1, to nastąpi żądanie przerwania. Układ Slave może kontynuować umieszczanie nowych danych do przesłania w rejestrze SPDR przed odczytem nadchodzących danych. Ostatni odebrany bajt będzie przechowywany w rejestrze buforowym do późniejszego wykorzystania.

System buforuje pojedynczo w kierunku nadawczym i podwójnie w kierunku odbiorczym. Oznacza to, iż bajty do przesłania nie mogą być zapisywane do rejestru danych SPI przed zakończeniem całego cyklu przesuwania. Jednakże przy odbiorze danych odebrany znak musi zostać odczytany z rejestru danych SPI, zanim następny znak nie zostanie w całości wsunięty. W przeciwnym razie ten pierwszy bajt zostanie utracony.

W trybie Slave SPI układ sterowania próbkuje nadchodzący sygnał na końcówce SCK. Aby zapewnić poprawne próbkowanie sygnału zegarowego, minimalne okresy stanów niskich i wysokich powinny spełniać poniższe wymagania:

Stany niskie: dłuższe niż 2 okresy zegara mikroprocesora
Stany wysokie: dłuższe niż 2 okresy zegara mikroprocesora

Gdy interfejs SPI zostanie uaktywniony, kierunek danych na końcówkach MOSI, MISO, SCK, i SS jest wymuszany zgodnie z poniższą tabelą:

Końcówka Kierunek w trybie MASTER Kierunek w trybie SLAVE
MOSI Określany przez użytkownika Wejście
MISO Wejście Określany przez użytkownika
SCK Określany przez użytkownika Wejście
SS Określany przez użytkownika Wejście

Poniższe przykłady kodów pokazują, w jaki sposób należy zainicjować interfejs SPI w trybie Master i jak wykonać prostą transmisję. DDR_SPI w tych przykładach musi zostać zastąpione przez właściwy rejestr kierunku danych, który steruje końcówkami SPI. DD_MOSI, DD_MISO i DD_SCK muszą być zastąpione przez rzeczywiste bity kierunku danych dla tych końcówek. Na przykład, jeśli MOSI znajduje się na końcówce PB5, zamień DD_MOSI przez DDB5 a DDR_SPI przez DDRB.
Przykład w kodzie maszynowym
SPI_MasterInit:
    ; Ustaw MOSI i SCK jako wyjścia, pozostałe jako wejścia
    ldi r17,(1<<DD_MOSI)|(1<<DD_SCK)
    out DDR_SPI,r17
    ; Włącz SPI Master, ustaw częstotliwość zegara na fck/16
    ldi r17,(1<<SPE)|(1<<MSTR)|(1<<SPR0)
    out SPCR,r17
    ret
SPI_MasterTransmit:
    ; Rozpocznij transmisję danych (r16) 
    out SPDR,r16
Wait_Transmit:
    ; Czekaj na zakończenie transmisji
    in r16, SPSR
    sbrs r16, SPIF
    rjmp Wait_Transmit
    ret
Przykład w języku C
void SPI_MasterInit(void)
{
    /* Ustaw MOSI i SCK jako wyjścia, pozostałe jako wejścia */
    DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
    /* Włącz SPI Master, ustaw częstotliwość zegara na fck/16 */
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}
void SPI_MasterTransmit(char cData)
{
    /* Rozpocznij transmisję danych */
    SPDR = cData;
    /* Czekaj na zakończenie transmisji */
    while(!(SPSR & (1<<SPIF)))
        ;
}

Poniższe przykłady kodów pokazują, jak zainicjować interfejs SPI w trybie Slave i wykonać prosty odbiór danych.
Przykład w kodzie maszynowym
SPI_SlaveInit:
    ; Ustaw MISO jako wyjście, wszystkie pozostałe jako wejścia
    ldi r17,(1<<DD_MISO)
    out DDR_SPI,r17
    ; Włącz SPI
    ldi r17,(1<<SPE)
    out SPCR,r17
    ret
SPI_SlaveReceive:
    ; Czekaj na koniec odbierania
    in r16, SPSR
    sbrs r16, SPIF
    rjmp SPI_SlaveReceive
    ; Odczytaj odebrane dane i powróć
    in r16,SPDR
    ret
Przykład w języku C
void SPI_SlaveInit(void)
{
    /* Ustaw MISO jako wyjście, wszystkie pozostałe jako wejścia */
    DDR_SPI = (1<<DD_MISO);
    /* Włącz SPI */
    SPCR = (1<<SPE);
}
char SPI_SlaveReceive(void)
{
    /* Czekaj na koniec odbierania */
    while(!(SPSR & (1<<SPIF)))
    ;
    /* Zwróć rejestr danych */
    return SPDR;
}


Na początek:  podrozdziału   strony 

Funkcjonalność końcówki SS

Tryb Slave

Gdy SPI zostało skonfigurowane do pracy w trybie Slave, to końcówka SS (ang. Slave Select) pracuje zawsze jako wejście. Gdy na końcówce tej zostanie wymuszony stan niski, aktywuje się interfejs SPI, a MISO staje się wyjściem, jeśli tak ją skonfigurował program użytkownika. Wszystkie pozostałe końcówki interfejsu są wejściami. Gdy SS zostanie ustawione w stan wysoki, wszystkie końcówki stają się wejściami, a SPI przechodzi w stan pasywny, co oznacza, że nie będzie odbierać nadchodzących danych. Zwróć uwagę, iż logika sterowania interfejsem SPI zostaje zresetowana po wymuszeniu stanu wysokiego na końcówce SS.

Końcówka SS jest przydatna do synchronizacji pakietu/bajtu, aby utrzymywać licznik bitów układu Slave w synchronizacji z generatorem zegara układu Master. Gdy końcówka SS zostanie ustawiona w stan wysoki, układ SPI Slave natychmiast zresetuje logikę nadawania i odbioru oraz odrzuci wszelkie dane częściowo odebrane w rejestrze przesuwającym.

Tryb Master

Gdy interfejs SPI jest skonfigurowany do pracy w trybie Master (ustawiony bit MSTR w rejestrze SPCR), użytkownik może określić kierunek końcówki SS.

Jeśli SS skonfigurowane jest jako wyjście, to końcówka ta staje się ogólną końcówką wyjścia, która nie wpływa na system SPI. Zwykle końcówka SS będzie sterowała końcówką SS  układu SPI Slave.

Jeśli SS jest skonfigurowane jako wejście, to musi być utrzymywana w stanie wysokim, aby zapewnić pracę SPI Master. Jeśli układ zewnętrzny ustawi końcówkę SS w stan niski, gdy interfejs SPI pracuje w trybie Master z SS jako wejście, to system SPI zinterpretuje to jako wybranie tego SPI przez inny układ SPI Master, który rozpoczyna przesyłanie danych do tego SPI tak, jakby pracowało w trybie Slave. Aby uniknąć sporu na magistrali, system SPI podejmuje następujące działania:

  1. Bit MSTR w rejestrze SPCR zostaje wyzerowany i SPI przechodzi w tryb Slave. W wyniku stania się układem podporządkowanym Slave, końcówki MOSI i SCK przechodzą do pracy jako wejścia.
  2. Znacznik SPIF w rejestrze SPSR zostaje ustawiony, a jeśli są włączone przerwania SPI oraz jest ustawiony bit I w rejestrze stanu SREG, to zostanie wykonana procedura obsługi tego przerwania.

Stąd, gdy stosowana jest transmisja SPI sterowana przerwaniami w trybie Master i istnieje możliwość, że SS znajdzie się w stanie niskim, to przerwanie powinno zawsze sprawdzać, czy bit MSTR jest wciąż ustawiony. Jeśli bit MSTR został wyzerowany przez końcówkę SS, to musi on zostać ustawiony przez użytkownika, aby ponownie uaktywnić tryb SPI Master.


Na początek:  podrozdziału   strony 

Tryby danych

Istnieją cztery kombinacje fazy i polaryzacji SCK odnośnie danych szeregowych, które określa się bitami sterującymi CPHA i CPOL. Formaty przesyłu danych SPI pokazują poniższe rysunki.

Format przesyłu SPI z CPHA = 0
obrazek

Format przesyłu SPI z CPHA = 1
obrazek

Bity danych są wysuwane i zatrzaskiwane na przeciwległych zboczach sygnału SCK, dając dostateczny czas na ustabilizowanie się sygnałów danych. Jest to pokazane w poniższej tabeli:

Tryb SPI Warunki Zbocze początkowe Zbocze końcowe
0 CPOL=0, CPHA=0 Próbkowanie (narastające) Przygotowanie (opadające)
1 CPOL=0, CPHA=1 Przygotowanie (narastające) Próbkowanie (opadające)
2 CPOL=1, CPHA=0 Próbkowanie (opadające) Przygotowanie (narastające)
3 CPOL=1, CPHA=1 Przygotowanie (opadające) Próbkowanie (narastające)

Na początek:  podrozdziału   strony 

Opis rejestrów

SPCR – SPI Control Register – Rejestr sterujący SPI

Bit 7 6 5 4 3 2 1 0  
0x0D (0x2D) SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0 SPCR
Zapis/Odczyt Z/O Z/O Z/O Z/O Z/O Z/O Z/O Z/O  
Wartość początkowa 0 0 0 0 0 0 0 0  

Bit 7 – SPIE: SPI Interrupt Enable – Uaktywnienie przerwań SPI

Ten bit powoduje wykonanie przerwania SPI, jeśli są ustawione bity SPIF w rejestrze SPSR oraz I w rejestrze stanu SREG.

Bit 6 – SPE: SPI Enable – Włączenie SPI

Gdy bit SPE zostanie ustawiony na 1, włącza się interfejs SPI. Bit ten należy ustawić, aby uaktywnić jakiekolwiek operacje SPI.

Bit 5 – DORD: Data Order – Kolejność bitów danych

Gdy do DORD zostanie wpisana jedynka logiczna, to najpierw będzie przesyłany najmłodszy bit (LSB) danych.
Gdy do DORD zostanie wpisane zero logiczne, to najpierw będzie przesyłany najstarszy bit (MSB) danych.

Bit 4 – MSTR: Master/Slave Select – Wybór pracy w trybie Master/Slave

Ten bit wybiera tryb Master SPI, jeśli zostanie do niego wpisana jedynka logiczna, lub tryb Slave SPI, jeśli zostanie do niego wpisane zero. Jeśli końcówka SS jest skonfigurowana jako wejście i zostanie zewnętrznie wysterowana stanem niskim przy ustawionym bicie MSTR, to bit MSTR będzie wyzerowany, a znacznik przerwania SPIF w rejestrze SPSR ustawia się na 1. Użytkownik będzie musiał w tym przypadku ustawić bit MSTR, aby ponownie uaktywnić tryb SPI Master.

Bit 3 – CPOL: Clock Polarity – Polaryzacja zegara

Gdy do tego bitu zostanie wpisana logiczna jedynka, to w stanie nieaktywnym sygnał SCK ma wartość wysoką. Gdy do CPOL zostanie wpisane zero, sygnał SCK jest nieaktywny w stanie niskim. Poniższa tabela podsumowuje funkcjonalność CPOL:

CPOL Zbocze początkowe Zbocze końcowe
0 Rosnące Opadające
1 Opadające Rosnące

Bit 2 – CPHA: Clock Phase – Faza zegara

Ustawienie bitu fazy zegara określa, czy dane będą próbkowane na zboczu początkowym, czy na zboczu końcowym sygnału zegarowego SCK. Poniższa tabela podsumowuje funkcjonalność bitu CPHA:

CPHA Zbocze początkowe Zbocze końcowe
0 Próbkowanie Przygotowanie
1 Przygotowanie Próbkowanie

Bity 1:0 – SPR[1:0]: SPI Clock Rate Select 1 and 0 – Wybór częstotliwości zegarowej

Te dwa bity kontrolują częstotliwość sygnału SCK urządzenia skonfigurowanego jako Master. W trybie Slave bity SPR1 i SPR0 nie dają żadnych efektów. Związek pomiędzy SCK a częstotliwością zegara we/wy fclk_I/O pokazuje tabela poniżej:

SPI2X SPR1 SPR0 Częstotliwość SCK
0 0 0 fclk_I/O/4
0 0 1 fclk_I/O/16
0 1 0 fclk_I/O/64
0 1 1 fclk_I/O/128
1 0 0 fclk_I/O/2
1 0 1 fclk_I/O/8
1 1 0 fclk_I/O/32
1 1 1 fclk_I/O/64

SPSR – SPI Status Register – Rejestr stanu SPI

Bit 7 6 5 4 3 2 1 0  
0x0E (0x2E) SPIF WCOL - - - - - SPI2X SPSR
Zapis/Odczyt O O O O O O O Z/O  
Wartość początkowa 0 0 0 0 0 0 0 0  

Bit 7 – SPIF: SPI Interrupt Flag – Znacznik przerwania SPI

Gdy zostanie zakończona transmisja szeregowa, ustawiany jest znacznik SPIF. Przerwanie jest generowana, jeśli są ustawione na 1 bit SPIE w rejestrze SPCR oraz bit globalnego uaktywniania przerwań I w rejestrze stanu SREG. Jeśli końcówka SS jest wejściem i zostanie wysterowana stanem niskim, gdy interfejs SPI pracuje w trybie Master, to to również ustawi znacznik SPIF.

Znacznik SPIF jest zerowany sprzętowo, gdy zostanie wywołany odpowiedni wektor obsługi przerwania. Alternatywnie bit SPIF jest zerowany przez odczytanie najpierw rejestru stanu SPI przy ustawionym SPIF, a następnie wykonanie dostępu do rejestru danych SPI (SPDR).

Bit 6 – WCOL: Write COLlision Flag – Znacznik kolizji zapisu

Bit WCOL jest ustawiany, jeśli rejestr danych SPI (SPDR). Bit WCOL (i bit SPIF) jest zerowany przez odczytanie najpierw rejestru stanu SPI z ustawionym bitem WCOL, a następnie wykonanie dostępu do rejestru danych SPI.

Bity 5:1 – Zarezerwowane

Te bity są zarezerwowane i przy odczycie zawsze zwracają stan zero.

Bit 0 – SPI2X: Double SPI Speed Bit – Bit podwójnej prędkości SPI

Gdy bit ten zostanie ustawiony na 1, to prędkość SPI (częstotliwość SCK) będzie podwojona przy pracy w trybie Master. Oznacza to, iż minimalny okres SCK będzie równy dwóm okresom zegara we/wy. Przy pracy w trybie Slave interfejs SPI daje gwarancję pracy tylko przy częstotliwości fclk_I/O / 4 lub niższej.


SPDR – SPI Data Register – Rejestr danych SPI

Bit 7 6 5 4 3 2 1 0  
0x0F (0x2F) MSB             LSB SPDR
Zapis/Odczyt Z/O Z/O Z/O Z/O Z/O Z/O Z/O Z/O  
Wartość początkowa X X X X X X X X Niezdefiniowane

Rejestr danych SPI jest rejestrem do odczytu i do zapisu używanym przy przesyłaniu danych pomiędzy rejestrami mikroprocesora a rejestrem przesuwającym SPI. Zapis do tego rejestru inicjuje transmisję danych. Odczyt z tego rejestru powoduje odczyt rejestru buforowego odebranych danych w rejestrze przesuwającym.


Na początek:  podrozdziału   strony 

Zespół Przedmiotowy
Chemii-Fizyki-Informatyki

w I Liceum Ogólnokształcącym
im. Kazimierza Brodzińskiego
w Tarnowie
ul. Piłsudskiego 4
©2024 mgr Jerzy Wałaszek

Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.

Informacje dodatkowe.