Den Inter-Integreret Kredsløb (I2C-bus er en chip-niveau seriel kommunikation mekanisme, der opererer i løbet af blot to ledninger. Nogle udviklere udtaler busens navn eye-t .o-see, andre eye-s .uared-see, men begge henviser til den samme ting. Udviklet af Philips i begyndelsen af 1980’erne, I2C blev etableret for at standardisere kommunikationen mellem selskabets chips, men det er siden blevet en de facto standard, der understøttes af mange microcontroller enheder fra Arduino boards til Raspberry Pi og, selvfølgelig, imp.,
den fysiske Bus
I2C består af to ledninger. En I2C-linje transmitterer data, den anden kloksignalerne, der synkroniserer samtalen mellem enheder. Datalinjen kaldes’ SDA’, urlinjen ‘SCL’.
typisk er både SDA og SCL hver forbundet til en 3,3 eller 5V strømledning gennem en enkelt ‘pull-up’ modstand, en på hver linje. Dette er nødvendigt, fordi enhedens SDA-og SCL-forbindelser er’ åbne drænledninger’: de kan tvinge spændingen på linjen til 0V eller ‘lav’, men kan ikke hæve den til 3.3 V eller ‘høj’., Høj og lav er de elektriske repræsentationer af 1s og 0s, der er de grundlæggende komponenter i digital information. Tilføjelse af disse to modstande — og bussen har kun brug for to, uanset hvor mange enheder der er tilsluttet den — sikrer, at spændingen stiger tilbage til 3, 3 V uden kortslutning.
I2C insisterer på, at enheder har åbne drænledninger for at sikre, at ingen komponentskadende høje strømme er i stand til at strømme, når to enheder prøver at signalere samtidigt.
i de fleste tilfælde forventes det, at du selv tilføjer disse modstande, men nogle enheder, typisk dem, der fungerer ved 3.,3V, medtag dem for at være kompatible med enheder, der leverer 5V. Husk, at du kun har brug for et par pull-up modstande pr. Selvom imp har interne pull-up modstande af sine egne, disse er for svage til at være nyttige for I2C og så de er automatisk deaktiveret, når dens stifter er indstillet til at håndtere I2C signaler.
controllere og eksterne enheder
I2C-bussen adskiller enheder til ‘controllere’ og ‘eksterne enheder’., Kun en enhed kan sende timingimpulser på SCL-linjen ad gangen, og det er den, der er valgt til at være controlleren. Alle de andre synkroniserer deres timinger til controlleren og betragtes således som perifere enheder. Controlleren-typisk imp-og dens perifere enheder kan alle transmittere og modtage data, men kun controlleren kan fortælle en perifer, hvornår de skal transmittere data tilbage.
adressering
for at en I2C-enhed kan kommunikere med en anden på en-til-en-basis, skal begge enheder være entydigt identificerbare. Denne identitet er enhedens I2C-adresse., I2C-adresser er normalt 7-bit-numre, så en bus kan omfatte op til 127 enheder i alt. En byte består af otte bit; den ekstra bit bruges til at indikere, om signalet sendes af controlleren til periferien — en ‘skrive’ — eller i den anden retning — en ‘læse’. Denne ottende bit er faktisk lidt nul i adressebyten sendt ud på bussen. Den 7-bit adresse er placeret i bits en til syv af adressen byte.i overensstemmelse med dette format tager imp API en I2C-adresser som en 8-bit værdi., Enhedsleverandører giver normalt deres produkters adresser som et 7-bit nummer, så det er nødvendigt at konvertere adressen fra syv bit til otte. Dette opnås med S Squirreluirrel ‘ s <<
operatør, der flytter et tals individuelle bitværdier til venstre. Denne proces svarer til at multiplicere med to. I kode, denne proces ser sådan ud:
local sevenBitAddress = 0x39;local eightBitAddress = sevenBitAddress << 1;
s Squirreluirrel indstiller automatisk bit nul til den korrekte I2C-definerede værdi: 0 for en skrive operation, 1 for en læse., Nu er du klar til at bruge en af imp ‘ s i2c metoder til at skrive data til bus:
i2c.write(eightBitAddress, dataInStringForm);
7-bit-adressen på den enhed, som du ønsker, at din imp til at kommunikere med, vil blive leveret af komponent fabrikanten, og som er opført på maskinens dataark. Det er muligvis ikke løst, men valgt fra en række adresser i henhold til den spænding, der påføres en anden af enhedens stifter., For eksempel, en TAOS TSL2561 lys sensor har tre mulige adresser: 0x29
0x49
eller 0x39
, afhængigt af om sin ADR-pin-koden er fastsat til 0V, 3.3 V eller “flydende” mellem de to. Vi siger, at værdien flyder, fordi den ikke er aktivt valgt til at fungere ved en bestemt spænding; det kan være alt fra 0 til 3.3 V inklusive.
signalering
I2C bus’ controller bruger en periferis 7-bit adresse til at identificere den komponent, den vil tale med., Faktisk er signaleringen mere kompleks end det, men heldigvis håndteres alle detaljer af imp, så du kun behøver at levere adressen som en 8-bit værdi.
Hvis du skriver til periferien, skal du også levere de data, der skal skrives, hvilket ofte inkluderer registerværdier, der instruerer periferien, hvad de skal gøre med dataene. Imp API-dokumentationen henviser til disse registre som ‘underadresser’:
i2c.write(eightBitAddress, dataString);
skrive() kræver data i strengform. Derfor skal du muligvis konvertere den værdi, der er gemt i andre typer variable, til strengform.,
læsning af oplysninger fra en enhed kan kræve en kommando for at fortælle enheden, hvilke data der skal hentes. Fortæller imp til at læse data fra I2C-bussen indebærer også, at en tredje parameter, det antal byte, du kan forvente at modtage:
i2c.read(eightBitAddress, controlDataString, numberOfBytesToRead);
Bag disse operationer er I2C elektriske signaler, der anvendes til SDA linje, der er synkroniseret med timing bælgfrugter, der anvendes til SCL-line. Skrivning til bussen involverer en startmarkør: at droppe SDA til 0V, mens SCL er 3.3 V. ændring af SDA-spændingen, når SCL ‘ s spænding er høj, definerer start-og stopmarkører., Hvis SDA-spændingen ikke ændres, mens SCL er høj, ved I2C-enheder, at data, snarere end markører, sendes.
SDA går nu højt eller lavt for at sende hver bit af adressebyten: 7-bit enhedsadressen efterfulgt af læse/skrive bit. Bytes bits sendes ud til venstre-den ‘mest betydningsfulde bit’ – først, med SDA, der går højt, hvis bitens værdi er 1 eller lav, hvis den er nul. Målet perifere vil nu trække SDA lav til signal kvittering for modtagelse af data, og derefter ud går otte bits af kontrol oplysninger eller data, efterfulgt af flere data, hvis det er nødvendigt., Der er en enkelt puls ‘ack’ bekræftelsespause på SDA mellem hver otte bit sendt, timet til en niende SCL-puls. Hvis periferien ikke anerkender modtagelsen på denne måde, registrerer controlleren, at SDA har været høj og vil signalere en fejl.,
Når data strømme fra det perifere til den registeransvarlige, sidstnævnte ligeledes anerkender modtagelsen af otte bits ved at trække SDA lave den niende SCL puls, medmindre dette er den sidste byte i en batch, i hvilket tilfælde den registeransvarlige ikke trække SDA lave — det gør en ‘nak’ signal, eller “ingen kvittering” — for at lade de perifere vide, at den er færdig.
Når vi er færdige, går SDA højt som en stopmarkør.,
start transmission er angivet af SDA falder fra Høj til Lav spænding (rektangel til venstre),
stop ved den omvendte (højre rektangel). SCL skal være høj, når dette finder sted
Timing
standardklokhastigheden for I2C — kommunikation er 100kh. – 100.000 SCL-impulser pr. Det er muligt at gå hurtigere, op til 400kh.. Nogle enheder kan muligvis ikke understøtte denne hastighed; kontroller databladet, der følger med den enhed, du vil oprette forbindelse til din imp., Imidlertid bruger mange langsomme enheder en teknik kaldet ‘urstrækning’ for at tvinge hurtigere enheder til at arbejde til deres hastighed. Imp understøtter enheder, der gør brug af denne teknik. I det væsentlige holder de SCL lavt, mens de henter de data, du vil have dem til at sende til imp. Imp registrerer dette, frigiver SCL-linjen og venter, indtil SCL går højt igen, før du fortsætter.
det kan dog være nødvendigt at sænke I2C-hastigheden selv, hvis de elektriske egenskaber ved din opsætning sænker hastigheden for overgangen mellem 0V og 3.3 V, kaldet ‘stigningstid’., Dette skyldes ofte lange ledninger, hvilket øger kredsløbets kapacitans. For at enhederne skal kunne registrere transmissionen af hver bit, skal bussen køre langsommere. Datakorruption eller uventede resultater er de ledetråde, du skal kigge efter. Reducer I2C-bushastigheden, indtil dataene læses med succes.imp API giver i øjeblikket fire foruddefinerede urværdier: 10, 50 100 og 400kh.., De er valgt ved at bestå en konstant til I2C konfiguration metode som parameter:
i2c.configure(speedConstant);
hvor værdien af speedConstant er en af
- CLOCK_SPEED_10_KHZ
- CLOCK_SPEED_50_KHz
- CLOCK_SPEED_100_KHZ
- CLOCK_SPEED_400_KHZ
opsætning af En imp Til I2C
I2c objekt i eksemplet linjer af kode, der er angivet ovenfor, ikke er leveret direkte af imp, men som du har valgt i henhold til, hvilke af dine valgte imp ‘ s stifter, som du vil bruge til I2C-kommunikation., Hver type imp har flere I2C-busser, som alle stilles til rådighed ved opstart. Tjek pin mu.for den type imp, du bruger til at se, hvilke I2C objekter er tilgængelige for dig. Her antager vi, at du bruger en imp001. Den imp001 to I2C-busser er på pin 1 og 2, og stifter 8 og 9, henholdsvis udmøntet som egenskaber i2c12 og i2c89 af hardware objektet, når imp starter op. Pins 1 og 8 er tildelt SCL, 2 og 9 til SDA.,
Det er almindeligt at henvise til dit valg med en global variabel:
i2c <- hardware.i2c12;i2c.configure(CLOCK_SPEED_100_KHZ);
Eksempel-Kode
følgende kode arbejder med TAOS TSL2561 synligt og infrarødt lys-sensor, en 3,3 V-enhed, der bruger I2C til at kommunikere med sin vært, microcontroller. Chippens datablad kan do .nloades fra Adafruit-websiteebstedet. Adafruit sælger chippen på en billig breakout bord, som omfatter egnede pull-up modstande på Po .er pin, VCC. Dette betyder, at den er klar til at oprette forbindelse direkte til en IMPS I2C-stifter.,
Adafruit ‘ s TSL2561 breakout board
Bemærk Efter at denne artikel blev skrevet, opdaterede Adafruit sit tsl2561 sensorkort. Den nye version fungerer med den aktuelle kode.
Her er koden for agenten og derefter enheden:
hvad koden gør
agentkoden reagerer på en indgående HTTP-anmodning ved at underrette enheden om, at den kræver en læsning. For nemheds skyld vises læsningen simpelthen i loggen.
enhedskoden læser sensoren og beregner en Lu. – værdi i henhold til den matematik, der er angivet i tsl2561-databladet., Den første del af programmet opretter konstanter til TSL2561S nøgleregistre og indstillinger, inklusive dens I2C-adresseindstillinger. Andre konstanter anvendes i lysstyrke konverteringsprocessen.
Ledninger op imp
I programmets start punkt, koden aliaser en af imp ‘ s I2C pin set som en global variabel, konfigurerer bus hastighed til 100kHz, og flytter derefter TSL2561 er I2C-adresse en smule til venstre, så det er klar til at blive brugt med imp I2C funktioner. Det sætter derefter sensoren op., Bare for at kontrollere, at dette har fungeret, læser vi kontrolregistret: returværdien skal være 3, hvis TSL2561 lige er startet, eller 51, hvis enheden allerede er tændt.
derefter indstiller koden sensorens ADC-opløsning gennem TSL2561S timeregister og indstiller derefter signalforstærkningen til høj.
endelig fortæller vi imp, hvordan man reagerer på "sense"
meddelelser fra agenten. Dette kalder en funktion, der læser TSL2561S to lyssensorer, digitale værdier, som gemmes i chipens fire 8-bit ADC-registre., De to første giver en 16-bit kombineret optisk og infrarød læsning, det andet par en 16-bit IR-kun værdi. Funktionerne readSensorAdc0 () og readSensorAdc1 () konverterer de individuelle registerværdier til 16-bit-tal ved at multiplicere den mest betydningsfulde byte med 256 og tilføje værdien af den mindst betydningsfulde byte. Multiplikation udføres ved at flytte de otte-bit antal bits venstre otte steder med Egern s << operatør.,
koden giver derefter begge disse aflæsninger til en tredje funktion for at beregne en endelig lysstyrke, ‘Lu.’ – værdi.
Yderligere Læsning
- I2C Fejl — Sådan debug I2C læse og skrive-problemer