Forum: Compiler & IDEs Verständnisfrage HW I2C ATmega8


von Michael D. (etzen_michi)


Lesenswert?

Nabend.


Ich bastel mir grad einen kleinen I2C Slave zusammen und frage mich 
jetzt ob ich das richtig verstehe:

Wenn der Slave mit seiner Adresse + W angesprochen wird steht im TWSR 
0x60
Nun kann man sagen ob nach dem Empfang des ersten Byte (welches 
anschließend empfangen wird) Ack oder Nack gesendet werden soll.

Man kann aber nicht! vor dem senden des Ack/Nack überprüfen ob man da 
einen gültigen Befehl hat.


Sehe ich das so richtig?
Ist das normal so?
Wird das Nack dann beim zweiten Byte/Adresse+R gesendet?

Vielen Dank im Vorraus

Klimper zwischenzeitlich die I2C Specs durch...


PS: Seite 185

von Gastino G. (gastino)


Lesenswert?

Michael D. schrieb:
> Sehe ich das so richtig?

Wenn ich mich recht erinnere, ja.

Der ATmega als I2C-Slave macht keinen Spaß, insbesondere dann, wenn er 
auch noch zeitweise Master sein soll.

von Michael D. (etzen_michi)


Lesenswert?

Deine Antwort höert sich an als wenn du dafür einen besseren Baustein 
kennen würdest.
Nach der Atmel Homepage ist das leider nicht wirklich ersichtlich wie 
gut sich die einzelnen Chips für I2C eignen.


Welche Chips würdest du empfehlen:

1x I2C wenig rechnen, wenig Daten, Verwaltet alles
1x I2C Daten empfangen und auf Display anzeigen (Display braucht 8 + 
5pins) speicherintensiv
2x I2C Daten empfangen und je nachdem funktionen auf zweiten I2C als 
Master
1x I2C Daten empfangen und berechnungen druchführen

von Gastino G. (gastino)


Lesenswert?

Da bei mir der ATmega so eine Art "Standard-Controller" ist, habe ich 
mich nicht groß mit Alternativen beschäftigt. Letztendlich läuft er bei 
mir auch als Master und Slave gleichzeitig, das war aber recht 
umständlich zu programmieren und wäre ohne Logic-Analyzer wahrscheinlich 
auch fast aussichtslos gewesen.

Ein kurzer Blick in die Datenblätter der XMega-Familie (vor einer Weile) 
hat mir gezeigt, dass dort auch am I2C-Interface kräftig geschraubt 
wurde. Ich gehe mal davon aus (weiß es aber leider mangels Erfahrung 
nicht), dass die sich besser eignen.
Die haben aber den Nachteil, dass sie nicht als DIP verfügbar sind und 
auch nicht mit 5 V Betriebsspannung betrieben werden können (was sie für 
meine Anwendungen nicht besonders brauchbar bzw. handlich macht).

von Michael D. (etzen_michi)


Lesenswert?

Ich finde das Programmieren des I2C nicht so schwer ...


Ich mache das über einen SwitchCase,


Hier ein auszug eines "Halb"fertigen Masters wo ich gerade den Slave 
hinzufüge:
1
ISR(TWI_vect){
2
     switch(TWSR) {
3
4
          case 0x08:
5
               TWDR=Slave;
6
               TWCR= 1<<TWEN | 1<<TWIE | 1<<TWINT;
7
               break;
8
9
          case 0x18:
10
               TWDR=Command[CountCommand-1];
11
               
12
               if(CountCommand--==0) {
13
                    TWCR= 1<<TWEN | 1<<TWIE | 1<<TWINT | 1<<TWSTA;
14
                    } else {
15
                    TWCR= 1<<TWEN | 1<<TWIE | 1<<TWINT;
16
               }
17
               break;
18
19
          case 0x28:
20
               TWDR=Command[CountCommand-1];
21
               
22
               if(CountCommand--==0) {
23
                    TWCR= 1<<TWEN | 1<<TWIE | 1<<TWINT | 1<<TWSTA;
24
                    } else {
25
                    TWCR= 1<<TWEN | 1<<TWIE | 1<<TWINT;
26
               }
27
               break;
28
29
          case 0x10:
30
               TWDR=Slave+1;
31
               TWCR= 1<<TWEN | 1<<TWIE | 1<<TWINT;
32
               break;
33
34
          case 0x40:
35
               if(--CountByte==0) {
36
                    TWCR= 1<<TWEN | 1<<TWIE | 1<<TWINT;
37
                    } else {
38
                    TWCR= 1<<TWEN | 1<<TWIE | 1<<TWINT | 1<<TWEA;
39
               }
40
               break;
41
42
          case 0x50:
43
               Byte[CountByte]=TWDR;               
44
               if(--CountByte==0) {
45
                   TWCR= 1<<TWEN | 1<<TWIE | 1<<TWINT;
46
                   } else {
47
                   TWCR= 1<<TWEN | 1<<TWIE | 1<<TWINT | 1<<TWEA;
48
               }
49
               break;
50
51
          case 0x58:
52
               Byte[CountByte]=TWDR;
53
               TWCR= 1<<TWEN | 1<<TWINT | 1<<TWSTO;
54
               flag=1;
55
               break;
56
57
          case 0x60:
58
               TWCR= 1<<TWEN | 1<<TWIE | 1<<TWINT | 1<<TWEA;
59
               break;
60
61
          case 0x80:
62
               Command[CountCommand++]=TWDR;
63
               TWCR= 1<<TWEN | 1<<TWIE | 1<<TWINT | 0<<TWEA;
64
               break;
65
66
          default:
67
               LCD_Hex(TWSR);
68
               LCD_Hex(TWDR);
69
               LCD_Hex(Command[--CountCommand]);
70
               LCD_Hex(Byte[--CountByte]);
71
               TWCR=0x00;
72
               flag=1;
73
               break;
74
75
     }
76
}


Kritik immer erwünscht.
Das gleiche gilt für Info wenn jemand sieht wo es bei diesem System 
hackt.
default nutze ich immer um mir die Daten auf einem LCD anzeigen zu 
lassen um zu wissen was gerade genau los ist.

Mir fällt auch gerade auf das ich kein Stop habe wenn ich nur Daten 
senden will sondern immer aufs Empfangen gehe.

von Michi (Gast)


Lesenswert?

Hallo Michael,

Was ich wärmstens empfehlen kann ist dieser Artikel:

Beitrag "DCF77-TWI(I2C)-Slave"

Hier findest du Funktionen und sehr gute Beispiele, wie man Attiny's mit 
USI als I²C-Slave verwenden kann!

Gruß
Michi

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.