Forum: Mikrocontroller und Digitale Elektronik I2C per Interrupt auf Atmega32


von Phillip H. (philharmony)


Lesenswert?

Hallo

Ich möchte zunächst den PCA9634 von einem Atmega32 aus ansteuern. Dabei
soll die I2C-Routine aber so flexibel wie möglich gehalten werden, damit
ich später ohne größeren Aufwand auch andere I2C Chips benutzen kann.
Da der Contoller noch jede Menge anderen Kram zu tun hat, möchte ich das
ganze per Interrupt machen.
Den UART habe ich schon per Ringpuffer interruptbasiert aufgebaut, daher
erscheint es mir recht sinnvoll, den I2C-Bus entsprechend zu
realisieren, daß der Aufrufer einfach sein Datenpaket in den Puffer
legt, der dann von der ISR abgearbeitet wird.
Allerdings ist der UART ASCII-basiert, und ich kann einzelne Blöcke sehr
schön mit dem Terminatorzeichen (0x00) von einander trennen. I2C ist
aber ja Byte-Basiert und ich kann keine Zeichen reservieren. Daher hatte
ich jetzt die Idee, jedem Datenpaket ein Byte voranzustellen, in dem die
Anzahl der zu diesem Paket gehörenden Daten steht. Eventuell zur
Überprüfung ans Ende eine Checksumme oder doch ein bestimmtes Zeichen.
Nun möchte ich aber das Rad auch nicht neu erfinden, daher die Fragen,
hat jemand sowas in der Art schonmal gemacht und könnte ein C Beispiel
posten, bzw. bin ich mit meiner Idee völlig auf dem Holzweg?

Viele Grüße

Phil

von Phillip H. (philharmony)


Lesenswert?

Ok um das nochmal auszugraben, ich hab das jetzt so gemacht wie oben
beschrieben. Die Ringpuffer-Sache funktioniert auch soweit, allerdings
ist mir bei der Ansteuerung der TWI-Schnittstelle eine Sache nicht ganz
klar.
Laut Datenblatt ist ja im TWCR das TWINT-Bit der Trigger, um die nächste
Aktion durchzuführen. TWEN möchte ich eigentlich beim initialisieren
einmal setzen und es dann gesetzt lassen. Die restlichen Bits TWSTA,
TWSTO etc. wollte ich dann jeweils einzeln setzen und zuletzt das TWINT
Bit setzen (um die Interrupt-Flag zu "clearen").
Problem an der Sache: Es funktioniert nicht.
Wenn ich allerdings das TWCR explizit mit dem gesamten Bitmuster setze
(TWCR = (1<<TWINT)|(0<<TWSTA)|...), dann funktioniert es plötzlich.
Warum?

Das zweite Problem betrifft die Stop-Condition. Diese löst nach
Abschluss ja kein weiteres Interrupt aus. Da der angesprochene Chip aber
per Default das soeben angewiesene erst nach Empfang der Stop-Condition
ausführt, habe ich jetzt ein Problem, wenn ich mehrere Datenblöcke aus
dem Puffer verschicken will.
(Also STA | SLA+W | OFFSET1 | VALUE1 | STOP | STA | SLA+W | OFFSET2
|...)
Eine Möglichkeit wäre, die Stop-Condition direkt in der ISR anzuweisen,
und dort zu warten, bis sie ausgeführt wurde, aber das widerspricht ja
ein wenig der Idee einer Interrupt-Routine. Ich möchte auch nicht in der
Mainfunction ständig nachschauen, ob der TWI grade nicht mehr läuft,
aber noch Datenblöcke vorhanden sind, auch das widerspricht der Idee
eines möglichst eigenständigen Hardware-Treibers. Habt Ihr da einen Tip
für mich?

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.