TWI Nack nach zweitletztem Byte?

Gast #3694632
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
Gast #3694763
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
Gast #3694790
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.
#3694798
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.
Gast #3694815
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
#3694851
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.
#3694855
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.
#3694869
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?
Gast #3694907
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.
Gast #3695107
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.

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