Tutorial: Arduino und der SPI-Bus

Dies ist das erste von zwei Kapiteln, in denen wir den SPI-Datenbus untersuchen und wie wir Geräte mit unseren Arduino-Systemen steuern können.

Der SPI-Bus scheint eine komplexe Schnittstelle zum Master zu sein, aber mit einigem kurzen Studium dieser Erklärung und praktischen Beispielen werden Sie bald ein Bus-Master! Dazu lernen wir die notwendige Theorie und wenden sie dann an, indem wir verschiedene Geräte steuern. In diesem Tutorial werden die Dinge so einfach wie möglich gehalten.

Aber zuerst, was ist das? Und einige Theorie…

SPI ist ein Akronym für „Serial Peripheral Interface“. Es handelt sich um einen synchronen seriellen Datenbus – Daten können gleichzeitig in beide Richtungen übertragen werden, im Gegensatz zum I2C-Bus, der dies nicht kann. Um eine synchrone Datenübertragung zu ermöglichen, verwendet der SPI-Bus vier Drähte. Sie heißen:

  • MOSI – Master-out, Slave-in. Diese Leitung überträgt Daten von unserem Arduino zu den SPI-gesteuerten Geräten;
  • MISO – Master-in, Slave-Out. Diese Leitung überträgt Daten von den SPI-gesteuerten Geräten zurück zum Arduino;
  • SS – Slave-auswählen. Diese Zeile teilt dem Gerät auf dem Bus mit, dass wir mit ihm kommunizieren möchten. Jedes SPI-Gerät benötigt eine eindeutige SS-Leitung zurück zum Arduino;
  • SCK – Serial clock.

In diesen Tutorials betrachten wir das Arduino-Board als Master und die SPI-Geräte als Slaves. Auf unseren Arduino Uno und kompatiblen Boards werden folgende Pins verwendet:

  • SS – digital 10. Sie können andere digitale pins, aber 10 ist in der regel die standard wie es ist neben die andere SPI pins;
  • MOSI-digital 11;
  • MISO-digital 12;
  • SCK-digital 13;

Arduino Mega Benutzer – MISO ist 50, MOSI ist 51, SCK ist 52 und SS ist normalerweise 53. Wenn Sie einen Arduino Leonardo verwenden, befinden sich die SPI-Pins auf den ICSP-Header-Pins. Weitere Informationen finden Sie hier. Sie können ein oder mehrere Geräte mit dem SPI-Bus steuern. Für ein Gerät wäre die Verdrahtung beispielsweise:

sspiss1

Die Daten werden entlang der MOSI- und MISO-Leitungen zwischen unserem Arduino und dem SPI-Gerät hin und her übertragen. Dies kann nur geschehen, wenn die SS-Linie auf LOW gesetzt ist. Mit anderen Worten, um mit einem bestimmten SPI-Gerät auf dem Bus zu kommunizieren, setzen wir die SS-Leitung zu diesem Gerät auf LOW, kommunizieren dann mit ihm und setzen dann die Leitung wieder auf HIGH. Wenn wir zwei oder mehr SPI-Geräte auf dem Bus haben, würde die Verdrahtung folgendermaßen aussehen:

sspiss2

Beachten Sie, dass es zwei SS–Leitungen gibt – wir benötigen eine für jedes SPI-Gerät auf dem Bus. Sie können jeden freien digitalen Ausgangspin Ihres Arduino als SS-Leitung verwenden. Denken Sie daran, alle SS-Leitungen hoch zu halten, mit Ausnahme der Leitung, die an das SPI-Gerät angeschlossen ist, das Sie zu diesem Zeitpunkt verwenden möchten.

Daten werden in Byte-Form an das SPI-Gerät gesendet. Sie sollten inzwischen wissen, dass acht Bits ein Byte ergeben und daher eine Binärzahl mit einem Wert zwischen Null und 255 darstellen.

Bei der Kommunikation mit unseren SPI-Geräten müssen wir wissen, auf welche Weise das Gerät mit den Daten umgeht – MSB oder LSB zuerst. MSB (höchstwertiges Bit) ist die linke Seite der Binärzahl und LSB (niedrigstwertiges Bit) ist die rechte Seite der Zahl. Das ist:

binnum

Neben dem Senden numerischer Werte entlang des SPI-Busses können Binärzahlen auch Befehle darstellen. Sie können acht Ein / Aus-Einstellungen mit einem Datenbyte darstellen, sodass die Parameter eines Geräts durch Senden eines Datenbytes festgelegt werden können. Diese Parameter variieren mit jedem Gerät und sollten im Datenblatt des jeweiligen Geräts dargestellt werden. Zum Beispiel ein digitaler Potentiometer-IC mit sechs Töpfen:

sdata1

Dieses Gerät benötigt zwei Datenbytes. Das ADDR-Byte teilt dem Gerät mit, welches von sechs Potentiometern gesteuert werden soll (nummeriert 0 bis 5), und das Datenbyte ist der Wert für das Potentiometer (0 ~ 255). Wir können Ganzzahlen verwenden, um diese beiden Werte darzustellen. Zum Beispiel, um Potentiometer Nummer zwei auf 125 zu setzen, würden wir 2 dann 125 an das Gerät senden.

Wie senden wir Daten an SPI-Geräte in unseren Skizzen?

Zunächst müssen wir die SPI-Bibliothek verwenden. Es ist in der Standard-Arduino-IDE-Installation enthalten, also setzen Sie Folgendes an den Anfang Ihrer Skizze:

#include "SPI.h"

Als nächstes in void.setup() deklariert, welche Pin(s) für SS verwendet werden und setzt sie als AUSGABE. Beispiel:

pinMode(ss, OUTPUT);

wobei ss zuvor als Ganzzahl mit dem Wert zehn deklariert wurde. Jetzt, zu aktivieren die SPI bus:

SPI.begin();

und schließlich müssen wir sagen die skizze, die weg zu senden daten, MSB oder LSB erste durch mit

SPI.setBitOrder(MSBFIRST);

oder

SPI.setBitOrder(LSBFIRST);

Wenn es ist zeit zu senden daten unten die SPI bus zu unsere gerät, drei Dinge müssen passieren. Erste, set die digitale pin mit SS zu niedrigen:

digitalWrite(SS, LOW);

Dann senden Sie die Daten in Bytes, Byte für Byte mit:

SPI.transfer(value);

Der Wert kann eine ganze Zahl / Byte zwischen Null und 255 sein. Wenn Sie mit dem Senden von Daten an Ihr Gerät fertig sind, beenden Sie die Übertragung, indem Sie SS high :

digitalWrite(ss, HIGH);

Das Senden von Daten ist recht einfach. Im Allgemeinen ist es für Menschen am schwierigsten, das Gerätedatenblatt zu interpretieren, um zu verstehen, wie Befehle und Daten für die Übertragung strukturiert werden müssen. Aber mit etwas Übung können diese kleinen Hürden überwunden werden.

Nun zu einigen praktischen Beispielen!

Zeit, auf den SPI-Bus zu steigen und einige Geräte zu steuern. Anhand der folgenden Beispiele sollten Sie ein praktisches Verständnis dafür erlangen, wie der SPI-Bus und die Geräte mit unseren Arduino-Boards verwendet werden können.

MCP4162–Beispiel

Unser erstes Beispiel verwendet ein einfaches, aber interessantes Teil – ein digitales Potentiometer (wir haben auch eines im I2C-Tutorial verwendet). Dieses Mal haben wir einen Microchip MCP4162-series 10k Rheostat:

digipotss

Hier ist das Datenblatt zum Durchlesen. Um es zu steuern, müssen wir zwei Datenbytes senden – das erste Byte ist das Steuerbyte, und zum Glück ist es in diesem Beispiel immer Null (da die Adresse für den Wischerwert 00h ist). Das zweite Byte ist der Wert zum Einstellen des Wischers, der den Widerstand steuert. Um den Wischer einzustellen, müssen wir drei Dinge in unserer Skizze tun …

Stellen Sie zuerst die SS-Zeile (Slave select) auf niedrig:

digitalWrite(10, LOW);

Senden Sie dann die beiden Byes von Daten:

SPI.transfer(0); // command byteSPI.transfer(value); // wiper value

Stellen Sie schließlich die SS-Zeile wieder auf hoch:

digitalWrite(10, HIGH);

Leicht gemacht. Die Verbindung zu unserem Arduino-Board ist sehr einfach – betrachten Sie die MCP4162-Pinbelegung:

mcp4162pinout

Vdd verbindet sich mit 5V, Vss mit GND, CS mit digital 10, SCK mit digital 13, SDI mit digital 11 und SDO mit digital 12. Lassen Sie uns nun die verfügbaren Werte des MCP4162 in der folgenden Skizze durchgehen:

/* SPI bus demo using a Microchip MCP4162 digital potentiometer */#include "SPI.h" // necessary libraryint ss=10; // using digital pin 10 for SPI slave selectint del=200; // used for various delaysvoid setup(){ pinMode(ss, OUTPUT); // we use this for SS pin SPI.begin(); // wake up the SPI bus. SPI.setBitOrder(MSBFIRST); // our MCP4162 requires data to be sent MSB (most significant byte) first}void setValue(int value){ digitalWrite(ss, LOW); SPI.transfer(0); // send command byte SPI.transfer(value); // send value (0~255) digitalWrite(ss, HIGH);}void loop(){ for (int a=0; a<256; a++) { setValue(a); delay(del); } for (int a=255; a>=0; --a) { setValue(a); delay(del); }}

Um nun die Ergebnisse der Skizze zu sehen. Im folgenden Videoclip, a Wir laufen durch den Widerstandsbereich und messen den Rheostat-Wert mit einem Multimeter:

Bevor Sie fortfahren, sollten Sie, wenn digitale Potentiometer für Sie neu sind, diese kurze Anleitung von Microchip über die Unterschiede zwischen mechanischen und digitalen Potentiometern lesen.

Ein weiteres Beispiel:

In diesem Beispiel verwenden wir das Vierkanal-Digitalpotentiometer AD5204 von Analog Devices (Datenblatt.PDF). Es enthält vier 10k Ohm Linearpotentiometer, und jedes Potentiometer ist auf eine von 256 Positionen einstellbar.

Die Einstellungen sind flüchtig, was bedeutet, dass sie beim Ausschalten nicht gespeichert werden. Daher, wenn power ist angewendet die potentiometer sind alle pre set zu der mitte der skala. Unser Beispiel ist das SOIC-24 Surface Mount-Beispiel, es wird jedoch auch im DIP-Format hergestellt.

ad5204ss

Um das Leben zu erleichtern, kann es auf ein SOIC-Breakout-Board gelötet werden, das es in ein Durchgangsloch-Paket umwandelt:

ad5204boardss1

In diesem Beispiel steuern wir die Helligkeit von vier LEDs. Verdrahtung ist sehr einfach. Pinouts sind im Datenblatt.

ex34p2schematic1

Und die Skizze:

#include <SPI.h> // necessary libraryint ss=10; // using digital pin 10 for SPI slave selectint del=5; // used for fading delayvoid setup(){ pinMode(ss, OUTPUT); // we use this for SS pin SPI.begin(); // wake up the SPI bus. SPI.setBitOrder(MSBFIRST); // our AD5204 requires data to be sent MSB (most significant byte) first. See data sheet page 5 allOff(); // we do this as pot memories are volatile}void allOff()// sets all potentiometers to minimum value{ for (int z=0; z<4; z++) { setPot(z,0); }}void allOn()// sets all potentiometers to maximum value{ for (int z=0; z<4; z++) { setPot(z,255); }}void setPot(int pot, int level)// sets potentiometer 'pot' to level 'level'{ digitalWrite(ss, LOW); SPI.transfer(pot); SPI.transfer(level); digitalWrite(ss, HIGH);}void blinkAll(int count){ for (int z=0; zvoid indFade(){ for (int a=0; a<4; a++) { for (int l=0; l<255; l++) { setPot(a,l); delay(del); } for (int l=255; l>=0; --l) { setPot(a,l); delay(del); } }}void allFade(int count){ for (int a=0; a<count; a++)="" {="" for="" (int="" l="0;" l<255;="" l++)="" setpot(0,l);="" setpot(1,l);="" setpot(2,l);="" setpot(3,l);="" delay(del);="" }="">=0; --l) { setPot(0,l); setPot(1,l); setPot(2,l); setPot(3,l); delay(del); } }}void loop(){ blinkAll(3); delay(1000); indFade(); allFade(3);}

Mit den Funktionen AllOff() und allOn() werden die Potentiometer auf Minimum bzw. Wir verwenden AllOff() am Anfang der Skizze, um die LEDs auszuschalten. Dies ist notwendig, da beim Einschalten die Scheibenwischer in der Regel auf halbem Weg eingestellt sind.

Außerdem verwenden wir sie in der Funktion blinkAll(), um … die LEDs zu blinken. Die Funktion setPot() akzeptiert eine Scheibenwischernummer (0 ~ 3) und einen Wert zum Einstellen dieses Scheibenwischers (0 ~ 255). Schließlich macht die Funktion indFade() einen guten Job, jede LED der Reihe nach ein– und auszublenden – was einen Effekt verursacht, der der Pulsweitenmodulation sehr ähnlich ist.

Endlich, hier ist es in Aktion:

Also da haben Sie es – hoffentlich eine leicht verständliche Einführung in die Welt des SPI-Busses und wie man die Geräte darin steuert. Wie immer liegt es jetzt an Ihnen und Ihrer Vorstellungskraft, etwas zu finden, das Sie kontrollieren oder zu anderen Spielereien bringen können. Im nächsten SPI-Artikel werden wir uns mit dem Lesen und Schreiben von Daten über den SPI-Bus befassen.

Dieser Beitrag wurde Ihnen von pmdway zur Verfügung gestellt.com – alles für Hersteller und Elektronik-Enthusiasten, mit kostenloser Lieferung weltweit.

Um mit neuen Beiträgen auf dem Laufenden zu bleiben tronixstuff.com , bitte abonnieren Sie die Mailingliste in der Box auf der rechten Seite, oder folgen Sie uns auf Twitter @tronixstuff.

Bitte teilen Sie mit anderen:

Drucken

Schreibe einen Kommentar

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