Unterrichts- und Lernmaterial für Mikrocontroller
Unterrichts- und Lernmaterial fürMikrocontroller

Propeller 8 Kern Controller - C Programmierung

1 - Beschleunigungssensor (3 Achsen) MMA7455

Ein Beschleunigungsmesser misst die Kräfte, die über die Beschleunigungsgröße und die immer vorhandene Gravitation auf eine kleine Masse im Sensor ausgeübt wird. Wir nehmen Beschleunigungen zum Beispiel wahr, wenn wir in einem Auto, einem Bus oder Flugzeug sitzen, das plötzlich stark beschleunigt wird. Man hat das Gefühl, in den Sitz gepresst zu werden. Die Gravitation zieht uns immer wieder zur Erde oder Erdoberfläche zurück. Große Sprünge können wir uns deshalb nicht leisten.

Beschleunigungsmesser reagieren auf die eben beschriebenen Kräfte. Mit dem vorliegenden 3-Achs-Beschleunigungsmesser MMA7455 lassen sich die Wirkkräfte in Richtung der drei Raumachsen x, y und z bestimmen.

2 - SPI Schnittstelle

Das Modul verfügt über eine sogenannte SPI Schnittstelle (serial peripheral interface). Der Datenaustausch zwischen dem Baustein und dem Propeller Controller erfolgt nach dem sogenannten SPI-Protokoll. Für einige SPI Bausteine werden Bibliotheksdateien mitgeliefert (Sammlung von Funktionen, Beschreibungen und Beispielprogrammen, die den Einsatz eines Bausteins erleichtern). Gibt es für einen SPI-Baustein keine Bibliotheksdateien des Herstellers, dann helfen die Datenblätter weiter, aus denen ersichtlich wird, wie der Baustein vom Controller angesprochen werden muss, damit eine Kommunikation zustande kommt.

In der ersten Übung benutzen wir das Datenblatt des Herstellers, um ein lauffähiges Programm zu entwickeln, dass die Kommunikation mit dem MMA7455 aufnimmt.

3 - Das Modul MMA7455

Das Modul verfügt über zwei Versorgungspin für GND und +3,3V. Zusätzlich gibt es die Anschlüsse für die SPI Kommunikation: CLK, DATA und CS.

  • CLK    Takteingang; wird in unserem Beispiel mit P8 verbunden. Der Propeller Controller überträgt HIGH/LOW-Signalfolgen über diese Datenleitung und teilt dem IC mit, dass es die Datenleitung DATA für die Übertragung von Datenbits vorbereiten oder senden soll. Die Bezeichnung CLK kann von anderen Herstellern auch mit SCLK (Systemclock) oder SCK angegeben sein.
  • DATA Binäre Daten werden über diese Leitung gesendet oder empfangen. Wird in diesem Beispiel mit P7 verbunden. Daten werden mit jedem Taktimpuls übertragen.
  • CS       steht für "chip select" und ist in unserem Beispiel mit P6 verbunden. Der Propeller Controller setzt die CS Leitung während eines Datenaustausches auf LOW und zurück auf HIGH, sobald der Datenaustausch abgeschlossen ist. Bei anderen Herstellern kann diese Leitung auch mit: nCS, CSB, CNS, NSS, STE oder SYNC bezeichnet sein.

4 - Aufbau eines SPI-Bus

Für den ersten und die weiteren Versuche gehen wir von folgendem Versuchsaufbau mit den hier beschriebenen Materialien aus.

3-Achs-Beschleunigungssensor mit SPI-Bus
Material
  • 1x  MMA7455 3-Achs-Beschleunigungsmesser
  • 1x  Propeller Board of Education oder Propeller Activity Board
  • 1x  Steckernetzteil
  • 1x  USB-Verbindungskabel
  • 5x  Steckdraht
Aufgaben
  • Baue die Schaltung nach der Schaltskizze oder dem Schaltungsplan auf.
  • Übertrage das Programm MMA7455_1.c in den SimpleIDE Editor und speichere es ab.
  • Starte das Programm mit einem Klick auf den Button Run.
  • Welche Zahlenwerte werden ausgegeben, wenn
    a) das Board flach auf dem Tisch steht und
    b) das Board um 180° gedreht wird?

Verbinde den Propeller Mikrocontroller mit dem SPI-Modul MMA7455 zu einem SPI Bus, so wie es Abb. 1 vorgibt.

Abbildung 1 - Schaltungsaufbau zum 3-Achs-Beschleunigungssensor (Courtesy of Parallax Inc.)

Wie in der Schaltskizze bereits angedeutet, ist die Datenleitung an P7 bidirektional ausgelegt. Andere SPI-Chips verfügen häufig über separierte Data-OUT und Data-IN Leitungen. In der Dokumentation zum Baustein werden die Ausgabe-Datenleitungen mit DOUT, DO oder MISO (Mikrocontroller-in-serial-out) bezeichnet; entsprechend werden die Eingabe-Datenleitungen mit DIN, DI oder MOSI (Mikrocontroller-out-serial-in) bezeichnet. Eine bidirektionale Leitung wird gekennzeichnet mit DIO.

Das Programm MMA7455_1.c

5 - Messung der Beschleunigung in z-Achsrichtung

Wir beginnen mit einer einfachen Schaltung, die sich nur auf eine Achsrichtung konzentriert. In diesem Fall die z-Achse, die senkrecht zur Erdoberfläche verläuft und das Gravitationsfeld repräsentiert.

Der bei mir angezeigte Wert für das flach auf dem Tisch aufgestellte Board ergibt einen Wert von 75, der der Gravitationskraft auf die Masse im Inneren des Sensors entspricht. Dreht man das Board auf den Kopf, dann sollte in diesem Fall ein Wert von -75 angezeigt werden. Bei mir liegt der Wert bei ca. -52. Stellt man das Board auf eine der Kanten, dann liegt der angezeigte Wert nahe bei 0.

6 - Wie arbeitet das Programm MMA7455_1.c?

Wir werden uns hier genau ansehen müssen, wie die beiden Befehle shift_out und shift_in mit dem SPI Modul kommunizieren. Zur Unterstützung sollte jetzt auch das Datenblatt des MMA7455 mit hinzugezogen werden.

 

Zeile 1

Die Bibliotheksdatei simpletools wird in das Programm eingebunden und stellt eine Reihe von Funktionen, wie pause und print zur Verfügung. Für die Übertragung von Daten nach dem SPI-Protokoll enthält sie die beiden Funktionen shift_in (Empfang von SPI-Daten) und shift_out (Senden von SPI-Daten).

Die Variable z wird in Zeile 2 deklariert und nimmt den z-Wert des Beschleunigungsmodul auf.

 

Zeile 8 und 9

CS wird auf HIGH gesetzt (high(6)) und teilt dem Modul mit, dass im Moment keine Kommunikation stattfinden soll. Der I/O Pin, der mit dem CLK Anschluss des Moduls verbunden ist, wird auf LOW gesetzt und bereitet das IC darauf vor, Zeittakte zu senden.

7 - Das SPI Modul konfigurieren

Aus dem Datenblatt lassen sich alle Informationen zu Einstellungen entnehmen, die vor Aufnahme einer Messung durchgeführt werden müssen und die Arbeitsweise des Moduls bestimmen.

Gestartet wird mit einem /CS LOW Signal, das den Baustein MMA7455 aufweckt und ihm dadurch mitteilt, dass gleich über die CLK- und DATA-Leitungen Daten übertragen werden. Beim Propeller Controller wird über P6 geweckt.

Anschließend müssen drei Werte über die Datenleitung an das Modul übertragen werden. Jeder Wert besteht aus einer fest vorgegebenen Anzahl Bits.

Zeilen 11, 12 und 13

Der erste Wert enthält 7 Bit, der zweite 1 Bit und der dritte 8 Bit. Mit jedem HIGH-Signal auf der CLK-Leitung wird ein Bit übertragen. Ist die DATA-Leitung auf HIGH, interpretiert das IC dieses Bit als binäre 1, ein LOW entsprechend als binäre 0. Die folgende Abbildung, aufgenommen mit einem PicoScope, zeigt den Zusammenhang, dabei bedeuten:

  • D0 Leitung an P6: CS
    
    
  • D1 Leitung an P7: DATA
    
    
  • D2 Leitung an P8: CLK
    
Abbildung 2 - Konfiguration des Moduls MMA7455 (Courtesy of Parallax Inc.)

Die Funktion shift_out aus der Bibliothek simpletools kümmert sich um die Taktimpulse auf der CLK Leitung und die Daten auf der DATA Leitung.

  • shift_out(pinDat, pinClk, mode, bits, value)

Die fünf Parameter haben folgende Bedeutung:

  • pinDat             gibt den Pin am Controller an, der mit DATA-Pin des Moduls verbunden ist.
  • pinClk             gibt den Pin am Controller an, der mit CLK-Pin des Moduls verbunden ist.
  • mode               MSBFIRST: "most significant bit first" heißt, das höchstwertige Bit.
  •                         LSBFIRST: "least significant bit first" heißt, das niedrigwertigste Bit.
  • bits                  Anzahl der zu übertragenden Bit.
  • value               der Wert, der übertragen werden soll in binärer Darstellung: 0bxxxxxxx

 

Die binären Zahlenwerte, die in den Programmzeilen 11 bis 13 übertragen werden, lassen sich aus dem Datenblatt zum IC entnehmen. In ihm werden auch die Register beschrieben (i. a. 8- oder 16-Bit Speicher), über die das Arbeitsverhalten eines IC beeinflusst wird. Sie tragen Namen, die über ihre Funktion Auskunft geben und haben eine Adresse, um sie ansprechen zu können.

Dem MMA7455 Datenblatt ist zu entnehmen, dass der erste Konfigurationsschritt aus der Übertragung eines 7-Bit Befehls besteht, der dem Baustein mitteilt, ob das Programm Daten übermittelt, die in eines der Register geschrieben oder gelesen werden sollen. Das höchstwertige Bit  (Bit 6) ist entweder eine 1 für Schreiben oder 0 für Lesen. Die folgenden sechs binären Stellen enthalten die Registeradresse, in die der Wert abgelegt werden soll.

Das Konfigurationsregister des MMA7455 wird mit MCTL bezeichnet und hat die Adresse 0x16 (hexadezimal),  22 (dezimal) oder 0b010110 (binär). Für eine Schreiboperation wird das 7. Bit auf 1 gesetzt, so dass sich der Wert 0b1010110 ergibt (Zeile 11).

Dem Datenblatt entnimmt man, dass anschließend ein "don´t care" Wert folgen muss, was so viel heißt, dass der Chip einen Taktimpuls benötigt, mit einer 1 oder 0 (we don´t care) auf der DATA-Leitung. Dies erledigt in Zeile 12 der Befehl mit dem Argument 0b0 oder 0b1. Wir haben hier 0b0 eingesetzt.

Damit ist das Modul bereit zum Empfang von Daten, die in das MCTL Register geschrieben werden sollen. Jetzt muss dieser Wert nur noch übertragen werden (Zeile 13). Der Übertragungswert stellt den Chip so ein, dass er im Modus +/- 2g arbeitet: 0b01100101.

Im Datenblatt werden die Biteinstellungen für das MCTL Register beschrieben.

In der Tabelle werden die 8 binären Stellen vom höchstwertigen Bit (D7, ganz links) bis zum niedrigstwertigen Bit (D0, ganz rechts) aufgelistet. In der Zeile darunter erscheinen Bezeichnungen, die einen Hinweis auf die Funktion des jeweiligen Bits geben. Die unterste Zeile zeigt die Werkseinstellung. Der Befehl 0b01100101 bewirkt, dass D7 auf 0, D6 (DRPD) auf 1, D5 (SPI3W) auf 1, STON auf 0, GLVL[1] und GLVL[0] auf 01 und mode[1] und mode[0] auf 01 gesetzt werden. Im Datenblatt wird erklärt welche Wirkung das Setzen auf 1 oder 0 hat; dies solltest du jetzt selber im Datenblatt nachschlagen.

 

Zeile 13

Mit high(6) wird die Übertragung von Daten nach dem SPI Protokoll beendet und die Konfiguration ist abgeschlossen.

Zeile 19 bis 21

In der folgenden Endlosschleife werden anschließend laufend die Daten der Messung in z-Achsrichtung eingelesen. Dazu ist ein weiterer Befehl notwendig, der die Übertragung von einem 7-Bit, einem 1-Bit und einem 8-Bit Wert notwendig macht. Dem Datenblatt ist zu entnehmen, dass das ZOUT8 Register den vorzeichenbehafteten 8-Bit Wert der Messung in z-Achsrichtung enthält. Diesen Wert müssen wir aus dem Register auslesen.

Mit low(6) wird das Modul wieder aufgeweckt. Die Adresse des ZOUT8 Registers ist im Datenblatt  mit 0x08 angegeben oder binär 0b001000. Für einen Lesebefehl muss Bit6 (die 7. binäre Stelle) auf 0 gesetzt werden. Damit wird der 7 Bit Befehl zu 0b0001000. Es muss wieder ein "don´t care" folgen (Zeile 20).

Nachdem der Sensor den Lese-Befehl für das ZOUT8 Register erhalten hat, antwortet er mit der Ausgabe des dort gespeicherten Wertes. Gesteuert über den Taktimpuls durch den Controller wartet er auf die Daten, die vom Sensor über die DATA-Leitung ausgegeben werden. Der Gegenspieler zum shift_out Befehl ist der shift_in Befehl. Diese Funktion gibt Taktimpulse auf der CLK-Leitung aus und setzt den I/O Pin des Controller auf der DATA-Leitung auf Input und wartet auf die vom Sensor ausgegebenen Werte. 

Zeile 21

Daten (jeweils 8 Bit) werden an P7 im Modus MSBPRE eingelesen und Taktimpulse an P8 ausgegeben.

MSBPRE ist eine von vier mode-Optionen der Funktion shift_in.

MSB ähnelt MSBFIRST          lädt den ersten binären Wert ganz links im Speicher und füllt die weiteren Werte nach rechts hin auf.

LSB                                        lädt den ersten binären Wert ganz rechts im Speicher und füllt die

                                               weiteren Werte nach linke hin auf.

PRE                                        überprüfe die Datenleitung vor jedem Taktimpuls auf einen Wert.

POST                                     überprüfe die Datenleitung nach jedem Taktimpuls auf einen Wert.

Zeile 22

high(6) beendet die Datenübertragung nach SPI-Protokoll.

Abbildung 3 - Datenausgabe beim MMA7455 über SPI-Schnittstelle - aufgenommen mit PicoScope 2205AMSO

Die im Timingdiagramm dargestellte Zahl 0b01001010 auf der Datenleitung entspricht dezimal 74, der Zahl, die im Terminal zum Zeitpunkt der Messung angezeigt wurde.

Die Zeile 23 regelt die Datenausgabe im Terminal.

8 - Bitmasken

Mit Hilfe von sogenannten Bitmasken lässt sich das Programm aus Abschnitt 4 verbessern. Wie das funktioniert, soll hier geklärt werden.

Um zu verstehen, wie Bitmasken arbeiten, schauen wir uns erst einmal die Wahrheitstabellen einer UND (AND) und ODER (OR) Verknüpfung an.

9 - Die OR Verknüpfung

Betrachten wir die OR-Tabelle. Werden zwei Bit mit OR verknüpft, dann ergibt sich immer eine 1, wenn einer der beiden Bits eine 1 enthält und sonst 0. Wenn wir die Spalte B als Maskenbit bezeichnen, dann ließe sich auch sagen, dass eine 0 in der Maske den anderen Wert in Spalte A nicht beeinflusst.

Wie man mit diesem Tabellenwissen ein Computerprogramm beeinflussen kann, zeigt der nächste Schritt. Dazu gehen wir von drei Variablen MCTL, SchreibMaske und konfiguration vom Typ integer aus. MCTL und SchreibMaske enthalten zum Beispiel die binären Zahlenwerte

  • MCTL         = 0b0010110     und
  • SchreibMaske = 0b1000000

Verknüpft man jetzt MCTL und SchreibMaske mit einem logischen OR, dann ergibt sich nach dem oben Gesagten

An dem Ergebnis erkennt man, dass ein Bitwert 0 in der Maske den entsprechenden Original-Bitwert durchlässt, während eine 1 in der Maske immer eine 1 an der entsprechenden Stelle setzt. Eine OR-Maske eignet sich deshalb sehr gut dazu, an einer beliebigen Stelle in einer binären Zahl eine 1 zu setzen.

Für die Darstellung der Zahl 0b1000000 gibt es in der Sprache C eine Kurzform

  • SchreibMaske = 1 << 6;       (1)

Die Bedeutung der Symbolik ist einfach; bei der Zahl 1 = 0b0000001 wird die 1 in der binären Darstellung um 6 Stellen nach links verschoben: 0b1000000. Der C-Operator für eine bitweise OR-Verknüpfung hat die Form

  • konfiguration = MCTL | SchreibMaske;  (2)

10 - Die AND Verknüpfung

Die Wahrheitstabelle kennen wir bereits. Eine 1 ergibt sich nur dann, wenn sowohl die Maske als auch das Original an der betrachteten Bitstelle eine 1 haben. In jedem anderen Fall ergibt sich eine Null. Betrachten wir zu dieser Verknüpfung die Variablen ZOUT8, LeseMaske und konfiguration, mit

  • ZOUT8     = 0b1001000    und
  • LeseMaske = 0b0111111

Verknüpft man jetzt ZOUT8 und maske mit einem logischen AND, dann ergibt sich

An diesem Beispiel erkennt man, dass eine Null in der Maske den entsprechenden Bitwert im Original auf 0 zurücksetzt (kann vorher 0 oder 1 sein) und eine 1 in der Maske den Originalwert an der entsprechenden Stelle reproduziert.

Eine Kurzschreibweise für die Erzeugung der maske 0b0111111 lautet

  • LeseMaske = ~ (1 << 6);    (3)

Den in Klammern stehenden Term kennen wir bereits aus Formel (1); er führt zum Wert 0b1000000. Die Tilde vor der Klammern kehrt jeden Bitwert um; das ergibt dann den Wert

  • LeseMaske = 0b0111111      (4)

Die bitweise AND Verknüpfung wird in der Sprache C durch das kaufmännische UND-Symbol ausgedrückt

  • konfiguration = ZOUT8 & LeseMaske;  (5)

11 – Ein Beispielprogramm

Im Datenblatt des MMA7455 Bausteins sind die Registeradressen in hexadezimaler Schreibweise angegeben: MCTL = 0x16 und ZOUT8 = 0x08. Im folgenden Beispielprogramm werden diese Werte Konstanten zugeordnet und mit Hilfe von Bitmasken einzelne Bits gesetzt.

Arbeiten mit Bitmasken
Aufgaben
  • Übertrage das Programm Bitmaske1.c in den Editor und speichere es ab.
  • Starte das Programm über Run with Terminal.
  • Überprüfe die Ergebnisse.

Das Programm Bitmaske1.c

12 – Das Programm MMA7455.c verbessern

Zu einem guten lesbaren Programmierstil gehört, dass man all die Register, die zum Beispiel bei einem SPI-IC angesprochen werden (sollen), im Programm benennt und ihnen die im Datenblatt angegebenen Adressen zuordnet. Zum Setzen und Löschen von einzelnen Bit werden Bitmasken erstellt und den Datenpin eines IC werden „sprechende“ Namen zugeordnet. Ein solches Programm lässt sich auch nach Wochen oder Monaten noch verstehen, wenn es in einem anderen Zusammenhang wieder gebraucht wird. Das Programm MMA7455.c aus Abschnitt 4 ändert sich mit diesen Vereinbarungen wie folgt:

Programm MMA7455_2.c

Ein letzter Gedanke

Schlage die Adressen der Register XOUT8 und YOUT8 im Datenblatt des MMA7455 nach und erweitere das Programm um diese beiden Achsrichtungen. Am Ende sollen im Terminal die gemessenen Beschleunigungswerte für alle drei Raumachsen ausgegeben werden.

Druckversion | Sitemap
© Reinhard Rahner - Gettorf