Für ein Projekt möchte ich, dass drei PICs (zwei Slaves PIC18F4620, ein Master PIC18F46K22) über den I2C-Bus kommunizieren. Später können weitere Slaves hinzugefügt werden (wie EEPROM, SRAM, ...). Ich schreibe den Code für diese PICs in C mit dem C18-Compiler. Ich habe mich im Internet viel umgesehen, konnte aber keine Bibliotheken für das (M) SSP-Peripheriegerät finden. Ich habe das Datenblatt beider PICs auf dem (M) SSP-Peripheriegerät im I2C-Modus gelesen, konnte aber nicht herausfinden, wie der Bus angeschlossen werden soll.
Also brauche ich Master- und Slave-Bibliotheken.
Was empfehlen Sie? Hast du irgendwo eine solche Bibliothek? Ist es im Compiler eingebaut und wenn ja, wo? Gibt es irgendwo im Netz ein gutes Tutorial?
Antworten:
Microchip hat dazu Anwendungshinweise geschrieben:
Die Anwendungshinweise funktionieren mit ASM, können jedoch problemlos auf C portiert werden.
Die kostenlosen C18- und XC8-Compiler von Microchip verfügen über I2C-Funktionen. Weitere Informationen hierzu finden Sie in der Dokumentation zu Compiler-Bibliotheken , Abschnitt 2.4. Hier einige Informationen zum Schnellstart:
Einrichten
Sie haben bereits den C18- oder XC8-Compiler von Microchip. Beide verfügen über integrierte I2C-Funktionen. Um sie zu verwenden, müssen Sie Folgendes einschließen
i2c.h
:Wenn Sie sich den Quellcode ansehen möchten, finden Sie ihn hier:
installation_path
/v
x.xx
/h/i2c.h
installation_path
/v
x.xx
/src/pmc_common/i2c/
installation_path
/v
x.xx
/include/plib/i2c.h
installation_path
/v
x.xx
/sources/pic18/plib/i2c/
In der Dokumentation finden Sie, in welcher Datei sich im
/i2c/
Ordner eine Funktion befindet.Verbindung öffnen
Wenn Sie mit den MSSP-Modulen von Microchip vertraut sind, wissen Sie, dass sie zuerst initialisiert werden müssen. Mit der
OpenI2C
Funktion können Sie eine I2C-Verbindung an einem MSSP-Port öffnen . So wird es definiert:Mit
sync_mode
können Sie auswählen, ob das Gerät Master oder Slave ist und ob es ein Slave ist, ob es eine 10-Bit- oder eine 7-Bit-Adresse verwenden soll. Meistens werden 7-Bit verwendet, insbesondere in kleinen Anwendungen. Die Optionen fürsync_mode
sind:SLAVE_7
- Slave-Modus, 7-Bit-AdresseSLAVE_10
- Slave-Modus, 10-Bit-AdresseMASTER
- Master-ModusMit
slew
können Sie auswählen, ob das Gerät die Anstiegsgeschwindigkeit verwenden soll. Mehr darüber, was es hier ist: Was ist die Anstiegsrate für I2C?Zwei MSSP-Module
Geräte mit zwei MSSP-Modulen wie dem PIC18F46K22 haben etwas Besonderes . Sie haben zwei Funktionssätze, einen für Modul 1 und einen für Modul 2. Stattdessen
OpenI2C()
haben sie stattOpenI2C1()
undopenI2C2()
.Okay, Sie haben alles eingerichtet und die Verbindung geöffnet. Lassen Sie uns nun einige Beispiele machen:
Beispiele
Master schreiben Beispiel
Wenn Sie mit dem I2C-Protokoll vertraut sind, wissen Sie, dass eine typische Master-Schreibsequenz folgendermaßen aussieht:
Zuerst senden wir eine START-Bedingung. Betrachten Sie dies als Abheben des Telefons. Dann die Adresse mit einem Schreibbit - Wählen der Nummer. Zu diesem Zeitpunkt weiß der Sklave mit der gesendeten Adresse, dass er angerufen wird. Er sendet eine Bestätigung ("Hallo"). Jetzt kann das Master-Gerät Daten senden - er beginnt zu sprechen. Er sendet eine beliebige Anzahl von Bytes. Nach jedem Byte sollte der Slave die empfangenen Daten bestätigen ("Ja, ich höre dich"). Wenn das Master-Gerät aufgehört hat zu sprechen, legt er mit der STOP-Bedingung auf.
In C würde die Master-Schreibsequenz für den Master folgendermaßen aussehen:
Master liest Beispiel
Die Master-Lesesequenz unterscheidet sich geringfügig von der Schreibsequenz:
Wieder leitet der Master den Anruf ein und wählt die Nummer. Jetzt möchte er jedoch Informationen erhalten. Der Slave nimmt zuerst den Anruf entgegen und beginnt dann zu sprechen (Daten senden). Der Master bestätigt jedes Byte, bis er genügend Informationen hat. Dann sendet er ein Not-ACK und legt mit einer STOP-Bedingung auf.
In C würde dies für den Hauptteil folgendermaßen aussehen:
Slave-Code
Für den Slave ist es am besten, eine Interrupt Service Routine oder ISR zu verwenden. Sie können Ihren Mikrocontroller so einrichten, dass er einen Interrupt empfängt, wenn Ihre Adresse angerufen wird. Auf diese Weise müssen Sie den Bus nicht ständig überprüfen.
Lassen Sie uns zunächst die Grundlagen für die Interrupts einrichten. Sie müssen Interrupts aktivieren und einen ISR hinzufügen. Es ist wichtig, dass PIC18s zwei Ebenen von Interrupts haben: hoch und niedrig. Wir werden I2C als Interrupt mit hoher Priorität festlegen, da es sehr wichtig ist, auf einen I2C-Anruf zu antworten. Was wir tun werden, ist Folgendes:
GOTO
dem allgemeinen ISR eine Anweisung für den Interruptvektor mit hoher Priorität hinzu. Wir können den allgemeinen ISR nicht direkt auf den Vektor setzen, da er in vielen Fällen zu groß ist.Hier ist ein Codebeispiel:
Als nächstes muss der Interrupt mit hoher Priorität aktiviert werden, wenn der Chip initialisiert wird. Dies kann durch einige einfache Registermanipulationen erfolgen:
Jetzt arbeiten Interrupts. Wenn Sie dies implementieren, würde ich es jetzt überprüfen. Schreiben Sie eine Basis
SSPISR()
, um eine LED zu blinken, wenn ein SSP-Interrupt auftritt.Okay, du hast deine Interrupts zum Laufen gebracht. Schreiben wir nun einen echten Code für die
SSPISR()
Funktion. Aber zuerst eine Theorie. Wir unterscheiden fünf verschiedene I2C-Interrupt-Typen:Sie können überprüfen, in welchem Zustand Sie sich befinden, indem Sie die Bits im
SSPSTAT
Register überprüfen . Dieses Register ist im I2C-Modus wie folgt (nicht verwendete oder irrelevante Bits werden weggelassen):Mit diesen Daten ist leicht zu erkennen, in welchem Zustand sich das I2C-Modul befindet:
In Software ist es am besten, Status 5 als Standard zu verwenden. Dies wird angenommen, wenn die Anforderungen für die anderen Status nicht erfüllt sind. Auf diese Weise antworten Sie nicht, wenn Sie nicht wissen, was los ist, weil der Sklave nicht auf einen NACK reagiert.
Schauen wir uns den Code an:
Sie können sehen, wie Sie das
SSPSTAT
Register (zuerst UND-verknüpft,0x2d
damit wir nur die nützlichen Bits haben) mit Bitmasken überprüfen können, um festzustellen, welchen Interrupt-Typ wir haben.Es ist Ihre Aufgabe, herauszufinden, was Sie senden oder tun müssen, wenn Sie auf einen Interrupt reagieren: Dies hängt von Ihrer Anwendung ab.
Verweise
Ich möchte noch einmal die Anwendungshinweise erwähnen, die Microchip über I2C geschrieben hat:
Es gibt Dokumentation für die Compiler-Bibliotheken: Dokumentation für Compiler-Bibliotheken
Wenn Sie selbst etwas einrichten, überprüfen Sie das Datenblatt Ihres Chips im Abschnitt (M) SSP auf I2C-Kommunikation. Ich habe den PIC18F46K22 für den Master-Teil und den PIC18F4620 für den Slave-Teil verwendet.
quelle
Erstens würde ich empfehlen, auf den XC8-Compiler umzusteigen, nur weil er der neueste ist. Es gibt periphere Bibliotheken, aber ich habe sie nie viel benutzt. Weitere Informationen und die Dokumentation finden Sie auf der Microchips-Website.
Okay, ich habe hier einige sehr alte Grundroutinen für I2C-EEPROM-Kommunikation, die ich vor langer Zeit mit einem PIC16F und dem alten Microhip-Midrange-Compiler (möglicherweise der Hi-Tech-Compiler) verwendet habe, aber ich denke, sie funktionieren möglicherweise in Ordnung mit dem PIC18, da ich denke, dass das Peripheriegerät das gleiche ist. Sie werden sowieso sehr schnell herausfinden, ob alles anders ist.
Sie waren Teil einer größeren Datei, die mit einem Temperaturlogger-Projekt verwendet wurde, also habe ich schnell alle anderen nicht verwandten Funktionen herausgerissen und als die folgenden Dateien gespeichert. Es ist also möglich, dass ich ein bisschen durcheinander gebracht habe, aber hoffentlich Sie wird in der Lage sein, eine Vorstellung davon zu bekommen, was benötigt wird (es kann sogar nur funktionieren, man weiß es nie ;-))
Sie müssen sicherstellen, dass die Haupt-Header-Datei korrekt ist, und die Pins überprüfen / ändern, um sicherzustellen, dass es sich um die richtigen I2C-Peripherie-Pins handelt, sowie die Registernamen, wenn sie vom Hi-Tech-Compiler stammen, was die Dinge etwas anders gemacht hat bezüglich der Registernamenskonvention.
I2C.c-Datei:
I2C.h Header-Datei:
quelle
SSP1ADD = ((_XTAL_FREQ/100000)/4)-1;
für 1 kHz usw.XC8- und XC16-Compiler enthalten Bibliotheken für I2C.
Das Problem, auf das ich gestoßen bin, ist, dass die Dokumentation nicht sehr gut ist! Wenn Sie die Beispiele aus der Microchip-Dokumentation verwenden, haben Sie kein Glück. Selbst die Unterstützung von Microchip kann Ihnen nicht helfen. Ich war selbst dort.
Vor einiger Zeit habe ich mit einem Mikrocontroller der PIC24EP512GP-Serie gearbeitet, und die Bibliothek hat bei mir nicht funktioniert, wie von Microchip dokumentiert.
quelle