Forum: Mikrocontroller und Digitale Elektronik TWI liefert bei Adressierung NACK


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Bucki E. (buckied)


Bewertung
0 lesenswert
nicht lesenswert
Hallo liebe Forengemeinde,

ich habe leider ein kleines Problem den I2C-Bus bzw. das TWI des 
Atmega32U4 in Betrieb zu nehmen. Ich habe bisher alles Standardmäßig 
geschrieben und nutze zur Auswertung zusätzlich noch einen TTL/Seriell 
Wandler um mir den Zwischenstatus anzeigen zu lassen.

Mein Problem ist nun, dass die TWI nur beim Power Up der kompletten 
Schaltung bei der Adressierung ein ACK des Slaves bringt. Sobald ich 
aber (momentan wird der Slave einfach periodisch angesprochen um die 
Adressierung erstmal richtig zu bekommen) den Slave erneut anspreche, 
also direkt ab Abfrage Nr. 2 liefert er nur noch ein NACK. Kann mir 
eventuell Jemand sagen an was das liegen könnte? Oder ist das sogar 
normal so, wenn man dem Slave keinen Befehl schickt?

Noch kurz zur Info: uC ist ein Atmega32U4 (Arduino Micro, schreibe aber 
"normal" in Atmel Studio ohne die Arduino IDE), Slave ist der SL030 RFID 
Card Reader mit Standard-Adresse 1010000b und ich führe einfach 
periodisch den I2C Start aus (also Start --> Adressierung + SLA+W ACK 
erhalten? -->weiter bis return 0 --> direkt I2C Stopp ohne weitere 
Befehle zu schicken) und stoppe die Kommunikation direkt danach wieder.

Ich hoffe das hat das Problem gut genug umschrieben.


Grüße,
BuckiED

von TK (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe selbst noch nie mit TWI gearbeitet - daher erst mal die Frage 
nach einem Oszi Bild vom IIC-Bus für den GUT- und den SCHLECHT-Fall. 
Damit kann man bestimmt erkennen, woran es liegen könnte.
Weiterhin mögen manche Bausteine keine "leeren" Abfragen mit START-STOP 
Kombination, oder in Deinem Fall kann es sein, dass der Baustein auf 
eine Anfrage mit Schreibzugriff auch einen weiteren Datenwert erwartet?
Es hängt doch nicht etwa noch ein IIC Slave am Bus (z.B. ein EEPROM wg 
der Device-Address von 0xA0)?

Gruß
TK

von Bucki E. (buckied)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mal zwei Bilder beigefügt. Bild 1 zeigt die erfolgreiche 
Kommunikation mit Bestätigung durch ACK und Bild 2 zeigt die 
"Dauerschleife" der NACK's nach dem Power Up und dem ersten 
erfolgreichen Adressieren.

Das befürchte ich momentan auch, obwohl ich es mir nicht erklären kann. 
Nach einem klaren Stopp müsste man den Baustein doch wieder ganz normal 
adressieren können oder nicht?

Sonst hängt nichts weiter am Bus, nur der Atmega und der SL030.

Grüße
BuckiED

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Bucki E. schrieb:
> Ich habe mal zwei Bilder beigefügt.

Kläre vielleicht erstmal, wieso dein SDA-Pegel so durch die Gegend 
driftet.

von Bucki E. (buckied)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Das lag nur an der Oszi Einstellung, irgendwie hat mein Tastkopf bei x10 
nen Klatsch... habs nun auf 1x gestellt und ein sauberes Signal 
bekommen. Jedoch bin ich bei meinem eigentlichen Problem noch nicht 
wirklich weiter. :/

von N2 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hi,

I2C kann schon gemein sein:

* Es gibt Softwareimplementierungen auf uC, die machen, was sie wollen. 
Der beste Kanidat war mal ein Touch I2C Slave Controller (eigentlich nur 
ein AVR mit Firmware I2C per Bit Banging), der hat auch geantwortet auf 
seine Adresse, wenn die im Datenstrom vorkam, obwohl er gar nicht das 
adressierte Device war :-)

* Es gibt nicht standardkonforme Hardwareimplementierungen, wie bei dem 
Master, wo Clock Stretching mal halt nicht implementiert war oder wo 
sich die State Machine des Slave eben nicht (warum auch immer) über ein 
STOP zurücksetzt

* Und es gibt natürlich auch die standartkonformen Teile, bei denen 
alles implementiert ist und auch funktioniert

Aber momentan würde ich sagen, dem SL030 geht es nicht so gut, da ich 
vermute, Du versorgst das Teil vom Atmega mit 5V (Deine IO Spannung ist 
ja 5V) ? Oder hast Du einen 3V3 LDO ?
Der SL030 hat zwar 5V tolerante IOs, aber die Versorgung darf nicht mehr 
als 3,6V sein.

Ansonsten gibt der State Machine? im SL030 nach dem Stopp mal noch 10 
Clock Zyklen zu tun (also SDA auf High und SCL 10 mal takten). Danach 
sollte sich die State Machine? wieder einkriegen.

Gruß N2

von TK (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,
zuerst mal ist der Hinweis mit den 3V3 schon mal gut. Daher sollten die
Pull-Ups auf die 3V3 Seite um dann den SL030 auch mit 3V3 Pegeln 
anzusteuern.
Wenn TWI sauber in Hardware implementiert ist, dann wird auch nur ein 
"open Drain" angesteuert - aber der Atmel könnte Probleme mit 3V3 am SDA 
während des Einlesens bekommen (andere Baustelle).

Aber ich vermute mal, dass der SL030 keine leere Anweisung mag. Im 
Datenblatt steht auch was drin, dass er ein NACK ausgibt, während 
STATE-BUSY. Ich kenne selbst Sensoren, die mir für exakt 1s ein NACK 
gegeben haben, weil sie interne Wandlungen ausgeführt haben (hat lange 
gedauert, bis ich darauf gekommen bin) - egal, versuch doch mal eine 
vollständige Anweisung zu senden (also mit LEN und COMMAND)

Ansonsten sieht die Übertragung auf den 1.Blick gut aus.

Gruß
TK

von Bucki E. (buckied)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Danke für eure Antworten!

Leider hat sich wenig getan. :/ Nun habe ich "erfolgreich" das Senden 
der Länge+Befehl erledigt, jedoch wieder nur im ersten Durchgang. Ich 
bekomme jedes mal ein ACK, sobald ich aber in der Master Receiver Mode 
wechseln möchte und nach einer repeated Start Condition das Read-Bit 
anhänge bekomme ich direkt ein NACK vom Sensor.. ich weis nicht so recht 
wie ich weitermachen soll...

Grüße,
BuckiED

von Curby23523 N. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Im Datenblatt zum SL030 steht aber nichts von einem RepeatStart. Siehe 
Seite 7.

Dort steht entweder man schreibt oder man liest. Und immer schön einen 
Stop erzeugen. So verstehe ich es. Das Wort "repeat" kommt nicht einmal 
im Datenblatt vor.

von Bucki E. (buckied)


Bewertung
0 lesenswert
nicht lesenswert
Da hast du recht, das ist vor allem etwas was mich verwundert. Aber ist 
es für den Atmega nicht notwendig den Modus zu wechseln, damit er dem 
Slave die Kontrolle über den Bus überlässt?
Es ist ja nicht möglich nur SLA+R zu schicken und darauf Length+Command 
zu schreiben, da der Master in dem Modus ja nichts außer ein ACK auf den 
Bus geben kann oder missverstehe ich da etwas grundlegend?

Grüße,
BuckiED

von Jim Beam (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Mag der vielleicht keinen REPEATED-START?
Mal mit regulärem STOP + NEUEM-START versuchen?

Und hast Du das ganze auch mal mit ultra-niedriger Clockrate probiert,
um Timing-Überforderung des Slave auszuschliessen?

von Curby23523 N. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Bucki E. schrieb:
> Da hast du recht, das ist vor allem etwas was mich verwundert. Aber ist
> es für den Atmega nicht notwendig den Modus zu wechseln, damit er dem
> Slave die Kontrolle über den Bus überlässt?

DU bist der Master. DU gibts die CLk aus ;). Immer.
Der Slave sendet höchzstens Daten auf SDA, aber DU machst die Clock.

Modus? Was für ein Modus? Du beendest deinen Schreibvorgang und danach 
kannst du z.B. einen Lesevorgang durchführen. Es gibt da keinen "Modus". 
Siehe Seite 7 vom Datenblatt.

Ich vermute dir fehlen noch ein paar Grundlagen vom I²C.

von Bucki E. (buckied)


Bewertung
0 lesenswert
nicht lesenswert
Okay, ich habs jetzt mal in die Richtung probiert und da kommt sogar was 
an, jetzt ist wohl glaube ich noch mein Problem, dass ich nicht weiß, 
wie ich als Master einen ACK nach auslesen des Registers liefern kann. 
Könnt ihr mir dahingehend noch weiterhelfen? :)
(Momentan kommt eben nach jedem "auslesen" das gleiche an, da ich ja 
noch kein ACK geschickt habe, verstehe ich das richtig?)

Ist das auslesen denn überhaupt richtig geschrieben?
1
unsigned char I2C_Daten_Lesen(void)
2
{
3
  TWCR = (1<<TWINT)|(1<<TWEN);
4
  while(!(TWCR&(1<<TWINT)));
5
  return TWDR;
6
}

Grüße,
BuckiED

von Bucki E. (buckied)


Bewertung
0 lesenswert
nicht lesenswert
Da liegst du leider richtig Curby, ich mache das erste mal was mit I2C 
(was natürlich nichts rechtfertigen soll). Aber laut ATmega Datenblatt 
hatte ich es eben so verstanden, dass man nach dem Transmitter Mode (wo 
man eben Befehle verschicken kann) in den Receiver Mode wechseln muss, 
aber da lag ich ja anscheinend falsch.

Grüße,
BuckiED

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.