heim - Erholung
AVR-Schulung. Arbeiten mit dem SPI-Modul

Dieser Artikel sollte zunächst die Implementierungsmerkmale der synchronen seriellen SPI-Schnittstelle in der ADuC70xx-Familie von Single-Chip-Mikrocontrollern von Analog Devices beschreiben. Der Autor wollte nicht nur die Funktionen der SPI-Implementierung überprüfen, sondern auch diskutieren, wann diese Funktionen nützlich sind, wie und wofür sie verwendet werden sollten. Beim Schreiben des Artikels stellte sich heraus, dass der Anteil des Textes, der den Fragen „wann, wie und wofür“ gewidmet war, 50 % überstieg. Dann wurde beschlossen, die Art der Darstellung in die im Titel angegebene Richtung zu ändern . Aufgrund des größeren Umfangs wird das Material in drei separate Artikel unterteilt. 1. Prinzipien der SPI-Schnittstelle und Organisation von Slave-Geräten. 2. SPI-Schnittstellensubsysteme in Mikrocontrollern: Organisationsmöglichkeiten und Verwendung. 3. SPI-Schnittstellensubsystem in Mikrocontrollern der ADuC70xx-Familie.

Alle Artikel der Serie:

  • Synchrone serielle Schnittstelle SPI in Mikrocontrollern „von A bis Z“ und ihre Umsetzung am Beispiel ADuC70xx von Analog Devices. Teil 1
  • Synchrone serielle Schnittstelle SPI in Mikrocontrollern „von A bis Z“ und ihre Implementierung im ADuC70xx von Analog Devices. Teil 2
  • Synchrone serielle Schnittstelle SPI in Mikrocontrollern von „A bis Z“ und ihre Implementierung im ADuC70xx von Analog Devices. Teil 3

Beim Schreiben des Artikels stellte sich heraus, dass der Textanteil, der den Fragen „Wann, Wie und Warum“ gewidmet war, 50 % überstieg. Dann wurde beschlossen, die Art der Präsentation in die im Titel angegebene Richtung zu ändern.

Aufgrund des größeren Umfangs wird das Material in drei separate Artikel unterteilt:

  1. Prinzipien der SPI-Schnittstelle und Organisation von Slave-Geräten.
  2. SPI-Subsysteme in Mikrocontrollern: Organisationsmöglichkeiten und Verwendung.
  3. SPI-Subsystem in der ADuC70xx-Mikrocontroller-Familie.

Geschichte von SPI

Erfinder der SPI-Schnittstelle Motorola. Die Erfindung wurde jedoch nicht von Grund auf neu gemacht. Der Vorgänger war die MicroWire-Schnittstelle von National Semiconductor. Der Autor des Artikels lernte die SPI-Schnittstelle kennen, als er Ende der 1980er Jahre mit der beliebten M68HC11-Familie arbeitete, praktisch der ersten, in der SPI auftauchte. Der Hauptzweck dieser Schnittstelle besteht darin, verschiedene Peripheriegeräte an den MK anzuschließen. SPI erfreute sich aus folgenden Gründen sehr schnell großer Beliebtheit:

  1. Mindestanforderungen an die Hardware des an das MK angeschlossenen Geräts (Schieberegister);
  2. Ein SPI-Master in einer Minimalkonfiguration kann problemlos in Software emuliert werden, wenn der MK nicht über eine Hardware-Implementierung von SPI verfügt.

In den letzten zwei Jahrzehnten haben zahlreiche Unternehmen eine große Anzahl verschiedener Peripherieknoten hergestellt, die über SPI mit der MCU verbunden sind (siehe beispielsweise). Dies sind Sensoren für physikalische Größen (Temperatur, Druck, Beschleunigung usw.), Analog-Digital-Umwandlungsgeräte (ADC, DAC, digitale Potentiometer), Schnittstellenumwandlungsgeräte (CAN-Controller, Ethernet-Controller), nichtflüchtige Speichermodule ( Flash-MMC- und SD-Karten, EEPROM-Chips) und viele andere. (2005) gibt an, dass „ungefähr 85 % der MCUs mit einer SPI-Schnittstelle ausgestattet sind“.

Historisch gesehen gab es jedoch keinen offiziellen, allgemein akzeptierten Standard für die SPI-Schnittstelle. Daher können sich die Eigenschaften des SPI-Subsystems in Mikroschaltungen verschiedener Hersteller sowohl in der Menge der Fähigkeiten als auch in ihrer Implementierung unterscheiden, was häufig zu Schwierigkeiten bei der Verwendung führt. Entwickler überwinden diese Schwierigkeiten größtenteils durch Versuch und Irrtum oder durch Erfahrungsaustausch. MK-Hersteller wiederum beschreiben die Eigenschaften des Subsystems häufig zu kurz, wenn sie davon ausgehen, dass es sich bei SPI um einen bekannten Standard handelt. Dies ist insbesondere das Problem bei der technischen Beschreibung des Mikrocontrollers der ADuC70xx-Familie von Analog Devices.

Es ist sehr schwierig, Quellen zu finden, die alle (oder zumindest die meisten) möglichen Funktionen der SPI-Schnittstelle systematisch beschreiben. In Entwicklerforen wird normalerweise empfohlen, die technische Beschreibung des MK zu verwenden, der SPI enthält. Aber natürlich wird dort nur ein Teil der in einem bestimmten MK implementierten Optionen beschrieben.

Dem Autor sind nur wenige Veröffentlichungen bekannt, in denen versucht wurde, die Eigenschaften von SPI ohne Bezug auf einen bestimmten Mikrocontrollertyp zu beschreiben [, , ,], und alle weisen Unvollständigkeit auf. Einige Firmen haben ihre „Vision“ von SPI veröffentlicht, zum Beispiel [ , ], aber die genannten Dokumente sind größtenteils „mit den Implementierungen der von diesen Firmen hergestellten Mikrocontroller verbunden“.

Minimale Schnittstellen- und Konfigurationsarchitektur

Die minimale Architektur ist in Abb. dargestellt. 1. Die SPI-Schnittstelle enthält vier Zeilen:

  • MOSI (Master Out Slave In) Master-Datenausgang (auch als Slave-Dateneingang bezeichnet);
  • MISO (Master In Slave Out) Master-Dateneingang (auch als Slave-Datenausgang bezeichnet);
  • SCK (Serial ClocK) Taktung (Synchronisation);
  • SS (Slave Select) Slave-Auswahl.

Reis. 1. Kommunikationsstruktur und SPI-Schnittstellenleitungen

Übertragungssynchronisation

Die Häufigkeit der Bitintervalle in den SPI-Datenleitungen wird durch das SCK-Taktsignal bestimmt, das von einem der Teilnehmer, dem Master, generiert wird. Andere Teilnehmer (Slaves), von denen es einer oder mehrere geben kann, bestimmen anhand des Taktsignals, wann sich die Bits auf der Datenleitung ändern. Slave-Geräte können die Häufigkeit von Bitintervallen in keiner Weise beeinflussen (anders als beispielsweise die I 2 C-Schnittstelle).

Spitzenreiter ist in den allermeisten Fällen der im MK enthaltene SPI-Transceiver (wenn kein Hardware-SPI vorhanden ist, kann dieser in Software emuliert werden). Dem Autor ist jedoch die Implementierung eines SPI-Master-Geräts als Teil von PLD-Chips von Xilinx sowie im IC eines parallelen Schnittstellenkonverters zu einer USB-Schnittstelle bekannt. In beiden Fällen konzentriert sich der Master auf die Verbindung eines bestimmten Chiptyps: EEPROM mit einer SPI-kompatiblen Schnittstelle.

Slave-Gerät Dies ist normalerweise ein Peripheriechip. Allerdings kann SPI auch zur Kommunikation zwischen zwei (oder mehr) MCUs verwendet werden; diese Funktion wird später erläutert.

Bits werden in Paketen übertragen. Die Paketlänge beträgt am häufigsten 1 Byte (8 Bit), obwohl es SPI-Implementierungen mit einer anderen Paketlänge gibt [, ,]. Sowohl der Master als auch der Slave verfügen über einen (normalerweise nicht per Software zugänglichen) Taktimpulszähler (Bitzähler). Über einen Zähler im Slave-Gerät kann dieses das Ende der Paketübertragung ermitteln. Der Bitzähler wird auf Null zurückgesetzt, wenn das SPI-Subsystem ausgeschaltet (deaktiviert) wird. Diese Option ist im Master-Gerät immer verfügbar. Im Slave-Gerät wird der Bitzähler üblicherweise durch Deaktivieren des Schnittstellensignals SS zurückgesetzt. Die Übertragung des Pakets, also der Start des Taktgenerators im Master, erfolgt in der Regel automatisch beim Schreiben des übertragenen Bytes in das Master-Schieberegister.

Die Einstellung der Bitfrequenz F SCK erfolgt standardmäßig für serielle Schnittstellen: F SCK =F G /DIV, wobei F G konstante Frequenz des SPI-Masteroszillators, deren Wert in der technischen Beschreibung der Mikroschaltung DIVA- angegeben ist. 217. (O-Teiler, der per Software festgelegt werden kann. Bei einigen MCUs kann der Teiler DIV nur aus einer Reihe vordefinierter Werte ausgewählt werden. In der MCU-Familie M68HC11 ist dies beispielsweise einer von vier Werten: 2, 4, 16, 32. Bei einem Nennwert von F G gleich 2 MHz kann die Verschiebungsfrequenz in diesen Mikrocontrollern 1000, 500, 125 oder 62,5 kHz betragen. Bei anderen Mikrocontrollern kann der DIV-Wert innerhalb von a beliebig gewählt werden begrenzte Kapazität. In der Mikrocontroller-Familie ADuC70xx beträgt diese Kapazität ein Byte, der Divisorwert kann im Bereich von 5 bis 255 eingestellt werden, was die Auswahl einer von 251 Verschiebungsfrequenzen im Bereich von 3482 bis 81,2 kHz ermöglicht.

Da die Aktionen auf den Master- und Slave-Geräten durch dasselbe SCK-Signal getaktet werden, gibt es keine Anforderungen an die Frequenzstabilität dieses Signals (mit Ausnahme einer Obergrenze für die Halbzyklusdauer, die durch die maximale Betriebsfrequenz des langsameren Teilnehmers bestimmt wird). ). Dies ermöglicht den Einsatz von SPI in Systemen mit einer niedrigstabilen Taktfrequenz (Taktgenerator ohne Quarzstabilisierung, mit Timing-RC-Schaltung) und erleichtert zudem die Software-Emulation des Master-Geräts erheblich. Darüber hinaus ist es bei der Software-Emulation durchaus akzeptabel, die Übertragung „in der Mitte“ eines Bytes anzuhalten, wenn das Slave-Gerät dies zulässt.

Datentransfer

Bei SPI erfolgt die Übertragung bitweise: vom Master über die MOSI-Leitung und vom Slave (in umgekehrter Richtung) über die MISO-Leitung. Somit ist ein Vollduplexbetrieb möglich, bei dem Daten gleichzeitig und synchron in beide Richtungen übertragen werden. Die Bitreihenfolge in der Originalversion von Motorolas SPI kann als „höchstwertige zuerst“ definiert werden, später erlaubten einige Mikrocontroller-Hersteller jedoch die Angabe in der Software. Es sind Implementierungen möglich, bei denen eine einzige bidirektionale Leitung zur Datenübertragung genutzt wird; Eine ähnliche Konfiguration wird insbesondere in einem Dokument von Freescale, einer Halbleitertochter von Motorola, beschrieben.

Slave-Auswahl SS-Signal

Das vierte Signal der Schnittstelle SS (Slave Select, Slave-Auswahl) hat den Hauptzweck, das Slave-Gerät mit einem Signal vom Master (vom MK) ein- oder auszuschalten.

Wenn der SS-Signalpegel aktiv (niedrig) ist:

  • Die Schaltkreise des Slave-Geräts befinden sich im aktiven Zustand.
  • MISO-Ausgabe im „Ausgabe“-Modus.
  • Das SCK-Taktsignal des Masters wird vom Slave wahrgenommen, wodurch die Werte der vom Master übertragenen Bits am MOSI-Eingang gelesen und das Register des Slaves verschoben werden.

Wenn das SS-Signal passiv (hoch) ist, haben das SCK-Taktsignal und das MOSI-Signal keine Auswirkung auf das Slave-Gerät.

In den einfachsten SPI-Anwendungsfällen kann das SS-Signal möglicherweise nicht verwendet werden. In anderen, komplexeren Peripheriegeräten wird das SS-Signal nicht nur verwendet, sondern führt auch zusätzliche Funktionen aus, auf die noch näher eingegangen wird.

Signal-Timing-Diagramm

Es sind mehrere Diagrammoptionen möglich. Eine davon ist in Abb. dargestellt. 2 und andere werden weiter unten besprochen. Lassen Sie uns das Diagramm im Detail beschreiben.


Reis. 2. SPI-Diagramm, Modus 0

Vor Beginn der Paketübertragung, links vom Zeitpunkt A, befindet sich das SS-Signal am Master-Ausgang in einem High-Zustand Abb. 2e) ist der Slave inaktiv, sein MISO-Ausgang ist ausgeschaltet und die Slave-MOSI- und SCK-Eingänge nehmen die vom Master erzeugten Signale nicht wahr. Das Taktsignal am Master-Ausgang ist während dieser Zeit niedrig.

Um den Slave zu aktivieren, versetzt der Master das Slave-Auswahlsignal SS (Zeitpunkt A) in den aktiven (niedrigen) Zustand. Der Slave schaltet sich ein, sein Takteingang kann ein Taktsignal erkennen und der MISO-Pin wechselt in den Ausgangsmodus. Die Uhr ist noch nicht gestartet, die Ausgänge auf den MOSI- und MISO-Datenleitungen spiegeln nun die Werte des Bits wider, das zuerst an das andere Ende übertragen wird (Zeitintervall von A bis 1).

Nach einiger Zeit beginnt das Vorfach, ein Paket von Scherimpulsen zu bilden Abb. 2a), Signal SCK. Taktflanken führen dazu, dass sich der Inhalt der Master- und Slave-Schieberegister verschiebt und nach der Verschiebung neue Bitwerte erfasst werden. Die Momente der Verschiebung und Erfassung müssen zeitlich getrennt sein, sodass diese Aktionen in der SPI-Schnittstelle an unterschiedlichen Taktflanken ausgeführt werden. Das Diagramm wird unter der Annahme dargestellt, dass die Erfassung erfolgt, wenn das Taktsignal ansteigt (an ungeraden Kanten in der Abbildung); die entsprechenden Zeiten sind auch in Abb. markiert. 2b) und die Registerverschiebung erfolgt entlang des Abfalls (gerade Kanten). Daher kann die Reihenfolge der Ereignisse während jedes Taktimpulses als „Latch, dann Shift“ beschrieben werden.

Nachdem der Paketaustausch beendet ist (rechts von der 16-Takt-Flanke), spiegelt die Ausgabe auf jeder der MOSI- und MISO-Datenleitungen den Wert des Bits wider, das zuerst übertragen wurde. Die Paketübertragung wird abgeschlossen, indem das SS-Signal am Master-Ausgang entfernt wird (Moment B), wodurch der Slave deaktiviert wird. Nach einiger Zeit kann die Übertragung des nächsten Pakets beginnen (Moment C).

Das SS-Signal kann auf unterschiedliche Weise am Master-Ausgang erzeugt werden. In einigen MKs wird es in Hardware generiert: Nachdem das übertragene Byte in das Senderdatenregister in Software geschrieben wurde, wechselt das Ausgangssignal SS automatisch auf einen niedrigen Pegel und kehrt am Ende des Pakets auf seinen ursprünglichen inaktiven Wert (hoch) zurück ). Wenn das Master-Gerät nicht über eine hardwareimplementierte SS-Signalerzeugung verfügt, wird diese in Software unter Verwendung der Ausgabe des Allzweck-Parallelports generiert. Bei der Arbeit mit einigen Peripheriegeräten ist es jedoch erforderlich, das SS-Signal in der Software zu erzeugen, auch wenn ein Hardware-Shaper vorhanden ist. Beispiele folgen später.

Damit ist unsere Betrachtung der grundlegenden Eigenschaften der SPI-Schnittstelle abgeschlossen und wir werden deren detailliertere Diskussion anhand von Anwendungsbeispielen fortsetzen.

Das einfachste Beispiel für die Verwendung von SPI

Betrachten wir ein einfaches Beispiel für die Verwendung der SPI-Schnittstelle zur Erhöhung der Anzahl diskreter Ausgangsleitungen (paralleler Ports) im MK, beispielsweise zur Steuerung einer Gruppe von LEDs oder einer LCD-Anzeige mit sieben Segmenten. Dazu können Sie als Slave ein normales Schieberegister, zum Beispiel 74HC164, nehmen. Dieses Acht-Bit-Register verfügt über einen seriellen Dateneingang, einen Takteingang (Schiebeeingang) und acht parallele Ausgänge. In diesem Register gibt es keinen separaten seriellen Datenausgang, dafür kann jedoch der MSB-Ausgang D7 genutzt werden. Der Anschlussplan ist in Abb. dargestellt. 3. Es werden nur zwei der vier SPI-Schnittstellenleitungen verwendet.


Reis. 3. Anschließen eines Schieberegisters an die MCU über SPI

Das Schaltungsdesign des 74HC164-Chips ist so ausgelegt, dass sowohl die Wahrnehmung des neuen Wertes des MOSI-Eingangssignals als auch die Verschiebung (wodurch sich die Zustände der parallelen Ausgänge D7, ..., D0 ändern) als Takt erfolgen Signal SCK steigt. Somit können Sie durch die Verwendung von zwei Pins (MOSI und SCK) zusätzlich acht digitale Ausgänge im System erhalten.

Bei fast allen Mikrocontrollern mit SPI-Schnittstelle sind die Leitungen dieser Schnittstelle mit den Pins von Allzweck-Parallelports gemultiplext. Diese Tatsache ermöglicht es Ihnen, ungenutzte Mikrocontroller-Pins MISO und SS für andere Zwecke zu verwenden. Aufgrund dieser Tatsache muss der Programmierer jedoch daran denken, die entsprechenden parallelen Port-Pins für ihre Verwendung in SPI neu zu konfigurieren.

Serielle Verbindung von Slaves

Wenn Sie die Anzahl der Ausgänge erhöhen müssen, können Sie eine Verbindung herstellen N 74HC164 registriert sich in Reihe in einer Kette, die 8× bildet N-Bit-Schieberegister und liefert 8× N Ausgänge. In Abb. Abbildung 4 zeigt, wie es aussieht N = 2.


Reis. 4. Serielle Anbindung einfacher Schieberegister als Slaves an die MK

Um dieses zusammengesetzte Schieberegister zu laden, müssen die neuen Inhalte seriell über SPI übertragen werden N Bytes Der Nachteil dieser Lösung besteht darin, dass während der Übertragung einer Bitfolge durch ein Multibit-Schieberegister die Zustände seiner Ausgänge wechseln, dies ist jedoch für die Steuerung eines Satzes LEDs oder eines Multibit-Siebensegments durchaus akzeptabel Indikator.

Ebenso können Sie über die SPI-Schnittstelle einen oder mehrere Schieberegister-ICs vom Typ 74HC299 mit bidirektionalen parallelen Pins an den MK anschließen, die eine zusätzliche Anzahl bidirektionaler I/O-Leitungen bereitstellen.

Peripheriechips mit SPI-Schnittstelle können komplexer sein als die oben diskutierten Schieberegister und erfordern eine bestimmte Sequenz von SCK- und MOSI-Signalen an ihren Eingängen. Es gehört:

  • auf die Polarität der Taktimpulse (oder auf andere Weise auf den Signalpegel, der am SCK-Eingang von der peripheren Mikroschaltung in den Intervallen zwischen Paketübertragungen benötigt wird),
  • und auch auf die Reihenfolge der Ereignisse „Capture and Shift“.

Aus diesem Grund unterscheiden die SPI-Schnittstellenspezifikationen vier Betriebsmodi; Diagramme für diese Modi sind in Abb. 5.


Reis. 5. Vier Betriebsarten der SPI-Schnittstelle

Die Buchstaben S und L über den Diagrammen stehen für Shift bzw. Latch. Das zuvor besprochene Diagramm entspricht Modus 0. Es wird angenommen, dass Modus 0 und Modus 3 am häufigsten vorkommen.

Um im Master-Gerät (in der MCU) einen der Modi auszuwählen, die sich in der Polarität der Taktimpulse und ihrer „Phase“ (Reihenfolge der Aktionen) unterscheiden, befinden sich in einem der Peripherieregister des SPI-Subsystems normalerweise zwei Steuerelemente Bits: CPOL (Polarität) und CPHA (Phase) Die angegebenen Bitbezeichnungen und Modusbezeichnungen sind weit verbreitet. Peripheriegeräte (Slaves) unterstützen meist einen einzelnen Modus, und vor Beginn des Austauschs muss der Master (MK) für diesen Modus konfiguriert werden.

Machen wir den Leser darauf aufmerksam, dass im obigen Beispiel der Arbeit mit einem regulären Schieberegister jeder dieser vier Modi gleichermaßen geeignet ist.

Mögliche Topologien von Kommunikationssystemen basierend auf der SPI-Schnittstelle

Der einfachste Fall: Ein einzelner Slave ist mit dem Master verbunden und es ist ein bidirektionaler Austausch erforderlich. In diesem Fall kann die Verbindungsstruktur ein Dreidrahtdesign verwenden (Abbildung 6).


Reis. 6. Bidirektionale Kommunikation mit einem Slave ohne Verwendung des SS-Signals

Der SS-Auswahleingang am Slave kann dauerhaft aktiv (low) betrieben werden, während der SS-Ausgang des Masters überhaupt nicht verwendet wird und als Parallelport-Ausgang verwendet werden kann.

Über die SPI-Schnittstelle können Sie mehrere Slave-Geräte an einen Master anschließen, und zwar auf verschiedene Arten. Die erste davon ermöglicht die Implementierung einer radialen Kommunikationsstruktur („Stern“) und gilt als Hauptanwendungsfall für die SPI-Schnittstelle. Die entsprechende Anschlusskonfiguration ist in Abb. dargestellt. 7 (entlehnt von).

Reis. 7. Radiale Verbindungsstruktur
mit mehreren Slaves über SPI

Wie in der Abbildung zu sehen ist, muss der Master für die Kommunikation mit mehr als einem Slave eine entsprechende Anzahl von Slave-Auswahlsignalen SS erzeugen. Dies ist genau dann der Fall, wenn SS-Signale softwaremäßig generiert werden müssen, da im Master nicht mehr als ein SS-Signal hardwaremäßig generiert wird. Wenn es notwendig ist, den Austausch nur zwischen dem Master und nur einem der Slaves sicherzustellen, muss das Programm auf dem Master alle SS-Signale in den Intervallen zwischen den Datenübertragungen und für den Austausch mit einem der Slaves in einem inaktiven (hohen) Zustand halten , Übertragen Sie das entsprechende Signal an den aktiven (niedrigen) Pegel SS (daher der Name „Slave-Auswahl“ Slave Select). Die Datenpins der MISO-Slaves sind parallel geschaltet, „stören“ sich aber nicht gegenseitig, da sie sich im deaktivierten Zustand befinden und vor Beginn des Austauschs nur einer dieser Ausgänge (am ausgewählten Slave) aktiv wird Modus. Um diesen Zustand sicherzustellen, muss der Programmierer aufmerksam sein.

Einige Anwendungen möchten jedoch möglicherweise eine „Broadcast“-Übertragung verwenden, bei der die vom Master gesendeten Daten von mehreren (vielleicht allen) Slaves gleichzeitig empfangen und verwendet werden. Dieser Modus ist ohne die Gefahr eines elektrischen Konflikts auf der MISO-Leitung möglich. Wenn keine Daten von den Slaves zum Master-Gerät übertragen werden müssen, gibt es einfach keine Rückdatenleitungen von den Slaves.

Wenn die betrachtete Struktur auch MCs als Slaves verwendet, bei denen es möglich ist, den Modus der MISO-Ausgänge programmgesteuert zu steuern, ist es möglich, die Rundfunkübertragung bei Vorhandensein eines Rückkanals (MISO-Leitung) zu organisieren. Dazu müssen Programme, die auf Slave-Mikrocontrollern laufen, die MISO-Pins ständig im deaktivierten Zustand halten, während der Broadcasting-Modus vom Master möglich ist. Wenn es erforderlich ist, Daten von einem der Slaves zu empfangen, kann der Master ihn im Broadcast-Modus darüber informieren, indem er ein Paket mit einem Befehlsidentifizierungscode sendet und erkennt, dass einer der Slaves seinen MISO-Pin in den aktiven Zustand schalten muss. Danach erfolgt ein bidirektionaler Datenaustausch zwischen Master und ausgewähltem Slave. Am Ende des bidirektionalen Austauschs muss der Master den ausgewählten Slave in seinen ursprünglichen Zustand zurückversetzen. Mit anderen Worten: Um eine solche Möglichkeit zu erhalten, muss der Entwickler ein bestimmtes Austauschprotokoll entwerfen, das auf den SPI-Diagrammen aufbaut und in dem einige Bytewerte (oder ihre Sequenzen) die Rolle von Befehlen für die Slave-MKs spielen. Auf dieses Thema wird im nächsten Artikel der Serie näher eingegangen, wenn es um die Organisation eines symmetrischen Busses mit mehreren Mastern auf SPI-Basis geht.

Die zweite Methode, mit der Sie einen Master-Teilnehmer mit mehreren Slaves verbinden können, ist eine „Ring“-Struktur (manchmal wird diese Struktur auch „Kette“ oder Kaskadierung genannt, in der englischen Terminologie wird der Name Daisy-Chain verwendet). Diese Struktur ist in Abb. dargestellt. 8 (entlehnt von).

Reis. 8. Ringkommunikationstopologie über SPI

Es nutzt ein einziges SS-Signal, um mehrere Slaves gleichzeitig zu aktivieren, und die Datenpins aller Teilnehmer sind in Reihe geschaltet und bilden einen geschlossenen Stromkreis (Ring). Wenn ein Paket vom Master gesendet wird, wird das Paket vom ersten Slave empfangen, der sein Paket wiederum an den nächsten Slave usw. sendet. Schließlich überträgt der letzte Slave in der Kette sein Paket an den Master. Damit ein Paket von einem Master einen bestimmten Slave erreicht, muss der Master mehrere weitere Pakete versenden. Eine Variante dieser Struktur (mit offenem Ring) wurde bereits diskutiert (Abb. 4).

Einige SPI-Peripherie-ICs sind speziell für den Einsatz in Daisy-Chain-Konfigurationen konzipiert. Ein Beispiel für solche Mikroschaltungen sind die Digital-Analog-Wandler AD5444 und AD5446 von Analog Devices. Ihre Struktur ist in Abb. dargestellt. 9.


Reis. 9. AD5444/AD5446 DAC-Struktur angepasst für die SPI-Kette

Die SPI-kompatible Schnittstelle dieser Geräte umfasst ein 16-Bit-Schieberegister mit seriellem SDIN-Dateneingang (MOSI), seriellem SDO-Datenausgang (MISO), SCLK-Schiebetakteingang (SCK) und SYNC-Steuereingang. Die ersten drei Pins haben eine völlig ähnliche Funktion wie die SPI-Pins (sie sind in Klammern angegeben). Durch das Vorhandensein eines SDO-Schieberegisterausgangs können Sie mehrere DAC-Chips in einer Kettenstruktur an den MK (Master) anschließen. Die Erfassung des Werts am Eingang des AD5444/6-Slave-Registers erfolgt, wenn das SCLK-Signal fällt; der Signalwechsel an diesem Eingang (Verschiebung des Master-Ausgangsregisters) muss erfolgen, wenn SCLK ansteigt. Dieser Aktionsablauf entspricht Modus 1 (Abb. 5). Die Länge des an den DAC-Chip übertragenen Pakets beträgt 16 Bit, von denen die beiden ältesten Steuerfunktionen erfüllen und die nächsten 14 Bit (im AD5446) bzw. 12 Bit (im AD5444) den in Spannung umgewandelten Abtastwert darstellen. Der Programmierer hat die Möglichkeit, den SPI-Betriebsmodus im Slave-AD544x umzuschalten, indem er den Wert der beiden höchstwertigen Bits des Pakets auf 11 setzt, wodurch der Slave-AD544x in Modus 2 wechselt und das Eingangssignal erfasst wird wenn das SCLK-Signal ansteigt.

Der SYNC (SS)-Eingang erfüllt jedoch mehrere Funktionen gleichzeitig. Erstens aktiviert es auf einem niedrigen Pegel die Funktion, Signale von der Eingangsdatenleitung SDIN (MOSI) und der Taktleitung SCLK (SCK) im DAC-Chip zu erfassen. Darüber hinaus initiiert nach Abschluss der Übertragung des Pakets an die DAC-Chips ein Übergang auf den hohen Pegel des SYNC-Signals die Übertragung des empfangenen 16-Bit-Pakets an den Eingangspuffer der DAC-Schaltung (was zum Auftreten führt). eines neuen Spannungswerts am Analogausgang des DAC synchron in allen Slaves) und entzieht außerdem den Schnittstellenschaltungen Strom, um den Stromverbrauch des DAC-Chips zu reduzieren.

Daher umfasst der normale Betriebsmodus mit einer Kette von DAC-Chips das Einstellen des aktiven Pegels des SYNC (SS)-Signals, das die Stromversorgung der Schnittstellenschaltung im DAC einschaltet, und anschließendes sequentielles Senden der erforderlichen Anzahl von 16-Bit-Nachrichten , unter Berücksichtigung der Reihenfolge der in der Kette enthaltenen Slaves (wobei die Ausgangs-DAC-Spannungen nicht geändert werden) und schließlich das aktive SYNC-Signal ausschalten, wodurch sich gleichzeitig die Ausgangsspannungen aller DACs in der Kette ändern. Das SYNC-Signal muss ohne Umschalten aktiv (low) bleiben, bis alle Übertragungen übertragen wurden.

Einige weitere Beispiele für die Verwendung von SPI

Sowohl beim Radial-Broadcast-Design als auch beim letztgenannten DAC-Daisy-Chain-Beispiel wurden zusätzliche Fähigkeiten durch das Vorhandensein und die Verwendung eines High-Level-Multibyte-Protokolls erreicht. Im Broadcast-Beispiel muss die Entwicklung eines solchen Protokolls vom Anwendungsprogrammierer durchgeführt werden, während im Fall der AD5444/AD5446-ICs dieses Protokoll in deren Datenblatt spezifiziert ist.

Die weit verbreitete JTAG-Debug-Schnittstelle ist auch ein Beispiel für eine High-Level-Protokollimplementierung auf SPI. Bei JTAG handelt es sich um die Verbindung mehrerer gesteuerter Geräte (Slaves) zu einem Ring und die Anwesenheit eines einzelnen Masters (JTAG-Host) in diesem Ring [ , , ]. Die in JTAG verwendeten Nachrichtenlängen können recht groß sein, ihre Größe beträgt jedoch ein Vielfaches von 8 Bit.

Betrachten wir ein weiteres Beispiel, bei dem die Datenübertragung nur in umgekehrter Richtung vom Slave zum Master erfolgt und das SS-Signal zusätzlich die Funktion hat, einen Vorgang im Peripheriegerät auszulösen.


Reis. elf. Funktionsdiagramm des ADC MAX1240/1241 mit SPI-Schnittstelle und getriggert durch das SS-Signal

Wenn das CS-Signal zunächst inaktiv (hoch) ist, befindet sich der DOUT-Datenausgang im ausgeschalteten Zustand (hohe Impedanz).

Wenn das CS-Signal vom Master-MC zum Slave-MAX1240/1241 abnimmt, geschieht Folgendes:

  1. Erfassung des analogen Eingangssignals auf dem eingebauten Abtast-/Speichergerät UVH;
  2. Starten des Analog-Digital-Umwandlungsprozesses mit gleichzeitigem Übergang des DOUT-Signals auf einen niedrigen Pegel.

Am Ende (nach 7,5 μs) des AD-Wandlungsprozesses wechselt der UVH vom Zustand „Speicher“ (HOLD) in den Zustand „Abtastung“ (TRACK) und das DOUT-Signal auf einen hohen Pegel: Letzteres signalisiert dem Mikrocontroller über das fertige Ergebnis.

Danach kann die Master-MCU (sofort oder nach einiger Zeit) damit beginnen, das Ergebnis der AD-Umwandlung zu lesen, indem sie eine Folge von Taktimpulsen an die SCLK-Leitung anlegt. Um es zu empfangen, muss der Master die Übertragung von zwei Bytes vom Slave veranlassen. Sie tragen 16 Bits, von denen die ersten 12 das Ergebnis darstellen und die letzten vier (Nullen) einfach verworfen werden müssen. Das Diagramm zeigt, dass der Master zum Wiederholen der Messung den aktiven Pegel des SS-Signals für eine vorgegebene Zeit (mindestens 0,24 μs) entfernen muss. Danach kann der Prozess neu gestartet werden, indem das SS-Signal auf den aktiven (niedrigen) Pegel geschaltet wird .

In diesem Beispiel führt das CS (SS)-Signal im MAX1240/1-Slave mehrere Funktionen aus:

  1. aktiviert die interne SPI-Schaltung und bringt den DOUT (MISO)-Signalausgang aus dem deaktivierten Zustand;
  2. startet den Analog-Digital-Umwandlungsprozess im ADC. Beachten Sie, dass während der AD-Wandlung das SS-Signal aktiv (niedriger Pegel) sein muss, aber keine Shift-Clocks vorhanden sein dürfen. Dies ist nur mit Software-Steuerung des SS-Signals im Master-Gerät möglich.

Getrennt davon ist das SHDN-Signal in den Mikroschaltungen MAX1240/MAX1241 zu erwähnen. Es soll den Peripheriechip in den Energiesparmodus versetzen. Für diesen Zweck könnte SS verwendet werden, aber die internen Schaltkreise der Spannungswandler (für den ADC) benötigen einige Zeit, um in den Modus zu gelangen (ca. 4 µs). Die Chipentwickler hätten eine interne Verzögerung implementieren können, entschieden sich jedoch für die Verwendung eines zusätzlichen Steuersignals. Dies wird dadurch begründet, dass SHDN nur einmal eingeschaltet werden muss und der ADC viele Male gestartet werden muss, wenn eine kontinuierliche Konvertierung erforderlich ist. Sie können den Allzweck-Port-Ausgang zur Steuerung des SHDN-Signals verwenden.

Was soll das Programm im Master (im MK) machen?

Hier ist die Abfolge von Aktionen, die der Mikrocontroller im letzten Beispiel ausführen könnte, wenn sein SPI-Subsystem eine Standard-Burst-Länge von 8 Bit hat:

  1. Stellen Sie den SHDN-Signalpegel hoch ein (Software).
  2. Mindestens 4 µs warten (Zugriff auf Spannungswandlermodus für ADC).
  3. Stellen Sie das SS-Signal auf Low (Software).
  4. Stellen Sie sicher, dass das DOUT-Signal einen Protokollwert angenommen hat. 0 (per Software oder per Interrupt).
  5. Überprüfen Sie den Zustand des DOUT-Signals (ein Zeichen für das Ende der AD-Wandlung), bis dieses Signal auf log wechselt. 1 (per Software oder per Interrupt).
  6. Initiieren Sie eine Byteübertragung von einem Peripheriechip. Die Taktwiederholungsrate sollte 2,1 MHz nicht überschreiten.
  7. Warten Sie, bis das erste Byte empfangen wurde (per Programm oder per Interrupt).
  8. Lesen und speichern Sie das erste empfangene Byte.
  9. Übertragung des zweiten Bytes einleiten.
  10. Warten Sie, bis das zweite Byte empfangen wurde (per Programm oder per Interrupt).
  11. Lesen und speichern Sie das zweite Byte.
  12. Setzen Sie das SS-Signal auf High, damit in Zukunft ohne Verzögerung mit der nächsten Messung begonnen werden kann.
  13. Wenn es erforderlich ist, sofort eine weitere Messung durchzuführen, stellen Sie den SS-Signalpegel auf niedrig ein (die Zeit, in der sich das SS-Signal zwischen zwei Messzyklen auf einem hohen Pegel befindet, muss mindestens 0,24 μs betragen).
  14. Nehmen Sie von den beiden empfangenen Bytes die ersten 12 Bits und schreiben Sie sie in eine für das Ergebnis vorgesehene Variable.

Wie Sie sehen, ist die Sequenz ziemlich lang und die Belastung des MC erweist sich als erheblich, wenn Sie Messungen mit einer Frequenz nahe dem Maximum durchführen möchten.

Und zum Schluss noch ein komplexeres Beispiel eines Slave-Geräts. Atmel produziert Flash-Speicherchips mit SPI-Schnittstelle. Schauen wir uns die Merkmale der Verbindung der Mikroschaltung AT45DB161B mit einer 2M×8-Bit-Organisation an. In Abb. 12 zeigt ein Blockdiagramm des Geräts mit Angabe aller externen Ausgänge.


Reis. 12. Struktur und Pinbelegung des AT45DB161B Flash-Speicher-ICs mit SPI-Schnittstelle

Die Signale SI (MOSI), SO (MISO), SCK (SCK), CS (SS) bilden eine SPI-kompatible Schnittstelle. Der Austausch mit dem internen Flash-Array erfolgt über zwei Puffer von (512+16) Bytes. Der interne Zustand „Der Chip ist damit beschäftigt, eine Operation auszuführen“ oder „Die Operation ist abgeschlossen, der Chip ist frei“ wird durch den Zustand des RDY/BUSY-Signals widergespiegelt. Bei Langzeitoperationen kann der Zustand dieses Signals per Software oder mithilfe eines Hardware-Interrupt-Mechanismus analysiert werden.

Ein Merkmal des Flash-Speicherchips ist, dass beim Austausch Multibyte-Pakete variabler Länge verwendet werden. Das erste Byte jedes Pakets ist ein Befehl, und die nachfolgenden Bytes enthalten zu schreibende Parameter oder Daten. Der Übergang des CS-Signals auf den aktiven (niedrigen) Pegel markiert den Anfang des Pakets, und die Rückkehr des CS-Signals auf den hohen Pegel markiert das Ende des Pakets. Einige der zum Lesen von Daten aus dem Flash-Speicher vorgesehenen Pakete haben eine variable Länge. Die Struktur des Lese-/Schreibbefehls-Headers ist in Abb. dargestellt. 13.


Reis. 13. Struktur eines Paket-Headers mit Befehls- und Adressinformationen

Wie in Abb. zu sehen ist. In 13 enthält das erste Byte den Befehl (Operationscode) und die nächsten drei Bytes enthalten zwei Parameter: die Adresse der Seite im Flash-Array und die Adresse des Bytes auf der Seite, von dem geschrieben oder gelesen werden muss. Die Parameter sind nicht an Bytegrenzen ausgerichtet, daher muss der Header vorab vom Programmierer generiert werden, bevor das Paket übertragen wird.

Anweisungen

SPI- Serielle Peripherieschnittstelle oder „Serielle Peripherieschnittstelle“ ist ein synchrones Übertragungsprotokoll zur Verbindung eines Master-Geräts mit Peripheriegeräten (Slave). Das Master-Gerät ist häufig . Die Kommunikation zwischen Geräten erfolgt über vier Drähte, weshalb SPI manchmal als „Vierdrahtschnittstelle“ bezeichnet wird. Das sind die Reifen:
MOSI (Master Out Slave In)- Datenübertragungsleitung von Master- zu Slave-Geräten;
MISO (Master In Slave Out)- Übertragungsleitung vom Slave- zum Master-Gerät;
SCLK (Serielle Uhr)- vom Master-Gerät erzeugte Synchronisationstaktimpulse;
SS (Slave-Auswahl)- Auswahlzeile für Slave-Geräte; wenn die Leitung „0“ ist, „versteht“ das Slave-Gerät, dass es nun angesprochen wird.
Es gibt vier Datenübertragungsmodi (SPI_MODE0, SPI_MODE1, SPI_MODE2, SPI_MODE3), die durch die Kombination der Polarität der Taktimpulse bestimmt werden (wir arbeiten auf HIGH- oder LOW-Pegel). Taktpolarität, CPOL, und die Phase der Taktimpulse (Synchronisation auf der steigenden oder fallenden Flanke des Taktimpulses), Taktphase, CPHA.
Die Abbildung zeigt zwei Möglichkeiten zum Anschluss von Geräten über das SPI-Protokoll: unabhängig und kaskadiert. Bei unabhängiger Verbindung mit dem SPI-Bus greift das Master-Gerät individuell auf jedes Slave-Gerät zu. Bei der Kaskade werden die Geräte nacheinander in einer Kaskade ausgelöst.

In Arduino befinden sich SPI-Schnittstellenbusse an bestimmten Ports. Jede Platine hat ihre eigene Pinbelegung. Der Einfachheit halber sind die Pins dupliziert und auch auf einem separaten ICSP-Anschluss platziert (In Circuit Serial Programming, ein Gerät, das mithilfe eines seriellen Protokolls in einen Schaltkreis eingebunden wird). Bitte beachten Sie, dass der ICSP-Anschluss keinen Slave-Auswahlpin hat – SS, weil Es wird davon ausgegangen, dass der Arduino als Master-Gerät im Netzwerk verwendet wird. Bei Bedarf können Sie jedoch einen beliebigen Arduino-Pin als SS zuweisen.
Die Abbildung zeigt die Standardentsprechung von Pins zu SPI-Bussen für Arduino UNO und Nano.

Für Arduino wurde eine spezielle Bibliothek geschrieben, die das SPI-Protokoll implementiert. Es verbindet sich so: Am Anfang des Programms fügen wir hinzu #include SPI.h
Um mit der Verwendung des SPI-Protokolls zu beginnen, müssen Sie die Einstellungen festlegen und dann das Protokoll mit der Prozedur SPI.beginTransaction() initialisieren. Sie können dies mit einer Anweisung tun: SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0)).
Das bedeutet, dass wir das SPI-Protokoll mit einer Frequenz von 14 MHz initialisieren, die Datenübertragung erfolgt beginnend mit MSB (höchstwertiges Bit) im Modus „0“.
Wählen Sie nach der Initialisierung das Slave-Gerät aus, indem Sie den entsprechenden SS-Pin in den LOW-Zustand versetzen.
Anschließend übertragen wir die Daten mit dem Befehl SPI.transfer() an das Slave-Gerät.
Bringen Sie SS nach der Übertragung wieder in den HIGH-Zustand zurück.
Die Arbeit mit dem Protokoll wird mit dem Befehl SPI.endTransaction() abgeschlossen. Es empfiehlt sich, die Übertragungszeit zwischen den Anweisungen SPI.beginTransaction() und SPI.endTransaction() zu minimieren, um Probleme zu vermeiden, wenn ein anderes Gerät versucht, eine Datenübertragung mit anderen Einstellungen zu initiieren.

Betrachten wir die praktische Anwendung der SPI-Schnittstelle. Wir werden die LEDs zum Leuchten bringen, indem wir das 8-Bit-Schieberegister über den SPI-Bus steuern. Verbinden wir das Schieberegister 74HC595 mit dem Arduino. Wir werden an jeden der 8 Ausgänge eine LED anschließen (über einen Begrenzungswiderstand). Das Diagramm ist in der Abbildung dargestellt.

Schreiben wir eine Skizze wie diese.
Verbinden wir zunächst die SPI-Bibliothek und initialisieren wir die SPI-Schnittstelle. Definieren wir Pin 8 als Pin für die Auswahl des Slave-Geräts. Löschen wir das Schieberegister, indem wir ihm den Wert „0“ senden. Initialisieren Sie die serielle Schnittstelle.
Um eine bestimmte LED mithilfe eines Schieberegisters zum Leuchten zu bringen, müssen Sie eine 8-Bit-Zahl an deren Eingang anlegen. Damit beispielsweise die erste LED aufleuchtet, geben wir die Binärzahl 00000001 an, für die zweite - 00000010, für die dritte - 00000100 usw. Diese Binärzahlen bilden bei der Umrechnung in das dezimale Zahlensystem die folgende Folge: 1, 2, 4, 8, 16, 32, 64, 128 und sind Zweierpotenzen von 0 bis 7.
Dementsprechend berechnen wir im loop()-Zyklus basierend auf der Anzahl der LEDs von 0 auf 7 neu. Funktion pow(Basis, Grad) Erhöht den Schleifenzähler um 2. Mikrocontroller arbeiten mit Zahlen vom Typ „double“ nicht sehr genau, daher verwenden wir die Funktion „round()“, um das Ergebnis in eine ganze Zahl umzuwandeln. Und wir übertragen die resultierende Zahl in das Schieberegister. Der Übersichtlichkeit halber zeigt der Monitor der seriellen Schnittstelle die bei diesem Vorgang erhaltenen Werte an: Man läuft die Ziffern durch – die LEDs leuchten in einer Welle.

Eine weitere Schnittstelle, über die sich ein Gerät problemlos mit einem elektronischen Projekt verbinden lässt, ist die SPI-Schnittstelle.

SPI(Serial Peripheral Interface – serielle Peripherieschnittstelle) ist wie UART eine ziemlich alte, einfache und beliebte Schnittstelle. An dieser Schnittstelle arbeiten viele Geräte (Mikrocontroller, EEPROM, ADC, DAC...). Wir werden es auch für unsere Geräte nutzen.
Die SPI-Schnittstelle nutzt drei Leitungen zur Datenübertragung: MOSI- Übertragung; MISO– Empfang; SCK– stempeln. Es wird eine zusätzliche Zeile verwendet SS(Slave Select?) – Wählen Sie ein Gerät aus (falls mehrere vorhanden sind). SPI ist eine synchrone Vollduplex-Schnittstelle – Senden und Empfangen erfolgen parallel. Das Master-Gerät initiiert und taktet den Austausch – Meister(kann nur einer sein). Sklave - Sklave- Ein Gerät (es können mehrere sein) empfängt/sendet ein Byte unter dem Einfluss eines Taktsignals.

In AVR-Mikrocontrollern wird die SPI-Schnittstelle doppelt genutzt, als Kommunikationsschnittstelle und als Schnittstelle für serielle In-Circuit-Programmierung. Die überwiegende Mehrheit der Controller verfügt über eine SPI-Schnittstelle (es gibt Ausnahmen bei Tiny-Modellen), aber selbst wenn diese nicht vorhanden ist, wird es nicht schwierig sein, sie in Software zu implementieren.

Wie funktioniert also die SPI-Schnittstelle?
Und sein Design ist unglaublich einfach (es ist schwer, es überhaupt als Schnittstelle zu bezeichnen) – zwei Schieberegister (Master und Slave) plus ein Generator auf der Master-Seite – das ist alles! Die Schieberegister sind ringförmig entlang der MOSI- und MISO-Leitungen geschlossen, das Taktsignal vom Generator wird beiden Schieberegistern (über die SCK-Leitung dem Slave) zugeführt.

Bevor der Austausch beginnt, werden die Daten in Schieberegister gelegt, der Master startet den Generator, der Generator „schaltet“ 8 Taktzyklen aus, während dieser 8 Taktzyklen „ändern“ die Schieberegister ihren Inhalt (der Master empfängt das Byte des Slaves, und der Sklave erhält die des Meisters) - das war's!
Bei mehreren Slave-Geräten erfolgt der Austausch nur mit einem, dessen Signal an SS Low ist.

SPI ist die schnellste serielle Schnittstelle. Mit einer Mikrocontroller-Master-Oszillatorfrequenz von 20 MHz kann er mit einer Geschwindigkeit von 10.000.000 Baud austauschen
(1,2 Megabyte pro Sekunde)!

Der Nachteil der Schnittstelle besteht darin, dass der Initiator des Austauschs immer der Master ist. Das heißt, wenn an der Peripherie etwas passiert ist, erfährt der Master erst dann davon, wenn er selbst „beschließt“, eine Kommunikationssitzung durchzuführen (Effizienz geht verloren). AVR-Hersteller haben einen Weg gefunden, diesen Nachteil zu umgehen. Wenn der SPI des Mikrocontrollers als Master konfiguriert ist, kann der SS-Pin sowohl als Eingang als auch als Ausgang konfiguriert werden. Wenn der Pin als Ausgang konfiguriert ist, wird er zur Auswahl des Slave-Geräts verwendet. Wenn der SS-Pin jedoch als Eingang konfiguriert ist, schaltet der Mikrocontroller den SPI automatisch in den Slave-Modus und kann Daten von einem anderen Master empfangen, wenn an diesem Pin ein niedriger Pegel auftritt. Nach der Austauschsitzung bleibt SPI im Slave-Modus. Um es in den Master-Modus zu übertragen, müssen Sie SPI neu konfigurieren.

Ich denke, dass dieser Master-Slave-Umschaltalgorithmus für Blog-Geräte selten benötigt wird, daher werden wir SPI nur als Master oder nur als Slave verwenden.
Wenn das Blog-Gerät ein Ausgabegerät ist (z. B. eine Tastatur), ist der SPI der Master und in Ihrem Projekt der SPI der Slave.
Wenn es sich bei dem Blog-Gerät um ein Eingabegerät handelt (z. B. eine digitale Anzeige), ist der SPI der Slave und in Ihrem Projekt der SPI der Master.

Um das Gerät über die SPI-Schnittstelle mit Ihrem Projekt zu verbinden, benötigen Sie:
1 Verbinden Sie das Blog-Gerät mit den entsprechenden Pins des Mikrocontrollers.
2 Konfigurieren Sie den SPI Ihres Controllers (als Master oder Slave). Schreiben Sie dazu bestimmte Werte auf die entsprechenden I/O-Ports.
3 Haben (Schreib-)Prozeduren zum Empfangen/Übertragen von Nachrichten über SPI in Ihrem Programm.
Schauen wir uns nun jeden Punkt im Detail an:


1 ANSCHLUSS VON GERÄTEN ÜBER SPI.
Wir verbinden einfach die gleichnamigen Pins MOSI-MOSI, MISO-MISO, SCK-SCK, SS-SS. Wenn die Verbindung nur zwischen zwei Geräten besteht, ist SS-SS grundsätzlich nicht erforderlich, Sie müssen jedoch sicherstellen, dass der SS-Pin des Slave-Geräts niedrig ist (auf Masse gezogen), andernfalls nimmt das Gerät nicht teil der Austausch.


2 SPI-EINSTELLUNG.

SPI verfügt über vier Betriebsarten (0, 1, 2, 3). Die Betriebsart hängt davon ab, an welcher Flanke des Taktsignals der Austausch durchgeführt wird. Darüber hinaus können Sie konfigurieren, welches Bit (höchstwertiges oder niedrigstwertiges) zuerst übertragen wird. Für den Austausch spielt dies keine Rolle – das Ergebnis wird das gleiche sein (Betriebsmodi sind erforderlich, um SPI an Geräte verschiedener Hersteller anzupassen). Master und Slave müssen im gleichen Modus arbeiten.
Für Blog-Geräte verwenden wir die folgenden SPI-Einstellungen:
Modus - 0
Es wird das höchstwertige Bit übertragen Erste
Taktfrequenz - je nach den Umständen(Für SPI ist die Frequenz nicht so wichtig, da der Takt aus einer einzigen Quelle stammt).
Nehmen wir zum Beispiel den ATmega8-Mikrocontroller mit einem internen 8-MHz-Masteroszillator. Wir werden die Steuereingangs-/-ausgangsports des Controllers in verschiedenen Programmierumgebungen konfigurieren.

Algorithmus-Builder.
Erstellen Sie ein Projekt ( Datei/Neu). Wählen Sie den Mikrocontroller und die Frequenz des Master-Oszillators aus Optionen/Projektoptionen…(ATmega8, interner Master-Oszillator bei 8 MHz). Klicken Sie in der Symbolleiste auf die Schaltfläche „S“ – Control Register Customizer“ und wählen Sie SPI aus.
Einstellungen für Meister(zur Kommunikation mit einem Ausgabegerät):

Einstellungen für Sklave(zur Kommunikation mit Eingabegerät):


OK klicken". Bereit – SPI ist initialisiert und einsatzbereit.

Monteur. Sie können tiefer in das Datenblatt für den Controller eintauchen, Sie können ein Stück Asma aus einem kompilierten Projekt in C übernehmen, Sie können die mnemonischen Befehle des Algorithm Builder übersetzen – wählen Sie, was Ihnen gefällt.
Einstellungen für Master (zur Kommunikation mit Ausgabegerät):

init-SPI-slave: sbi 0x17,0x04 ldi r16,0x00 out 0x0E,r16 ldi r16,0xC0 out 0x0D,r16

CodeVisionAVR. Um SPI-Einstellungen zu generieren, klicken Sie auf das Zahnradsymbol ( CodeWisardAVR) in der Symbolleiste. Wählen Sie im sich öffnenden Fenster zunächst die Registerkarte „Chip“ aus, wählen Sie darin den Mikrocontroller aus und stellen Sie die Frequenz ein, mit der der Master-Oszillator arbeiten soll. Als nächstes wählen Sie die Registerkarte SPI aus und füllen sie entsprechend den erforderlichen Merkmalen aus.

Einstellungen für Master (zur Kommunikation mit Ausgabegerät):

// Initialisierung von Port B // Func7=In Func6=In Func5=Out Func4=In Func3=Out Func2=Out Func1=In Func0=In // State7=T State6=T State5=0 State4=T State3=0 State2=0 State1=T State0=T PORTB= 0x00 ; DDRB= 0x2C ; // SPI-Initialisierung // SPI-Typ: Master // SPI-Taktpolarität: Niedrig // SPI-Datenreihenfolge: MSB First SPCR= 0xD0 ; SPSR= 0x00 ;

// Initialisierung von Port B // Func7=In Func6=In Func5=Out Func4=In Func3=Out Func2=Out Func1=In Func0=In // State7=T State6=T State5=0 State4=T State3=0 State2= 0 State1=T State0=T PORTB=0x00; DDRB=0x2C; // SPI-Initialisierung // SPI-Typ: Master // SPI-Taktrate: 2000.000 kHz // SPI-Taktphase: Zyklushälfte // SPI-Taktpolarität: Niedrig // SPI-Datenreihenfolge: MSB First SPCR=0xD0; SPSR=0x00;

Einstellungen für Slave (zur Kommunikation mit Eingabegerät):

// Initialisierung von Port B // Func7=In Func6=In Func5=In Func4=Out Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=0 State3=T State2=T State1=T State0=T PORTB= 0x00 ; DDRB= 0x10 ; // SPI-Initialisierung // SPI-Typ: Slave // SPI-Taktrate: 2000.000 kHz // SPI-Taktphase: Zyklushälfte// SPI-Taktpolarität: Niedrig // SPI-Datenreihenfolge: MSB First SPCR= 0xC0 ; SPSR= 0x00 ;

// Initialisierung von Port B // Func7=In Func6=In Func5=In Func4=Out Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=0 State3=T State2= T State1=T State0=T PORTB=0x00; DDRB=0x10; // SPI-Initialisierung // SPI-Typ: Slave // ​​​​SPI-Taktrate: 2000.000 kHz // SPI-Taktphase: Zyklushälfte // SPI-Taktpolarität: Niedrig // SPI-Datenreihenfolge: MSB First SPCR=0xC0; SPSR=0x00;

Speichern Sie das generierte Projekt ( Datei\Generieren, Speichern und Beenden). Es wurde ein Projekt mit allen notwendigen Einstellungen für SPI erstellt. Auch andere (oft unnötige) Peripheriegeräte werden im Projekt initialisiert. Nachdem Sie ein Projekt erstellt haben, können Sie es korrigieren – entfernen Sie alles, was nicht erforderlich ist.


3 ERSTELLUNG VON SPI-VERARBEITUNGSVERFAHREN.

Die Arbeit mit SPI im Mikrocontroller ist sehr einfach organisiert. Um den Datenaustausch im Master-Controller zu starten, schreiben Sie einfach das übertragene Byte in das SPDR-Register – der Austausch beginnt automatisch. Nach Abschluss des Austauschs wird die Interrupt-Handling-Prozedur aufgerufen, bei der wir das empfangene Byte aus dem SPDR lesen. Mit einem Slave-Controller ist es noch einfacher: Nach Abschluss des Austauschs wird die Interrupt-Handling-Prozedur aufgerufen, bei der wir das empfangene Byte aus dem SPDR lesen.

Algorithmus-Builder.
Übertragen. Sowohl beim Master als auch beim Slave muss das übertragene Byte in das SPDR-Register geschrieben werden. Für den Master leitet das Schreiben eines Bytes in SPDR den Austausch ein.
Rezeption. Sowohl beim Master als auch beim Slave wird nach dem Empfang des Bytes ein Interrupt aufgerufen, in dem das Senden verarbeitet wird.

Wenn während einer Byteübertragung versucht wird, in das SPDR-Register zu schreiben, kommt es zu einem Schreibkonflikt. Daher muss das Programm sicherstellen, dass das nächste Byte übertragen wird, nachdem das vorherige empfangen wurde. Die beste Lösung für dieses Problem wäre der folgende Algorithmus: Das erste Byte, der Anfang des Bytepakets, wird vom Hauptteil des Programms übertragen, und der Rest wird vom Interrupt am Ende der Übertragung über SPI übertragen. Auf diese Weise wird das Hauptprogramm von der Arbeit der Übertragung eines Bytestrings „befreit“ und gleichzeitig kann es nicht zu einem Schreibkonflikt kommen, da der Interrupt aufgerufen wird, wenn der Austausch abgeschlossen ist.

Da wir planen, einzelne Bytes über SPI zu übertragen, werden wir den oben genannten Algorithmus nicht verwenden.

Monteur.
Der Code ist äußerst einfach. Zur Übertragung schreiben wir in SPDR, das empfangene Byte wird von SPDR im Interrupt-Body gelesen.

CodeVisionAVR. Zusätzlich zur Initialisierung erstellt CodeWisardAVR auch eine Interrupt-Behandlungsprozedur. Es ist nichts Zusätzliches erforderlich.

// Empfangen/Übertragen von Daten über SPI im Interrupt-Körper Interrupt void spi_isr(void) ( unsigned char data; data=SPDR; ) // Vorbereiten/Übertragen von Daten über SPI im Hauptteil des Programms unsigned char data; SPDR=Daten;

Das scheint alles zu sein, was ich über SPI sagen wollte.
Die Benutzeroberfläche ist recht einfach und sollte bei der Verwendung keine Probleme bereiten.

(5.231 Mal besucht, 1 Besuch heute)

Guten Tag! Der heutige Artikel ist ein kleiner theoretischer Exkurs, der uns dabei helfen wird, den Arduino-Programmierkurs zu meistern. Wir werden über die SPI-Schnittstelle sprechen. Was es ist und wozu man es isst, versuchen wir in diesem Artikel herauszufinden.

Zunächst die Definition. SPI(Serielle Peripherieschnittstelle – serielle Peripherieschnittstelle) ist ein serieller synchroner Datenübertragungsstandard, der für die Kommunikation des Controllers mit verschiedenen Peripheriegeräten konzipiert ist. Diese Schnittstelle ist einfach und bequem. Für Arduino wurde eine spezielle Bibliothek für die Arbeit mit SPI geschrieben.

Die Kommunikation erfolgt nach dem „Master-Slave“-Prinzip. Der Controller ist normalerweise das Master-Gerät. Alle anderen Geräte, die an das System angeschlossen sind, sind Slaves. Daten vom Master-Gerät werden über den Datenbus an einen der ausgewählten Slaves oder umgekehrt vom Slave-Gerät zum Master synchron unter Verwendung des Master-Taktsignals übertragen.

Pinbelegung des SPI-Datenbusses besteht aus 4 Zeilen: MOSI, MISO, CS und SCLK:

  • MOSI(Master Out Slave In – Master-Ausgang, Slave-Eingang) oder einfach S.I.– Die Datenübertragung erfolgt vom Master-Gerät zum Slave-Gerät.
  • MISO(Master In Slave Out – Master-Eingang, Slave-Ausgang) oder einfach ALSO– Die Datenübertragung erfolgt vom Slave-Gerät zum Master-Gerät.
  • C.S.(Chipauswahl – Chipauswahl) oder SS(Slave-Auswahl – Slave-Auswahl) – Auswahl eines Slave-Geräts.
  • SCLK(Serielle UHR) oder einfach SCK– Übertragung eines Taktsignals vom Master zum Slave.

Um Daten von einem Master zu einem Slave zu übertragen, muss der Master den Signalpegel auf der CS-Leitung des Slaves, mit dem er eine Kommunikation aufbauen möchte, auf niedrig setzen. Die Bits werden dann über die MOSI-Leitung übertragen. Um die Datenübertragung zu stoppen, „gibt“ der Leiter sozusagen die CS-Leitung frei und stellt auf diese einen hohen Signalpegel ein.

Um mehrere Slave-Geräte an den SPI-Datenbus anzuschließen, muss jedes über eine eigene CS-Leitung verfügen. Sobald dies erledigt ist, kann das Master-Gerät abwechselnd die Leitungen „ziehen“ und so zwischen den Slave-Geräten wechseln. Mehrere Slaves können auf unterschiedliche Weise angeschlossen werden: parallel oder in Reihe.

Parallelschaltung von Slave-Geräten über SPI-Datenbus

Die Besonderheit der Parallelschaltung mehrerer Slave-Geräte besteht darin, dass zur Herstellung der Kommunikation gemeinsame Leitungen SCLK, MOSI und MISO verwendet werden. In diesem Fall verfügt jedes Slave-Gerät über eine eigene SS(CS)-Leitung. Das Master-Gerät bestimmt, mit welchem ​​„aktuellen Slave“ der Datenaustausch aufgebaut werden soll, indem es auf der entsprechenden SSn-Leitung einen niedrigen Signalpegel erzeugt (wobei n – 1,2...).

Um n-fache Slave-Geräte über die SPI-Schnittstelle mit der Steuerung zu verbinden, müssen Sie diese für diesen Zweck zuordnen n+3 Mikrocontroller-Pins.

Serieller Anschluss von Slave-Geräten an den SPI-Bus

Für die serielle Verbindung von Slave-Geräten verwenden sie gemeinsame Leitungen SCLK und SS, und der Ausgang des einen ist mit dem Eingang des anderen verbunden. Die MOSI-Leitung des Masters ist mit dem ersten Slave verbunden und die MISO-Leitung ist mit dem letzten verbunden. Betrachtet man diese Verbindung aus der Sicht des Master-Geräts, dann ist ein Slave-Gerät über den SPI-Datenbus verbunden.

Hervorzuheben ist der Vorteil dieser Verbindungsart: Sie können die n-te Anzahl von Geräten anschließen, indem Sie zu diesem Zweck nur 4 Pins des Mikrocontrollers verwenden.

Das ist alles für den Moment, Fortsetzung folgt...

In diesem Artikel möchte ich einen kurzen Überblick über den SPI-Bus geben (eine in der Embedded-Technologie weit verbreitete Schnittstelle, die zum Anschluss verschiedener Geräte verwendet wird) und versuchen, den Prozess der Erstellung eines SPI-Gerätetreibers auf Protokollebene für Linux zu beschreiben. Dieses Dokument stellt keinen vollständigen Leitfaden dar, sondern soll vielmehr in die richtige Richtung weisen. Da der Artikel nicht in ein Thema passte, musste ich ihn in zwei Teile aufteilen.

0. Statt Einleitung

Was ist das für ein Artikel?
Bei diesem Artikel handelt es sich um eine Zusammenstellung von Informationen aus verschiedenen Quellen, eine kostenlose Übersetzung einiger Teile der Dokumentation sowie eigene Kommentare, Ergänzungen und Beschreibungen aufgetretener Probleme.

Für wen ist dieser Artikel?
Zunächst einmal für Anfänger, was ich bin. In Embedded-Linux-Foren stößt man oft auf die Frage: „Wie kann ich mit SPI auf diesem Board arbeiten?“ Genau das werde ich versuchen zu beantworten. Als Beispiel gebe ich den Code an, der für die Arbeit mit meinem Test-SPI-Gerät geschrieben wurde.

Artikelstruktur
Aufgrund der Fülle an Informationen ist der Artikel in mehrere Unterabschnitte unterteilt:

  1. Was ist SPI?
  2. Übersicht über das SPI-Subsystem in Linux
  3. Entwicklung eines Userspace-Protokoll-SPI-Treibers mit spidev
  4. Entwicklung eines SPI-Protokolltreibers auf Kernel-Ebene
  5. Dokumentation
Die ersten beiden Punkte werden in den ersten Teil des Artikels aufgenommen, die restlichen in den zweiten.

Der erste Unterabschnitt beschreibt die Funktionsweise des SPI-Busses; dieser Teil des Artikels ist nicht speziell auf Linux bezogen und kann daher von denjenigen gelesen werden, die sich nicht für Linux interessieren, sondern nur Informationen über diese Schnittstelle benötigen.

Der zweite Unterabschnitt beschreibt die Strukturen und Mechanismen, die der Arbeit mit SPI unter Linux zugrunde liegen; er muss gelesen werden, um zu verstehen, was im dritten und vierten Teil besprochen wird.

Wenn Sie an meinen Übersetzungen und Ergänzungen kein Interesse haben, können Sie getrost direkt zum fünften Teil springen, wo Sie Informationen darüber finden, wo Sie alle notwendigen Informationen zu diesem Thema erhalten.

Fehler
Ich bin kein Zauberer, ich lerne nur. Wenn Sie Fehler oder Ungenauigkeiten finden, teilen Sie mir dies bitte mit.

1. Was ist SPI?

Die Abkürzung SPI bedeutet „Serial Peripheral Interface“ oder in der russischen Version „Serial Peripheral Interface“. Der Name spricht für sich; diese Schnittstelle dient der Arbeit mit verschiedenen Peripheriegeräten. Dies können beispielsweise verschiedene DACs/ADCs, Potentiometer, Sensoren, Input/Output-Port-Expander (GPIO), verschiedene Speicher und noch komplexere Peripheriegeräte wie Audio-Codecs und Ethernet-Controller sein.

Aus technischer Sicht handelt es sich bei SPI um einen synchronen Vierdrahtbus. Dabei handelt es sich um eine Verbindung zweier synchroner Schieberegister, die das zentrale Element jedes SPI-Geräts darstellt. Die Verbindung verwendet eine Master/Slave-Konfiguration. Nur der Master kann Synchronisationsimpulse erzeugen. Es gibt immer nur einen Master in der Schaltung (im Gegensatz zum gleichen I2C-Bus, wo eine Option mit mehr als einem Master möglich ist), kann die Anzahl der Slaves unterschiedlich sein. Im Allgemeinen ist der Master-Ausgang mit dem Slave-Eingang verbunden und umgekehrt ist der Slave-Ausgang mit dem Master-Eingang verbunden. Wenn Taktimpulse an den SCK-Ausgang angelegt werden, werden Daten vom Master am MOSI-Ausgang ausgegeben und vom Slave am MISO-Eingang erfasst. Wenn Sie also die Anzahl der Synchronisationsimpulse anwenden, die der Bitgröße des Schieberegisters entspricht, tauschen die Daten in den Registern ihre Plätze. Daraus folgt, dass SPI immer im Vollduplexmodus arbeitet. Aber ob wir die vom Gerät empfangenen Daten für die Aufzeichnung eines Parameters benötigen, ist eine andere Frage. Es kommt oft vor, dass die vom Gerät beim Schreiben von Daten empfangenen Daten Müll sind. In diesem Fall werden sie einfach ignoriert, wir erhalten sie jedoch unabhängig von unserem Wunsch.

Der SPI-Controller wird typischerweise als Peripherieeinheit in einer MCU oder eMPU implementiert. Bei den meisten Chips kann er entweder im Master- oder im Slave-Modus betrieben werden. Derzeit unterstützt Linux jedoch nur den Master-Modus.

Es gibt mehrere Möglichkeiten, SPI-Geräte zu aktivieren.

Die einfachste davon sehen Sie im Bild oben (Danke an Wikipedia für die Bilder unter der kostenlosen GFDL-Lizenz). In diesem Fall sind alle Slaves mit Ausnahme des Slave-Select-Signals (~CS) parallel mit dem Master verbunden. Jeder Slave benötigt ein separates Slave-Auswahlsignal (in der Abbildung mit SSx gekennzeichnet). Für Slave-Auswahlsignale können entweder dedizierte SPI-Controller-Ausgänge oder GPIO-Ports (General Purpose Input/Output) am Mikrocontroller verwendet werden.

Für die Datenübertragung werden zwei Drähte verwendet, einer für die Versorgung mit Taktimpulsen und ein Slave-Auswahlsignal für jeden der Slaves.
Beschreibung der verwendeten Signale:

  • MOSI – Master-Ausgang, Slave-Eingang (Master-Ausgang, Slave-Eingang). Dieses Signal ist für die serielle Datenübertragung vom Master zum Slave gedacht. Kann auch SDO, DO usw. genannt werden.
  • MISO – Master-Eingang, Slave-Ausgang (Master-Eingang, Slave-Ausgang). Dieses Signal ist für die serielle Datenübertragung vom Slave zum Master vorgesehen. Kann als SDI, DI usw. bezeichnet werden.
  • SCK – Serieller Takt (Synchronisationssignal). Wird zur Synchronisierung während der Datenübertragung verwendet. Es kann auch SCLK, CLK usw. genannt werden.
  • ~CS - Chip Select (Chipauswahl). Dieses Signal aktiviert das Slave-Gerät. Normalerweise ist es umgekehrt, das heißt, ein niedriger Pegel gilt als aktiv. Manchmal wird es ~SS (Slave Select, russisch „Sklavenwahl“) genannt.

Ein Sonderfall der unabhängigen Verbindung ist die Option mit einem einzigen Slave. In diesem Fall möchten Sie möglicherweise das ~CS-Signal auf Masse ziehen, damit sich das Gerät immer im aktiven Zustand befindet. Dies wird jedoch dringend nicht empfohlen, da das Slave-Gerät das CS-Signal zur Initialisierung oder für andere Servicezwecke verwenden kann.

Der Hauptnachteil der unabhängigen Verbindung von Slaves besteht darin, dass jeder Slave ein separates ~CS-Signal benötigt. Das Kaskadenverbindungsschema, in der ausländischen Literatur „Daisy-Chain“ genannt (kann als „Girlande“ übersetzt werden), weist keinen solchen Nachteil auf.

Wie Sie der Abbildung oben entnehmen können, wird dabei ein gemeinsames Slave-Auswahlsignal für alle Slaves verwendet. Der Ausgang jedes Slaves ist mit dem Eingang des nächsten verbunden. Der Ausgang des letzten Slaves ist mit dem Eingang des Masters verbunden und bildet so einen geschlossenen Stromkreis. Bei dieser Verbindung können wir davon ausgehen, dass die in Reihe geschalteten Geräte ein großes Schieberegister bilden. Dementsprechend können Daten „in einer Sitzung“ auf alle Geräte geschrieben werden, nachdem zuvor das erforderliche Paket zusammengestellt wurde, das die Daten für jedes der Geräte in der Reihenfolge kombiniert, die der physischen Reihenfolge der Verbindung entspricht. Aber es gibt hier einen subtilen Punkt. Erstens müssen alle Chips diese Art der Verbindung unterstützen; Zweitens unterstützt der Linux-Kernel diese Art der Verbindung nicht. Wenn Sie sie also weiterhin verwenden möchten, müssen Sie vorhandene Treiber ändern oder eigene Treiber schreiben.

Es gibt vier Betriebsmodi für SPI-Geräte. Sie sind in der Regel diejenigen, die bei Anfängern am meisten Verwirrung stiften. Diese vier Modi sind eine Kombination aus zwei Bits:

  • CPOL (Clock Polarity) – bestimmt den Anfangspegel (Polarität) des Taktsignals.
    CPOL=0 zeigt an, dass das Taktsignal niedrig beginnt, sodass die Vorderflanke ansteigt und die Hinterflanke fällt.
    CPOL=1, das Taktsignal beginnt hoch, sodass die Vorderflanke fällt und die Hinterflanke steigt.
  • CPHA (Clock Phase) – die Synchronisationsphase bestimmt, welche Flanke des Taktsignals zum Abtasten von Daten verwendet wird.
    CPHA=0 zeigt an, dass eine Abtastung an der Vorderkante erforderlich ist
    CPHA=1 gibt an, dass Daten bei einer fallenden Flanke abgetastet werden müssen.
Diese beiden Bits bilden die Modusnummer. CPOL ist das höchstwertige Bit und CPHA ist das niedrigstwertige Bit. Manchmal wird in der Gerätedokumentation die Modusnummer nicht explizit angegeben, sie kann jedoch anhand von Zeitdiagrammen immer leicht ermittelt werden. Es ist auch wichtig zu verstehen, dass die Datenabtastung und -einstellung immer an entgegengesetzten Flanken des Taktsignals erfolgt. Lassen Sie unser Gerät beispielsweise im Modus 0 arbeiten (die häufigste Option). In diesem Fall liest das Slave-Gerät ein Datenbit vom MOSI-Eingang bei der steigenden Flanke des Taktsignals und das Master-Gerät liest Daten von der Slave am MISO-Eingang auch an der steigenden Flanke. Zur besseren Übersicht stelle ich Oszillogramme für alle vier Betriebsarten zur Verfügung:

Diese Abbildung zeigt die Signale MOSI (blaue Linie) und SCK (gelbe Linie). In allen Fällen wird die Zahl 0x64 übertragen. Helle vertikale Linien zeigen an, wann die Daten erfasst wurden. Betrachten wir Modus 2, für den, wie wir uns erinnern, CPOL=1 und CPHA=0 gilt. Wir sehen also, dass das Synchronisierungssignal zunächst einen hohen Pegel hat und die Abtastung entlang der Vorderflanke (in diesem Fall der Abstiegsflanke) erfolgt. Da mein Oszilloskop nur zwei Kanäle hat, werden die Signale ~CS und MISO nicht angezeigt. In diesem Fall sind sie jedoch nicht so interessant, da beispielsweise das ~CS-Signal während der gesamten Datenübertragung lediglich ein „Fehler“ ist.

2. Überblick über das SPI-Subsystem in Linux

SPI-Treiber unter Linux sind in zwei Teile unterteilt. Der erste sind SPI-Controller-Treiber, die direkt mit der Hardware eines bestimmten Controllers arbeiten. Solche Treiber bestimmen, wie der Controller konfiguriert wird, welche Aktionen beim Wechsel in den Energiesparmodus (suspend) und beim Verlassen des Modus (resume) ausgeführt werden sollen und wie die nächste Übertragung (spi_transfer) aus der Übertragungswarteschlange in einer Nachricht (spi_message, Informationen zu Warteschlangen unten) ausgewählt wird. und das direkte Senden an einen Port wird auch als Aktivieren/Deaktivieren eines bestimmten Geräts über CS (cs_activate/cs_deactivate-Funktionen) definiert. In diesem Artikel werde ich diesen Treibertyp nicht beschreiben. In der Regel sind sie bereits für diejenigen MCUs/eMPUs implementiert, für die es einen Linux-Port gibt, und Sie müssen nur dann darauf zugreifen, wenn Sie eine bestimmte Funktion wie Chip Select Decoding benötigen, um das gewünschte Slave-Gerät aktivieren zu können über eine externe Logik. Manchmal ist dies nützlich, beispielsweise bei GPIO-Mangel.

Der zweite Teil sind die Protokolltreiber, die für die Arbeit mit verschiedenen Slave-Geräten verwendet werden, die an den SPI-Bus angeschlossen sind. Diese Treiber werden „Protokoll“-Treiber genannt, da sie nur verschiedene Daten von Slave-Geräten senden und empfangen, ohne direkt mit Hardware zu arbeiten. Dieser Treibertyp ist für uns am interessantesten, da er es uns ermöglicht, dem System Unterstützung für das gewünschte Slave-Gerät hinzuzufügen, was wir in Betracht ziehen werden.

Die meisten Protokolltreiber sind Kernelmodule. Wenn es sich bei dem Gerät beispielsweise um einen über SPI angeschlossenen Audio-Codec handelt, nutzt der Treiber auch die von ALSA bereitgestellten Funktionen und Programme (z. B. madplay) können über das Zeichengerät /dev/audio damit arbeiten. ohne die geringste Ahnung zu haben, wie es in der Hardware aufgebaut ist und an welchen Bus es angeschlossen ist.

Der Kernel stellt außerdem einen Allzweck-Protokolltreiber namens spidev mit einer Zeichengeräteschnittstelle bereit. Sie können damit Halbduplex-Aufrufe an das SPI-Slave-Gerät mit Standard-Systemaufrufen read() und write() durchführen, den Betriebsmodus festlegen und auch einen Vollduplex-Datenaustausch mit ioctl()-Aufrufen durchführen.

Daher können Protokolltreiber für SPI-Geräte in zwei Typen unterteilt werden:

  • Userspace-Treiber, die im Userspace arbeiten und gewöhnliche Programme in einer beliebigen Sprache sind, die mit einem SPI-Gerät arbeiten, indem sie das entsprechende Spidev-Zeichengerät lesen/schreiben.
  • Treiber, die im Kernel-Space ausgeführt werden und über Gerätedateien im Verzeichnis /dev oder über Attribute im Geräteverzeichnis in sysfs eine Schnittstelle zum Userspace bereitstellen.
Linux stellt alle Anrufe an SPI-Geräte in die Warteschlange. SPI-Protokolltreiber arbeiten explizit oder implizit mit Nachrichten, die durch die Struktur struct spi_message dargestellt werden, bei der es sich um eine SPI-Transaktion mit mehreren Segmenten handelt.
struct spi_message ( struct list_head Transfers; struct spi_device *spi; unsigned is_dma_mapped:1; void (*complete)(void *context); void *context; unsignedactual_length; int status; struct list_head queue; void *state; );
Transfers – verknüpfte Liste der übertragenen Segmente in einer Transaktion (Transfers);
spi – Zeiger auf das spi-Gerät, in dessen Warteschlange sich diese Nachricht befindet;
is_dma_maped – wenn dieses Flag wahr ist, werden für jeden Sendepuffer sowohl virtuelle DMA- als auch CPU-Adressen bereitgestellt;
Complete – ein Rückruf, der aufgerufen wird, um das Ende einer Transaktion anzuzeigen;
context – Argument für den Complete()-Rückruf;
tatsächliche_Länge – die Gesamtzahl der Bytes, die bei allen erfolgreichen Übertragungen übertragen wurden;
status – 0 im Erfolgsfall oder ein negativer Wert mit errno im Fehlerfall;

Stichworte:

  • Linux
  • spi
  • spidev
  • eingebettet
  • Kernelmodul
Tags hinzufügen

 


Lesen:



Erhalten Sie Preise für das Dokumentdatum in einer Anfrage. Wir speichern den Bericht als Datei.

Erhalten Sie Preise für das Dokumentdatum in einer Anfrage. Wir speichern den Bericht als Datei.

Sehr oft besteht die Notwendigkeit, mit Variablen vom Typ „Datum“ zu arbeiten. In diesem Artikel werden wir uns mit den grundlegenden Techniken befassen – dem Übertragen des Stroms...

1c 8.3 auf einer Domäne installieren. Installation und Aktualisierung der Plattform auf einer großen Anzahl von Computern über ein gemeinsames Netzwerkverzeichnis. Konfigurationsdatei, die den Speicherort des freigegebenen Netzwerkverzeichnisses definiert

1c 8.3 auf einer Domäne installieren.  Installation und Aktualisierung der Plattform auf einer großen Anzahl von Computern über ein gemeinsames Netzwerkverzeichnis.  Konfigurationsdatei, die den Speicherort des freigegebenen Netzwerkverzeichnisses definiert

Welche Methoden zur Bereitstellung unserer Software bietet uns 1C? 1. Installation über ein Anmeldeskript 2. Installation durch Platzierung im Allgemeinen...

Iterieren über Zeilen der Wertetabelle 1s 8

Iterieren über Zeilen der Wertetabelle 1s 8

Hier ein kleiner Fakt für den Anfang – einfache Beispiele für die Arbeit mit einer Wertetabelle: 1. Erstellen Sie eine WertetabelleValueTable = Neu...

So finden Sie die Sendungsnummer eines per Post versendeten Pakets heraus

So finden Sie die Sendungsnummer eines per Post versendeten Pakets heraus

Wertvolle Pakete und Briefe werden oft per Post verschickt. Die Absender machen sich Sorgen um ihre Sicherheit, doch dank spezieller Dienste ist es nun...

Feed-Bild RSS