I2C deadlock vermeiden

OP Persönliche Seite #4927691
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
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.
(Firma: Vescomp)
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.
Gast
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.