So langsam komme ich der Sache näher, jedoch hat sich seit dem letzten
Thema einiges bei dem Code verändert. Desshalb dieses Neue.
Der Master (Sender):
1 | #include "twi_com.h"
|
2 |
|
3 |
|
4 | int slave = 0b0100111;
|
5 |
|
6 | void twi_init(void) {
|
7 | TWBR = 0x5c; //SCL auf 400KHz: 0x11 ; 200KHz: 0x2A ; 100KHz : 0x5C
|
8 | TWSR &= ~(1<<TWPS0) | ~(1<<TWPS1); //Prescale Bits - Teiler = 1
|
9 | }
|
10 |
|
11 | void twi_trans_value (void) {
|
12 |
|
13 | int value =100;
|
14 |
|
15 | TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); //Start Condition senden
|
16 |
|
17 | while (!(TWCR & (1<<TWINT))); //Warten ob erfolgreich
|
18 |
|
19 | TWDR = (slave<<1) | TW_WRITE; //Slave adresse + Zugriffsart (W) in Datenregister schreiben
|
20 |
|
21 | TWCR = (1<<TWINT) | (1<<TWEN); //TWDR senden
|
22 |
|
23 | while (!(TWCR & (1<<TWINT))); //Warten bis gesendet
|
24 |
|
25 | TWDR = value; //Daten in TWDR laden
|
26 |
|
27 | TWCR = (1<<TWINT) | (1<<TWEN); //Daten senden
|
28 |
|
29 | while (!(TWCR & (1<<TWINT))); //Warten bis gesendet
|
30 |
|
31 | TWDR = 130; //Daten in TWDR laden
|
32 |
|
33 | TWCR = (1<<TWINT) | (1<<TWEN); //Daten senden
|
34 |
|
35 | while (!(TWCR & (1<<TWINT))); //Warten bis gesendet
|
36 |
|
37 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); //STOP senden
|
38 |
|
39 | while (!(TWCR & (1<<TWINT)));
|
40 |
|
41 | }
|
Der Slave (Empfänger)
1 | int twi_data = 0;
|
2 | uint8_t zaehler=0;
|
3 |
|
4 | void twi_init(void) {
|
5 |
|
6 | TWAR = 0b01001110; //Slaveadr....
|
7 | TWCR = (1<<TWEA)|(1<<TWEN)|(1<<TWIE);
|
8 |
|
9 | }
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | ISR (TWI_vect)
|
15 | {
|
16 |
|
17 | cli();
|
18 |
|
19 | char buffer [3];
|
20 | itoa(zaehler,buffer,10);
|
21 |
|
22 | twi_data = TWDR;
|
23 |
|
24 | itoa(twi_data,buffer,10);
|
25 | lcd_puts(small_font,&buffer); // Ausgabe auf Display
|
26 |
|
27 |
|
28 | TWCR |= (1<<TWINT);
|
29 |
|
30 | sei();
|
31 |
|
32 | }
|
Ich bekomme vom Master Daten gesendet (1. 100 und 2. 130).
Allerdings erscheint auf meinem Display dann folgendes:
78 100 130 4
Woher die 78 kommt kann ich mir noch erklären. Das ist das erste Byte
welches übertragen wird wo die Slaveadresse inkl. Datenrichtungsbit drin
steht. Anschließend die 100 und die 130, so wie es soll.
UND auf einmal eine "4" ?! Wo kann die wegkommen. Auf dem Oszi sehe ich
auch nix, woher diese kommen könnte. Kommt immer zum Ende?!
Noch zwei Fragen zum Verständnis vom I²C:
1. Um das Ack/NACK kümmmert sich doch intern im AVRmega die Hardware
oder habe ich hier Softwareseitig was zu erfüllen? ACK kommt auf jeden
Fall an. TWEA ist hier wohl das Stichwort!
2. Wird die ISR im Slave wirklich schon bei der Adresssendung vom Master
aufgerufen oder erst nachdem der Slave mit seiner Adresse angesprochen
wurde und mit Ack bestätigt dass eine Verbindung aufgebaut ist? Wunderte
mich, dass er das erste Byte schon in der ISR einließt (also seine
Slaveadresse + Datenrichtungsbit).
Viele Dank!