Acasă - Antivirusuri
Interfață serială SPI (3 fire). Bazele protocolului SPI Programarea Spi

SPIîn Arduino, este unul dintre principalele protocoale pentru schimbul de date între placa Arduino și dispozitivele conectate. Împreună cu I2C și UART, acest protocol este adesea folosit pentru multe tipuri de dispozitive periferice, astfel încât cunoașterea principiilor de funcționare SPI este necesară pentru orice inginer Arduino. În acest articol ne vom uita pe scurt la principiile de bază, schema de interacțiune și metoda de conectare a senzorilor și ecranelor SPI la Arduino.

SPI este un protocol de transfer de date utilizat pe scară largă între un microcontroler (Master) și dispozitive periferice (Slave). În proiectele noastre, o placă Arduino este folosită cel mai adesea ca Master. Interfața SPI a fost inventată și folosită de Motorola, dar în timp a devenit un standard industrial. Principalul avantaj al lucrului cu această interfață este viteza mare și capacitatea de a conecta mai multe dispozitive pe o singură magistrală de date.

pini și știfturi SPI

Comunicarea prin interfața SPI arduino are loc între mai multe dispozitive care sunt situate aproape unul de celălalt. Plăcile Arduino sunt echipate cu pini separati pentru SPI. Asocierea are loc folosind patru contacte:

  • MOSI – informațiile sunt transmise prin această linie către Slave de la Master.
  • MISO – folosit pentru a transfera informații către Master de la Slave.
  • SCLK – crearea de impulsuri de ceas pentru transmiterea sincronă a datelor.
  • SS – selectarea dispozitivului slave.

Interacțiunea dispozitivelor SPI

Interacțiunea dispozitivului începe când ieșirea SS scade.

Înainte de a începe lucrul, trebuie să determinați:

  • De la ce bit ar trebui să înceapă schimbarea - sus sau scăzut? Ordinea este ajustată folosind funcția PI.setBitOrder().
  • Determinați nivelul la care ar trebui să fie linia SCK în absența unui impuls de ceas. Ajustabil prin funcția SPI.setDataMode().
  • Selectați rata de transfer de date. Determinat de funcția SPI.setClockDivider().

Următorul pas este să determinați în ce mod vor fi transferate informațiile. Alegerea modului este determinată de indicatori precum polaritatea și faza pulsului ceasului. Dacă nivelul este scăzut, se înregistrează 0, ridicat - 1. Există 4 moduri în total:

  • Mod 0 – SPI_MODE0: polaritate (CPOL) 0, fază (CPHA) 0.
  • Mod 1: polaritate 0, faza 1.
  • Modul 2: polaritatea 1, faza 0.
  • Modul 3: polaritatea 1, faza 1.

Inițial, Arduino a fost conceput pentru a transmite mai întâi datele cu bitul cel mai semnificativ, dar înainte de a începe, trebuie să clarificați acest lucru în documentație. Puteți demonstra modurile în imagine.

Există două tipuri de conexiuni posibile în interfața SPI: independente și în cascadă. În primul caz, la conectare, Master se adresează fiecărui Slave individual, în al doilea caz, conexiunea are loc unul câte unul, adică. cascadă.

Conectarea SPI la Arduino

Fiecare model Arduino are propriii pini SPI. Aceste concluzii:

  • Uno: MOSI corespunde pinului 11 sau ICSP-4, MISO – 12 sau ICSP-1, SCK – 13 sau ICSP-3, SS (slave) – 10.
  • Mega1280 sau Mega2560: MOSI – 51 sau ICSP-4, MISO – 50 sau ICSP-1, SCK – 52 sau ICSP-3, SS (slave) – 53.
  • Leonardo: MOSI – ICSP-4, MISO – ICSP-1, SCK – ICSP-3.
  • Datorită: MOSI – ICSP-4, MISO –ICSP-1, SCK –ICSP-3, SS (master) – 4, 10, 52.

Cel mai recent controler Arduino Due extinde capacitățile utilizatorului și vă permite să implementați mai multe sarcini decât alte microcontrolere. De exemplu, este posibil să controlați automat dispozitivul slave și să selectați automat diferite configurații (viteza ceasului, modul etc.).

Arduino SPI Library

Pentru a funcționa pe Arduino, a fost creată o bibliotecă separată care implementează SPI. Înainte de a începe codul, trebuie să adăugați #include pentru a activa biblioteca.

Functii principale:

  • begin() și end() – pornește și dezactivează lucrul. În timpul inițializării, liniile SCLK, MOSI și SS sunt configurate la ieșire, trimițând un nivel scăzut către SCLK, MOSI și un nivel ridicat către SS. Funcția end() nu modifică nivelurile de linie, este necesară pentru a dezactiva blocul asociat cu interfața de pe placa Arduino.
  • setBitOrder(order) – setarea ordinii de transmitere a biților de informații (MSBFIRST – prioritatea bitului cel mai semnificativ, LSBFIRST – prioritatea bitului cel mai puțin semnificativ).
  • setClockDivider(divider) – setarea divizoarelor principale de ceas de frecvență. Puteți seta divizori de 2, 4, 8, 16, 32, 64 și 128. Se scrie după cum urmează - SPI_CLOCK_DIVn, unde n este divizorul selectat.
  • setDataMode(mode) – selectați unul dintre cele patru moduri de operare.
  • transfer(valoare) – transferă un octet de la dispozitivul master și returnează octetul care este primit de la dispozitivul slave.
  • shiftIn(miso_pin, sclk_pin, bit_order) și shiftOut(mosi_pin, sclk_pin, order, value) – acceptarea și trimiterea datelor, pot fi conectate la orice pin digital, dar înainte de asta trebuie să le configurați singur.

Avantajele și dezavantajele SPI

Avantajele interfeței SPI:

  • Abilitatea de a transmite date mari, nelimitat la 8 biți.
  • Software ușor de implementat.
  • Simplitatea implementării hardware.
  • Sunt necesari mai puțini pini decât pentru interfețele paralele.
  • Doar viteza dispozitivelor limitează frecvența maximă de ceas.

Defecte:

  • Număr mare de pini în comparație cu I2C.
  • Slave nu poate controla fluxul de informații.
  • Lipsa unui protocol standard de detectare a erorilor.
  • Un număr mare de moduri de implementare a interfeței.
  • Lipsa confirmării primirii informațiilor.

Un exemplu de utilizare a Arduino SPI într-un proiect cu un senzor de presiune

Pentru a implementa proiectul avem nevoie de un Arduino, un senzor de presiune, un breadboard și fire. Un exemplu de conectare a senzorului este prezentat în figură.

Folosind senzorul SCP1000, este posibil să recunoașteți parametri precum presiunea și temperatura și să transmiteți aceste valori prin SPI.

Elemente de bază ale unei schițe de program

În primul rând, registrele senzorului sunt înregistrate în cod folosind setup(). Mai multe valori sunt returnate de la dispozitiv - una în 19 biți pentru presiunea primită, alta în 16 biți pentru temperatură. După aceasta, se citesc doi octeți de temperatură și se citește presiunea în două etape. În primul rând, programul ia cei trei biți cei mai semnificativi, apoi următorii 16 biți, după care, folosind o schimbare de biți, aceste două valori sunt combinate într-una singură. Presiunea reală este valoarea de 19 cifre împărțită la 4.

const int PRESIUNE = 0x1F; // prima etapă de determinare a presiunii (se detectează trei biți cei mai importanți)

const int PRESSURE_LSB = 0x20; // a doua etapă, care definește 16 biți pentru presiune

const int TEMPERATURA = 0x21; //16 biți pentru temperatură

Pentru a citi datele de temperatură și a le converti în Celsius, se folosește următorul element de cod:

int tempData = readRegister(0x21, 2);

float realTemp = (float)tempData / 20,0; // pentru a determina valoarea reală a temperaturii în Celsius, trebuie să împărțiți numărul rezultat la 20

Serial.print(„Temp

Serial.print(realTemp);

Citirea biților de presiune și combinarea acestora:

byte pressure_data_high = readRegister(0x1F, 1);

presiune_date_high &= 0b00000111;

unsigned int pressure_data_low = readRegister(0x20, 2);

presiune lungă = ((pressure_data_high<< 16) | pressure_data_low) / 4; //определение давления в Паскалях.

Scurte concluzii despre SPI

Scuturile și senzorii SPI se găsesc adesea în proiectele Arduino, așa că trebuie să știți cum funcționează acest protocol. În principiu, nu este nimic complicat în conectarea dispozitivelor SPI. Principalul lucru este să conectați firele corect și să utilizați metodele standard ale bibliotecii în ordinea corectă. Pentru unele dispozitive, de exemplu, carduri SD sau ecrane OLED, nu există, în principiu, alternative.

SPI - Serial Peripheral Interface sau „Serial Peripheral Interface” este un protocol de transfer de date sincron pentru împerechere dispozitiv principal Cu dispozitive periferice (slave). Dispozitivul principal este adesea un microcontroler. Comunicarea între dispozitive are loc pe patru fire, motiv pentru care SPI este uneori numită „interfață cu patru fire”. Acestea sunt anvelopele:

Există patru moduri de transfer de date ( SPI_MODE0, SPI_MODE1, SPI_MODE2, SPI_MODE3), cauzată de combinarea polarității impulsurilor de ceas (lucrăm la nivelul ÎNALT sau JOS), Polaritatea ceasului, CPOL, și faza impulsurilor de ceas (sincronizare pe marginea ascendentă sau descendentă a pulsului de ceas), Faza ceasului, CPHA. Ultima coloană a tabelului conține ilustrații explicative. asupra lor Eşantion sunt indicate momentele în care datele de pe linie trebuie să fie gata și citite de dispozitive. Scrisoare Z Se observă că starea datelor de pe linie este necunoscută sau neimportantă.

Interfața SPI oferă mai multe opțiuni pentru conectarea dispozitivelor slave: independentŞi cascadă. Când este conectat independent la magistrala SPI, dispozitivul master accesează fiecare dispozitiv slave individual. Cu o conexiune în cascadă, dispozitivele slave funcționează unul câte unul, ca în cascadă.


Tipuri de conectare a dispozitivului pentru funcționare prin interfața SPI: independentă și în cascadă

2 Implementarea interfeței SPI pe plăcile familiei Arduino

În Arduino, magistralele de interfață SPI sunt situate pe anumite porturi. Fiecare placă are propria sa atribuire de pin. Pentru comoditate, concluziile sunt duplicate și, de asemenea, plasate pe un separat conector ICSP(În Circuit Serial Programming, programarea unui dispozitiv inclus într-un circuit folosind un protocol serial). Vă rugăm să rețineți că conectorul ICSP nu are un pin de selecție slave - SS, deoarece se presupune că Arduino va fi folosit ca dispozitiv principal în rețea. Dar, dacă este necesar, puteți aloca orice pin digital al Arduino ca SS.

Figura arată corespondența standard a pinilor cu magistralele SPI pentru Arduino UNO și Nano.


3 Biblioteca standard pentru operare prin interfața SPI

A fost scrisă o bibliotecă specială pentru Arduino care implementează protocolul SPI. Este instalat împreună cu mediul de dezvoltare Arduino IDE. Se conectează astfel: la începutul programului adăugăm #include SPI.h.

Pentru a începe să utilizați protocolul SPI, trebuie să setați setările și apoi să inițializați protocolul utilizând procedura SPI.beginTransaction(). Puteți face acest lucru cu o singură instrucțiune: SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0))

Aceasta înseamnă că inițializam protocolul SPI la o frecvență de 14 MHz, transferul de date are loc începând cu MSB (bitul cel mai semnificativ), în mod SPI_MODE0.

După inițializare, selectați dispozitivul slave mutând pinul SS corespunzător în stare SCĂZUT. Apoi transferăm datele pe dispozitivul slave cu comanda SPI.transfer(). După transfer ne întoarcem SS la stat RIDICAT.


Lucrul cu protocolul este finalizat cu comanda SPI.endTransaction().

Este recomandabil să minimizați timpul de transfer între instrucțiunile SPI.beginTransaction() și SPI.endTransaction() pentru a evita problemele dacă alt dispozitiv încearcă să inițieze un transfer de date utilizând setări diferite.

Dacă intenționați să utilizați pini Arduino standard în schiță, nu trebuie să îi descrieți la începutul programului, deoarece sunt deja definite în bibliotecă și au următoarele nume:

#define PIN_SPI_SS (10) #define PIN_SPI_MOSI (11) #define PIN_SPI_MISO (12) #define PIN_SPI_SCK (13)

Acești pini sunt definiți în fișier pins_arduino.h, care este pe parcurs %programfiles%\arduino-(versiunea)\hardware\arduino\avr\variants\(dacă ați instalat programul într-o locație standard). Adică, de exemplu, pentru a coborî pinul de selecție slave la starea „0”, puteți scrie:

DigitalWrite(PIN_SPI_SS, LOW);

4 Conectarea unui registru de deplasare la Arduino

Să luăm în considerare aplicarea practică a interfeței SPI. Vom aprinde LED-urile controlând un registru de deplasare de 8 biți prin magistrala SPI. Să ne conectăm la Arduino registru de deplasare 74HC595. Vom conecta un LED cu o valoare nominală de 220 Ohmi la fiecare dintre cele 8 ieșiri ale registrului printr-un rezistor limitator. Diagrama este prezentată în figură.


5 Schiță pentru controlul unui registru de deplasare prin interfața SPI

Să scriem o schiță care implementează o „undă de călătorie” prin aprinderea secvențială a LED-urilor conectate la ieșirile registrului de deplasare.

#include const int pinSelect = 8; // se înregistrează selectați pin void setup() ( SPI.begin(); // inițializarea interfeței SPI pinMode(pinSelect, OUTPUT); // digitalWrite(pinSelect, LOW); // selectează dispozitivele slave (înregistrare) SPI.transfer(0); // șterge conținutul registrului digitalWrite(pinSelect, HIGH); // sfârșitul transmisiei Serial.begin(9600); } void loop() ( pentru (int i=0; i )

Mai întâi, să conectăm biblioteca SPI și să inițializam interfața SPI. Să definim pinul 8 ca pin de selecție a slave SS. Să ștergem registrul de deplasare trimițându-i valoarea „0”. Inițializați portul serial.

Pentru a aprinde un anumit LED folosind un registru de deplasare, trebuie să aplicați un număr de 8 biți la intrarea acestuia. De exemplu, pentru ca primul LED să se aprindă, furnizăm numărul binar 00000001, pentru al doilea - 00000010, pentru al treilea - 00000100 etc. Aceste numere binare, când sunt convertite în sistemul numeric zecimal, formează următoarea secvență: 1, 2, 4, 8, 16, 32, 64, 128 și sunt puteri a două de la 0 la 7.

În consecință, în ciclu buclă() Pe baza numărului de LED-uri, recalculăm de la 0 la 7. Funcție pow (bază, grad) Ridica 2 la puterea contorului de bucle. Microcontrolerele nu funcționează foarte precis cu numere de tip „dublu”, așa că folosim funcția de rotunjire pentru a converti rezultatul într-un număr întreg rundă(). Și transferăm numărul rezultat în registrul de deplasare. Pentru claritate, monitorul portului serial afișează valorile obținute în timpul acestei operațiuni: Unitatea „curge” prin descărcări - LED-urile se aprind într-un val.

6 „Val alergător” de la LED-uri

LED-urile se aprind unul câte unul și observăm un „val” de lumini. LED-urile sunt controlate folosind un registru de deplasare, la care ne-am conectat prin interfața SPI. Ca rezultat, doar 3 pini Arduino sunt folosiți pentru a controla 8 LED-uri. Dacă am conecta LED-urile direct la porturile digitale ale Arduino, ar trebui să folosim un port separat pentru fiecare LED.

Am studiat cel mai simplu exemplu de lucru Arduino cu magistrala SPI. Vom analiza mai detaliat funcționarea mai multor registre de deplasare cu conexiuni independente și în cascadă într-un articol separat.

Interfața serială sincronă SPI este proiectată pentru intrare-ieșire de date în interfețe punct la punct cu un dispozitiv master (SPI-master) și un dispozitiv slave (SPI-slave) (Fig. 1.24). Circuitul de control SPI-master generează impulsuri de ceas SCK, care transmit simultan semnale la ieșirea MOSI și primesc semnale la intrarea MISO. Aceleași impulsuri de ceas SCK, care intră în slave SPI, controlează recepția semnalelor la intrarea sa MOSI și generarea de semnale la ieșirea sa MISO. Circuitele de semnal MOSI și MISO separate permit implementarea ușoară a comunicației full-duplex.

Formate de date, parametri de semnal, caracteristici de sincronizare etc. nu sunt reglementate în interfață, de exemplu, rata de schimb de date este determinată doar de frecvența impulsurilor de ceas SCK generate de SPI-master. Distanța maximă depinde de nivelul de distorsiune a semnalului în liniile de comunicație, se presupune că este posibil un schimb de date fiabil la distanțe de până la câțiva metri.

În esență, nu este o interfață cu drepturi depline, nici măcar pentru stratul fizic. De fapt, SPI implementează o procedură standard de intrare/ieșire a datelor în registrele de deplasare, nu sunt furnizați algoritmi de control al operațiunilor sau de control al datelor transmise. Toate procedurile de control necesare trebuie efectuate de către SPI-master. Acest lucru, pe de o parte, necesită utilizarea unor instrumente de control suplimentare și, pe de altă parte, simplifică cât mai mult posibil implementarea interfeței SPI în sine. Slave SPI este un registru cu deplasare standard cu numărul necesar de biți de date.

De exemplu, microcontrolerele din familia AVR de la ATMEL acceptă intrarea/ieșirea datelor în ambele moduri SPI-master și SPI-slave. Ciclul de schimb standard implică transmiterea simultană a unui octet de date în ambele direcții (Fig. 1.24). La transmiterea mesajelor pe mai mulți octeți, SPI-slave trebuie să conțină un registru de deplasare de lățimea corespunzătoare, iar SPI-master trebuie să controleze schimbul secvenței necesare de octeți de date, procesând fiecare octet după următorul ciclu standard de operare a interfeței și asigurând începutul următorului ciclu de schimb standard.

Este folosit nu numai pentru schimbul de date între microcontrolere, ci și pentru interfațarea microcontrolerelor cu ADC-uri externe (ADC) și DAC-uri (DAC), cipuri de memorie - SRAM, FRAM, SEERAM și multe alte dispozitive. Datorită formatului de date seriale și organizării logice simple a interfeței SPI, aceste cipuri sunt fabricate în pachete compacte cu 8-16 pini. În tabel 1.6 prezintă exemple de microcircuite cu diverse scopuri funcționale și de la diferiți producători cu o interfață SPI. Aceste exemple arată că formatul interfeței seriale poate reduce semnificativ numărul necesar de linii I/O.

Tabelul 1.6

Tip de cip

Parametrii de bază

Tip de locuință

Producător

24 de biți, Delta-Sigma, 15 Hz

24 de biți, Delta-Sigma, 41 kHz

16 biți, SAR, 100 kHz

16 biți, PulSAR, 500 kHz

12 biți, U-out, 2,5 µs

16 biți, U-out, 10 µs

14 biți, I-out, 0,04 µs

12 biți, I-out, 0,6 µs

16 biți, U-out, 1 µs

www.maxim-ic.com

Tip de cip

Parametrii de bază

Tip de locuință

Producător

16 kBit, 1 trilion

4 kBit, nelimitat

64 kBit, nelimitat

256K, 32768×8, 0,1 milioane de cicluri

8K, 1024×8, 0,1 milioane de cicluri

16K, 8192×8, 0,1 milioane de cicluri

128K, 16384×8, 0,1 milioane de cicluri

256K, 32768×8, 0,1 milioane de cicluri

Termosenzor

13 biți, de la -40 la +150 C o (±0,5 C o)

Una dintre problemele care adesea trebuie rezolvată în instrumentele de automatizare este legată de numărul limitat de linii I/O pe microcontrolere. De obicei, numărul de semnale transmise depășește semnificativ capacitățile porturilor paralele, dar algoritmii de procesare pentru majoritatea semnalelor transmise permit întârzieri suplimentare asociate cu transmisia lor în format serial. În aceste cazuri, utilizarea registrelor standard serial-paralel este eficientă.

De exemplu, interfața SPI poate fi utilă pentru citirea stării unui număr mare de senzori on-off sau pentru introducerea datelor multi-biți într-un format paralel. În aceste scopuri, este convenabil să se utilizeze registre separate cu scriere paralelă și citire în serie (registru de schimb de 8 biți Parallel-In/Serial-Out), de exemplu CD74HCT166 (Fig. 1.25).

Schema de conectare pentru șaisprezece senzori cu două poziții (S1 – S16) prin interfața SPI a microcontrolerului este prezentată în Fig. 1.26. Trebuie remarcat faptul că înainte de a porni interfața SPI, este necesar să se genereze un semnal pentru a scrie informații în registrele de la intrările paralele D0-D7. Pentru aceasta, puteți utiliza una dintre ieșirile microcontrolerului, în acest exemplu PC0.

Orez. 1.25. Schema funcțională a registrului CD74HCT166

Orez. 1.26. Conectarea senzorilor cu două poziții la interfața SPI

Orez. 1.27. Conectarea unui indicator cu șase cifre la interfața SPI

Folosind registre cu înregistrare secvențială și ieșire paralelă a informațiilor (registru de deplasare pe 8 biți Serial-In, Parallel-Out) - SN74HC595, interfața SPI poate fi folosită și pentru ieșirea paralelă pe mai mulți octeți a informațiilor. Ca exemplu în Fig. Figura 1.27 prezintă o diagramă de conectare a unui indicator cu șase cifre și șapte segmente la un microcontroler. Spre deosebire de circuitul anterior, semnalul de ieșire paralel (PB1) trebuie generat după ce interfața SPI a terminat de transmis date prin mijloace din afara interfeței. De exemplu, algoritmul de interacțiune cu interfața trebuie să asigure monitorizarea numărului de octeți de date transferați, iar după finalizarea transferului ultimului octet, este necesar să se transmită suplimentar un semnal de ieșire paralel.

O altă interfață care poate fi folosită pentru a conecta fără probleme un dispozitiv cu un proiect electronic este interfața SPI.

SPI(Interfață periferică serială - interfață periferică serială), precum UART, este o interfață destul de veche, simplă și populară. Există multe dispozitive care lucrează pe această interfață (microcontrolere, EEPROM, ADC, DAC...). Îl vom folosi și pentru dispozitivele noastre.
Interfața SPI utilizează trei linii pentru transmiterea datelor: MOSI- transmitere; MISO– receptie; SCK– ceas. Se folosește o linie suplimentară SS(Selectare sclav?) – selectați un dispozitiv (dacă există mai multe dintre ele). SPI este o interfață sincronă full-duplex - transmisia și recepția sunt efectuate în paralel. Dispozitivul principal inițiază și fixează schimbul - maestru(poate fi doar unul). Sclav - sclav- un dispozitiv (pot fi mai multe) primește/trimite un octet sub influența unui semnal de ceas.

În microcontrolerele AVR, interfața SPI este utilizată dublu, ca interfață de comunicare și ca interfață pentru programarea serială în circuit. Marea majoritate a controlerelor au o interfață SPI (există excepții la modelele Tiny), dar chiar dacă nu este acolo, nu va fi dificil de implementat în software.

Deci, cum funcționează interfața SPI?
Și designul său este revoltător de simplu (este greu să-l numim chiar o interfață) - două registre de deplasare (master și slave), plus un generator pe partea master - asta este tot! Registrele de deplasare sunt închise într-un inel de-a lungul liniilor MOSI și MISO, semnalul de ceas de la generator este furnizat ambelor registre de deplasare (la slave prin linia SCK).

Înainte de începerea schimbului, datele sunt plasate în registre de deplasare, masterul pornește generatorul, generatorul „desprinde” 8 cicluri de ceas, în timpul acestor 8 cicluri de ceas registrele de deplasare „își schimbă” conținutul (masterul primește octetul slave, iar sclavul o primește pe a stăpânului) – asta e!
Dacă există mai multe dispozitive slave, schimbul se efectuează doar cu unul, al cărui semnal către SS este scăzut.

SPI este cea mai rapidă interfață serială. Cu o frecvență a oscilatorului master al microcontrolerului de 20 MHz, poate schimba la o viteză de 10.000.000 baud
(1,2 megaocteți pe secundă)!

Dezavantajul interfeței este că inițiatorul schimbului este întotdeauna maestru. Aceasta înseamnă că, dacă s-a întâmplat ceva la periferie, maestrul va ști despre asta numai atunci când el însuși „decide” să conducă o sesiune de comunicare (se pierde eficiența). Producătorii de AVR au găsit o cale de a ocoli acest dezavantaj. Dacă SPI-ul microcontrolerului este configurat ca master, pinul SS poate fi configurat atât ca intrare, cât și ca ieșire. Dacă pinul este configurat ca ieșire, acesta este utilizat pentru a selecta dispozitivul slave. Dar dacă pinul SS este configurat ca intrare, atunci când pe acest pin apare un nivel scăzut, microcontrolerul va comuta automat SPI-ul în modul slave și va putea primi date de la un alt master. După sesiunea de schimb, SPI rămâne în modul slave pentru a-l transfera în modul master, trebuie să reconfigurați SPI.

Cred că pentru dispozitivele de blog, acest algoritm de comutare master-slave va fi rar necesar, așa că vom folosi SPI doar ca master sau doar ca slave.
Dacă dispozitivul de blog este un dispozitiv de ieșire (de exemplu, o tastatură), atunci SPI-ul va fi master, iar în proiectul tău SPI-ul va fi slave.
Dacă dispozitivul de blog este un dispozitiv de intrare (de exemplu, un indicator digital), atunci SPI-ul va fi slave, iar în proiectul tău SPI-ul va fi maestru.

Pentru a conecta dispozitivul la proiectul dvs. prin interfața SPI aveți nevoie de:
1 Conectați dispozitivul blog la pinii corespunzători ai microcontrolerului.
2 Configurați SPI-ul controlerului dvs. (ca master sau slave). Pentru a face acest lucru, scrieți anumite valori în porturile I/O corespunzătoare.
3 Aveți proceduri (de scriere) pentru primirea/transmiterea mesajelor prin SPI în programul dvs.
Acum să ne uităm la fiecare punct în detaliu:


1 CONECTAREA DISPOZITIVELOR PRIN SPI.
Pur și simplu conectăm pinii cu același nume MOSI-MOSI, MISO-MISO, SCK-SCK, SS-SS. Dacă conexiunea este doar între două dispozitive, atunci SS-SS, în principiu, nu este necesar, dar trebuie să vă asigurați că pinul SS al dispozitivului slave este scăzut (tras la pământ), în caz contrar dispozitivul nu va participa la schimbul.


2 SETARE SPI.

SPI are patru moduri de operare (0, 1, 2, 3). Modul de funcționare depinde de marginea semnalului de ceas pe care se efectuează schimbul. În plus, puteți configura ce bit (cel mai semnificativ sau mai scăzut) este transmis primul. Pentru schimb, acest lucru nu contează - rezultatul va fi același (modurile de operare sunt necesare pentru a ajusta SPI la dispozitivele de la diferiți producători). Master și slave trebuie să funcționeze în același mod.
Pentru dispozitivele de blog vom folosi următoarele setări SPI:
Mod - 0
Se transmite cel mai semnificativ bit primul
Frecvența ceasului - după împrejurări(pentru SPI, frecvența nu este atât de importantă, deoarece ceasul provine dintr-o singură sursă).
De exemplu, să luăm microcontrolerul ATmega8 cu un oscilator master intern de 8 MHz. Vom configura porturile de intrare/ieșire de control ale controlerului în diferite medii de programare.

Generator de algoritmi.
Creați un proiect ( Fișier/Nou). Selectați microcontrolerul și frecvența oscilatorului principal în Opțiuni/Opțiuni de proiect...(ATmega8, oscilator master intern la 8 MHz). În bara de instrumente, faceți clic pe butonul „S” - controlați personalizarea registrului” și selectați SPI.
Setări pentru maestru(pentru comunicarea cu un dispozitiv de ieșire):

Setări pentru sclav(pentru comunicarea cu dispozitivul de intrare):


Faceți clic pe „OK”. Gata – SPI este inițializat și gata de utilizare.

Asamblator. Puteți săpa mai adânc în fișa de date pentru controler, puteți lua o bucată de asma dintr-un proiect compilat în C, puteți traduce comenzile mnemonice Algorithm Builder - alegeți ceea ce vă place.
Setări pentru master (pentru comunicarea cu dispozitivul de ieșire):

init-SPI-slave: sbi 0x17,0x04 ldi r16,0x00 out 0x0E,r16 ldi r16,0xC0 out 0x0D,r16

CodeVisionAVR. Pentru a genera setări SPI, faceți clic pe pictograma roată ( CodeWisardAVR) pe bara de instrumente. În fereastra care se deschide, selectați mai întâi fila Chip, selectați microcontrolerul din ea și setați frecvența cu care va funcționa oscilatorul principal. Apoi, selectați și completați fila SPI în conformitate cu caracteristicile necesare.

Setări pentru master (pentru comunicarea cu dispozitivul de ieșire):

// Inițializare portul B // Func7=In Func6=In Func5=Out Func4=In Func3=Out Func2=Out Func1=In Func0=In // Star7=T Star6=T State5=0 State4=T State3=0 State2=0 State1=T State0=T PORTB= 0x00 ;

// Inițializarea portului B // Func7=In Func6=In Func5=Out Func4=In Func3=Out Func2=Out Func1=In Func0=In // State7=T State6=T State5=0 State4=T State3=0 State2= 0 Stare1=T Stare0=T PORTB=0x00; DDRB=0x2C; // Inițializare SPI // Tip SPI: Master // Rată de ceas SPI: 2000.000 kHz // Faza ceas SPI: jumătate de ciclu // Polaritate ceas SPI: scăzută // Ordinea datelor SPI: MSB First SPCR=0xD0; SPSR=0x00;

Setări pentru slave (pentru comunicarea cu dispozitivul de intrare):

// Inițializare portul B // Func7=In Func6=In Func5=In Func4=Out Func3=In Func2=In Func1=In Func0=In // Stare7=T Stare6=T Star5=T Star4=0 Star3=T Star2=T Star1=T Star0=T PORTB= 0x00 ; DDRB= 0x10; // Inițializare SPI // Tip SPI: Slave// Rata de ceas SPI: 2000.000 kHz

// Faza ceasului SPI: jumătate de ciclu

// Polaritate ceas SPI: Scăzută // Ordinea datelor SPI: MSB First SPCR= 0xC0 ; SPSR= 0x00 ;// Initializarea portului B // Func7=In Func6=In Func5=In Func4=Out Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=0 State3=T State2= T Star1=T Star0=T PORTB=0x00; DDRB=0x10; // Inițializare SPI // Tip SPI: Slave // ​​​​Rată de ceas SPI: 2000.000 kHz // Faza ceas SPI: jumătate de ciclu // Polaritate ceas SPI: scăzută // Ordinea datelor SPI: MSB First SPCR=0xC0; SPSR=0x00;


Salvați proiectul generat (

File\Generate, Save and Exit

Generator de algoritmi.
). A fost creat un proiect cu toate setările necesare pentru SPI. Alte periferice (adesea inutile) sunt de asemenea inițializate în proiect. După crearea unui proiect, îl puteți corecta - eliminați tot ceea ce nu este necesar. 3 CREAREA PROCEDURILOR DE PRELUCRARE SPI.
Lucrul cu SPI în microcontroler este organizat foarte simplu. Pentru a începe schimbul de date în controlerul principal, trebuie doar să scrieți octetul transmis în registrul SPDR - schimbul va începe automat. La finalizarea schimbului, este apelată procedura de gestionare a întreruperilor, în care citim octetul primit de la SPDR. Cu un controler slave, este și mai ușor: după ce schimbul este complet, este apelată procedura de gestionare a întreruperilor, în care citim octetul primit de la SPDR. Difuzare

Dacă în timpul unui transfer de octeți există o încercare de a scrie în registrul SPDR, va apărea un conflict de scriere. Prin urmare, programul trebuie să se asigure că următorul octet este transmis după ce a fost primit cel anterior. Cea mai bună soluție la această problemă ar fi următorul algoritm: primul octet, începutul pachetului de octeți, este transmis din corpul programului, iar restul sunt transmise de la întreruperea de la sfârșitul transferului prin SPI. În acest fel, programul principal este „eliberat” de munca de transfer a unui șir de octeți și, în același timp, nu poate apărea un conflict de scriere, deoarece întreruperea este apelată când schimbul este finalizat.

Deoarece intenționăm să transferăm octeți unici prin SPI, nu vom folosi algoritmul de mai sus.

Asamblator.
Codul este extrem de simplu. Pentru transmisie, scriem la SPDR, octetul primit este citit din SPDR în corpul de întrerupere.

CodeVisionAVR. Pe lângă inițializare, CodeWisardAVR va crea și o procedură de gestionare a întreruperilor. Nu este necesar nimic suplimentar.

// primirea/transmiterea datelor prin SPI în corpul de întrerupere interrupt void spi_isr(void) ( unsigned char data; data=SPDR; ) // pregătirea/transmiterea datelor prin SPI în corpul programului unsigned char data; SPDR=date;

Asta pare să fie tot ce am vrut să spun despre SPI.
Interfața este destul de simplă și nu ar trebui să provoace probleme atunci când o utilizați.

(Vizitat de 5.231 ori, 1 vizite astăzi)

Acum aveți o înțelegere generală a interfeței periferice seriale, puteți trece la modulul SPI.
Modulul SPI al microcontrolerului AVR atmega16 folosește 4 pini pentru funcționarea sa - MOSI, MISO, SCK și SS. Când modulul nu este utilizat, acești pini sunt linii de porturi I/O de uz general. Când modulul este activat, modurile de funcționare ale acestor pini sunt redefinite conform următorului tabel.

Dacă la microcontroler sunt conectate mai multe dispozitive periferice, orice pini de uz general pot fi utilizați ca pini de selecție suplimentari (SS). În acest caz, pinul SS standard trebuie întotdeauna configurat corect, chiar dacă nu este utilizat.

Registrele modulului SPI

Microcontrolerul atmega16 folosește trei registre pentru a lucra cu modulul SPI:

registru de control SPCR,
- Registrul de stare SPSR,
- Registrul de date SPDR.

Toate cele trei registre sunt pe opt biți.

Configurația modulului SPI este setată folosind SPCR (SPI Control Register).

SPIE– activează/dezactivează întreruperile din modulul SPI. Dacă acest bit este setat la 1, întreruperile SPI sunt activate.

SPE– pornește/oprește modulul SPI. Dacă bitul este setat la 1, modulul SPI este activat.

DORD– determină ordinea transferului datelor. Când bitul este setat la 1, conținutul registrului de date este transmis mai întâi bitul cel mai puțin semnificativ. Când un bit este șters, bitul cel mai semnificativ este primul.

MSTR– determină modul de funcționare al microcontrolerului. Dacă bitul este setat la 1, microcontrolerul funcționează în modul Master. Dacă bitul este resetat, este în modul Slave. De obicei, microcontrolerul funcționează în modul master.

CPOLŞi CPHA– determinați în ce mod funcționează modulul SPI. Modul de operare necesar depinde de dispozitivul periferic utilizat.


SPR1
Şi SPR0– determinați frecvența semnalului de ceas al modulului SPI, adică cursul de schimb. Viteza maximă de transfer posibilă este întotdeauna indicată în specificațiile dispozitivului periferic.


Registrul de stare SPSR (SPI Status Register) este conceput pentru a monitoriza starea modulului SPI
, în plus, conține un bit suplimentar de control al vitezei de transmisie.


SPIF
– flag de întrerupere SPI. Este setat la 1 la finalizarea unui transfer de octeți de date. Dacă întreruperile modulului sunt activate, o întrerupere SPI este generată simultan cu setarea acestui flag. Acest flag este, de asemenea, setat la 1 atunci când microcontrolerul este transferat din modul master în modul slave folosind pinul SS.
Flag-ul este resetat de hardware, la apelarea unei rutine de întrerupere sau după citirea registrului SPSR și apoi accesarea registrului de date SPDR.

WCOL- scrieți steag de conflict. Indicatorul este setat la 1 dacă se încearcă scrierea în registrul de date SPDR în timpul transferului de date. Indicatorul este șters de hardware după citirea registrului SPSR și apoi accesarea registrului de date SPDR.

SPI2X- bit de dublare a vitezei de transmisie. Setarea acestui bit la 1 dublează frecvența semnalului de ceas SCK. Microcontrolerul trebuie să funcționeze în modul master.

Relația dintre biții SPR0, SPR1, SPI2X și frecvența de ceas SCK este prezentată în tabel.

Unde Fosc este frecvența de ceas a microcontrolerului AVR.


Registrul SPDR (SPI Data Register) este destinat transmiterii și primirii datelor.
. Scrierea datelor în acest registru inițiază modulul SPI să transmită date. Când acest registru este citit, conținutul buffer-ului de registru de deplasare al modulului SPI este citit.

Cod program

Codul minim de program pentru lucrul cu modulul SPI constă din două funcții:

Funcții de inițializare.
- funcții de transmitere/recepție de octeți de date

Inițializarea modulului SPI

Inițializarea include configurarea pinilor SPI ai modulului și a registrului de control SPCR.


#define SPI_PORTX PORTB
#define SPI_DDRX DDRB

#define SPI_MISO 6
#define SPI_MOSI 5
#define SPI_SCK 7
#define SPI_SS 4

/*inițializați modulul SPI în modul master*/
void SPI_Init(void)
{

/*configurarea porturilor I/O
toți pinii, cu excepția ieșirilor MISO*/
SPI_DDRX |= (1<SPI_PORTX |= (1<

/*rezoluție spi, cel mai semnificativ bit înainte, master, modul 0*/
SPCR = (1<SPSR = (0<}

Transmiterea/recepția datelor

Procesul de transmitere/recepție a datelor folosind un modul SPI care funcționează în modul Master constă în următoarea secvență de acțiuni:

1. stabilirea unui nivel logic scăzut pe linia SS
2. încărcarea datelor în registrul SPDR
3. așteptarea încheierii transferului (verificarea steagului SPIF)
4. Salvați datele primite (citiți SPDR) dacă este necesar
5. reveniți la pasul 2 dacă nu au fost transferate toate datele
6. Setarea nivelului logic înalt pe linia SS

Mai jos sunt câteva opțiuni pentru funcția de transmisie/recepție a datelor.

Transferarea unui octet de date prin SPI


void SPI_WriteByte (date uint8_t)
{
SPI_PORTX &= ~(1<SPDR = date;
în timp ce(!(SPSR & (1<SPI_PORTX |= (1<}

Transmiterea și primirea unui octet de date prin SPI

uint8_t SPI_ReadByte(date uint8_t)
{
raport uint8_t;
SPI_PORTX &= ~(1<SPDR = date;
în timp ce(!(SPSR & (1<raport = SPDR;
SPI_PORTX |= (1<raport de retur;
}

Transferarea mai multor octeți de date prin SPI
*data este un pointer către matricea de date transmise, iar num este dimensiunea matricei


void SPI_WriteArray(uint8_t num, uint8_t *data)
{
SPI_PORTX &= ~(1<în timp ce(num--)(
SPDR = *date++;
în timp ce(!(SPSR & (1< }
SPI_PORTX |= (1<}

//Exemplu de utilizare:
uint8_t buf = (12, 43, 98);


SPI_WriteArray(3, buf);

Transmiterea și primirea mai multor octeți de date prin SPI
*data este un pointer către matricea de date transmise, iar num este dimensiunea matricei.
Datele primite vor fi stocate în aceeași matrice.


void SPI_ReadArray(uint8_t num, uint8_t *data)
{
SPI_PORTX &= ~(1<în timp ce(num--)(
SPDR = *date;
în timp ce(!(SPSR & (1<*date++ = SPDR;
}
SPI_PORTX |= (1<}

Fișiere

Un driver SPI simplu care combină toate funcțiile descrise mai sus -



 


Citire:



Utilizarea stilurilor în Excel Cum să vă creați propriul stil nou

Utilizarea stilurilor în Excel Cum să vă creați propriul stil nou

Dacă utilizați în mod constant aceleași opțiuni pentru a formata celulele foii de lucru din foile de calcul, ar putea fi înțelept să creați un stil de formatare...

Ce erori apar în timpul instalării?

Ce erori apar în timpul instalării?

Notă: Programele AutoLISP pot fi executate numai pe versiunea completă a AutoCAD, ele nu funcționează sub AutoCAD LT. (excluzând cazurile de încărcare...

Statutul social al unei persoane în societate

Statutul social al unei persoane în societate

Sugerați ceea ce determină alegerea unei persoane cu privire la statutul său principal. Folosind textul și faptele vieții sociale, faceți două presupuneri și...

Interpretarea completă a erorilor

Interpretarea completă a erorilor

Destul de mulți utilizatori s-au confruntat cu fenomenul ecranului albastru al morții. Ce trebuie să faceți (Windows 7 este cel mai adesea predispus la această problemă)...

imagine-alimentare RSS