Loading AI tools
Från Wikipedia, den fria encyklopedin
I²C ("Inter-Integrated Circuit") är en synkron seriell multimasterbuss från Philips som används för att koppla låghastighetsenheter till moderkort, inbyggda system, mobiltelefoner och andra elektroniska enheter. Från mitten av 90-talet har flera konkurrenter (såsom Siemens, NEC, Texas Instruments och Motorola) utvecklat I²C som är fullt kompatibla med Philips system. NXP, som tidigare var Philips halvledardivision, kräver dock fortfarande en avgift för att dela ut slavadresser för enheter, även om det är gratis att implementera I²C-protokollet.[1]
SMBus som utvecklades av Intel 1995 är en delmängd av I²C som har en mer precis definition. Ett av målen för SMBus är att uppnå stabilitet och kompatibilitet. Som en följd av detta använder moderna I²C-system regler och policies från SMBus och stöder ibland båda protokollen med minimala inställningsskillnader.
I²C använder tvåvägskommunikation på två ledare med öppen kollektor – SDA (Serial Data Line, datasignal) och SCL (Serial Clock Line, klocksignal). Normalt används spänningar om +5 eller +3,3 volt, men andra spänningar tillåts.
Referensdesignen för I²C specificerar 7 eller 10 bitars minnesadressering, beroende på implementation.[2]. Vanliga busshastigheter är 100 kb/s i standard mode eller 10 kb/s i low-speed mode, även om godtyckligt lägre klockfrekvenser tillåts. Sentida implementationer kan kommunicera med fler noder och klarar högre hastigheter (400 kb/s för Fast mode, 1 Mb/s för Fast mode plus eller Fm+, samt 3,4 Mb/s för High Speed mode). Dessa används mer i inbyggda system än i persondatorer. En ytterligare förbättring är 16 bitars minnesaddressering.
Notera dock att de datahastigheter som omnämns är för överföring mellan en masternod och en slavnod utan hänsyn tagen till overhead i hårdvara. Overhead i protokollet innefattar slavnodadressering och möjligen registeradressering inom slavnoden, såväl som ACK/NACK-bitar för varje byte. Den faktiska överföringshastigheten av nyttodata kan, beroende på dessa förhållanden, vara markant lägre.
Antalet slavnoder begränsas av minnesadresseringen och av bussens kapacitans på 400 pF, vilket i praktiken begränsar den fysiska busslängden till ett par meter.
Referensdesignen innehåller, som ovan nämnts, en buss med klocka (SCL) och data (SDA) samt 7 bitars minnesadressering. Bussen har två roller för noder - master och slav:
Bussen är en multi-master buss, vilket innebär att fler än en master kan vara inkopplade. Dessutom kan noder byta från slav- till masterläge under drift.
Varje nod kan arbeta i fyra olika moder, även om de flesta enheter använder en roll och dess två moder:
Masternoden börjar alltid i sändmod och sänder en startbit med efterföljande 7 bitars adressering för att bestämma vilken slavnod som ska kommuniceras med. Nästa bit indikerar om masternoden vill skriva data till (0) eller läsa data från (1) slavnoden.
Om slavnoden som adresseras är inkopplad på bussen kommer denna att svara med en ACK (acknowledgement) genom att sätta en bit låg för den adressen. Masternoden fortsätter sedan i antingen mottagar- eller sändmod, beroende på hur läs- och skrivbiten sattes, och slavnoden fortsätter i motsvarande slavmod (sändmod om masternoden är i mottagningsmod).
Adress- och databytes sänds med mest signifikanta siffra först. Startbiten (START) indikeras av en hög-lågövergång på SDA när SCL är hög. Stoppbiten (STOP) är en låg-högövergång på SDA när SCL är hög.
Om masternoden vill skriva data till en slavnod skickar den upprepade gånger en byte till slavnoden som svarar med en ACKbit. Masternoden är här i sändmod medan slavnoden är i mottagarmod.
Om masternoden vill läsa data från en slavnod mottar den upprepade gången en byte från slavnoden, och masternoden svarar med en ACKbit efter varje byte förutom den sista. Masternoden är här i mottagarmod och slavnoden i sändmod.
Masternoden avslutar en sändning med en stopbit, eller ännu en startbit om man önskar låta masternoden behålla busskontroll för ytterligare en sändning.
I²C definierar tre grundläggade meddelandetyper som alla börjar med START och slutar med STOP:
I kombinerade meddelanden börjar varje meddelande med START och en adress till en slavnod. Efter den första START:en sänds flera START med slavnodsadresser utan mellanliggande STOP. Det är på det viset slavnoder tolkar dessa meddelanden som delar av ett fullständigt meddelande.
Slavnoder svarar bara på meddelanden eller kommandon som specificerats av tillverkaren, vanligtvis dokumenterade i produktdokumentationen.
Rena I²Csystem stöder godtyckliga meddelandestrukturer medan SMBus begränsar antalet strukturer till nio, såsom read word N och write word N till en enda slavnod. PMBus utökar SMBus med ett grupprotokoll som tillåter att ett flertal sådana SMBusmeddelanden sänds inom samma meddelande. Det avslutande STOPkommandot anger att sådana grupperade meddelanden eller kommandon ska exekveras eller ta effekt. Ett exempel är en PMBusoperation som konfigurerar om tre spänningsaggregat via tre olika slavnodsadresser; den nya konfigurationen implementeras samtidigt när alla tre slavnoder mottar STOP.
Men få undantag bestämmer varken I²C eller SMBus meddelandesemantiken, det vill säga vad en viss byte ska betyda. Semantiken är produktspecifik. Bland undantagen märks meddelanden till I²Cbussens general calladress (0x00) eller till SMBus Alert Response Address, samt meddelanden som rör SMBus Address Resolution Protocol och för dynamisk adresshantering.
I praktiken använder de flesta slavnoder förfrågan / svarsmodeller, där en eller flera av byten efter ett skrivkommando behandlas som ett kommando eller adress. Dessa byte bestämmer hur de efterföljande skrivna byten behandlas och/eller hur slavnoden ska reagera på efterföljande läskommandon. De flesta SMBusoperationer använder kommandon som bara tar upp en byte.
Eftersom både SCL och SDA har öppna kollektorer krävs pull-upmotstånd. En kollektor som kopplas till jord via motstånd (pull-down) anses beskriva en logisk nolla, medan en kollektor som varken kopplas till spänning eller jord anses beskriva en logisk etta.
En viktig följd av detta är att om en av många noder sätter en av ledarna låg, sätts den till låg för alla anslutna enheter. Om en slavnod försöker sända en logisk etta kan varsebli detta och på så sätt se att en annan nod försöker sända samtidigt.
På SCL-ledaren kallas detta "clock stretching", eller "klocksträckning" och ger slavnoder en mekanism för flödeskontroll. På SDA-ledaren kallas det "arbitration", eller "arbitrering", och det säkerställer att bara en enhet sänder åt gången.
Om ingen trafik pågår sätts båda ledarna höga. För att påbörja en sändning (START) dras SDA låg medan SCL förblir hög. Om SDA sedan släpps till hög utgör det en STOP. Emedan detta inte bryter mot designen är det ofta meningslöst, och normalt efter START är att dra SCL låg.
START och STOP undantaget, ändras spänningen på SDA bara då SCL är låg, och att sända en bit består av att pulsera SCL hög medan SDA läggs på önskad nivå. Medan SCL är låg sätter sändaren (inledningsvis masternoden) SDA till önskad nivå. Efter en kort paus släpps SCL till hög - en process som tar ett kort ögonblick på grund av tidskonstanten hos svängningskretsen som utgörs av pull-upmotståndet och bussens kapacitans, samt klocksträckning av en annan inkopplad nod.
Sedan SCL satts hög väntar masternoden en kort stund (4 µs för standard speed) för att säkerställa att mottagaren sett biten, och drar sedan ner SCL låg. Detta repeteras för varje bit som ska överföras. Efter 8 bitar i en riktning skickar mottagaren en ACK-bit i andra riktningen. De två noderna byter roll och en logisk nolla sänds tillbaka. Om den då mottagande noden istället ser en logisk etta (NACK), betyder det att:
Sedan ACK-biten förståtts kan masternoden göra en av tre saker:
En av de viktigaste egenskaperna hos I²Cprotokollet är "klocksträckning". En slavnod kan hålla klockledaren låg efter mottagande eller sändande av en byte, vilket då innebär att slavnoden inte ännu är redo för mer data. Masternoden som kommunicerar med slavnoden får då inte avsluta sändningen av dåvarande bit, utan måste vänta till slavnoden släpper SCL hög. Om slavnoden använder klocksträckning kommer SCL att hållas låg. Detsamma gäller om en annan långsammare masternod försöker dra ner SCL samtidigt. I situationer med fler än en masternod kommer normalt sett alla utom en att förlora genom arbitrering.
Masternoden måste vänta till SCL släpps hög, och sedan ytterligare en kort tid (4 µs för 100 kbps) innan den tillåts dra SCL låg igen.
Även om en masternod kan hålla SCL låg så länge som önskas, används uttrycket klocksträckning normalt bara när en slavnod använder metoden. Teoretiskt kan vilken klockpuls som helst sträckas, men oftast används klocksträckning i intervallet före eller efter en ACK. Om till exempel slavnoden är en mikrokontroller kommer den att sträcka klockan efter varje byte medan mjukvaran i kontrollern bestämmer sig för att skicka en ACK eller NACK.
Den enda gången en slavnod driver SCL är just när klocksträckning används. Många slavnoder behöver inte använda metoden och hanterar således SCL som en insignal utan möjlighet att påverka denna. Vissa masternoder, som till exempel ASICar, stöder inte klocksträckning och kallas då "two-wire interface" istället för I²C.
För att kunna garantera en lägsta trafikhastighet använder sig SMBus av en begränsning på hur länge en klockpuls kan sträckas. Master- och slavnoder kan således inte låsa bussen längre än korta ögonblick, något som inte garanteras i rena I²Csystem.
Varje masternod bevakar bussen för START- och STOPbitar och påbörjar inte sändningar medan en annan masternod sänder. Det kan dock hända att två masternoder börjar sända ungefär samtidigt, och denna situation leder till arbitrering. Slavnodssändningar kan även de arbitreras när en masternod sänder till flera slavnoder, men detta är mindre vanligt. Till skillnad från protokoll som använder slumpvisa fördröjningar (till exempel Ethernet) använder I²C en deterministisk arbitreringspolicy. Varje sändare kontrollerar spänningen på SDAledaren, och om spänningen inte stämmer överens med förväntat värde, har den sändaren förlorat arbitreringen och avslutar sändningen.
Om en sändare släpper SDA hög och en annan sändare drar SDA låg, blir resultatet att SDAledaren är låg. Den första sändaren noterar att spänningen på SDAledaren inte är den förväntade och drar slutledningen att en annan nod också håller på att sända. Den första noden som finner att SDAledarspänningen inte stämmer överens med vad som förväntas förlorar arbitreringen och släpper både SDA och SCL och väntar sedan på ett STOPmeddelande. Den andra noden har under tiden inte märkt någon skillnad mellan förväntade och faktiska spänningsvärden på SDA och fortsätter därför sin sändning. Eftersom spänningen på SDA är som förväntat har meddelandet inte förvanskats av andra sändare.
Om två masternoder sänder meddelanden till två olika slavnoder kommer noden som sänder till den lägre slavnodsadressen alltid att vinna arbitreringen om den inträffar när adressen sänds. Om två masternoder sänder till samma slavnod går arbitreringen vidare till efterföljande fas då data sänds.
Arbitrering är ovanligt, men krävs för att kunna stödja flera masternoder. Precis som med klocksträckning finns det enheter som inte stöder arbitrering. De som har stöd för arbitrering brukar säljas som "supporting multi-master".
I mycket sällsynta fall kan två masternoder sända identiska meddelanden samtidigt. I dessa fall kommer båda noderna att anser att sändningen lyckades, men slavnoden kommer bara att se ett av meddelandena. Slavnoder som kan adresseras av ett flertal masternoder måste ha kommandon som är idempotenta.
Medan I²C bara arbitrerar mellan masternoder använder SMBus arbitrering i ytterligare tre fall, där ett flertal slavnoder svarar på en förfrågan från en masternod och en av dem lyckas.
Om ett system innehåller många I²Cnoder kan det bli nödvändigt att implementera buffertar eller multiplexorer (mux) för att dela up stora bussar i mindre segment. Detta kan användas för att hålla bussens kapacitans inom tillåtna värden eller för att låta flera enheter med samma adress att kommunicera genom en multiplexer. Det finns många typer av buffertar och muxar, men de måste alla ta hänsyn till det faktum att I²C är ett tvåvägsprotokoll. Muxar kan implementeras med analoga brytare som kan knyta ihop ett segment med ett annat. Analoga brytare stöder bidirektionalitet, men kan inte isolera kapacitanser mellan segment.
Buffertar kan isolera kapacitans mellan segment, eller tillåta I²Csignaler att sändas över längre avstånd. Dessa bidirektionella buffertar måste använda en av flera tillgängliga metoder för att förhindra latch-up, eller kortslutningar till följd av felaktig kretsdesign. Eftersom I²C använder öppna kollektorer måste en buffert dra en ledare låg på en sida när ledaren på andra sidan går låg. En metod för att förhindra latch-up är att noggrant välja spänningsnivåer på in- och utgångar för att förhindra att bufferten aktiverar sig själv. En buffert kan till exempel ha en ingångströskel på 0,4 V för att detektera en låg signal, men skicka ut 0,5 V på en utgång som låg signal. Detta kräver att alla andra noder på bussen har tröskelvärden som är kompatibla och betyder ofta att man inte kan implementera flera buffertar i serie.
Alternativa bufferttyper använder strömförstärkare, eller håller reda på vilken sida om bufferten som signalen först drogs låg på.
Dataöverföringen påbörjas med STARTbiten (S) när SDA dras låg medan SCL lämnas hög. SDA sätter sedan överförd bit medan SCL dras låg (blå) och biten mottas när SCL släpps hög (grön). När överföringen är avslutad sänds en STOPbit (P) genom att släppa SDA hög medan SCL lämnas hög.
Nedanstående kod är ett exempel på mjukvaruimplementering av I²Cprotokollet, så kallad bit-banging. Exemplet, som är skrivet i pseudokod, är skrivet från en masternods synvinkel. Koden illustrerar alla egenskaper hos I²Cprotokollet, såsom klocksträckning, arbitrering, START/STOP och ACK/NACK.
/* Hardware-Specific Support Functions That MUST Be Customized */
#define I2CSPEED 100
void I2CDELAY() {volatile int v; int i; for(i=0;i<I2CSPEED/2;i++) v;}
bool READSCL(void) {return 1;} /* Set SCL as input and return current level of line, 0 or 1 */
bool READSDA(void) {return 1;} /* Set SDA as input and return current level of line, 0 or 1 */
void CLRSCL(void) {} /* Actively drive SCL signal low */
void CLRSDA(void) {} /* Actively drive SDA signal low */
void ARBITRATION_LOST(void) {}
/* Global Data */
bool started = false;
void i2c_start_cond(void)
{
/* if started, do a restart cond */
if (started) {
/* set SDA to 1 */
READSDA();
I2CDELAY();
/* Clock stretching */
while (READSCL() == 0)
; /* You should add timeout to this loop */
/* Repeated start setup time, minimum 4.7us */
I2CDELAY();
}
if (READSDA() == 0)
ARBITRATION_LOST();
/* SCL is high, set SDA from 1 to 0 */
CLRSDA();
I2CDELAY();
CLRSCL();
started = true;
}
void i2c_stop_cond(void)
{
/* set SDA to 0 */
CLRSDA();
I2CDELAY();
/* Clock stretching */
while (READSCL() == 0)
; /* You should add timeout to this loop */
/* Stop bit setup time, minimum 4us */
I2CDELAY();
/* SCL is high, set SDA from 0 to 1 */
if (READSDA() == 0)
ARBITRATION_LOST();
I2CDELAY();
started = false;
}
/* Write a bit to I2C bus */
void i2c_write_bit(bool bit)
{
if (bit)
READSDA();
else
CLRSDA();
I2CDELAY();
/* Clock stretching */
while (READSCL() == 0)
; /* You should add timeout to this loop */
/* SCL is high, now data is valid */
/* If SDA is high, check that nobody else is driving SDA */
if (bit && READSDA() == 0)
ARBITRATION_LOST();
I2CDELAY();
CLRSCL();
}
/* Read a bit from I2C bus */
bool i2c_read_bit(void)
{
bool bit;
/* Let the slave drive data */
READSDA();
I2CDELAY();
/* Clock stretching */
while (READSCL() == 0)
; /* You should add timeout to this loop */
/* SCL is high, now data is valid */
bit = READSDA();
I2CDELAY();
CLRSCL();
return bit;
}
/* Write a byte to I2C bus. Return 0 if ack by the slave */
bool i2c_write_byte(bool send_start, bool send_stop, unsigned char byte)
{
unsigned bit;
bool nack;
if (send_start)
i2c_start_cond();
for (bit = 0; bit < 8; bit++) {
i2c_write_bit((byte & 0x80) != 0);
byte <<= 1;
}
nack = i2c_read_bit();
if (send_stop)
i2c_stop_cond();
return nack;
}
/* Read a byte from I2C bus */
unsigned char i2c_read_byte(bool nack, bool send_stop)
{
unsigned char byte = 0;
unsigned bit;
for (bit = 0; bit < 8; bit++)
byte = (byte << 1) | i2c_read_bit();
i2c_write_bit(nack);
if (send_stop)
i2c_stop_cond();
return byte;
}
I²C är lämpligt för utrustning där enkelhet och låg tillverkningskostnad är viktigare än hög överföringshastighet. Vanliga användningsområden för I²C innefattar:
En styrka hos I²C är att en mikrokontroller kan kontrollera ett helt nätverk av enheter med bara två ledare. Många andra bussteknologier kräver fler ledare och signaler.
Under utveckling eller felsökning av I²Csystem kan det vara mycket viktigt att kunna se signaler på hårdvarunivå.
Det finns ett flertal hårdvarulösningar för värddatorer som kör Linux, Mac eller Windows. De flesta baseras på USB och erbjuder ett gränssnitt mellan USB och I²C. Några av dem kräver inte slutna lösningar utan tillämpar istället öppna drivrutiner och APIer.
I²C protokollanalysatorer är verktyg som bevakar en I²Cbuss och avkodar de elektriska signalerna för att kunna ge en bättre överblick på en högre nivå av vilken data som sänds.
Logikanalysatorer är verktyg som bevakar, lagrar och analyserar the fysiska signalerna på I²Cbussen så att de sedan kan undersökas mer i detalj. De kan även tillåta stegning mellan signalförändringar så att fel kan hittas på det viset.
År | Revision | Kommentar |
---|---|---|
1982 | Första implementation av I²C skapades som en enkel intern buss för att kontrollera byggnader med hjälp av chip från Philips. | |
1992 | 1.0 | Den första standardiserade versionen lade till fast mode för 400 Kbps och 10 bitars adressering för att öka kapaciteten till 1008 noder per buss. |
1998 | 2.0 | High-speed Mode om 3,4 Mbps lades till. |
2000 | 2.1[4] | Mindre upprensning av version 2.0. |
2007 | 3.0[5] | Fast Mode plus och nodidentitetsmekanismer lades till. |
En av svagheterna med I²C är tilldelning av adresser för slavnoder. Sju bitar är för lite för att förhindra adresskonflikter mellan de tusentals olika noder som finns, och tillverkare använder sällan tillräckligt många ledare för att konfigurera hela slavnodsadressen. Tre ledare är ganska vanligt, vilket bara ger åtta olika nodadresser. Vissa noder tillåter flera adressbitar per ledare,[6][7] till exempel genom att använda inom kretsen lediga ADCledare för att bevaka en av 8 olika spänningsnivåer som kan konfigureras med en utombords spänningsdelare. Vissa tillverkare medger konfiguration av ett par tre låga adressbitar och sätter de högre bitarna godtyckligt beroende på nodmodell. Detta begränsar antalet noder av den modellen som kan kopplas in på en buss. Dessutom är det bara en dellösning på adresseringsproblemet. 10 bitars adressering är ännu inte vedertaget och många operativsystem på värddatorer har ännu inte stöd för det. Detta gäller även ARP-metoden som SMBus använder, med PCI-kort undantaget eftersom det är ett krav för att dessa kort ska kunna kopplas till SMBus.
Automatisk busskonfiguration är ett besläktat problem. En viss adress kanske används av ett antal olika och protokollinkompatibla noder i olika system. Den enda tillitliga metoden är att använda "out-of-band", det vill säga en metod som inte kommuniceras över bussen själv.
I²C stöder ett begränsat antal överföringshastigheter. Värdar som stöder hastigheter i flera megabits är ovanliga. Fast mode plus stöd (1 Mbps) är vanligare eftersom elektroniken som används är förenklade varianter av komponenter som används vid lägre hastigheter. Många noder stöder inte heller 400 kbps, delvis eftersom SMBus inte stöder det. Om en I²Cnod implementeras i mjukvara kanske inte ens 100 kbps kan stödjas.
Eftersom I²C är en seriell buss finns risken att en enda nod kan hänga eller låsa hela bussen. Till exempel kan en nod dra SDA eller SCL låg och på så sätt förhindra att masternoden återställer bussen genom START eller STOP. Implementationer kan därför ha en separat återställningsledare där en nod kan återställas om den låses. Om en nod inte har en sådan återställningsledare kan en implementerare tvingas bygga en krets som temporärt bryter strömförsörjningen till noden om den låser sig.
På grund av dessa svagheter är det ovanligt med I²Cbussegment med fler än tolv noder. Det är däremot vanligt att system har ett flertag sådana segment, varav ett segment kan vara vigt åt höghastighetsnoder för snabb kontroll av energibesparingshantering. Ett annat segment kanske används för noder där fördröjningar och överföringshastigheter inte är speciellt viktiga.
I²C ligger till grund för ACCESS.bus, VESA Display Data Channel (DDC), System Management Bus (SMBus), Power Management Bus (PMBus) och Intelligent Platform Management Bus (IPMB, ett av protokollen för IPMI). Dessa implementationer har olika spänningsnivåer och klockfrekvenser och kan även ha speciella avbrottsledare.
TWI (Two Wire Interface) eller TWSI (Two-Wire Serial Interface) är till stor del samma buss och används på olika chip från Atmel och andra leverantörer.[8] Leverantörer använder gärna namnet TWI, trots att I²C inte är ett registrerat varumärke. Varumärkesskydd existerar bara för logotypen och patenten på I²C har gått ut.
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.