I²C/TWI Tutorial

#574768
Lesenswert?

Hallo zusammen,
ich weis es gibt schon viele fertige Programmbeispiele, zum Thema aber 
irgendwie steig ich da nicht so sehr durch. Ich möchte gern 2 Bytes 
(Werte von 0...255) von einem ATMega16 auf einen ATMega8 übertragen. Das 
ganze soll über TWI/I²C geschehen. Jetzt weis ich nicht so recht, wie 
ich dass programmieren soll. Schön wäre, wenn jemand mal ein Bespiel 
hätte, bei dem an einem µC eine Taste gredrückt wird und an einem 
anderen ne LED leuchtet. Die Programmierung für Master und Slave in C 
und so simple wie möglich gehalten. Ich denke sowas als Tutorial wäre 
echt hilfreich für viele User.
MFG Benny
#575437
Lesenswert?

Hallo,

ich kann die Anfrage schon verstehen, denn auch ich habe hier und 
woanders im web keine vernünftige Implementierung des TWI/I2C gefunden 
und mir deshalb ne eigene kleine Funktionssammlung geschrieben. Ich 
wollte die TWI-Kommunikation über Interrupts - also asynchron - lösen 
und habe es nach vielem Testen und Verzweifeln auch irgendwann 
hinbekommen und möchte meine Ergebnisse der interessierten Allgemeinheit 
nicht vorenthalten :)

Hier mal die Prototypen der Funktionen. Den ganzen Quellcode gibts im 
Anhang.
1
#define TWI_OK              0
2
#define TWI_ERR_BUSY        1
3
#define TWI_ERR_BUFFER_LEN  2
4

5
// init the twi
6
// piSlaveaddress:  own I2C address
7
// piBR:            baudrate prescaler (register TWBR)
8
void twi_init (uint8_t piSlaveAddress, uint8_t piBR);
9

10
// checks for a received message and copies the message into the supplied buffer
11
// ppiBuffer:   pointer to local databuffer
12
// piBufLen:    max len of databuffer
13
uint8_t twi_getMsg (uint8_t *ppiBuffer, uint8_t piBufLen);
14

15
// starts an async write request to slave with address piSlaveAddr.
16
// piSlaveAddr: I2C address of slave
17
// ppiData:     pointer to databytes
18
// piDataLen:   bufferlen in bytes
19
uint8_t twi_WriteBytesAsync (uint8_t piSlaveAddr, uint8_t *ppiData, uint8_t piDataLen);
20

21
// starts an async read request for slave with address piSlaveAddr and tries to receive piDataLen databytes
22
uint8_t twi_ReadBytesAsync (uint8_t piSlaveAddr, uint8_t piDataLen);
23

24
// checks for IDLE state
25
// returns "0" when IDLE, "1" else
26
uint8_t twi_busy (void);

Der Empfänger macht jetzt also etwas in dieser Form:
1
 uint8_t liRet;
2
 uint8_t laiTWIBuf[100];
3

4
 twi_init(1);
5

6
 sei();
7

8
 while (1)
9
 {
10
   // TWI Msg Handler
11
   liRet = twi_getMsg (laiTWIBuf, 100);
12
   if (liRet)
13
   {
14
     // Nachricht empfangen ...
15
   }


Der Sender könnte so aussehen:
1
 uint8_t laiTWIBuf[100];
2

3
 twi_init(2);
4

5
 sei();
6

7
 // laiTWIBuf mit Daten füllen
8
 // ...
9

10
 // und 3 Bytes an Slave 1 senden
11
 twi_WriteBytesAsync (1, laiTWIBuf, 3);

  

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren