Forum: Mikrocontroller und Digitale Elektronik I2C Probleme


von Hagen (Gast)


Lesenswert?

Hi Experten,

das Hardware TWI ist ja gut und schön, aber die Beispiele in den
Datenblättern sind wohl falsch.

Die meisten TWI Routinen die im Netz rumschwirren funktionien nur dann
richtig wenn man auch tatsächlich am I2C Bus ein I2C Gerät
angeschlossen hat.

Vielleicht mal von Anfang an:

Ich teste das TWI im Polling Modus. Das erste Kommando das man sendet
ist die Start Kondition.

In C sähe das so aus:
1
void i2cStart(void) {
2
3
    TWCR = (1 << TWEN) | (1 << TWINT) | (1 << TWSTA);
4
    while (!(TWCR & (1 << TWINT)));
5
}


So sollte es laut Datenblätter sein, und die meisten TWI Sourcen gehen
auch so oder ähnlich vor.

Nur !! im Falle das der I2C Bus überhaupt nicht reagiert, also zB.
keine Pullups oder keine I2C Geräte angeschlossen sind, kehrt obige
while Schleife NIEMALS zurück. Was natürlich die MCU virtuell in einer
Endlosschleife zum Stoppen bringt.

D.h. das Hardware TWI hat keinen Timeout und keine explizite Erkennung
ob der I2C Bus überhaupt ansprechbar ist.

Sehe ich das richtig so ??

Leider konnte ich in den Datenblättern über diesen speziellen Fall
nichts finden.


Gruß Hagen

von Uwe (Gast)


Lesenswert?

Normalerweise startest du mit dem Startbefehl (1<<TWSTA) einen Timer und
nimmst keine while schleife sondern if ,so das du über einen
Timerinterrupt

1. Die Schleife beenden kannst
2. In eine "Fehlerroutine" springst

Bei Bedarf schick ich dir eine Interrupt TWI Routine per mail zu.
Ist zwar alles nicht zu 100% aufgeräumt und kommentiert aber recht
einfach zu implementieren.
Allerdings hab ich keine Fehlerzeit eingebaut da ich zu einen über ein
BUSY  ERROR  OK Bit den Status überwache und im Fehlerfall nur ne LED
einschalte und zum anderen immmer ein Watchdog Timer läuft der das
ganze System resetet wenn es hängt.

MfG   Uwe

von Hagen (Gast)


Lesenswert?

Komischerweise läuft es jetzt so wie erwartet. Also auch wenn der Bus
keine Geräte enthält klappt es jetzt. Ich hatte beim i2cStop()
ebenfalls diese while Schleife drinnen, und das war ein Fehler.

In meinem Falle kann und will ich keine Interrupts oder Timer benutzen,
bzw. diese wären sinnlos, denn ich muß pollen. Dafür sind alle anderen
Operationen meines Projektes weitestgehend Interruptbasiert. Nur die
I2C Routinen werden in Callbacks benutzt um benötigte Daten aus einem
EEPROM zu lesen. D.h. so oder so muß die Callback warten damit sie die
nötigen Bytes aus dem EEPROM zurück liefern kann. Ich habe diesen Weg
beschritten weil besonders das TWI durch Interrupts unterbrochen werden
kann, also zeitunkritisch ist.

D.h. in allen TWI Operationen kann mit obiger Loop gewartet werden, bis
auf den Zeitpunkt wenn man STOP senden will. z.Z. habe ich nach dem
senden der STOP Kondition eine kleine Wartezeit von 8 Taktzyklen
eingebaut und danach deaktiviere ich das TWI vollständig. Bisher klappt
alles wunderbar.

Ein Interruptbasiertes I2C würde im meinem Falle 1. wesentlich mehr
Code benötigen, 2. keine Vorteile bringen und 3. die Abhänigkeiten zu
den anderen IRQ's stark erhöhen.

Das kouriose dabei ist und bleibt aber der Punkt das ich mit der
gleichen Hardwarekonfiguration am Anfang mit mehreren verschiedenen TWI
Sourcen die obigen Probleme hatte. Nunmehr aber funktionieren alle
diese TWI Source einwandfrei. Es kann also nur an meiner Hardware
gelegen haben. Naja, ich habe alles auf einem Steckboard aufgebaut, es
wird wohl daran gelegen haben.


Gruß Hagen

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.