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.
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
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.
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
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" ?
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.