interfața periferică serială (SPI) a fost dezvoltată de Motorola pentru a permite cipurilor sale să comunice între ele, la fel cum Philips a conceput magistrala serială I2C pentru propriile circuite integrate. În timp ce aceste două autobuze fac în mare parte aceeași treabă, ambele au devenit aproape la fel de obișnuite, iar multe dispozitive periferice folosesc unul sau altul pentru a comunica cu un microcontroler gazdă. Această ubicuitate este motivul pentru care imps îi sprijină pe amândoi.

SPI are unele avantaje față de I2C, în special suport pentru o rată mai mare de transfer de date., SPI are, de asemenea, o capacitate duplex, ceea ce îl face deosebit de potrivit pentru acele aplicații care necesită o comunicare simultană bidirecțională.pe de altă parte, SPI necesită cel puțin trei fire, partajate de toate dispozitivele din magistrală și un număr de linii de selecție a dispozitivelor, câte unul pentru fiecare periferic conectat la dispozitivul de control. I2C, în schimb, necesită doar două fire; utilizează adrese unice pentru a identifica toate dispozitivele din autobuz., Acest lucru face ca lucrul cu mai multe dispozitive să fie mai simplu decât abordarea fără adrese a SPI, deși unii dezvoltatori preferă să utilizeze hardware pentru a selecta un dispozitiv, mai degrabă decât datele adresei.

Controlere și periferice

SPI separă dispozitivele în „controlere” și „periferice”. Un singur dispozitiv poate trimite impulsuri de sincronizare pentru a sincroniza transferurile de date, iar acesta este cel ales pentru a fi controlerul. Toate celelalte, care își sincronizează temporizările cu controlerul, sunt considerate periferice subsidiare., Controlerul — care în produsul dvs. trebuie să fie în prezent imp — și perifericele sale pot transmite și primi date, dar numai controlerul poate stabili modelul de sincronizare la care funcționează toate. Această stabilire a unei scheme de sincronizare fixă este ceea ce face ca SPI, cum ar fi I2C, să fie o magistrală „sincronă”.

magistrala fizică

implementarea SPI a imp are patru linii:

  • SCLK, semnalul ceasului serial de la controler.
  • copii, prescurtarea de la „Controller Out, periferic In” (MOSI uneori etichetat în fișe tehnice vechi).,
  • CIPO, prescurtarea de la „Controller In, Peripheral Out” (uneori etichetat MISO).
  • CS, prescurtarea de la „Chip Select” (uneori etichetate SS, NSS sau SYNC)

COPI și CIPO sunt liniile de transfer de date.

imp001 și imp002 nu oferă Pinuri CS dedicate: în schimb, poți folosi oricare dintre celelalte Pinuri GPIO ale acestor imp. Imp003 și versiuni ulterioare oferă PIN-uri CS dedicate ca parte a autobuzelor SPI, marcate pe pagina imp pin MUX.notă imp005 oferă un cip dedicat selectați pin-ul pe fiecare dintre cele două autobuze SPI. Pentru spiBCAD acesta este pinul D; pentru spi0 acesta este pinul CS0., Imp API metoda chipselect () poate fi folosit pentru a prelua controlul asupra afirmării și de-afirmare a acestor cip selectați pini (vă rugăm să consultați documentația metoda pentru mai multe informații).


SPI pe imp: până la patru linii se conecteze la un singur dispozitiv periferic

Această abordare urmează Motorola definiție a SPI: că fiecare autobuz tranzacție — în esență, un lot de bytes de date — ar trebui să fie legate de un anumit periferic., Texas Instruments a modificat specificația SPI pentru a permite fiecărui octet să fie trimis la un anumit periferic, deși acest lucru necesită o linie CS dedicată. Acest mod nu este acceptat în prezent de niciun imp.

semnalizare

presupunând că avem un singur periferic conectat la controler, comunicațiile sunt inițiate de către controler trăgând linia CS scăzută. Îi spune perifericului să se pregătească să converseze. Acum, controlerul începe să trimită impulsuri de ceas de-a lungul liniei SCLK; de obicei, transmisiile de date sunt fixate la marginea în creștere a fiecărui impuls, deși acest lucru nu este întotdeauna cazul.,


Pontaj datele în și în afara: imp trimite o comandă, periferice se întoarce de date

sistemul De comandă va transmite datele pe COPI linie, în mod activ de conducere pe linie de mare pentru a semnala un 1 sau scăzut pentru un 0. Perifericul va citi semnalul — care ar putea fi o comandă pentru ca o citire a senzorului să fie trimisă, de exemplu — și va returna aceste informații pe linia CIPO, conducând din nou linia să rămână ridicată pentru a semnala un 1 sau conducând-o scăzută pentru a transmite un 0., Această cerință ca linia să fie condusă în mod activ ridicat sau scăzut, mai degrabă lăsându-l să se stabilească într-o stare sau alta prin conectarea unui rezistor, este motivul pentru care SPI poate suporta viteze mai mari decât I2C poate. I2C pierde timpul de transmisie în timp ce rezistența sa de tracțiune readuce linia la înălțime.acestea fiind spuse ,este totuși o practică bună să aveți și o tragere pe o linie CS pentru a vă asigura că aceasta crește atunci când imp pornește sau doarme și, prin urmare, nu este capabilă să conducă linia înaltă manual. Menținerea liniei ridicate asigură perifericul va ignora orice glitches pe liniile de date și de ceas.,

când controlerul are ceea ce dorește, conduce linia CS ridicată încă o dată, iar perifericul se poate odihni.

imp SPI Opțiuni

fiecare imp are un număr de autobuze SPI independente, accesate ca proprietăți ale obiectului hardware al dispozitivului, care este instantiat la pornire. Tabelul pin MUX al fiecărui imp arată că există mai multe opțiuni, în funcție de tipul de imp pe care îl utilizați în produsul dvs. Acest document presupune că utilizați un imp001, deci ar trebui să consultați tabelul pin MUX dacă lucrați cu un alt imp., Cele două autobuze SPI imp001 sunt ambele implementări cu trei fire ale autobuzului și sunt conectate la pinii 1, 8 și 9, respectiv 2, 5 și 7. Pinii 1 și 5 sunt SCLK; 8 și 7 copii; și 9 și 2 CIPO. Oricare dintre cele două autobuze utilizați, este o practică bună să alias-o de la început:

spi1 <- hardware.spi257;spi2 <- hardware.spi189;

Configurarea fie pentru utilizare este pur și simplu o chestiune de a spune imp cât de repede doriți autobuz pentru a rula, și pentru a oferi un set de constante care determină modul în care autobuzul va funcționa:

spi1.configure(modeFlags, speed);

în Primul rând, de viteza., This is simply an integer value giving the throughput in kiloHertz (kHz):

The specific SPI data rates available (in kHz) are as follows:

imp001, imp002 imp003 imp004m imp005 imp006
spi189 spi257 spiEBCA
spiLGDK
spiAHSR
spiGJKL
spiBCAD
spi0
spiXTUVW
15,000 30,000 18,000 24,000 The SPI data rates
available range
from 5KHz to 22.,8MHz
The SPI is clocked
by dividing 160MHz
by any integer
from 7 to 32,000
inclusive
Min. 187KHz, max. 750KHz
7500 15,000 9000 12,000
3750 7500 4500 6000
1875 3750 2250 3000 All others
937.50 1875 1125 1500 Min. 187KHz,
theoretical max. 24MHz
468.75 937.50 562.50 750
234.,375 468.75 281.25 375
117.1875 234.375 140.,g) c
MSB_FIRST Trimite cel mai semnificativ bit prima (default)
LSB_FIRST Trimite bitul cel mai puțin semnificativ primul
NO_SCLK SCLK pin nu este folosit
USE_CS_L Permite utilizarea dedicat chip selectați pin (imp005 numai)

Acestea pot fi combinate, dacă aveți nevoie de ele pentru a fi, cu ajutorul logic SAU un operator, |, deși unele se exclud reciproc deci nu ar trebui să fie combinate: SIMPLEX_TX și SIMPLEX_RX, de exemplu., Pentru a utiliza ambele CLOCK_IDLE_LOW și CLOCK_2ND_EDGE, de exemplu, în loc de a introduce o singură constantă ca un parametru în configure() metoda ar include atât, separate prin | simbol:

spi1.configure(SIMPLEX_TX | MSB_FIRST | CLOCK_IDLE_LOW, 400);

Combinații pot fi necesare, dacă acestea sunt specificate de către periferic e datasheet, deși acest lucru poate să nu fie imediat evidente la nou-venit. Fișele tehnice pot vorbi despre „modul SPI” al unui dispozitiv sau despre valorile CPOL (polaritatea ceasului) și CPHA (Faza ceasului)., CPOL și CPHA determină care margini ale semnalului ceasului sunt utilizate pentru a conduce și a proba semnale de date. Fiecare dintre acești doi parametri are două stări posibile, pentru cele patru combinații posibile în toate:


SPI Moduri

SPI Moduri, pur și simplu, indicele aceste combinații, mai degrabă decât separat CPOL și CPHA valori. Controlerul și perifericul trebuie să comunice folosind aceleași valori CPOL și CPHA și astfel același mod., Perifericele Multiple pot însemna configurații diferite, astfel încât controlerul va trebui să se reconfigureze de fiecare dată când trebuie să comunice cu un periferic specific.,tabelul de mai jos:

Citirea Și Scrierea de Date

Având configurat SPI autobuz, utilizați metoda write() pentru a trimite un șir de octeți de la un dispozitiv periferic:

spi1.write("This is an LCD display");

Utilizarea unui șir este opțional: puteți trimite, de asemenea, o pată de date brute bytes:

local blob = blob(4); // Create a four-byte blob...blob.writen(0xDEADBEEF, 'i'); // ...and write a 32-bit value to itspi1.write(blob);

Dacă doriți pentru a citi un șir de caractere sau o pată de cerneală, aveți nevoie de unul dintre imp API două SPI citit metode:

local bytes = spi1.readblob(8);local inputString = spi1.readstring(16);

valoarea întreagă a trecut ca un parametru este, respectiv, numărul de octeți pentru a fi citit în blob și numărul de caractere care urmează să fie puse în șir., Desigur, deoarece un personaj ocupă un octet, aceste două metode sunt echivalente. Acesta din urmă convertește pur și simplu blob la șir pentru tine.din cauza naturii „full duplex” a autobuzului SPI, scrie și citește apar întotdeauna simultan. Cu comenzile de citire și scriere pe care le-am văzut până acum, datele care se deplasează în direcția opusă celei care ne interesează sunt ignorate sau zero. Deci, atunci când scrieți un șir, să zicem, orice date care ajung la imp de la periferic sunt ignorate., În timpul uneia dintre cele două operațiuni de citire, o dimensiune de potrivire a „dummy” octeți zero este scris la periferic: dacă citiți opt octeți, să zicem, opt 0s sunt scrise automat.

Pentru a gestiona acest simultană a două-mod de comunicare, imp API a patra metodă care combină citește și scrie:

local inputString = spi1.writeread(outputString);

Deci, ca o coardă outputString, este trimis de-a lungul COPI linie, variabila inputString este umplut de bytes de date vine pe la CIPO. Puteți trimite și primi șiruri sau blobs, dar atât de intrare și de ieșire trebuie să fie de același tip., Cu toate acestea mare blob de ieșire, blob de intrare va fi de aceeași dimensiune. De asemenea, șirurile de intrare și ieșire vor avea aceeași lungime.operațiunea Full duplex poate fi de asemenea utilizată cu un dispozitiv care nu se așteaptă să funcționeze în acest fel — cele care necesită citirea și scrierea octeților „dummy” pentru a fi o valoare specifică, diferită de zero. Această cerință exclude utilizarea regulată scrie(), readblob() și readstring() metode, dar writeread() poate fi folosit în locul lor să asigurați-vă că dispozitivul este de preferat dummy valori sunt utilizate.,

exemplu de cod

următorul cod funcționează cu accelerometrul Digital Analog Devices ADXL345, o parte care utilizează SPI pentru a comunica cu microcontrolerul gazdă. Aceasta susține, de asemenea, I2C, și pinii de pe această placă breakout Adafruit, care se bazează pe cip, sunt etichetate în consecință. Fișa tehnică a cipului poate fi descărcată de pe site-ul Analog Devices.

cum funcționează codul

folosim un autobuz spi257 imp001, alias aproape de începutul listării ca spi. De asemenea, alias pin 8 ca linie CS. Funcția spiWriteReg () arată modul în care acestea sunt utilizate., O tranzacție de scriere este semnalizată prin comutarea liniei CS la un nivel scăzut. În continuare, adresa registrului în care vrem să scriem este convertită dintr-un număr întreg semnat pe 32 de biți veveriță la o valoare de 8 biți scriind-o într-o pată. Acest blob este apoi scris în autobuzul SPI. Facem același lucru cu valoarea pe care dorim ca ADXL345 să o pună în acel registru și apoi setăm din nou linia CS ridicată pentru a semnala sfârșitul tranzacției.,


Adafruit/Dispozitive Analogice ADXL345

funcția spiReadReg() funcționează în același mod, numai că de data asta am citit valoarea datele din autobuz după ce a scris sursa înregistra adresa lui. ADXL345 necesită unele ajustări la adresa de înregistrare în acest caz: bit 7 trebuie să fie setat pentru a marca tranzacția ca o operație de citire, și biți 6 trebuie să fie setat pentru a spune cip că ne așteptăm mai mult de un singur octet să fie trimis înapoi.,în cazul în care începe programul propriu-zis, configurăm magistrala SPI a imp pentru a se potrivi cerințelor cipului ADXL345. Acesta utilizează modul SPI 3-ie. ambele CPOL și CPHA ar trebui să fie stabilită — așa că vom folosi echivalentul imp parametru: CLOCK_IDLE_HIGH | CLOCK_2ND_EDGE în configure() apel. De asemenea, am setat viteza la 100kHz. Apoi, pinul imp 8, care funcționează aici ca pinul CS, este configurat ca o ieșire digitală și setat la un nivel ridicat.


Cabluri de până la ADXL345

Alte funcții în program inițializa ADXL345 sine, mai degrabă decât SPI autobuz., ADXL345 este inițializat, iar codul citește în valoarea de la adresa registru 0x00 pentru a se asigura că dispozitivul este prezent în autobuz. Cipul are un mod de auto-testare care permite luarea unei serii de citiri de calibrare; acest lucru îl facem și stocăm rezultatele. Ulterior, în bucla funcțională (), aceste valori sunt utilizate pentru a regla citirile finale din accelerometru.,

ADXL345 salvează x-, y – si z-axa probe ca 16-bit valori, fiecare în două 8-bit registre; loop() folosește spiReadReg() funcție pentru a dobândi fiecare valoare are două componente și apoi le transformă în valori unice prin înmulțirea cel mai semnificativ octet cu 256 și adăugarea la rezultatul valoarea octetul cel mai puțin semnificativ.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *