Forum: Mikrocontroller und Digitale Elektronik TWI Nack nach zweitletztem Byte?


von Roman (Gast)


Lesenswert?

Hallo zusammen,

Ich habe ein für mich seltsames Problem mit meinem TWI.
Wenn mein Atmega8 als Master von einem Sensor Daten liest, dann muss er 
schon nach dem zweitletztem Byte, welches er empfangen will, dem Sensor 
ein NACK (not acknowledge) senden. Wenn er das nicht tut, dann bleibt 
der Controller in der while Schleife einer darauffolgendne TWI_Start 
Funktion hängen, sprich das TWINT Flag wird nicht mehr gesetzt.
Die Stelle im Code sieht so aus:
1
** Send START condition
2
*/
3
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
4
/*
5
** Wait until transmission completed
6
*/
7
  while (!(TWCR & (1<<TWINT))){} !!!!!hier bleibt er hängen !!!!!!!!!
Anscheinden wird in diesem Fall das TWINT Flag nicht mehr gesetzt, 
obwohl eine Start Kondition vom Controller gesendet wurde.

Ich verstehe dieses Verhalten nicht, sollte es nicht so sein, dass der 
Master als Receiver nach dem letzten Byte, welches er empfangen will, 
ein NACK senden sollte und somit der Sensor weiss, dass er nichts mehr 
senden soll? Ich habe irgendwo in einem Forum mal aufgenommen, dass das 
passieren kann, wenn gewisse Register des Sensors doppelt gebuffert 
sind. Im Datenblatt finde ich allerdings nichts dazu.
Hat jemand eine Idee?

Vielen Dank,
Roman

von Peter D. (peda)


Lesenswert?

Roman schrieb:
> sollte es nicht so sein, dass der
> Master als Receiver nach dem letzten Byte, welches er empfangen will,
> ein NACK senden sollte

So isses.
Dazu muß er aber schon vor dem letzten Byte das NACK setzen, damit es 
danach gesendet wird.

von Stefan (Gast)


Lesenswert?

Hallo,

dass TWI beim Senden einer Start-Condition hängen bleibt kann aus 
verschiedenen Gründen passieren und ist absolut in Ordnung - das musst 
du durch einen TimeOut selbst abfangen.

Der Grund warum er hängen bleibt ist das interessante.
Ich vermute eher dass du bei der vorherigen Übertragung kein STOP 
gesendet hast und/oder deine Leitungen nicht auf HIGH liegen (aus 
welchem Grund auch immer)
also schau noch mal richtig nach
an dem ACK/NACK liegt es sicher nicht, denn du kannst eine Übertragung 
jederzeit durch ein STOP beenden und alle (Slaves) gehen in 
Wartestellung


Gruss

von Roman (Gast)


Lesenswert?

Stefan schrieb:
> an dem ACK/NACK liegt es sicher nicht, denn du kannst eine Übertragung
> jederzeit durch ein STOP beenden und alle (Slaves) gehen in
> Wartestellung

Das wage ich zu bezweifeln, mein Code sieht nämlich folgendermassen aus:
1
I2C_interface.TWIM_Start(0x1D,TWIM_WRITE);
2
I2C_interface.TWIM_Write (0x01);
3
I2C_interface.TWIM_Start(0x1D,TWIM_READ);
4
5
x_high = I2C_interface.TWIM_ReadAck();
6
x_low = I2C_interface.TWIM_ReadAck();
7
y_high = I2C_interface.TWIM_ReadAck();
8
y_low = I2C_interface.TWIM_ReadAck();
9
z_high = I2C_interface.TWIM_ReadNack(); //!!!!!hier muss ich das NACK setzen!!!!
10
z_low = I2C_interface.TWIM_ReadNack();
11
12
I2C_interface.TWIM_Stop ();
Wenn ich das NACK nicht dort setze, wo ich es im Code markiert habe, 
dann hängt der Controller und das auch, obwohl ich die Übertragung mit 
einem Stop beende.

von Cyblord -. (cyblord)


Lesenswert?

Stefan schrieb:

> an dem ACK/NACK liegt es sicher nicht, denn du kannst eine Übertragung
> jederzeit durch ein STOP beenden und alle (Slaves) gehen in
> Wartestellung

Natürlich nicht. Wenn ein Slave sendet, wie soll er dann "jederzeit" 
eine Stopbedingung erkennen? Er benötigt zwingend ein NAK damit er 
aufhört zu senden und überhaupt auf ein STOP reagieren kann. Der Master 
hat ja vorher nur Kontrolle über SCL und da sendet der Slave dann bei 
jedem Takt was raus. Bis zum NAK. SDA wird in diesem Zeitraum von Slave 
gar nicht gelesen.

von Stefan (Gast)


Lesenswert?

Hallo,

Roman schrieb:
> Wenn ich das NACK nicht dort setze, wo ich es im Code markiert habe,
> dann hängt der Controller und das auch, obwohl ich die Übertragung mit
> einem Stop beende.

sollte das wirklich so sein, dann hast du was ganz Grundlegendes 
übersehen, denn ein Master darf sich nie von einem Slave blockieren 
lassen! (sofern er nicht zerstört ist)
Auch bei noch so falschen Signalen müssen alle Teilnehmer nach einer 
kurzen Ruhephase ( wenige Millisekunden)  wieder in Anfangsstellung 
gehen.

Gruss

von Stefan (Gast)


Lesenswert?

cyblord ---- schrieb:
> Er benötigt zwingend ein NAK damit er
> aufhört zu senden und überhaupt auf ein STOP reagieren kann.


NEIN,

mit jederzeit hatte ich natürlich "byte-boundary" gemeint !!!

von Peter D. (peda)


Lesenswert?

Da müßtest Du mal den Quellcode für Dein I2C_interface.TWIM_ReadNack 
zeigen. Vieleicht ist da was falsch implementiert.
Wurde NACK gesendet, muß vor dem Stop der Status 0x58 sein.

von Cyblord -. (cyblord)


Lesenswert?

Das Problem ist viel eher: Der Master kann überhaupt nicht "hängen" nur 
weil der Slave spinnt. Weder beim Lesen noch beim Schreiben. Er schreibt 
und liest einfach drauf los. Beim schreiben bekommt er dann halt nach 
jedem byte ein NAK, aber da gibts auf I2C-Busebene keinerlei warten, 
pollen oder sonstiges was der Master tun müsste um zu hängen.

von Peter D. (peda)


Lesenswert?

Stefan schrieb:
> Auch bei noch so falschen Signalen müssen alle Teilnehmer nach einer
> kurzen Ruhephase ( wenige Millisekunden)  wieder in Anfangsstellung
> gehen.

Nö.
Dumme I2C-Slaves gehen nie von allein in Reset. Du kannst sie auch mit 
einem SCL von 1 Bit/Jahr takten.

Nur Slaves mit MC können (müssen aber nicht) einen zusätzlichen 
Timeouthandler haben.

Will der Master ein Reset erzwingen, muß bis zu 9 mal versuchen ein Stop 
zu senden und solange das mißlingt, SCL einmal takten.
Das muß man allerdings zu Fuß machen (Bit-Banging), das HW-I2C kann das 
nicht.

von Stefan (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Nö.
> Dumme I2C-Slaves gehen nie von allein in Reset. Du kannst sie auch mit
> einem SCL von 1 Bit/Jahr takten.

Also von nicht normgerechten Sachen sollten wir nicht reden !!!

von Cyblord -. (cyblord)


Lesenswert?

Stefan schrieb:
> Peter Dannegger schrieb:
>> Nö.
>> Dumme I2C-Slaves gehen nie von allein in Reset. Du kannst sie auch mit
>> einem SCL von 1 Bit/Jahr takten.
>
> Also von nicht normgerechten Sachen sollten wir nicht reden !!!

In welcher "Norm" steht da was anderes zu? Wenn dann sollte die i2c-spec 
dazu was sagen. Tut sie es? Schreibt sie einen Timeout und damit auch 
eine Mindesttaktgeschwindigkeit vor?

: Bearbeitet durch User
von Stefan (Gast)


Lesenswert?

Hallo,

Stefan schrieb:
> Peter Dannegger schrieb:
>> Nö.
>> Dumme I2C-Slaves gehen nie von allein in Reset. Du kannst sie auch mit
>> einem SCL von 1 Bit/Jahr takten.
>
> Also von nicht normgerechten Sachen sollten wir nicht reden !!!

ich muss mich berichtigen !!!
In der Spec steht dass es für gewöhnliche keinen Timeout für den Reset 
gibt sondern lediglich für die Erweiterung zu SMBus

Originalton: There is no limit in the I2C-bus protocol as to how
long this delay can be, whereas for a SMBus system, it would be limited 
to 35 ms.

von Roman (Gast)


Lesenswert?

Mein Code für ACK/NACK ist der folgende:
1
uint8_t I2C::TWIM_ReadAck (void)
2
  {
3
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
4
  while (!(TWCR & (1<<TWINT)));
5
6
  return TWDR;
7
  }
8
9
uint8_t I2C::TWIM_ReadNack (void)
10
  {
11
  TWCR = (1<<TWINT)|(1<<TWEN);
12
  while(!(TWCR & (1<<TWINT)));
13
14
  return TWDR;
15
  }

Ich bin jetzt ein wenig verwirrt aufgrund der unterschiedlichen 
Meinungen.
Ich gehe jetzt mal davon aus, dass das NACK nach dem lesen des 
zweitletzten Bytes vom Master gesetzt werden muss, so wie es Peter 
Dannegger bestätigt hat. Ausserdem muss zwingend vor einem Stop ein NACK 
gesendet werden, zumindest geht bei mir ansonsten gar nichts mehr mit 
TWI.

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.