Detta avser att beskriva grunderna i I2C, som kan vara ett alternativ då det inte finns plats för breda adress- eller data-bussar. Detta gäller särskilt vid konstruktion med en mikrokontroller som har få ben och dessutom inte är mikroprocessoranpassad, vilket många kringkomponenter såsom vanliga minnen är.
I2C (Inter IC) är ett sätt för IC-kretsar att kommunicera med varandra via en seriell databuss, en I2C-buss. En I2C-buss består enbart av två ledningar, SDA (Serial DAta) och SCL (Serial CLock), till vilka man kan ansluta sina I2C-kretsar vid godtyckligt ställe på bussen.
+-------+ +5V
| Minne | ___
| | |
| | | | R
+-+---+-+ | |
SDA | | |
--------------+---|---+-------+------------+-----+-----+-------
| | | | |
SCL | | | | |
----------+---|---+-------+---|-------+----|------+----|-------
| | | | | | | |
+-+---+-+ +-+---+-+ +-+----+-+ +-+----+-+
| Minne | | RTC | |Expander| | PIC |
| | | | | | | |
| | | | | | | |
+-------+ +-------+ ++++++++++ ++++++++++
|||||||| ||||||||
Till SDA måste även ett pull-up-motstånd (R) anslutas. Resistansen på motståndet beror på hur många I2C-kretsar som finns på I2C-bussen och vilken data-takt som används, men som tumregel kan sägas att motståndet skall vara 4-10 kohm.
SCL är den signal som anger data-takten och skapas av den krets som är ‘master’ på I2C-bussen. SCL-signalen ska inte förväxlas med en klock-signal som svänger med konstant frekvens, utan SCL kan variera i frekvens och ändrar bara tillstånd när data ska skickas på SDA-ledningen. För övrigt håller SCL ett konstant högt eller lågt värde. Nu kan det tänkas att det finns fler än en ´master´ på en och samma I2C-buss (s k multimaster-mode, vilket kan vara svårt att hantera) varvid även SCL måste ha ett pull-up-motstånd. Övriga I2C-kretsar som styrs av SCL kallas för ´slave´.
Data på SDA skickas bara mellan två krestar åt gången. Den som skickar data kallas ´sändare´ och den som tar emot kallas följaktligen ´mottagare´. Sändaren skickar alltid 8 bitar åt gången varefter man byter riktning på SDA och mottagaren skickar en ACK-bit (ACKnowledge) till sändaren för att bekräfta att den tagit emot alla 8 databitarna. Därefter kan sändaren på nytt skicka 8 databitar (och sedan ta emot en ACK-bit). För varje databit på SDA krävs en klock-puls på SCL, vilket alltså innebär totalt 9 klock-pulser för en byte. En för varje databit och en för ACK-biten.
Varje I2C-krets har en förutbestämd 7-bitars adress. Den måste sändaren använda sig av för att välja ut rätt krets på I2C-bussen. Alla I2C-kretsar som sitter på en och samma I2C-buss måste ha olika adresser. Därför kan det finnas möjlighet att själv bestämma dom tre lägsta bitarna i adressen om det t ex skulle sitta två likadana minnen på I2C-bussen. På så sätt tillåts 8 minnen av samma typ på en och samma I2C-buss genom att ge olika kombinationer för dom tre adress-bitarna för varje minneskrets. Efter att sändaren skickat de 7 adress-bitarna skickas bit 8 (R/W-bit) som anger den efterföljande datariktningen, dvs läsning eller skrivning.
Kommunikationen av adress och data på I2C-bussen genomgår ett förfarande som alltid är detsamma enligt följande ordning:
1. Startvillkor, genereras av mastern
2. I2C-adress + R/W-bit skickas av sändaren (och bekräftas med ACK-bit
av mottagaren). Mest signifikant bit skickas först.
3. Eventuell inre adress skickas av sändaren, en eller flera byte
(om mottagaren t ex är ett minne så måste ju sändaren tala om
vilken adress i minnet som den vill göra något med. Varje
adress-byte bekräftas med en ACK-bit)
4. En eller flera data-byte skickas (eller tas emot) av den krets som
vid punkt 2 ovan var sändare. Om sändaren (t ex en PIC) i punkt 2
ovan vill ta emot (dvs läsa ur t ex ett minne) så blir förhållandet
det omvända för en stund, dvs sändaren (PIC:en) blir mottagare och
mottagaren (minnet) blir sändare av data-byten. Det innebär också att
det är PIC:en som ska generera ACK-biten för att bekräfta att den
tagit emot data.
5. Stopp-villkor, genereras av mastern
Under hela kommunikations-förfarandet är det endast två kretsar på I2C-bussen som “pratar” med varandra. För att två andra kretsar ska kunna göra detta börjar man om vid punkt 1 igen.
S1 1 0 1 1 0 0 1 A S5
____ ___ _______ ___ ____
SDA \____/ \___/ \__ ... __/ \______/
______ _ _ _ _ _ _ _ _ ______
SCL \___/ \_/ \_/ \_/ \_/ ... \_/ \_/ \_/
S1=startvillkor
A = ACK-bit
S5=stoppvillkor
Efter spänningspåslag till kretsarna vid I2C-bussen så ligger både SDA och SCL höga (om allt är som det ska). Ett startvillkor kännetecknas av att SDA går låg när SCL ligger hög. Därefter får SDA bara ändra värde när SCL ligger låg förutom när ett stoppvillkor ska genereras, vilket kännetecknas av att SDA går hög när SCL ligger hög.
Nedan ges exempel på pseudeo-kod för hur I2C-rutinerna i programmet kan se ut. Dessa är främst avsedda för PIC16C84 där all I2C-kommunikation måste styras “mjukvarumässigt”. I många andra mikrokontrollers finns inbyggd hårdvara som sköter stora delar av I2C-kommunikationen, men som måste programmeras till att fungera på önskat sätt.
SUBroutine START_I2C
SDA=0
SCL=0
RETURN
SUBroutine STOP_I2C
SDA=0
SCL=1
SDA=1
RETURN
SUBroutine INIT_I2C
CALL STOP_I2C
CALL STOP_I2C
CALL STOP_I2C
RETURN
SUBroutine READ_ACK
configure SDA as input
SCL=1
wait until SDA==0
SCL=0
configure SDA as output
RETURN
SUBroutine SEND_ACK
SDA=0
SCL=1
SCL=0
SDA=1
RETURN
SUBroutine WRITE_I2C_BYTE
store W in I2CBYTE
FOR bit= 7 to 0
SCL=0
SDA=I2CBYTE[bit]
SCL=1
NEXT bit
SCL=0
SDA=1
RETURN
SUBroutine READ_I2C_BYTE
configure SDA as input
FOR bit= 7 to 0
SCL=1
I2CBYTE[bit]=SDA
SCL=0
NEXT bit
SDA=1
configure SDA as output
RETURN
Specifik information om funktionen hos dom enskilda I2C-komponenterna finns förstås att läsa om i databladen för respektive komponent. Skulle denna “I2C för Dummies” plus databladen inte vara tillräcklig information eller svår att förstå så svarar vi gärna på frågor.