Ich habe ein seltsames Verhalten mit der Wire-Bibliothek von Energia, also dachte ich, ich würde versuchen, i2c selbst zu machen.
Ich schreibe meine eigene (bit-bang) Implementierung von i2c und halte es ziemlich einfach. Im Moment möchte ich nur ein bestimmtes i2c-Gerät erkennen. Hier ist mein grundlegender Algorithmus.
Ich weiß, dass das obige vielleicht etwas zu stark vereinfacht ist, aber ich wollte die Dinge nur in einen Zusammenhang bringen. Ich habe Probleme mit Schritt 4 und kenne den genauen Zeitpunkt, wann ich die Kontrolle über die SDA-Leitung während einer Bestätigung freigeben und wiedererlangen muss.
Nachdem also das letzte Lese-/Schreibbit auf SDA gesetzt und SCL auf HIGH gesetzt wurde, muss ich wissen, wie die Reihenfolge der Operationen ist, um eine Bestätigung vom Slave zu erhalten.
Ich habe jede erdenkliche Kombination ausprobiert, aber es scheint nicht richtig zu funktionieren. Es scheint, dass ich Folgendes tun sollte:
setMode(SDA, INPUT); //Release the SDA line to the slave device
digitalWrite(SCL,LOW); //Pulse the SCL line
digitalWrite(SCL,HIGH);
int ack = digitalRead(SDA) == LOW; //Read from the SDA line
setMode(SDA, OUTPUT); //Seize control of the SDA line
Die obige Sequenz scheint nicht zu funktionieren. Mein Digital Analyzer erkennt meine Kommunikation nicht so, wie es sollte.
Alle Korrekturen in meinen Annahmen oder Anpassungen am obigen Code wären sehr hilfreich.
Zur weiteren Klarstellung:
Ich verwende eine Entwicklungsumgebung namens 'Energia'. Es ist eine Abzweigung von Arduino und wird verwendet, um den Prozess der Programmierung von TI MSP430x-Prozessoren zu „vereinfachen“. Wie auch immer, es scheint kein Konzept des 'OpenCollector'-Modus zu haben.
Es ist entweder Input, Output oder Input_Pullup. Ich frage mich, ob Input_Pullup nicht ihre Version des OpenCollector-Modus ist. Ich werde das versuchen. Hier gibt es eine interessante Diskussion über Input, Output, Input_Pullup:
Die meisten Ihrer Probleme werden wahrscheinlich darauf zurückzuführen sein, dass Sie diese Linien hoch setzen, anstatt sie schweben zu lassen. SDA und SCL gehen hoch, weil ein Widerstand sie auf +V zieht, nicht weil sie hoch getrieben werden. Vielen ist nicht klar, dass die Uhrenlinie auch so betrieben werden soll.
Es gibt noch etwas anderes an der Art und Weise, wie Sie Ihre Logik beschreiben, was mich denken lässt, dass Sie, während Sie sehen, dass SCL als Ereignis, das die Daten zwischenspeichert, auf niedrig übergeht, Sie zu glauben scheinen, dass Sie SCL danach auf hoch zurücksetzen. Ich ermutige Sie, sich das Uhrenereignis eher so vorzustellen:
So wie Sie es tun, können Sie auf folgende Weise in Schwierigkeiten geraten:
Überraschung! Sie haben gerade eine STOP-Bedingung erstellt, ohne es zu merken.
Immer wenn ein Bit übertragen wird, treibt der Schreiber SDA (oder auch nicht), unmittelbar nachdem SCL auf Low geht, und der Leser liest den Zustand von SDA, wenn SCL auf High geht. (Das Hochgehen von SCL kann durch den Slave mit Clock-Stretching verzögert werden; Sie müssen warten, bis SCL tatsächlich hoch geht.)
Ihr Code muss SCL lange genug pulsieren, damit der Slave genügend Zeit hat, den Wert zu setzen (mindestens 4,7 µs).
Das Umschalten von SDA in den Ausgabemodus könnte es nach unten ziehen, wenn dies der letzte vorherige Wert war. Dies ist nicht erlaubt, wenn SCL hoch ist (es sei denn, Sie möchten tatsächlich einen wiederholten Start durchführen).
DoxyLover
DoxyLover
CL.
Curtis