I2C kommunikáció két ATmega328 között

Az I2C egy soros, 8 bit-es, kétirányú kommunikációs protokoll, amelynek sebessége normál üzemmódban 100kbit/s, gyors üzemmódban 400kbit/s. I2C busz csak két db kétirányú vezetékből áll (SDA és SCL), amelyre az összes eszköz is csatlakozik. Az egyik vezeték az (SDA – Serial DAta), amin a soros adatforgalom zajlik; a másik pedig az órajel vonal (SCL – Serial CLock), amit az I2C buszon történő mindkét irányú adatátvitel szinkronizására használunk. Az SDA és az SCL vonalak az I2C buszon lévő minden eszközhöz hozzá vannak kötve (plusz természetesen a tápvezeték és a föld is).

I2C = Inter-Integrated Circuit

SDA = Serial Data

SCL = Serial Clock Line

Képek a kísérletről

Bővebben

I 2 C MANUAL
• https://rheingoldheavy.com/i2c-signal-reverse-engineering/
• http://rheingoldheavy.com/i2c-basics/
• http://www.instructables.com/id/I2C-between-Arduinos/?ALLSTEPS

A lényeg csak annyi, hogy az egyik ATmega csipről egy másikra küldtem egy számot (9, 15, 20) I2C keresztül és oszcilloszkóppal, aztán egy  24 MHz logikai analizátorral is ránéztem.

Először is a két csipet felprogramozzuk, (részletek → ITT.)  lesz egy master és egy slave.

Master

#include <Wire.h>

void setup() {
  Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 0;

void loop() {
  Wire.beginTransmission(8); // transmit to device #8
 // Wire.write("x is ");        // sends five bytes
  Wire.write(9);              // sends one byte
  Wire.endTransmission();    // stop transmitting

 // x++;
  delay(500);
}

Az eredeti program a x mindig változott, ezeket a részeket töröltem, ebben az esetben egyetlen számot a 9-est küldi el.

Wire.write(9);

Slave

#include <Wire.h>
//int LED = 13;
void setup() {
 // pinMode (LED, OUTPUT);
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
}

void loop() {
  delay(100);
  
  
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
  while (1 < Wire.available()) { // loop through all but the last
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
  // if(x > 10){
   // digitalWrite(LED, HIGH);
   
    //}
 
}

Ez fogadja az adatot, és a soros portra ki is írja, ha van USB interface.

Adat írása esetén az I2C kommunikáció azzal kezdődik, hogy a Master kontroller (TRON Rulez…) elküld egy Start jelet…..  A részletekről egy jó leírás itt található:

http://shrek.unideb.hu/~herakles/hallgato/anyagok/I2C.pdf

Itt most csak az adat visszafejtésére koncentráltam. A méréshez PCSGU-250 oszcilloszkópot  és egy 8 csatornás, 24 MHz-es logikai analizátort használtam. Az első esetben egy 9-es került elküldésre.

Pirossal van az órajel (SCL) kékkel az adatjel (SDA). Ahol a adatjel átfedésben van az órajellel ott 1 van, ahol nincs ott 0.

Kiolvasva: 000100000000010010

A 9 binárisan 1001

data transfer_9

Ugyanez a logikai analizátorral vizsgálva kicsit egyértelműbb:

logic_analyzer_9

 

És így tovább, itt 15 lett elküldve

Kiolvasva: 000100000000011110

A 15 binárisan 1111

data transfer_15

Itt az érték 20

Kiolvasva: 000100000000101000

A 20 binárisan 10100

data transfer_20

 

Felhasznált irodalom

http://shrek.unideb.hu/~herakles/hallgato/anyagok/I2C.pdf

 

Hasznos oldalak

http://www.gammon.com.au/i2c

http://arduino.stackexchange.com/questions/16292/sending-and-receiving-different-types-of-data-via-i2c-in-arduino

Share This:

 
Loading Facebook Comments ...

COMMENTS

Leave a Comment