- Was ist das SPI-Kommunikationsprotokoll?
- Wie funktioniert das SPI-Protokoll?
- Unterschied zwischen I2C- und SPI-Kommunikation
- SPI mit PIC16F877A unter Verwendung des XC8-Compilers:
- Erläuterung der SPI-Headerdatei:
- Hauptprogramm Erläuterung:
- PIC mit SPI-Debugger simulieren:
PIC-Mikrocontroller sind eine leistungsstarke Plattform, die von microchip für eingebettete Projekte bereitgestellt wird. Seine Vielseitigkeit hat es ihm ermöglicht, Wege in viele Anwendungen zu finden und muss noch viel wachsen. Wenn Sie unseren PIC-Tutorials gefolgt sind, haben Sie bemerkt, dass wir bereits eine breite Palette von Tutorials zum PIC-Mikrocontroller behandelt haben, beginnend mit den Grundlagen. Im gleichen Ablauf lernen wir die mit PIC verfügbaren Kommunikationsprotokolle und deren Verwendung kennen. Wir haben I2C bereits mit PIC Microcontroller abgedeckt.
In dem riesigen System eingebetteter Anwendungen kann kein Mikrocontroller alle Aktivitäten selbst ausführen. Zu einem bestimmten Zeitpunkt muss es mit anderen Geräten kommunizieren, um Informationen auszutauschen. Es gibt viele verschiedene Arten von Kommunikationsprotokollen, um diese Informationen zu teilen. Die am häufigsten verwendeten sind USART, IIC, SPI und CAN. Jedes Kommunikationsprotokoll hat seine eigenen Vor- und Nachteile. Konzentrieren wir uns zunächst auf das SPI-Protokoll, da wir dies in diesem Lernprogramm lernen werden.
Was ist das SPI-Kommunikationsprotokoll?
Der Begriff SPI steht für " Serial Peripheral Interface ". Es ist ein allgemeines Kommunikationsprotokoll, das zum Senden von Daten zwischen zwei Mikrocontrollern oder zum Lesen / Schreiben von Daten von einem Sensor zu einem Mikrocontroller verwendet wird. Es wird auch zur Kommunikation mit SD-Karten, Schieberegistern, Display-Controllern und vielem mehr verwendet.
Wie funktioniert das SPI-Protokoll?
Die SPI-Kommunikation ist eine synchrone Kommunikation, dh sie funktioniert mithilfe eines Taktsignals, das von den beiden Geräten, die die Daten austauschen, gemeinsam genutzt wird. Es handelt sich auch um eine Vollduplex-Kommunikation, da Daten über einen separaten Bus gesendet und empfangen werden können. Für die SPI-Kommunikation sind 5 Drähte erforderlich. Eine einfache SPI-Kommunikationsschaltung zwischen einem Master und einem Slave ist unten gezeigt
Die fünf für die Kommunikation erforderlichen Drähte sind SCK (Serial Clock), MOSI (Master Out Slave In), MISO (Master In Slave Out) und SS (Slave Select). Die SPI-Kommunikation findet immer nur zwischen einem Master und einem Slave statt. An einen Master können mehrere Slaves angeschlossen sein. Der Master ist für die Erzeugung des Takts verantwortlich und wird von allen Slaves gemeinsam genutzt. Auch kann die gesamte Kommunikation nur vom Master initiiert werden.
Der SCK-Pin (auch bekannt als SCL-Serial Clock) teilt das vom Master erzeugte Taktsignal mit den Slaves. Der MOSI-Pin (auch bekannt als SDA - Serial Data Out) wird verwendet, um die Daten vom Master an die Salbe zu senden. Der MISO-Pin (auch bekannt als SDI - Serial Data In) wird verwendet, um die Daten von der Salbe zum Master zu bringen. Sie können auch der Pfeilmarkierung in der obigen Abbildung folgen, um die Bewegung von Daten / Signalen zu verstehen. Schließlich wird der SS-Pin (auch bekannt als CS –Chip Select) verwendet, wenn mehr als ein Slave-Modul an den Master angeschlossen ist. Hiermit kann der gewünschte Slave ausgewählt werden. Eine Beispielschaltung, bei der mehr als ein Slave mit dem Master für die SPI-Kommunikation verbunden ist, ist in der folgenden Schaltung dargestellt.
Unterschied zwischen I2C- und SPI-Kommunikation
Wir haben bereits die I2C-Kommunikation mit PIC gelernt und müssen daher wissen, wie I2C funktioniert und wo wir sie verwenden können, wie I2C zur Schnittstelle des RTC-Moduls verwendet werden kann. Aber warum brauchen wir jetzt das SPI-Protokoll, wenn wir bereits I2C haben? Der Grund dafür ist, dass sowohl I2C- als auch SPI-Kommunikation auf ihre Weise Vorteile bieten und daher anwendungsspezifisch sind.
In gewissem Maße kann davon ausgegangen werden, dass die I2C-Kommunikation einige Vorteile gegenüber der SPI-Kommunikation hat, da I2C weniger Pin verwendet und es sehr praktisch ist, wenn eine große Anzahl von Slaves an den Bus angeschlossen ist. Aber der Nachteil des I2C ist, dass es den gleichen Bus für das Senden und Empfangen von Daten hat und daher ist es vergleichsweise langsam. Die Entscheidung zwischen SPI und I2C-Protokoll für Ihr Projekt basiert also ausschließlich auf der Anwendung.
SPI mit PIC16F877A unter Verwendung des XC8-Compilers:
Lassen Sie uns nun lernen, wie wir die SPI-Kommunikation auf dem PIC16F877A- Mikrocontroller mithilfe der MPLABX IDE und des XC8-Compilers verwenden können. Bevor wir klarstellen, dass in diesem Lernprogramm nur SPI in PIC16F877a mit dem XC8-Compiler behandelt wird, ist der Vorgang für andere Mikrocontroller derselbe, es sind jedoch möglicherweise geringfügige Änderungen erforderlich. Denken Sie auch daran, dass der Compiler selbst für fortgeschrittene Mikrocontroller wie die PIC18F-Serie möglicherweise eine Bibliothek eingebaut hat, um die SPI-Funktionen zu nutzen. Für PIC16F877A gibt es jedoch nichts Vergleichbares. Erstellen wir also eine eigene. Die hier erläuterte Bibliothek wird unten als Header-Datei zum Herunterladen bereitgestellt, mit der PIC16F877A mit anderen SPI-Geräten kommunizieren kann.
In diesem Tutorial schreiben wir ein kleines Programm, das mithilfe der SPI-Kommunikation Daten vom SPI-Bus schreibt und liest. Wir werden dies dann mithilfe der Proteus-Simulation überprüfen. Der gesamte Code für SPI-Register wird in der Header-Datei PIC16f877a_SPI.h erstellt. Auf diese Weise können wir diese Header-Datei in allen anstehenden Projekten verwenden, in denen SPI-Kommunikation erforderlich ist. Und im Hauptprogramm werden wir nur die Funktionen aus der Header-Datei verwenden. Der vollständige Code zusammen mit der Header-Datei kann hier heruntergeladen werden.
Erläuterung der SPI-Headerdatei:
In der Header-Datei müssen wir die SPI-Kommunikation für PIC16F877a initialisieren. Wie immer ist das PIC16F877A-Datenblatt der beste Ausgangspunkt. Die Register, die die SPI-Kommunikation für PIC16F8777a steuern, sind das SSPSTAT- und das SSPCON- Register. Informationen dazu finden Sie auf den Seiten 74 und 75 des Datenblattes.
Bei der Initialisierung der SPI-Kommunikation müssen viele Parameteroptionen ausgewählt werden. Die am häufigsten verwendete Option ist, dass die Taktfrequenz auf Fosc / 4 eingestellt wird und in der Mitte erfolgt und die Uhr im Idealzustand auf niedrig eingestellt wird. Daher verwenden wir dieselbe Konfiguration auch für unsere Header-Datei. Sie können sie einfach ändern, indem Sie die entsprechenden Bits ändern.
SPI_Initialize_Master ()
Die SPI-Initialisierungs-Master-Funktion wird verwendet, um die SPI-Kommunikation als Master zu starten. Innerhalb dieser Funktion setzen wir die jeweiligen Pins RC5 und RC3 als Ausgangspins. Dann konfigurieren wir das SSPTAT- und das SSPCON-Register, um die SPI-Kommunikation einzuschalten
void SPI_Initialize_Master () { TRISC5 = 0; // SSPSTAT = 0b00000000; // S. 74/234 SSPCON = 0b00100000; // S. 75/234 TRISC3 = 0; // Als Ausgang für Slave - Modus }
SPI_Initialize_Slave ()
Mit dieser Funktion wird der Mikrocontroller so eingestellt, dass er für die SPI-Kommunikation im Slave-Modus arbeitet. Im Slave-Modus sollte der Pin RC5 als Ausgang und der Pin RC3 als Eingang gesetzt werden. Der SSPSTAT und der SSPCON werden sowohl für den Slave als auch für den Master auf die gleiche Weise eingestellt.
void SPI_Initialize_Slave () { TRISC5 = 0; // SDO-Pin sollte als Ausgang deklariert werden SSPSTAT = 0b00000000; // S. 74/234 SSPCON = 0b00100000; // S. 75/234 TRISC3 = 1; // Für den Master-Modus wie in out setzen }
SPI_Write (Zeichen eingehend)
Mit der SPI-Schreibfunktion werden Daten in den SPI-Bus geschrieben. Es erhält die Informationen vom Benutzer über die eingehende Variable und leitet sie dann an das Pufferregister weiter. Der SSPBUF wird im aufeinanderfolgenden Taktimpuls gelöscht und die Daten werden Stück für Stück in den Bus gesendet.
void SPI_Write (Zeichen eingehend) { SSPBUF = eingehend; // Schreibe die vom Benutzer angegebenen Daten in den Puffer }
SPI_Ready2Read ()
Mit der SPI-Ready-Read-Funktion wird geprüft, ob die Daten im SPI-Bus vollständig empfangen wurden und ob sie gelesen werden können. Das SSPSTAT-Register hat ein Bit namens BF, das gesetzt wird, sobald die Daten vollständig empfangen wurden. Wir prüfen also, ob dieses Bit gesetzt ist, wenn es nicht gesetzt ist. Dann müssen wir warten, bis es gesetzt wird, um etwas vom SPI-Bus zu lesen.
unsigned SPI_Ready2Read () { if (SSPSTAT & 0b00000001) return 1; sonst 0 zurückgeben; }}
SPI_Read ()
Mit dem SPI-Lesevorgang werden die Daten vom SPI-Bus in den Mikrocontroller eingelesen. Die im SPI-Bus vorhandenen Daten werden im SSPBUF gespeichert. Wir müssen warten, bis die vollständigen Daten im Puffer gespeichert sind, und können sie dann in eine Variable einlesen. Wir überprüfen das BF-Bit des SSPSTAT-Registers, bevor wir den Puffer lesen, um sicherzustellen, dass der Datenempfang abgeschlossen ist.
char SPI_Read () // Die empfangenen Daten lesen { while (! SSPSTATbits.BF); // Halten, bis das BF-Bit gesetzt ist, um sicherzustellen, dass die vollständigen Daten gelesen werden. Return (SSPBUF); // die gelesenen Daten zurückgeben }
Hauptprogramm Erläuterung:
Die im obigen Abschnitt erläuterten Funktionen befinden sich in der Header-Datei und können in die Haupt-C-Datei aufgerufen werden. Schreiben wir also ein kleines Programm, um zu überprüfen, ob die SPI-Kommunikation funktioniert. Wir werden nur wenige Daten in den SPI-Bus schreiben und mithilfe der Proteus-Simulation prüfen, ob dieselben Daten im SPI-Debugger empfangen werden.
Beginnen Sie das Programm wie immer mit dem Setzen der Konfigurationsbits und fügen Sie dann die gerade erläuterte Header-Datei wie unten gezeigt in das Programm ein
#einschließen
Wenn Sie das Programm über die oben heruntergeladene Zip-Datei geöffnet haben, befindet sich die Header-Datei standardmäßig im Header-Dateiverzeichnis Ihrer Projektdatei. Andernfalls müssen Sie die Header-Datei manuell in Ihr Projekt einfügen. Nach dem Hinzufügen sehen Ihre Projektdateien wie folgt aus
In der Hauptdatei müssen wir den PIC als Master für die SPI-Kommunikation initialisieren und dann in einer Endlos-while-Schleife zufällige drei Hex-Werte in den SPI-Bus schreiben, um zu überprüfen, ob wir diese während der Simulation erhalten.
void main () { SPI_Initialize_Master (); während (1) { SPI_Write (0X0A); __delay_ms (100); SPI_Write (0X0F); __delay_ms (100); SPI_Write (0X15); __delay_ms (100); } }
Beachten Sie, dass die im Programm verwendeten Zufallswerte 0A, 0F und 15 sind und Hex-Werte sind, sodass wir sie während der Simulation sehen sollten. Das heißt, der Code ist fertig. Dies ist nur ein Beispiel, aber wir können dieselbe Methode verwenden, um mit einer anderen MCU oder einem anderen Sensormodul zu kommunizieren, das mit dem SPI-Protokoll arbeitet.
PIC mit SPI-Debugger simulieren:
Nachdem unser Programm fertig ist, können wir es kompilieren und mit der Simulation fortfahren. Proteus hat eine nette praktische Funktion namens SPI-Debugger , mit der die Daten über einen SPI-Bus überwacht werden können. Also verwenden wir dasselbe und bauen eine Schaltung wie unten gezeigt.
Da die Simulation nur ein SPI-Gerät enthält , wird der SS-Pin nicht verwendet. Wenn er nicht verwendet wird, sollte er wie oben gezeigt geerdet werden. Laden Sie einfach die Hex-Datei in den Mikrocontroller PIC16F877A und klicken Sie auf die Wiedergabetaste, um unser Programm zu simulieren. Sobald die Simulation startet, wird ein Popup-Fenster angezeigt, in dem die Daten im SPI-Bus wie unten gezeigt angezeigt werden
Schauen wir uns die eingehenden Daten genauer an und prüfen Sie, ob sie mit denen übereinstimmen, die wir in unserem Programm geschrieben haben.
Die Daten werden in der Reihenfolge empfangen, in der wir sie in unser Programm geschrieben haben, und sie werden für Sie hervorgehoben. Sie können auch versuchen, ein Programm für die Kommunikation mit zwei PIC-Mikrocontrollern mithilfe des SPI- Protokolls zu simulieren. Sie müssen einen PIC als Master und den anderen als Slave programmieren. Alle dafür erforderlichen Header-Dateien sind bereits in der Header-Datei enthalten.
Dies ist nur ein kleiner Einblick in die Möglichkeiten von SPI. Es kann auch Daten auf mehrere Geräte lesen und schreiben. In unseren kommenden Tutorials werden wir mehr über SPI erfahren, indem wir verschiedene Module miteinander verbinden, die mit dem SPI-Protokoll arbeiten.
Ich hoffe, Sie haben das Projekt verstanden und daraus etwas Nützliches gelernt. Wenn Sie irgendwelche Zweifel haben, posten Sie sie im Kommentarbereich unten oder nutzen Sie die Foren für technische Hilfe.
Der vollständige Hauptcode wurde unten angegeben. Hier können Sie Header-Dateien mit dem gesamten Code herunterladen