SPI Kommunikation mit dem PIC18F4550

Was ist SPI?

SPI (=Serial Peripheral Interface) ist, wie der Name bereits sagt, eine Schnittstelle für die serielle Übertragung von Daten zwischen zwei (oder mehr) Komponenten (das können z.B. Mikrocontroller, der serielle Port eines PCs oder sonstige periphere Komponenten mit denen Daten ausgetauscht werden sollen). Seriell heist, das die Daten in einer Richtung immer nacheinander übertragen werden, also bit für bit, im Gegensatz zur gleichzeitigen Übertragung mehrere Bits wie bei paralleln Schnitstellen.

Das MSSP Modul (mehr dazu weiter unten) von Microchips PIC18F Modellen sendet Daten dabei immer in Paketen von 8 bit, also einem byte.

SPI ist vollduplex-fähig, d.h. es koennen Daten gleichzeitig gesendet und empfangen werden, da das Senden und das Empfangen über getrennte Leitungen erfolgt.

Die Taktung des SPI Buses wird vorgeben durch den Master (in unserem Fall der PIC), die Taktung wird ueber eine dedizierte Leitung (SCK/Takleitung) an alle anderen Teilnehmer des Buses geleitet.

SPI ist jedoch nicht gleich SPI, damit sich zwei oder mehr Komponenten unterhalten koennen, muessen ein paar Parameter eingehalten werden die alle Kompoenten gemeinsam haben. Unter anderem sind das folgende:

  • Die maximale Wortlaenge, also wie viele Bits in einem rutsch uebertragen werden koennen (beim MSSP des PIC sind wir limitiert auf 8 bit, wobei das meist unerheblich ist, da auch Pausen bei der Übetragung kein Problem sein sollten, da die Clock (Taktleitung) ebenfalls in einen idle-Status (=Wartestatus / pausiert) gesetzt wird wenn keine Daten übertragen werden, die Zeit bleibt also quasi stehen für die Teilnehmer der SPI Kommunikation.
  • die maximale Taktrate die alle Komponenten zum senden und empfangen von Daten gemeinsam haben. Das MSSP Modul des PIC18F4550 kann entweder mit 1/4, 1/16 oder 1/64 des Taktes des Quarzes (FOSC) arbeiten (der PIC18F Prozessor benoetigt zur Verarbeitung eines Befehls 4 Takte, somit entspricht TOSC = 1/4*FOSC) in oder aber mit der Haelfte des Taktes von Timer 2 Ausgangs (TMR2). Mit dem PIC18F4550 der eine maximale FOSC von 48 Mhz (entspricht 12 Mhz TOSC) vertraegt (laut Datenblatt) als Master ist somit eine maximale Taktung auf dem SPI Bus von 12 Mhz moeglich (entspricht 12 MBit/s; Achtung: Im Datenblatt des PIC1844550 steht hier ein Wert von 2.00Mbps, das ist ein Typo!)
  • die Uebrtragungsreihenfolge der Bits: MSB (=most siginifacnt bit) oder LSB (=leas significant bit), also ob das „Wort“ (dit Bitfolge an Daten) in der Reihenfolge vom hoechsten bit zum niedrigsten bit (MSB) erfolgt oder umgekehrt (LSB).
  • die polaritaet des Taktes (also ob die Clock im Ruhezustand low oder high ist), diese Einstellung wird abekuerzt mit CPOL (=clock polarity) und kann im PIC ueber das bit CKP (=Clock Polarity Select) bit im Register SSPCON1 gesetzt werden
  • der Zeitpunkt wann Daten vom Slave (sofern er welche sendet) an den Master gesendet werden, gemessen an der Flanke des Taktsignals. Diese Einstellung wird mit CPHA (=clock phase) bezeichnet. Damit der Master die Daten also zum richtigen Zeitpunkt einliest muss auch diese Einstellung bei allen Komponenten gleich sein. Im PIC werden dazu die beiden bits SMP (=sample bit) und CKE (=SPI Clock Select bit) im SSPSTAT Register gesetzt. Mehr Details dazu spaeter im Sourcecode.
  • Die beiden Einstellungen CPOL und CPHA erlauben vier verschiedene Einstellungen, oder Modi, in denen eine SPI kommunikation erfolgen kann. Das MSSP Modul des PIC unterstuetzt alle 4 Modi die ueber die enstprechenden Register SSPSTAT und SSPCON1 konfiguriert werden koennen

Der PIC18F4550 (gilt gleichermaßen fuer den PIC18F4455 (40 bzw 44 Pins), PIC18F2550 (28 Pins) und PIC18F2455 (28 Pins)) besitzt ein hardware Modul für die serielle Kommunikation namens „MASTER SYNCHRONOUS SERIAL PORT“ (kurz MSSP). Mit diesem Modul ist die serielle Kommunikation mit andern ICs/MCUs (z.B. mit anderen PIC Microcontrollern, Speicherbausteinen, Port-Multipliern, Treiber-Bausteinen und vielen anderen Komponenten) moeglich. das MSSP Modul kann dabei in zwei verschiedenen Modi betrieben werden:

  • SPI Modus, dem „Serial Peripheral Interface“, also eine serielle Schnitstelle zum ansteuern von diversen peripheren Komponenten (Slaves) an einen Master (z.B. einen Microcontroller).
  • I2C Modus, dem „Inter-Integrated Circuit“ Interface, ebenfalls eine serielle Schnittstelle bei der jedoch ein paar Unterschiede zur SPI Schnittstelle gelten. Insbesondere kommt I2C mit zwei Leitungen aus (SDA(=Daten) und SCL(=Clock)) wohingegen SPI drei Leitungen benötigt. Bei I2C werden die Daten-Pakete oder Nachrichten mit Empfägeradresse versehen so das es nicht notwendig ist wie bei SPI für jeden Teilnehmer eine Slave-Select Leitung zu legen (abhängig vom Anwendungsfall kann das auch entfallen bei SPI), die Datenübertragung per SPI ist jedoch schneller und der Overhead pro Nachricht ist geringer. Weitere Infromatinen zum Vergleich der beiden Schnittstellen werden im Artikel SPI vs I2C erklärt.un

das MSSP Modul kann im SPI Modus in zwei verschiedenen Rollen agieren: als Master oder als Slave (Eine Erklärung zwischen den beiden Begriffen hier Artikel „Master und Slave…„). Zusaetzlich koennen noch grundlegende Kommunikationsparameter konfiguriert werden die klären wann genau Daten im Verhältnis zur Taktfrequenz zu senden sind von den Teilnehmern und die das Taksignal aussieht.

Zu Begin betrachten wir den Einsatz als SPI-Master, der PIC wird also als Master Daten über das SPI Interface senden.

SPI Grundlagen

Für die Kommunikation sind Hardwareseitig in einfachsten Fall mindestens drei Leitungen (gemeinsame Masse-Verbindung vorausgesetzt, andernfalls 4 Leitungen) erforderlich zwischen den Teilnehmern der Kommunikation (ein Master und ein Slave), bei mehreren Slaves die an einen Master angeschlossen werden sollen und die dediziert angesprochen werden sollen, ist zu dem pro Slave eine weitere Leitung notwendig. Zudem müssen die Teilnehmer natürlich eine gemeinsame Masse-Verbindung (Ground/GND) aufweisen, sonst fliesst ja kein Strom auf der Datenleitung.

Dabei haben die Leitungen folgende Funktionen:

Bezeichnung alternative Bezeichnung Funktion
SCK (=serial clock) SCLK (=serial clock) Transportiert das Taktsignal (=Clock), dass der Master generiert an dem sich alle Slaves orientieren
SDI (=serial data in) MOSI bzw. MISO (je nach Komponente) Der PIN eines Master oder Slaves an dem Daten eingehen, also empfangen werden
SDO (=serial data out) MOSI bzw. MISO (je nach Komponente) Der PIN eines Master oder Slaves an dem Daten ausgehen, also gesendet werden.
SS (slave select) CS (=chip select), STE (=slave transmit enable) Wird in der Regel nur bei mehreren Slaves benoetigt, pro Slave wird eine Slave Select-Leitung benötigt, in Schaubildern dann meisst durch aufsteigende Nummern gekennzeichnet: SS1, SS2, SS3… Der PIN RA5/SS des PIC wird benoetigt wenn der PIC selbst als Slave aggiert in der SPI Kommunikation. Ist der PIC der Master kann ein bzw. mehrere beliebige Asugangs PINs des PICs als CS/SS Pin gewaehlt werden und ueber die Software gesteuert werden.
Sonstige: MOSI (=Master Out, Slave In) SIMO (=Slave Out, Master In) Im Prinzip eine uebergreifende Bezeichnung fuer die DatenLEITUNG (im Gegensatz zum PIN selbst) auf welcher der Master Daten zum Slave sendet, die unabhängig davon ist ob man den Master oder den Slave Baustein betrachtet. Bei einem Slave kann MOSI auch dem SDI PIN entsprechen, da der Slave auf diesem PIN Daten empfaengt. beim Master ist jedoch der PIN SDO dem MOSI gleichzusetzen, da er ja hier Daten sendet.
MISO (=Master In, Slave Out) SOMI (=Slave Out, Master In) Im Prinzip eine übergreifende Bezeichnung fuer die DatenLEITUNG auf der der Master Daten empfängt. Dabei ist es egal ob man einen PIN beim Master oder den Slave Baustein betrachtet. Bei einem Slave führt die MISO Leitung immer zum SDO PIN, da der Slave auf diesem PIN Daten zuruük an den Master sendet. Beim Master ist der PIN SDI an der MISO Leitung angeschlossen, da er ja hier Daten sendet.

Die verwendeten IO-PINs des PIC

Die PINs fuer SCK, SDI und SDO sind bei der Verwendung des MSSP Moduls bei den meisten PICs durch das Hardware Layout fest vorgegeben (eine Ausnhame stellen die neuen PIC18F und PIC24F chips da, deren PINs dynamisch gewissen Funktionen zugewiesen werden koennen, eine sehr praktische Sache, aber das soll uns aktuell nicht weiter beschaeftigen da wir uns auf den PIC18F4550 und seine direkten Verandten konzentrieren). Die ggf. benoetigten PINs fuer die Slave Select Leitungen sind im Prinzip frei waehlbar (Achtung: gilt nur wenn der PIC der Master ist, im Slave Modus ist der Slave Select PIN vorgegeben, er liegt an PIN 5 des Ports A an RA5/SS und ist als digitaler Eingang zu konfigurieren) unter den vorhanden, freien PINs des PICs da diese spaeter ueber die Software gesteuert werden.

Im Falle des PIC18F2455/2550 bzw. PIC18F4550/2550 hilft uns ein Blick in das Datenblatt um zu sehen welche IO-PINs des Mikrochip die entstprechende Funkion aufweisen.
2550_spi

Die enstprechenden PINs für die SPI Schnittstelle sind im rechten Schaubild farblich markiert.

Wie man sieht sind bei beiden Typen die Belegung der Funktionen auf den Ports identisch (lediglich die PIN Number variiert).

SCK (Clock) liegt auf Port B und dort dem ersten PIN des Ports, also auf RB1.

SDI (Dateneingang) liegt ebenfalls auf Port B auf Pin null, also auf RB0.

SDO (Datenausgang) liegt auf Port C auf Pin sieben, also auf RC7.
pic4550_SPI

Bei anderen PIC Modellen kann die Belegung abweichen und es sollte immer das entsprechende Datenblatt herangezogen werden welches auf der microchip-webseite heruntergeladen werden kann.

Erklärung für Einsteiger: Wie man sieht haben viele PINs mehr als nur eine Funktion. So sind die PINs die wir hier im Beispiel für die SPI Kommunikation benutzen auch für andere Zwecke einsetz bar. Welche Funktion ein PIN tatsaechlich hat wird immer in der Software bestimmt die auf dem PIC laeuft. In den Datenblättern von Microchip werden in den Schaubildern der Chips immer alle PINs nummeriert und als Bezeichner werden alle Abkürzungen für all möglichen verschiednen Funktionen dieses PINs genannt. In dem Bild auf der Linken Seite vom PIC18F2455/PIC18F2550 sieht man z.B. das der PIN mit der Nummer 22 die Bezeichnung „RB1/AN10/INT1/SCK/SCL“ hat. Dies beschreibt die folgenden möglichen Funktionen zur Nutzung dieses PINs:

RB1 = es handelt sich um den zweiten PIN (es wird immer bei 0 angefangen zu zählen) aus dem PORT B des Mikrocontroller, ein Port ist quasi eine Gruppierung von einzelnen PINs. Pro Port gibts es bis zu 8 Pins. Die Ports werden meisst A, B, C, D… genannt, wobei die Anzahl an Ports variiert je nachdem wie viele PINs der eingestze Mikrocontroller hat und je nachdem wieviele IO-PINs (=Input-Output PINs, also PINs die als Ein- oder Ausgang genutzt werden können) insgesammt zur Verüfgung stehen.

AN10 = diese PIN kann auch als AD (=Analog-Digital-Wandler) genutzt werden, also ein Eingang bei dem ein analoges Signal in einer gewissen Auflösung abgetastet werden kann, z.B. um die anliegende Spanung zu messen

INT1 = diese PIN kann gentutzt werden um einen Interrupt von einer externen Komponente auslösen zu lassen, in dieser Funktion ist der PIN also auch ein Eingang

SCK = über diesen PIN kann das Taktsignal bei der Kommunikation mit dem MSSP Modul im SPI Modus ausgegeben (wenn der Mikrocontroller der Master ist) bzw. emfpangen werden (wenn der Mikrocontroller der Slave ist).

SCL = über diesen PIN kann das Taktsignal bei der Kommunikation mit dem MSSP Modul im I2C Modus ausgegeben (wenn der Mikrocontroller der Master ist) bzw. emfpangen werden (wenn der Mikrocontroller der Slave ist).

Alle Abkürzungen und Funktionen der PINs werden auch immer im Datenblatt detailiert erläutert. Die Datenblätter zu den verschiedenen Modellen von Mikrocontrollern können in der Regel immer kostenfrei auf den Seiten der Hersteller heruntergeladen werden. Für den hier vorgestellten PIC sind die Daten aller IO Pins auf Seite 12ff im Datenblatt zu finden

Ein PIN kann zu einem gewissen Zeitpunkt immer nur eine Funktion haben, jedoch kann man im Programm zur Laufzeit die Funktion des PINs aendern, wovon wir jedoch hier einmal absehen in diesem einfachen Beispiel.

In unserem Programm wird der PIN RB0 (RBO/AN12/INT0/FLT0/SDI/SDA) immer als digitaler Ausgang zum senden von seriellen Daten verwendet, der PIN RB1 (RB1/AN10/INT1/SCK/SCL) immer als digitaler Ausgang zum ausgeben des Taktes für die SPI Kommunikation und RC7 (RC7/RX/DT/SDO) immer als digitaler Eingang zum empfangen von Daten. Besonderes augenmerkt sollte hier auf das Stichwort „digital“ gelegt werden, da die PINs RB1 und RB0 auch als analoge Eingaenge genutzt werden koennen (AN10 und AN12 im Schaubild deutet an, dass hier ein Analog/Digital Wandler aktiviert werden kann), dies muss man wissen, da diese PINs explizit auf digital umgestellt werden sollten, da anonsten insbesondere der SDI Pin nicht korrekt funktionieren wird, da das MSSP Modul natuerlich logische Werte 1 und 0 erwartet und keine analogen Werte. Wir werden also spaeter sehen das wir in unserem Programm die PINs zu begin auf digital umstellen.

Hardware Layout für die Demo

Ermittlung der notwendigen SPI Parameter

Widmen wir uns nun also dem ersten Programmteil, in welchem das MSSP Modul als SPI Master konfiguriert wird.

Zuerst muss einmal geklaert werden, mit welcher Komponente unser PIC sich unterhalten soll und damit welche SPI Konfigurationsparameter diese Komponenten erwartet. Konkret muss folgendes geklaert werden (steht meist in den Datashets der Komponenten oder kann aus einem darin enhaltenen Diagramm abgelesen werden) damit wir wissen wie das MSSP Modul konfiguriert werden muss.

Konkret muss folgendes herausgefunden werden:

  • maximale SPI Taktrate der anzusprechenden Komponente [relevant fuer das Senden und das Empfangen von Daten]
  • die Clock-Polarity, also ist die Leitung SCK auf high (1) oder low (0) wenn gerade kein Takt auf der Leitung angelegt ist (der Takt wird nur angelegt wenn auch tatsaechlich Daten transferiert werden!) [relevant sowohl fuer das Senden und das Empfangen von Daten]
  • wann sollen am Master (=PIC in diesem Fall) eingehende Daten auf SDI (dem Eingang am PIC) gesampled (also abgegriffen) werden, (=Data Input Sample Phase) Soll dies bei einer steigenden Flanke des Taktsignals erfolgen oder bei der fallenden? [nur relevant fuer das Empfangen von Daten]
  • wann sollen Daten vom Master gesendet werden auf SDO, bei einer steigenden Flanke oder ein fallende Flanke des Taktsignals (=Clock Edge)? [nur relvant fuer das Senden von Daten]

Im Prinzip koennen alle Werte einfach auch durch Trial-and-Error ertestet werden, kaputt gehen kann dabei eigentlich nichts (keine Gewaehr auf diese Aussage!), es werden meist nur Daten nicht korrekt erkannt. Man kann also einfach eine niedrige Taktrate einstellen und dann alle 4 SPI Clock Modi (CKE bit im SSPSTAT Register und CKP bit im SSPCON1 Register) und zwei Input Sample Einstellungen (SMP bit im SSPSTAT Register) durchtesten. Nach spaetestens acht Tests sollte man also ein Einstellung gefunden haben die funktioniet.

Die 4 SPI Clock Modi sind wie folgt definiert:

Modus CPOL (=CKP bit) CPHA (=CKE bit) Beschreibung
0 0 0 der Ruhestatus (idle state) der SCK Leitung ist auf Low (0), der Master erwartet die eingehenden Daten auf SDI direkt zu Begin der Kommunikation, sobald er die SS/CS Leitung aktiviert (auf Low zieht) 
1 0 1 der Ruhestatus (idle state) der SCK Leitung ist auf Low (0), der Master erwartet die eingehenden Daten auf SDI erst bei der zweiten Flanke des Taktsignals, nachdem er die SS/CS Leitung aktiviert (auf Low zieht) 
2 1 0 der Ruhestatus (idle state) der SCK Leitung ist auf High (1), der Master erwartet die eingehenden Daten auf SDI direkt zu Begin der Kommunikation, sobald er die SS/CS Leitung aktiviert (auf Low zieht) 
3 1 1 der Ruhestatus (idle state) der SCK Leitung ist auf High (1), der Master erwartet die eingehenden Daten auf SDI erst bei der zweiten Flanke des Taktsignals, nachdem er die SS/CS Leitung aktiviert (auf Low zieht) 

Die input sample Einstellungen sind wie folgt zu setzen:

Die eingehenden Daten werden am in der Mitte einer ausgehenden Datenuebertragung eines jeden bits (an den Slave) gesampled
Die eingehenden Daten werden am Ende am der einer ausgehenden Datenuebertragung eines jeden bits (an den Slave) gesampled

Hinweis:

Microchip bietet in der Regel zu allen Basis-Funktionalitaeten der PICs diverse Hilfbibliotheken an, die im genutzten Compiler bereits integriert sind oder die von der microchip Webseite heruntergeladen werden koennen. Im Falle von SPI wird eine entsprechende Bibliothek bereits im C18 Compiler (und auch den anderen Compilern) mitgeliefert. Diese Bibliotheken machen einem manchmal das Leben einfacher, da sie einem Tiparbeit abnehmen fuer Standard-Aufgaben, andererseits abstrahiert man damit auch manchmal zu viel und verliehrt ein wenig die Kontrolle uber die Laufzeit von Programmen da man nicht immer genau weiss was alles in den Hilfmethoden passiert und mit welcher Auswirkung auf die Laufzeit des Programms. Gerade in Interrupt-Methoden sollte man das aufrufen von Methoden vermeiden, wenn man nicht genau weiss was diese tun und ob diese ggf. weitere Untermethoden aufrufen, da dies die Laufzeit enrom verlaengern kann wenn man nicht genau weiss was man tut (siehe dazu auch den Artikel zum effektiven Aufbau von Interrupt Methoden). Da wir hier weder mit Interrupts arbeiten, noch besonders auf geringe Laufzeiten und Speicherverbrauch achten muessen, zeige ich die Verwendung der spi bibliothek als auch einen Weg ohne diese Bibliothek.

Rahmenparameter für diese Code Beispiele

wir gehen bei allen folgenden Beispielen von folgender Grundannahme aus:

  • wir nutzen einen PIC18F4550 mit 40 Pins
  • die Taktung erfolgt extern durch ein Quarz mit 4 Mhz
  • als Slave nutzen wir einen Seriell zu USB Adapter der mit einem PC verbunden ist auf dem ein Terminal Programm laeuft
  • wir nutzen eine Datentranserrate (Baudrate) von 19800 kbit/s

SPI Schnittstelle im MSSP Modul Konfigurieren

Weitere Informationen zu dem PIC finden sich im Datenblatt:

http://ww1.microchip.com/downloads/en/devicedoc/39632c.pdf

Und manchmal sollte man auch in die ensprechenden Annotations schauen in denen Fehler in Datahseets korrigiert werden:

http://ww1.microchip.com/downloads/en/DeviceDoc/80478a.pdf

Dei entsprechende Dokumentation des MSSP / SPI moduls findet sich im Abschnitt „19.0 MASTER SYNCHRONOUS SERIAL PORT (MSSP) MODULE“ auf den Seiten 193ff.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

This site uses Akismet to reduce spam. Learn how your comment data is processed.