Den Serielle Perifere Interface (SPI) blev udviklet af Motorola til at give sine chips til at kommunikere med hinanden, så meget som Philips udtænkt I2C serial bus for sin egen integrerede kredsløb. Mens disse to busser stort set udfører det samme job, er begge blevet næsten lige så almindelige, og mange perifere enheder bruger enten den ene eller den anden til at kommunikere med en værtsmikrocontroller. Denne allestedsnærværende er grunden til, at IMP støtter dem begge.
SPI har nogle fordele i forhold til I2C, især støtte til højere dataoverførselshastighed., SPI har også en duple.kapacitet, som gør det særligt velegnet til de applikationer, der kræver samtidig tovejskommunikation.
På den anden side kræver SPI mindst tre ledninger, der deles af alle enheder på bussen, og et antal enhedsvalglinjer, en for hver perifer, der er tilsluttet controllerenheden. I2C kræver derimod kun to ledninger; det bruger unikke adresser til at identificere alle enheder på bussen., Dette gør arbejdet med flere enheder mere ligetil end SPI ‘ s adressefri tilgang, selvom nogle udviklere foretrækker at bruge hard .are til at vælge en enhed i stedet for adressedata.
controllere og eksterne enheder
SPI adskiller enheder i ‘controllere’ og ‘eksterne enheder’. Kun en enhed kan sende timingpulser til synkronisering af dataoverførsler, og det er den, der er valgt til at være controlleren. Alle andre, der synkroniserer deres tider med controlleren, betragtes som subsidiære perifere enheder., Controlleren — som i dit produkt i øjeblikket skal være dens imp-og dens perifere enheder kan alle sende og modtage data, men kun controlleren kan etablere det timingsmønster, som de alle fungerer til. Denne etablering af et fast timingskema er det, der gør SPI, som I2C, til en’ synkron ‘ bus.
den fysiske Bus
imp ‘ s SPI-implementering har fire linjer:
- SCLK, det serielle ursignal fra controlleren.
- COPI, forkortelse for ‘ Controller Out, Peripheral In ‘(undertiden mærket MOSI i gamle datablade).,
- CIPO, forkortelse for ‘Controller In, Peripheral Out’ (undertiden mærket MISO).
- CS, forkortelse for ‘Chip Select’ (undertiden mærket SS, nSS eller SYNC)
COPI og CIPO er dataoverførselslinjerne.
imp001 og imp002 leverer ikke dedikerede CS-stifter: i stedet kan du bruge nogen af disse imp ‘ s andre GPIO-stifter. Imp003 og opefter leverer dedikerede CS-stifter som en del af deres SPI-busser, der er markeret på imp pin mu. – siden.
Bemærk imp005 giver en dedikeret chip select pin på hver af sine to SPI busser. For spiBCAD er dette pin D; for spi0 er dette pin CS0., Imp API-metoden chipselect () kan bruges til at tage kontrol over påstanden og påstanden om disse chip select-stifter (se metodedokumentationen for mere information).
SPI på imp: op til fire linjer oprette forbindelse til en enkelt ekstern enhed
Denne fremgangsmåde følger Motorola ‘ s definition af SPI: at hver bus transaktion, som hovedsagelig er et parti af data byte — skal være knyttet til en bestemt perifere., Te .as Instruments ændrede SPI-specifikationen for at give hver byte mulighed for at blive sendt til en bestemt perifer, selvom dette kræver en dedikeret CS-linje. Denne tilstand understøttes ikke i øjeblikket af nogen imp.
signalering
Hvis vi antager, at vi har en enkelt perifer forbindelse til controlleren, initieres kommunikationen ved, at controlleren trækker CS-linjen lavt. Den fortæller periferien at blive klar til at tale. Nu begynder controlleren at sende urpulser ud langs SCLK-linjen; typisk dataoverførsler indtastes til den stigende kant af hver puls, selvom det ikke altid er tilfældet.,
Clocking dataene ind og ud: imp sender en kommando, den perifere returnerer data
controlleren sender nu data på COPI-linjen, der aktivt kører linjen højt for at signalere en 1 eller lav for en 0. Periferien læser signalet — hvilket kan være en kommando for en sensoraflæsning, der skal sendes, for eksempel-og det returnerer disse oplysninger på CIPO-linjen, igen kører linjen for at forblive høj for at signalere en 1 eller kører den lavt for at transmittere en 0., Dette krav om, at linjen aktivt køres højt eller lavt, snarere at lade det slå sig ned til den ene stat eller den anden ved at forbinde en modstand, er grunden til, at SPI kan understøtte højere hastigheder end I2C kan. I2C mister transmissionstiden, mens dens pull-up modstand returnerer linjen til høj.
når det er sagt, er det ikke desto mindre god praksis at også have en pull-up på en CS-linje for at sikre, at den går højt, når imp starter eller sover og derfor ikke er i stand til at køre linjen højt manuelt. At holde linjen høj sikrer, at periferien ignorerer eventuelle fejl på data-og urlinjerne.,
når controlleren har det, den ønsker, kører den CS-linjen højt igen, og periferien kan hvile.
imp SPI-indstillinger
hver imp har et antal uafhængige SPI-busser, der er adgang til som Egenskaber for enhedens hard .areobjekt, som instantieres ved opstart. Hver imp ‘ s pin mu. – tabel viser, at der er mange valg, afhængigt af hvilken type imp du bruger i dit produkt. Dette dokument forudsætter, at du bruger en imp001, så du bør se pin mu. – tabellen, hvis du arbejder med en anden imp., Imp001 ‘ s to SPI-busser er begge implementeringer i tre ledninger af bussen og forbundet til ben 1, 8 og 9, samt 2, 5 og 7. Pin 1 og 5 er SCLK; 8 og 7 COPI; og 9, og 2 CIPO. Uanset hvilken af de to busser, du bruger, er det god praksis at alias det i starten:
spi1 <- hardware.spi257;spi2 <- hardware.spi189;
Konfiguration enten til brug, er simpelthen et spørgsmål om at fortælle den integrerede havpolitik, hvor hurtigt du ønsker bussen til at køre, og til at give et sæt af konstanter, der sammen afgøre, hvor bussen vil fungere:
spi1.configure(modeFlags, speed);
for det Første er hastigheden., 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ørst (standard) | ||||
LSB_FIRST | Send den mindst signifikante bit først | ||||
NO_SCLK | SCLK pin-kode er ikke benyttet | ||||
USE_CS_L | Aktivere brugen af dedikeret chip, skal du vælge pin-kode (imp005 kun) |
Disse kan kombineres, hvis du har brug for dem til at blive, ved hjælp af den logiske ELLER operatør, |
, selvom nogle er gensidigt eksklusive, så bør ikke kombineres: SIMPLEX_TX og SIMPLEX_RX, for eksempel., At bruge både CLOCK_IDLE_LOW og CLOCK_2ND_EDGE, for eksempel, i stedet for at indtaste en enkelt konstant som en parameter i den konfigurere() metode, du vil medtage begge, adskilt af |
symbol:
spi1.configure(SIMPLEX_TX | MSB_FIRST | CLOCK_IDLE_LOW, 400);
Kombinationer kan være nødvendigt, hvis de er specificeret af perifere ‘ s datablad, selvom det måske ikke umiddelbart indlysende, at den nyankomne. Datablade kan tale om en enheds ‘SPI Mode’, eller dens CPOL (ur polaritet) og CPHA (ur fase) værdier., CPOL og CPHA bestemmer, hvilke kanter af kloksignalet der bruges til at drive og prøve datasignaler. Hver af disse to parametre har to mulige tilstande, for fire mulige kombinationer i alt:
SPI Tilstande
SPI Tilstande bare indeks disse kombinationer snarere end separat CPOL og CPHA værdier. Controlleren og periferien skal kommunikere ved hjælp af de samme CPOL-og CPHA-værdier og dermed den samme tilstand., Flere perifere enheder kan godt betyde forskellige konfigurationer, så controlleren bliver nødt til at konfigurere sig selv hver gang den har brug for at kommunikere med en bestemt perifer.,den følgende tabel:
Læsning Og Skrivning af Data
Der er konfigureret SPI-bus, skal du bruge write () – metode for at sende en perlerække af bytes til den perifere enhed:
spi1.write("This is an LCD display");
Brug af en streng er valgfri: du kan også sende en klat af rå data bytes:
local blob = blob(4); // Create a four-byte blob...blob.writen(0xDEADBEEF, 'i'); // ...and write a 32-bit value to itspi1.write(blob);
uanset Om du ønsker at læse en streng eller en klat, du har brug for en af imp API ‘ s to SPI læs metoder:
local bytes = spi1.readblob(8);local inputString = spi1.readstring(16);
Det heltal, der gik som en parameter er, henholdsvis antallet af bytes der skal læses ind i den klat, og antallet af tegn til at blive sat ind i strengen., Selvfølgelig, da et tegn optager en byte, er disse to metoder ækvivalente. Sidstnævnte konverterer simpelthen blob til streng for dig.
På grund af den ‘fuld duple.’ karakter af SPI bus, skriver og læser altid forekomme samtidigt. Med de læse-og skrivekommandoer, vi har set indtil videre, ignoreres eller nulstilles data, der bevæger sig i den modsatte retning fra den, vi er interesseret i. Så når du skriver en streng, siger du, at data, der ankommer til imp fra periferien, ignoreres., Under en af de to læseoperationer skrives en matchende størrelse af’ dummy ‘nul byte til periferien: hvis du læser otte byte, siger, otte 0’ er skrives automatisk.
til At styre denne samtidige to-vejs kommunikation, imp API har en fjerde metode, som kombinerer læser og skriver:
local inputString = spi1.writeread(outputString);
Så, som strengen outputString bliver sendt ud langs COPI linje, variabel inputString er ved at blive fyldt af data bytes, der kommer på på CIPO. Du kan sende og modtage strenge eller klatter, men både input og output skal være af samme type., Uanset hvor stor din outputblob er, vil din inputblob være af samme størrelse. Ligeledes vil input og output strenge være af samme længde.
fuld duple .operation kan også bruges med enhed, der ikke forventer at fungere på den måde — dem, der kræver, at læse og skrive ‘dummy’ bytes er en specifik, ikke-nul værdi. Dette krav udelukker ved hjælp af de almindelige skrivemetoder(), readblob() og readstring (), men wrriteread() kan bruges i deres sted for at sikre, at enhedens foretrukne dummyværdier bruges.,
Eksempel-Kode
følgende kode arbejder med de Analoge Enheder ADXL345 digitale accelerometer, en del, der bruger SPI til at kommunikere med sin vært, microcontroller. Det understøtter også I2C, og stifterne på dette Adafruit breakout-kort, der er baseret på chippen, er mærket i overensstemmelse hermed. Chippens datablad kan do .nloades fra Analebstedet for analoge enheder.
hvordan koden fungerer
Vi bruger en imp001 spi257 bus, aliased nær begyndelsen af notering som spi. Vi har også alias pin 8 som CS linje. Funktionen spi .ritereg () viser, hvordan disse anvendes., En skrivetransaktion signaleres ved at skifte CS-linjen lav. Derefter konverteres adressen på det register, vi vil skrive til, fra et egern 32-bit underskrevet heltal til en 8-bit værdi ved at skrive det til en blob. Denne klat skrives derefter til SPI-bussen. Vi gør det samme med den værdi, vi ønsker, at AD .l345 skal indsættes i det register, og så sætter vi CS-linjen højt igen for at signalere afslutningen af transaktionen.,
Det Adafruit/Analog Devices ADXL345
Den funktion spiReadReg() virker på samme måde, kun denne gang, vi læser værdi data fra bussen efter at skrive den kilde, registeret adresse. Ad .l345 kræver nogle justeringer af registeradressen i dette tilfælde: bit 7 skal indstilles for at markere transaktionen som en læseoperation, og bit 6 skal indstilles for at fortælle chippen, at vi forventer, at mere end en enkelt byte sendes tilbage.,
hvor selve programmet starter, konfigurerer vi imp ‘ s SPI-bus til at matche kravene i AD .l345-chippen. Det bruger SPI Mode 3-dvs .. både CPOL og CPHA skal indstilles-så vi bruger den tilsvarende imp-parameter: CLOCK_IDLE_HIGH / CLOCK_2ND_EDGE i configure () – opkaldet. Vi sætter også hastigheden til 100kh.. Dernæst er imp ‘ s pin 8, der fungerer her som CS-pin, konfigureret som en digital udgang og indstillet højt.
Ledninger op ADXL345
Andre funktioner i programmet initialisere ADXL345 sig selv snarere end SPI-bus., ADXL345 er initialiseret, og koden læser i værdi fra register-adresse 0x00
for at sikre, at enheden er til stede på bussen. Chippen har en selvtesttilstand, der gør det muligt at foretage en række kalibreringsaflæsninger; dette gør vi og gemmer resultaterne. Senere i funktionssløjfen () bruges disse værdier til at justere de endelige aflæsninger fra accelerometeret.,
ADXL345 gemmer sine x-, y – og z-aksen prøver som 16-bit-værdier, hver i to 8-bit-registre; loop() bruger spiReadReg() funktionen til at erhverve hver værdi er to komponenter, og derefter konverterer dem til indre værdier ved at multiplicere den mest betydende byte med 256 og tilføjer, at resultatet værdien af den mindst betydende byte.