Forum: Mikrocontroller und Digitale Elektronik I2C deadlock vermeiden


von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Hi,

ich verwende die twimaster.h Lib von
Peter Fleury <pfleury@gmx.ch>  http://jump.to/fleury

ich habe in einer Testumgebung ein LCD Panel erfolgreich laufen gehabt 
und wollte dann zu Demozwecken "einfach" zusätzlichen Code für einen 
weiteren I2C Slave Chip einfügen.

Ich kam erst relativ spät darauf, dass der BUS für den bestehenden SLAVE 
geöffnet wird und dann in der:

/*********************************************************************** 
**
 Terminates the data transfer and releases the I2C bus
************************************************************************ 
*/
void i2c_stop(void)
{
    /* send stop condition */
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

  // wait until stop condition is executed and bus released
  while(TWCR & (1<<TWSTO));

}/* i2c_stop */

hängen bleibt.

Gibt es eine mehr oder minder "schlaue" Abwandlung, um während der 
Entwickung Code für mehrere SLAVES auf den Chip zu bringen jedoch nur 
EIN I2C Gerät am BUS zum Testen zu betreiben?

Also Fallbeispiel:
- Ich bespiele meinen AVR mit Code für 3 verschiedene Displays/Adressen.
- Der Master ist aber nur mit EINEM Kabelsatz mit EINEM Display 
verbunden.
- Ich Ziehe das Display 1 ab und hänge das 2 an und "reboote"(vom Strom 
trennen) das System.

Ist dies möglich ohne neu zu flashen und die Methoden für Display 1 
auszukommentieren und entsprechend für 2 ein?

Grüße Oekel

von Joe F. (easylife)


Lesenswert?

Du kannst nach dem Start erstmal den Bus nach vorhandenen Slaves 
durchsuchen, indem du zwischen START und STOP nur die (Read-)Adresse 
eines Slaves auf den Bus legst, und guckst ob der Slave ein ACK macht.
Die nicht antwortenden Slaves merkst du dir, und ignorierst sie im 
weiteren Verlauf.

Warum dein Programm in der i2c_stop() Funktion hängen bleibt (bei nicht 
vorhandenem Slave) ist allerdings seltsam. Das sollte nicht so sein.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

D a v i d K. schrieb:
> Gibt es eine mehr oder minder "schlaue" Abwandlung, um während der
> Entwickung Code für mehrere SLAVES auf den Chip zu bringen jedoch nur
> EIN I2C Gerät am BUS zum Testen zu betreiben?

 Selbstverständlich.

 I2C Adresse (oder Control Byte, ist egal) senden, auf ACK checken.
 Wenn ACK zurückkommt, ist Device mit dieser Adresse am Bus, STOP
 senden, Flag setzen und nächste Adresse abfragen.

> // wait until stop condition is executed and bus released
>   while(TWCR & (1<<TWSTO));
>
> }/* i2c_stop */
>
> hängen bleibt.
>

 Wenn du keinen Systick hast, die Abfrage auf TWSTO in einem loop
 machen. Falls Zähler überläuft, rausspringen und Fehler melden -
 Device Error oder so.

von A. S. (Gast)


Lesenswert?

D a v i d K. schrieb:
> und "reboote"(vom Strom trennen) das System.

Beim hantieren darauf achten, wirklich auch alle slaves durch einen 
spgs-reset zu führen.

von Klaus (Gast)


Lesenswert?

Joe F. schrieb:
> Du kannst nach dem Start erstmal den Bus nach vorhandenen Slaves
> durchsuchen, indem du zwischen START und STOP nur die (Read-)Adresse
> eines Slaves auf den Bus legst, und guckst ob der Slave ein ACK macht.

Starte ein Write, kein Read. Sehr doofe Slaves wollen bei einem Read 
unbedingt etwas loswerden, das dann als letztes Byte auch noch mit NAK 
quittiert werden muß, und hängen, wenn keiner das Byte abholt. Also 
immer mit Write pollen.

MfG Klaus

von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Ich danke euch allen. Mit diesen Infos konnte ich wirklich sehr gut 
testen.
Mir hat es ausreichend weit geholfen.

Grüße Oekel

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.