VanHeden Old VanHeden

Datablad

Robot-plattformar Digitala/analoga komponenter AVR/Raspberry Kommunikation Kringutrustning Displayer Sensorer Knappar & LEDs Gott & Blandat Alla PDF:er

Övrig information

Handledningar Karta över ISY Tips o Trix Kuriosa FAQ

I2C

I2C

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.

Diverse tips

Pseudo-kod

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.


W3.CSS

Sunday