McPrx-Logo

Mikrocontrollerpraxis

Flowcode und Arduino - Einstieg

Nun soll es aber endlich losgehen. Für den ersten Einstieg in die Mikrocontroller-Entwicklung ist natürlich eine geeignete Entwicklungsumgebung erforderlich. Diese besteht aus einem Personalcomputer und dem Mikrocontroller-Zielsystem. Auch wenn es mittlerweile viele Anwendungsprogramme gibt, welche gleichzeitig für die PC-Betriebssysteme Windows, Linux und Mac verfügbar sind, bevorzuge ich Windows (zur Zeit Windows 7), da dafür aus meiner Sicht die breiteste Software-Unterstützung existiert.

Auf dem Personalcomputer werden mindestens ein Software-Editor, d.h. ein Eingabe-Programm, ein Compiler oder Assembler und eine Download-Software benötigt. Mit dem Editor werden zunächst auf einer abstrakten Ebene der Mikrocontroller-Programmablauf und die benötigten Datenstrukturen festgelegt. Diese Eingaben werden in einer oder auch in mehreren Quelltext-Dateien gespeichert. Während in der Anfangszeit der Computer noch manuell die Befehls-Codes eingegeben werden mussten und jedes Sprungziel vom Programmierer berechnet werden musste, war die Einführung der Assembler-Technik eine große Erleichterung. Für die Befehlscodes können jetzt sogenannte symbolische Befehls-Mnemoniks notiert werden. Diese kann man sich leichter merken. Auch Sprungziele und Datenspeicher-Adressen lassen sich mit sinnvollen symbolischen Bezeichnern verknüpfen, wodurch sich die Programm-Lesbarkeit weiter erhöht. Der Assembler sorgt jetzt dafür, diesen Quelltext in die Befehlcodes für den Programmspeicher des Computers zu übersetzen. Wird der Quellcode auf mehrere Dateien aufgeteilt, müssen diese nacheinander assembliert werden. Ein weiteres Zusatzprogramm, der Linker berechnet die noch offenen Adressbezüge zwischen den Quellen und erzeugt die endgültige Programm-Datei für den Mikrocontroller. Diese muss danach noch in den Programmspeicher des Mikrocontrollers programmiert werden, damit die Mikrocontroller-CPU den Code ausführen kann.

Die Assembler-Technik gibt dem Programmierer alle Freiheiten zur Optimierung des Codes bezüglich Speicherbedarf oder Laufzeitanforderung. Dem gegenüber steht aber der Nachteil, dass es wenig Mechanismen gibt, um eine strukturierte Programmierung zu unterstützen. Auch ist der Abstraktionsgrad bei Assemblerprogrammierung noch sehr gering. Die Übertragung eines Programms, welches für einen speziellen Mikrocontrollertyp erstellt wurde auf einen Typ einer anderen Familie ist mit sehr großem Aufwand verbunden. Aufgrund der bereits angesprochenen großen Vielfalt der Anwendungsgebiete, gibt es natürlich viele Hersteller von unterschiedlichen Mikrocontroller-Typen und -Familien und ständig werden die Architekturen weiterentwickelt, verbessert bzw. neue entwickelt.

Zur Erhöhung des Abstraktionsgrades wurde deshalb bereits in den frühen 1970er Jahren die Programmiersprache C entwickelt, welche auch heute noch als Basis-Standard der Software-Entwicklung bezeichnet werden kann. Diese Programmiersprache enthält wichtige Elemente, die eine strukturierte Proagrammierung unterstützen. Ein C-Compiler übersetzt den weitgehend CPU-unabhängigen Quelltext in den Maschinencode des jeweiligen Mikrocontrollers. Da der C-Standard allerdings nicht für alle Aspekte der Software-Entwicklung geeignete Strukturen definiert, gibt es in der Regel immer noch einigen CPU-spezifischen Quellcode.

Für unsere ersten Experimente möchte ich eine integrierte Entwicklungsumgebung (engl. integreated development environment - IDE) vorschlagen, welche einen C-Compiler nur indirekt nutzt: Flowcode. Die Firma Matrix Technology Solutions Ltd bietet diese Software in Versionen für unterschiedliche Mikrocontroller-Familien an. Um den Einstieg in die Mikrocontroller-Programmierung zu erleichtern wird in dieser IDE der Quellcode nicht als Text eingegeben, sondern in einem grafischen Editor (eine Art Zeichenprogramm) ein sogenanntes Programmfluss-Diagramm erstellt. Die Software erzeugt daraus auf Knopfdruck einen Quelltext in C, welcher automatisch von einem integrierten C-Compiler in Maschinencode übersetzt wird und mittels einer ebenfalls integrierten Download-Software in den Programmspeicher eines angeschlossenen Mikrocontrollers programmiert wird.

Elemente Programmfluss-Diagramm
Bild 1: Elemente eine Programmfluss-Diagramms

Zur Darstellung eines Software-Algorithums mit einem Programmfluss-Diagramm (manchmal auch als Programm-Ablauf-Plan - PAP bezeichnet) benötigt man eigentlich nur vier Elemente (Bild 1). Mit Flussrichtungspfeilen wird die Reihenfolge und Richtung der Abarbeitung dargestellt. Sie dienen als Verbindungselemente zwischen den drei anderen Bausteinen. Jeweils ein Rechteck mit gerundeten Seitenkanten kennzeichnet den Anfang und das Ende eines Diagramms. Mit einem normalen Rechteck werden alle Aktionen dargestellt (z.B. Berechnungen). Für Programmverzweigungen wird die Raute verwendet. Dieses Elemet besitzt einen Eingang und zwei Ausgänge an welchen alternativ der Programmfluss fortgesetzt wird, je nachdem, ob die enthaltene logische Abfrage mit ja oder nein beantwortet wird. Durch die Einfügung von Flussrichtungspfeilen welche im Ablauf über einen oder mehrere Anweisungsblöcke zurück führen, werden Schleifen abgebildet. Durch den Aufruf eines anderen Programmfluss-Diagramms innerhalb eines Anweisungsblocks ist eine Hierachiebildung (Nutzung von Unterprogrammen) möglich.

Beispiel PAP
Bild 2: Einfaches Programmfluss-Diagramm

In Bild 2 ist beispielhaft ein einfaches Programmfluss-Diagramm mit dem Namen "LED_an" abgebildet. Nach einer Aktion "Init IO-Pins" wird ein Signal "Ta1" ausgewertet. Ist dieses Signal gleich Null, wird eine LED angeschaltet. Andernfalls wird sie ausgeschaltet. Danach erfolgt ein unbedingter Sprung zurück vor die Auswertung des Signals "Ta1", wodurch eine sogenannte Endlosschleife gebildet wird. Das eigentliche Ende des Programmfluss-Diagramms wird dadurch niemals erreicht.

Diese Beispiel zeigt bereits einige wichtige grundlegende Dinge von Mikrocontrollerprogrammen. So die Unterteilung in Aktionen zur Initialisierung, welche nur einmalig nach dem Start ausgeführt werden und in Aktionen, welche innerhalb einer Endlosschleife immer wieder ausgeführt werden. Typisch ist auch, dass die I/O-Pins initialisiert werden müssen. Im Allgemeinen können die Digital-Pins eines Mikrocontrollers sowohl als Eingang als auch als Ausgang genutzt werden. Damit es innerhalb einer Mikrocontrollerschaltung beim Einschalten nicht zu Kurzschlüssen kommen kann, sind nach einem Reset alle Pins zunächst als Eingang konfiguriert. Daraus folgt, dass ein Pin, an welches eine LED angeschlossen ist, vor eine Signalausgabe als Ausgang programmiert werden muss.

Arduino Nano
Bild 3: Arduino Nano

Als Zielsystem wollen wir eine kleine Steckbrettschaltung mit einem Arduino Nano (Bild 3) realisieren. Bei der Arduino-Familie handelt es sich um bereits einsatzfertige Mikrocontroller-Platinen, für welche es verschiedene Erweiterungs-Shields zum Aufstecken gibt. Der Arduino Nano weicht von diesem Konzept etwas ab, eignet sich aber aufgrund der kleinen Bauweise gut für Steckbrett-Experimente. Arduino-Controller enthalten einen 8-Bit-Mikrocontroller aus der AVR-Familie der Firma Atmel. Im Programmspeicher des Controllers befindet sich bereits eine Bootloader-Firmware. Auf der Platine ist eine USB-Schnittstelle integriert, welche zur Spannungsversorgung und zum Programm-Download genutzt wird. Arduino Nano Controller sind sehr preiswert von verschiedenen Anbietern über ebay.de erhältlich.

Zur Software-Entwicklung gibt es für die gesamte Arduino-Familie die Arduino-IDE. In dieser Entwicklungsumgebung wird in C bzw. objektorientiert in C++ programmiert. Wie aber bereits angedeutet, wollen wir die Entwicklungsumgebung Flowcode einsetzen. Von dieser gibt es eine AVR Free-Version, welche auch den Arduino Nano unterstützt.

Nach dem ersten Start bestätigt man die erste Dialog-Abfrage unter Auswahl der Option 'Create a new Flowcode flowchart...'. Danach gelangt man in den Dialog für die Projekt-Einstellungen. Hier ist auf dem Tab 'Choose a Target' die Option 'Arduino Nano 328' auszuwählen. Das Programmfenster sieht danach etwa wie in Bild 4 aus.

Flowcode
Bild 4: Flowcode Programmfenster

Die wichtigsten Elemente sind der Editor in dem bereits ein Tabulator für das Fluss-Diagramm 'Main' existiert, der Project Explorer zur Verwaltung von Variablen, Macros (Unterprogramme bzw. Funktionen) und Components, das Panel sowie die Toolbar, die Command Toolbox und die Components Toolbox. In dem zusätzlichem Fenster 'Chip' kann man sich die Pinbelegung des Mikrocontrollers anzeigen lassen.

Die gelbe Command Toolbox enthält alle Elemente, die in das Programmfluss-Diagramm eingefügt werden können. Abweichend zu den obigen allgemeinen Erläuterungen gibt es keinen Flussrichtungspfeil, da die Verbindungen automatisch zwischen eingefügten Elementen hergestellt werden. Für die Programmierung von Schleifen existiert ein zusätzliches mit Loop bezeichnetes Element. Für verschiedene Aktionen gibt es jeweils etwas unterschiedliche Anweisungsblöcke: Input, Output, Delay, Macro, Component Macro, Calculation und C Code. Das erhöht zwar etwas die Vielfalt der Elemente, führt aber im Ergebnis zu einem besser lebaren Programmfluss-Diagramm.

Blinky
Bild 5: Flussdiagramm Blinky

Für unser erstes Mikrocontroller-Programm wollen wir die auf dem Arduino aufgelötete und mit dem I/O-Port Digital13 verbundene LED blinken lassen. Wir fügen dazu mit der Maus ein Loop in unser Diagramm ein. Durch einen Doppelklick auf das eingefügte Element öffnet sich der entsprechende Eigenschaftsdialog, den wir aber nicht verändern wollen. Wir sehen hier, dass es sich um eine universelles Schleifen-Element handelt, was je nach Anwendung speziell konfigurierbar ist. Die eingefügte Schleife besteht, wie wir sehen, aus einem Anfang- und einem End-Teil. Zwischen diese Teile fügen wir nun einen Output ein. Den Eigenschaftsdialog des Output konfigurieren wir so, dass der Wert 0 (Variable or value) auf den PORTB auf das Bit 5 (Single Bit) ausgegeben wird. Danach fügen wir einen Delay ein und konfigurieren diesen für eine Verzögerung von 100 Milisekunden. Indem wir mit der Maus einen Kasten um die zwei Aktionen Output und Delay ziehen, können wir diese Auswählen und mit den bekannten Windows-Funktionen Copy und Paste duplizieren. Im neuen Output ändern wir noch den Wert 0 in 1 und speichern das ganze ab. Unser Programmflussdiagramm sollte nun wie in Bild 5 aussehen.

Bevor wir unser Programm in den Codespeicher des Mikrocontrollers laden können, müssen wir zunächst kontrollieren, ob der Treiber für unseren Arduino Nano, beim ersten Verbinden mit einem USB-Port des PC, korrekt installiert wurde und welcher COM-Port diesem zugewiesen wurde. Das geht am einfachsten über den Gerätemanager in der Systemsteuerung (Anschlüsse).

Danach sind, wie in Bild 6 dargestellt, die Einstellungen für den Programmer vorzunehmen (Menü: Build\Compiler Options... / Tab Programmer).

Durch Betätigung des Buttons 'Compile to chip' ganz rechts in der Toolbar wird aus dem Diagramm der C-Code erzeugt, dieser compiliert und gelinkt und danach der Code in den Controller geladen. Es öffnet sich automatisch das Fenster 'Compiler Messages'. Wenn am Ende hoffentlich die Meldung 'Programming successsful!' erscheint, war dieser Versuch erfolgreich.

© Heiko Böhmer, Stand: 18.08.15