Serial Peripheral Interface (SPI) ble utviklet av Motorola for å tillate sine sjetonger til å kommunisere med hverandre, mye som Philips utviklet I2C serial bus for sin egen integrerte kretser. Mens disse to busser gjøre i stor grad den samme jobben, begge har blitt nesten like vanlig, og mange eksterne enheter bruke enten den ene eller den andre til å kommunisere med en rekke produkter. Dette allestedsnærvær er derfor smådjevler støtte både av dem.
SPI har noen fordeler over I2C, særlig støtte for høyere dataoverføringshastighet., SPI har også en tosidig evne som gjør det spesielt egnet for de programmer som krever samtidig to-veis kommunikasjon.
På den annen side, SPI krever minst tre ledninger, som deles av alle enheter på bussen, og en rekke av enheten-utvalget linjer, en for hver perifer koblet til kontrolleren enheten. I2C, derimot, krever bare to ledninger; den bruker unike adresser for å identifisere alle enhetene på bussen., Dette gjør du arbeider med flere enheter mer oversiktlig enn SPI-adresse-mindre tilnærming, selv om noen utviklere foretrekker å bruke maskinvare for å velge en enhet snarere enn adresse data.
– Kontrollere Og-Tilbehør
SPI skiller enheter i ‘kontrollere’ og ‘enheter’. Bare en enhet kan sende ut timing pulser for å synkronisere data overføringer, og det er ett valgt å være kontrolleren. Alle andre, som du vil synkronisere tidsberegning med kontrolleren, anses som datterselskap til eksterne enheter., Kontrolleren — som i ditt produkt må tiden være sin imp — og periferiutstyr alle kan sende og motta data, men bare kontrolleren kan etablere timing mønster som de alle virker. Dette hotellet av en fast timing ordningen er det som gjør SPI, som I2C, en ‘synkron’ buss.
De Fysiske Buss
imp ‘ s SPI gjennomføringen har fire linjer:
- SCLK seriell klokke signal fra senderen.
- COPI, kort for ‘Controller Ut, Perifer I’ (noen ganger merket MOSI i gamle datablader).,
- CIPO, kort for ‘Controller I, Perifer Ut» (noen ganger merket MISO).
- CS, kort for «Chip Velg’ (noen ganger merket SS, nSS eller SYNKRONISERING)
COPI og CIPO er data-overføring linjer.
imp001 og imp002 ikke gi dedikert CS pinner: i stedet kan du bruke noen av disse imp ‘ s andre GPIO pinner. Den imp003 opp og gi dedikert CS pinner som en del av deres SPI-busser, som er merket på imp pin-mux side.
Merk imp005 gir en dedikert chip velg pin-kode på hver av sine to SPI busser. For spiBCAD dette er pin-D; for spi0 dette er pin CS0., Imp API-metoden chipselect() kan bli brukt til å ta kontroll over påstanden og de-påstanden om disse chip velg pinner (se metode-dokumentasjonen for mer informasjon).
SPI på imp: opp til fire linjer koble til en enkelt ekstern enhet
Denne tilnærmingen følger Motorola ‘ s definisjon av SPI: at hver buss transaksjon — egentlig en batch av data byte — bør knyttes til en bestemt ytre., Texas Instruments modifisert med SPI-spesifikasjon for å tillate hver byte til å bli send til en bestemt perifer, selv om dette krever en dedikert CS linje. Denne modusen er for øyeblikket ikke støttes av noen imp.
Signalering
Forutsatt at vi har et enkelt perifer koblet til kontrolleren, kommunikasjon er initiert av kontrolleren trekke CS linje lav. Den forteller perifer å få klar til å snakke. Nå kontrolleren begynner å sende klokke pulser ut langs SCLK linje, vanligvis dataoverføringer er knyttet til den stigende flanke av hver puls, men det er ikke alltid tilfelle.,
Klokkes data inn og ut: imp sender en kommando, perifere returnerer data
kontrolleren vil nå overføre data på COPI linje, aktivt kjører line høy til å signalisere en 1 eller lav for en 0. Den perifere vil lese signal — som kan være en kommando for en sensor lesing for å bli sendt, for eksempel — og det vil gå tilbake at informasjon på CIPO linje, igjen kjører linjen for å holde seg høy til å signalisere en 1 eller kjøre det lite å sende en 0., Dette kravet at linjen være aktivt drevet høy eller lav, heller la den slå seg til en stat eller den andre ved å koble en motstand, er det grunn SPI kan støtte høyere hastigheter enn I2C kan. I2C mister overføring tiden mens pull-up motstander returnerer linje til høy.
når Det er sagt, er det likevel lurt å også ha en pull-up på en CS linje for å sikre at det går høyt når imp er å starte eller sover og derfor ikke i stand til å kjøre linjen høy manuelt. Holde linjen høy sikrer de perifere vil ignorere eventuelle feil på data og klokke linjer.,
Når kontrollen ikke hva den vil, – stasjoner CS line høy gang, og det perifere kan hvile.
imp SPI Valg
Hver imp har en rekke uavhengige SPI busser, tilgjengelige egenskapene til enhetens maskinvare-objektet, som er lagt på start-up. Hver imp er pin-mux tabellen viser at det er mange valgmuligheter, avhengig av hvilken type imp du bruker i ditt produkt. Dette dokumentet antar at du bruker en imp001, så bør du kontakte pin-mux tabellen hvis du arbeider med et annet imp., Den imp001 er to SPI busser er både tre-wire implementeringer av bussen, og koblet til pinne 1, 8 og 9, og 2, 5 og 7, henholdsvis. Pinne 1 og 5 er SCLK; 8 og 7 COPI, og 9 og 2 CIPO. Uansett hvilken av de to busser du bruker, det er god praksis å alias det innledningsvis:
spi1 <- hardware.spi257;spi2 <- hardware.spi189;
Konfigurere enten for bruk er rett og slett et spørsmål om å fortelle imp hvor fort du ønsker buss å kjøre, og for å gi et sett av konstanter som til sammen avgjør hvor bussen skal fungere:
spi1.configure(modeFlags, speed);
Først hastighet., 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) kant | |||
MSB_FIRST | Send mest signifikante bit første (standard) | ||||
LSB_FIRST | Send den minst signifikante bit første | ||||
NO_SCLK | SCLK pin-koden ikke brukes | ||||
USE_CS_L | Aktiverer bruk av dedikert chip velg pin-kode (imp005 bare) |
Disse kan kombineres, hvis du trenger dem for å være, ved hjelp av logisk ELLER operatør, |
, selv om noen er gjensidig utelukkende, så bør ikke kombineres: SIMPLEX_TX og SIMPLEX_RX, for eksempel., Å bruke begge CLOCK_IDLE_LOW og CLOCK_2ND_EDGE, for eksempel, i stedet for å skrive en eneste konstante som en parameter i konfigurer – () metode som du vil inkludere begge deler, atskilt av |
symbol:
spi1.configure(SIMPLEX_TX | MSB_FIRST | CLOCK_IDLE_LOW, 400);
Kombinasjoner kan være nødvendig hvis de er angitt av perifer er dataark, selv om dette kanskje ikke umiddelbart klart til årets nykommer. Dataark kan snakke om en enhet er «SPI-Modus», eller sin CPOL (Klokke Polaritet) og CPHA (Klokke Fase) verdier., CPOL og CPHA bestemme hvilke kanter av klokke signal er brukt til å kjøre bil og sample data signaler. Hver av disse to parameterne har to mulige tilstander, for fire mulige kombinasjoner i alt:
SPI-Modus
SPI Moduser bare indeksere disse kombinasjonene snarere enn egen CPOL og CPHA-verdier. Kontrolleren og den perifere har til å kommunisere ved hjelp av den samme CPOL og CPHA-verdier, og dermed samme Modus., Flere enheter kan godt bety forskjellige konfigurasjoner, slik det kontrolleren for å konfigurere seg selv hver gang det er behov for å kommunisere med en bestemt ytre.,følgende tabell:
Lesing Og Skriving av Data
etter å Ha konfigurert SPI-buss, bruker du skriv() metode for å sende en streng av byte til ekstern enhet:
spi1.write("This is an LCD display");
Bruk av en streng er valgfritt: du kan også sende en blob av raw-data byte:
local blob = blob(4); // Create a four-byte blob...blob.writen(0xDEADBEEF, 'i'); // ...and write a 32-bit value to itspi1.write(blob);
Enten du vil lese en streng eller en blob, trenger du en av imp API er to SPI les metoder:
local bytes = spi1.readblob(8);local inputString = spi1.readstring(16);
heltallsverdien gått som en parameter er henholdsvis antall byte som skal leses inn i blob og antall tegn som skal settes inn i strengen., Selvfølgelig, siden en karakter tar opp en byte disse to metodene er likeverdige. Sistnevnte bare konverterer blob å string for deg.
på Grunn av den «full duplex» naturen av SPI-buss, skriver og leser alltid opptrer samtidig. Med lese-og skrive-kommandoene vi har sett så langt, data beveger seg i motsatt retning fra den vi er interessert i er ignorert eller zeroed. Så, når du skriver en streng, si, alle data som kommer på imp fra de perifere er ignorert., Under en av de to leseoperasjoner, en matchende størrelse på ‘dummy’ – null byte er skrevet til den perifere: hvis du leser åtte byte, si, åtte 0s er skrevet automatisk.
for Å behandle denne samtidige to-veis kommunikasjon, imp API har en fjerde metode som kombinerer leser og skriver:
local inputString = spi1.writeread(outputString);
Så, som strengen outputString sendes ut langs COPI linje, variabelen inputString blir fylt av data byte kommer på på CIPO. Du kan sende og motta strenger eller blobs, men både inngang og utgang må være av samme type., Imidlertid store din utgang blob, dine innspill blob vil være av samme størrelse. Likeledes, inngang og utgang strenger vil være av samme lengde.
Full-duplex drift kan også brukes med enheten som ikke forvente å operere på den måten — de som krever lese-og skrive ‘dummy’ – byte for å være en bestemt, ikke-null-verdi. Dette kravet regler ut med vanlig skriv(), readblob() og readstring () – metodene, men writeread() kan bli brukt på sin plass å sørge for at enheten er foretrukket dummy-verdier som er brukt.,
Eksempel Kode
følgende koden fungerer med de Analoge Enheter ADXL345 digital akselerometer, en del som bruker SPI til å kommunisere med sin vert mikrokontroller. Den støtter også I2C, og pinnene på dette Mer breakout styret, som er basert på chip, er merket i henhold til dette. Brikken har datablad kan lastes ned fra Analog Devices nettstedet.
Hvordan Koden Fungerer
Vi bruke en imp001 er spi257 buss, aliased nær begynnelsen av oppføringen som spi. Vi har også alias pin-8 som CS linje. Funksjonen spiWriteReg() viser hvordan disse er brukt., En skrive transaksjonen er signalisert ved å bytte CS linje lav. Neste adressen til registeret vi ønsker å skrive til er konvertert fra et Ekorn 32-bit signert heltall til et 8-bits verdi ved å skrive det til en blob. Dette blob er da skrevet til SPI-buss. Vi gjør det samme med den verdien vi ønsker ADXL345 å sette inn i registeret, og deretter har vi satt CS line høy igjen for å signalisere slutten av transaksjonen.,
Mer/Analog Devices ADXL345
funksjonen spiReadReg() fungerer på samme måte, bare denne gangen kan vi lese verdi data fra bussen etter skriftlig kilde registrere adresse. Den ADXL345 krever noen justeringer som skal gjøres for å registrere adressen i dette tilfellet: bit 7 behov for å bli sett for å markere den transaksjonen som en leseoperasjon, og bit 6 behov for å bli sett, for å fortelle chip at vi forventer mer enn en eneste byte for å bli sendt tilbake.,
Hvor programmet starter riktig, vi konfigurere imp ‘ s SPI buss for å matche kravene til ADXL345 chip. Den bruker SPI-Modus 3 — dvs. både CPOL og CPHA bør bli sett — så vi bruker den tilsvarende imp parameter: CLOCK_IDLE_HIGH | CLOCK_2ND_EDGE i konfigurer – () anropet. Vi har også angi hastighet til 100kHz. Neste, imp ‘ s pinne 8, som er i drift her som CS pin-koden er konfigurert som en digital utgang og satt høyt.
Kabling opp ADXL345
Andre funksjoner i programmet, må du initialisere det ADXL345 seg selv heller enn SPI-buss., Den ADXL345 er initialisert, og koden leser i verdi fra registrerer adressen 0x00
for å sikre at enheten er til stede på bussen. Brikken har en selv-test-modus, noe som gir en rekke kalibrering målinger som skal tas, dette gjør vi, og lagre resultatene. Senere, i funksjon loop(), verdiene brukes til å justere den siste målingene fra akselerometeret.,
ADXL345 sparer sin x-, y – og z-aksen prøver som 16-bits verdier, hver i to 8-bit registre; loop() bruker spiReadReg () – funksjonen for å få hver verdi er to komponenter, og deretter konverterer dem til én verdier ved å multiplisere den mest signifikante byte av 256 og legge til resultatet verdien av de minst signifikante byte.