Forum: Mikrocontroller und Digitale Elektronik I2C Master und Slave mit PIC16F876


von Christian M. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Forumisten,

ich habe erfolgreich einen PIC16F876 als Slave programmiert. Compiler 
ist mikroBasic for PIC von MikroE. Siehe Anhang Slave.pbas

Das funktioniert wunderbar beim Empfang und beim Senden. Getestet mit 
USB4ALL von Sprut als Master.

Nun soll in der entgültigen Anwendung ein weiterer PIC16F876 als Master 
fungieren. Auch das klappt. Meistens. Sporadisch treten periodische 
Fluktuationen auf. Die zeigen sich wie folgt: Irgendwann während der 
Uebertragung werden alle Ausgänge auf 0 gesetzt. Wie Ihr im angehängten 
Bild erkennen könnt. Zu sehen sind 2 verschiedene Aufnahmen einer I2C 
Sequenz, getriggert mit dem auf 0 setzen eines Ausgangs, die aber mit 
jeder Sequenz alle auf 1 gesetzt werden. Eine Sequenz enthält einmal ein 
Byte schreiben und einmal ein Byte lesen, das wiederholt sich alle 
100ms. Beides auf Adresse 0. Im Diagramm scheint alles OK zu sein. 
Interessant ist, dass sich das Auf-Null-setzen an verschiedenen Zeiten 
im Protokoll abspielen kann, und das Wieder-auf-Eins-gehen nicht erst 
beim nächsten Schreiben auf 1 geht, sondern ein paar ms VORHER.

Als weitere Information habe ich auch das Programm des Masters 
angehängt, was aber lang ist, unvollständig und unübersichtlich.

Wenn ich die Lese-Sequenz aus dem Master entferne, funktioniert es 
einwandfrei, darum habe ich vermutet, das der Fehler aus der 
VORHERGEHENDEN Lese-Sequenz kommt, was ich aber nicht Post-Triggern kann 
mit meinem alten LA. Darum suche ich nach Möglichkeiten, wie ich den 
Fehler eingrenzen kann. Da es mit einem anderen Master funktioniert, 
vermute ich einen Fehler beim Master. Aber die Routine funktioniert mit 
PCF8574 seit Jahren, darum habe ich sie kopiert. Andere Taktrate ändert 
nichts.

Danke und Gruss Chregu

von Christian M. (Gast)


Lesenswert?

Nachtrag:

Bit0 im Diagramm: SDA,
Bit1: SCL und Bit 2: getriggerter Ausgang

Habe unterdessen versucht, zuerst zu Lesen und dann zu Schreiben. Immer 
noch der Fehler!

Der Slave Slave resettet NICHT, er geht wirklich auf Null für ~85ms.

Gruss Chregu

von Christian M. (Gast)


Lesenswert?

Ach du K*ck*, sehe grade, die Ausgänge im Slave bleiben in der Tat 90ms 
auf 0, solange ist die Zykluszeit im Slave in der Endlosschlaufe, dann 
wird der Wert wieder auf den Richtigen gesetzt.

Jetzt muss ich nur noch herausfinden, warum er eine 0 nimmt. In der 
Interrupt-Routine wird ja der die Variable "lesen" nur ein einziges Mal 
aus dem SSPBUF Register aktualisiert. Aber warum enthält dieses Register 
manchmal den Wert 0, oder "lesen"?

Gruss Chregu

von Christian M. (Gast)


Lesenswert?

Ich habe jetzt das Problem soweit eingegrenzt. Es liegt definitiv im 
Slave!

Ich muss mich an den Gedanken gewöhnen, dass ein Interrupt jederzeit im 
Hauptprogramm auftreten kann. Das heisst, auch die zu Schreibenden Daten 
muss ich zuerst in einer Hilfsvariablen zubereiten, und dann in die 
richtige Variable kopieren. Das ist noch falsch, sollte aber die 
Funktion beim Empfangen nicht beeinträchtigen.

Das Problem beim Empfangen tritt asynchron auf. Immer wenn die Werte von 
der Variablen in die Ports kopiert werden, WAEHREND des gesamten 
Empfangszyklus auf dem I2C Bus, wird 0 in die Ports geschrieben. Da ich 
ein Zyklus von 90ms im Slave habe und Einen von 100ms tritt der Fehler 
sporadisch/periodisch auf.

Wird die Variable "lesen" während eines I2C-Zyklus verändert? Was wird 
wie beeinflusst? Das gilt es jetzt herauszufinden!

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.