Forum: Mikrocontroller und Digitale Elektronik PIC als I2C Slave, Was tun bei Overflow?


von Christoph (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich versuche seit Tagen, eine stabile I2C Kommunikation zwischen eine 
PIC16F877 (Master) und einem PIC16F872(Slave) hinzubekommen. Fuer den 
Master hab ich die Routinen von www.sprut.de uebernommen und die 
Routinen des Slaves sind aus der Application note von Microchip 
(http://ww1.microchip.com/downloads/en/AppNotes/00734a.pdf).
Solange kein Overlow auftritt, also der Slaves alles direkt per 
Interrupt verarbeiten kann, laueft die Kommunikation ohne Probleme. 
Jetzt muss der Slave aber zeitabhängige Messungen machen, darum wuerd 
ich gern fuer einen kurzen Moment die Interrupts deaktivieren. In der 
Zeit kann dann aber ein Buffer Overflow auftreten. Meine Idee ist, dann 
den Master solange das Datenbyte erneut senden zu lassen, bis er wieder 
ein ACK vom Slaver erhält. Danach kann er dann wie gewohnt weiter 
machen.
Das Problem ist aber jetzt, dass ich durch das loeschen von SSPCON, 
SSPOV den Slave nicht dazu bewegen kann, beim naechsten Byte wieder ein 
ACK zu senden, d.h. tritt einmal ein Overflow auf, dann bekommt der 
Master nie mehr ein ACK zurueck, auch wenn der Slave eigentlich wieder 
bereit wäre. Und das obwohl ich wirklich alles schon versucht habe. Im 
Datenblatt steht: Das ACK signal wird erzeugt wenn BF=0 und SSPOV=0 ist; 
ich lese aber bei Overlflow das SSPBUF Register aus, loesche Damit das 
BF Bit, und setze SSPCON, SSPOV = 0. Warum erzeugt der PIC das ACK 
Signal danach nicht mehr???

Anbei mein I2C Slave Interrupt Handler.

von Marc Seiffert (Gast)


Lesenswert?

Hi,
es gibt eine möglichkeit, wie der slave den master am senden neuer daten 
hindern kann, ist auch im I2C protokoll festgehalten.

meines wissens nach zieht der slave den takt daueraft low, bis er wieder 
bereit ist. das muss der master nat. erkennen und nicht einfach stupide 
weiterversuchen zu senden ;) Ist nat auch unpraktisch wenn mehrere 
slaves da sind...

Gruß, Marc

von Christoph (Gast)


Lesenswert?

Hi,

ja die Möglichkeit kenn ich, aber leider fällt die für mich raus, weil 
der Slave unter Umständen nicht direkt in der Lage ist die CLK Leitung 
low zu ziehen.
Es kann z.B. sein, dass der Master einen Write Versuch startet, während 
der Slave gerade keine Zeit hat. Das SSP Modul des Slaves erzeugt dann 
automatisch das ACK, weil der Buffer beim ersten Byte noch nicht voll 
ist. Jetzt müsste der Slave CLK auf low ziehen um den Master am Senden 
weiterer Bytes zu hindern, das kann er aber nicht, weil er noch nicht 
auf das interrupt reagiert hat (er ist ja noch beschäftigt). Der Master 
sendet also das zweite Byte und es kommt zum Overflow. Erst jetzt sendet 
das SSP Modul vom Slave NOT ACK und der Master kann darauf reagieren.

von Peter D. (peda)


Lesenswert?

Sobald ein I2C-Slave eine Aktion erfordert, d.h. einen Interrupt 
auslöst, zieht er SCL auf Low, daran kannst Du nichts ändern.

Erst, wenn im Interrupthandler das Flag rückgesetzt wird, kann der 
Master weiter machen.

Es kann also nie einen Buffer-Overflow geben, der I2C-Bus synchronisiert 
sich immer auf den langsamsten Teilnehmer.


Peter

von Christoph (Gast)


Lesenswert?

Das wär schön, wenn dem so wäre. Der PIC macht das aber leider nicht 
automatisch. Das entsprechende Flag (SSPCON, CKP) muss per Software auf 
0 gesetzt werden um SCL auf Low zu ziehen.
Wenn es nie einen Buffer-Overflow geben kann, warum gibt es dann ein 
"receive overflow indicator bit" ?

von Peter D. (peda)


Lesenswert?

Ich kenne zwar nur AVR, ARM und 8051-I2C, aber kann mir nicht 
vorstellen, daß die das im PIC total vergurkt haben.

Keine CPU kann sicherstellen, daß sie innerhalb 1µs den Interrupthandler 
ausführt um den SCL per Software auf low zu ziehen.

Dazu ist ja das I2C in Hardware gegossen, damit das automatisch 
geschieht und dann der Interrupt ausgeführt werden kann, wenn Zeit ist.


Ich hab grad keinen DSL-Zugang, um mal ins PIC-Datenblatt zu schauen.


Peter

von Christoph (Gast)


Lesenswert?

Das ACK Bit, also das Low ziehen beim 9. Taktimpuls geht automatisch bzw 
in Hardware. SDL Low halten, damit der Slave zeit hat die Daten zu 
verarbeiten geht nur per software soweit ich das datenblatt verstehe.

von Peter D. (peda)


Lesenswert?

So, ich hab mal ins Datenblatt geschaut, der PIC hat tatsächlich nur ein 
sehr rudimentäres I2C.

Du mußt die Daten abholen nach dem 9.Takt und vor dem 8.Takt des 
nächsten Bytes, ansonsten Pech gehabt.

Da hilft dann nur noch, den Master-Takt runter zu setzen.

Und der Slave muß dem I2C die allerhöchste Priorität geben und darf 
nicht viel machen (Daten in SRAM-Puffer schreiben und fertig).
Die Auswertung muß dann im Main erfolgen.

Interrupts länger sperren geht natürlich nicht, oder Du mußt das I2C 
vorher komplett abschalten.


Peter

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.