Alle hier dargestellten Vorgänge und Erklärungen lassen sich auf alle anderen Atmel-Controller übertragen. Im Einzelnen muss immer das Datenblatt hinzugezogen werden; die Bezeichnungen unterscheiden sich - wenn überhaupt - nur geringfügig voneinander.
Wer sich ernsthafter mit Mikrocontrollern befassen möchte und bereits Erfahrung mit der BASIC STAMP, dem Propeller Controller oder Arduino UNO, vielleicht auch dem Raspberry Pi gesammelt hat, sollte hier einsteigen. Man erfährt mehr über die innere Struktur von Controllern, warum sie so arbeiten, wie sie es tun und ist nicht mehr auf fremde Bibliotheken angewiesen, wenn es um die Steuerung bestimmter Bauteile geht.
Programmiert wird vorrangig in ASSEMBLER und C. Die Möglichkeiten von AVR Studio, quasi hinter die Kulisse eines Programmes zu schauen, werden genutzt und gezeigt. Sehr hilfreich - aber nicht unbedingt notwendig - ist, wenn man vorher die Kapitel AVR-Assembler - Teil 0 durchgearbeitet hat.
In diesem Kapitel wird ausschließlich mit einem Kanda STK200 Board und AVR Studio 4.19 gearbeitet. Das Board besticht durch seinen günstigen Preis und die auf der Platine vorinstallierten Elemente (Taster, LEDs, Potentiometer, ADC etc.). Programmiert wird ein 40-poliger ATmega 8515 über einen ebenfalls zum Kit gehörenden ISP-Programmer. Alternativ kann auch ein AVR Dragon eingesetzt werden. Dazu später mehr. Zusätzlich wird ein Schaltnetzteil von 9V DC, 1000 mA benutzt.
AVR Studio in der Version 4.19 wurde deshalb gewählt, weil es schnell und nicht so überfrachtet ist, wie die neueste Studioversion aus dem Hause ATMEL. Es ist kostenfrei aus dem Internet herunterladbar und muss für die Durchführung der Übungen auf einem PC oder Laptop installiert sein. Gleiches gilt für den ISP2-Programmer.
Statt des ISP2-Programmers wird an anderer Stelle auch gezeigt, wie man den AVR-Dragon mit dem Board nutzen kann und welche zusätzlichen Möglichkeiten sich dadurch ergeben.
Einige Eigenschaften des ATmega8515 und ATmega16
In einer ersten Übung wird ein sehr einfaches Assemblerprogramm geschrieben, das nur eine bestimmte LED auf der Bargraf-Anzeige des STK200 einschaltet. Das kurze Programm dient dazu, sich mit der Oberfläche von AVR Studio vertraut zu machen, den Workflow kennenzulernen und mit Begriffen wie OP-Code, Fetch und Execute Zyklus sowie Stromsenke und Stromquelle etwas mehr anfangen zu können.
Was man wissen sollte - Schreibweise von Zahlen
Bei der Darstellung von Zahlen muss das zugrunde liegende Zahlsystem (binär, hexadezimal, dezimal, ...) angegeben werden. Durchgesetzt haben sich verschiedene Schreibweisen:
Zahlsystem | Schreibweisen | Präfix/Suffix |
Binärsystem |
0b00011010 %00011010 00011010b |
Präfix Präfix Suffix |
Hexadezimalsystem |
0x0A $0A 0Ah |
Präfix Präfix Suffix |
Dezimalsystem |
11010 | ohne Präfix oder Suffix |
Eine LED zum Leuchten bringen (Assembler) | |
Material |
|
Aufgaben |
|
Den Quellcode übersetzen | |
Aufgaben |
|
Programmlisting anlegen | |
Aufgaben |
|
Aufgaben |
|
Programm in den Controller brennen | |
Aufgaben |
|
Das Programm LEDein.asm
Wie arbeitet das Programm LEDein.asm?
Zwischen .nolist und .list wird die Beschreibungsdatei für den im Programm benutzten Controller – hier ist es ein ATmega 8515 - aufgerufen.
In der folgenden Zeile taucht eine erste I/O Bit Instruction auf. Ihre Syntax setzt sich zusammen aus einem Operationscode (SBI -> Set Bit in I/O Register) sowie einer Adresse im I/O Adressierraum (DDRB - Data Direction Register B) mit Angabe des Zielbits (PB0). PB0 im DDRB wird HIGH (Set Bit) und damit Ausgang.
Nach dem gleichen Muster ist der folgende Befehl aufgebaut (CBI -> Clear bit in I/O Register).
Die erste Instruction setzt im Datenrichtungsregister den Portpin PB0 auf Ausgang und mit der zweiten Instruction wird Pin B0 auf 0 gesetzt. Die mit PB0 verbundene LED der Bargraf-Anzeige beginnt daraufhin zu leuchten.
Fetch-Execute Zyklus
Ein Programm besteht immer aus zwei Teilen: einem Operationscode (kurz: OP-Code) und einem Operanden, der vom OP-Code benötigt wird, um eine Anweisung sachgerecht ausführen zu können.
Der OP-Code und der Operand werden bei einem Atmel-Mikrocontroller mit zwei Systemtakten (s. Datenblatt, S.242 - Bit Instructions)
Diese Vorgänge wiederholen sich, bis alle OP-Codes abgearbeitet worden sind.
Warum leuchtet die LED an PB0 auf?
Um das verstehen zu können, muss man etwas über die innere Beschaltung der Portpins eines ATmega-Controllers wissen. Die Treibereigenschaften der Ausgänge eines Mikrocontrollers werden in seinem Datenblatt beschrieben. Je nach äußerer Beschaltung wirkt ein Pinport als Stromsenke oder Stromquelle, je nachdem, ob der Strom von einer externen Energiequelle über die LED in den Portpin des Controllers oder vom Controller über die LED nach GND fließt.
Wirkt ein Pinportausgang wie eine Stromsenke, dann leuchtet eine LED genau dann, wenn der Ausgang auf LOW gezogen wird (active low). Dafür verantwortlich ist bei einem Controller ein intern verbauter Transistor. Ein anderer Transistor wird eingeschaltet, wenn der Pinport auf HIGH gelegt wird.
Zum Abschluss der ersten Übung noch eine kurze Bemerkung zur Speicherorganisation.
Die Speicherorganisation eines ATmega8515
Für jeden Mikrocontroller stehen im zugehörigen Datenblatt des Herstellers Informationen über Typ, Größe und Ansprechbarkeit der jeweils implementierten Speicher. Ein ATmega 8515 verfügt über drei verschiedene Speichertypen:
Die 32 Register werden von der ALU wie Akkumulatoren benutzt.
Der I/O Registerraum ist reserviert für den Zugriff spezieller Funktionen der Mikrocontroller-Einheit. Die geläufigsten I/O Register sind:
Die Ein- und Ausgänge
Der ATmega8515 verfügt über 35 Ein- und Ausgänge, die in sogenannten Ports A, B, C und D mit je 8 sowie E mit 3 Anschlüssen organisiert sind.
Auf jeden Port kann mit drei Registern des I/O Adressraumes zugegriffen werden: DDRx, PORTx und PINx. x steht dabei für einen Buchstaben aus der Menge A ... E.
Data Direction Register (DDRx)
Für jeden Port muss bitweise festgelegt werden, welcher Pin als Ausgang ( HIGH oder 1) und welcher aus Eingang (LOW oder 0) vorgesehen ist.
Port Register (PORTx)
Dieses Register muss in einem Programm angesprochen werden, wenn der Mikroprozessor etwas nach "draußen" mitteilen möchte. In unseren Beispielen werden es sehr häufig LEDs sein, die ein- oder ausgeschaltet werden.
Pin Register (PINx)
Über dieses Register werden die Eingänge angesprochen, über die Daten an den Controller übertragen werden.
Code-, Daten- und EEPROM-Segment
Damit ein Mikrocontroller das macht, was von ihm gefordert wird, muss ihm detailliert mitgeteilt werden, was er tun soll. Der
Assembler-Programmierer übernimmt diese Aufgabe. Er schreibt Anweisungen so, das der Assembler anschließend genau das macht, was vorgegeben ist.
Beispiel
Aufgabe: Die Zahlen 47 und 11 vom Typ Byte sollen erzeugt werden.
Lösung:
; die Direktive .db
(define byte) macht genau dies. Direktiven beginnen immer mit einem Punkt (.).
; die Direktive .dw (define word) erzeugt ein 16-Bit Wort. 2863 des Zehnersystems entspricht einer
; Zahl 0x0B2F im 16-System. Word-Daten werden immer in umgekehrter Byteanordnung
; (little-endian order) assembliert; das erste Byte steht also immer am Ende.
; beide Direktiven erzeugen das gleiche Ergebnis
Nachdem die Bytes erzeugt wurden, muss angeben werden, wo diese im Speicherbereich abgelegt werden sollen. Dabei gibt es eine Konvention:
In dem folgenden kleinen Programm wird gezeigt, wie der Assembler das eben Gesagte umsetzt. Gib dazu im Editor des AVR
Studio die folgenden Programmzeilen ein:
.CSEG
.DB 0x2F, 0x0B
.DW 2863
.ESEG
.DB $A0, $0B
.DSEG
.byte 10
Nach dem Assemblieren (F7) werden im Projektfenster "Project" die Dateien *.EEP, *.HEX, *.LST und *.MAP angelegt. Am Ende der MAP-Datei wird eine Übersicht über die Speichernutzung gegeben.
Das zu diesem Programm zugehörige Maschinensprache-Programm wird vom Assembler in zwei Dateien mit den Suffixen *.HEX und *.EEP abgelegt. In der HEX-Datei findet man die Bytes 0x2F und 0x0B in Zeile 2 gleich zweimal. Das liegt daran, dass das Wort 2863 als Hexadezimalzahl ebenfalls die Darstellung 0x0B2F hat (little-endian-order).
In der EEP-Datei erscheinen die beiden Bytes 0xA0 und 0x0B in der ersten Zeile.
In diesem Abschnitt wird gezeigt, wie man zwei Zahlen addiert. Als optische Hilfe wird die Bargraf-Anzeige genutzt. Wer nicht (mehr) vertraut ist mit dem binären Zahlsystem, sollte sich das vorher noch einmal anschauen. Insbesondere, wie zwei Dualzahlen addiert, subtrahiert und multipliziert werden.
Bevor es an die Programmierarbeit geht, wird erst einmal das Datenblatt des ATmega8515 befragt. Gib eine Antwort auf die folgenden beiden Fragen:
Antworten:
Es sind über 10 OP-Codes im Datenblatt zu finden.
Ein Operation Code für die Division ist nicht angegeben.
Addition zweier 8-Bit Zahlen | |
Material |
|
Aufgaben |
|
Schaltungsaufbau
Hat man kein STK200 Board zur Verfügung, lässt sich die Schaltung auf einem Steckbrett aufbauen.
Das Programm rechnen1.asm
Wie arbeitet das Programm rechnen1.asm?
Über das in AVR-Studio integrierte Hilfe-Menü (Help - Assembler Help) lassen sich zu allen hier benutzten Operanden-Codes umfangreiche Hilfetexte mit Programmbeispielen aufrufen. Eine weitere Besprechung der Wirkungsweise dieser Operanden entfällt deshalb.
Mit 8-Bit lassen sich nur Zahlen von 0 bis 255 (0b1111_1111) darstellen. Was ist zu beachten, wenn zwei Zahlen - größer als 8-Bit - addiert werden sollen? Das wird in Übung 3 untersucht. Mit 16-Bit lassen sich Zahlen zwischen 0 und 65.535, mit 32-Bit zwischen 0 und 4.294.967.294 darstellen.
Die Addition zweier 16-Bit Zahlen verläuft im Prinzip wie die von zwei 8-Bit Zahlen. Es werden zuerst die lower Bytes und anschließend die higher Bytes mit Carry addiert. Fertig.
Das Addieren mit Carry wird über ADC, das Addieren ohne Carry mit ADD aufgerufen. Ein Ablaufplan oder Pseudocode könnte so aussehen:
Addition von zwei 16-Bit Zahlen | |
Material |
|
Aufgaben |
|
Schaltungsaufbau
wie in Abb. 4a.
Das Programm rechnen2.asm
Wie arbeitet das Programm rechnen2.asm?
Wenn man das Prinzip verstanden hat, dann ist die Addition von beliebig großen Zahlen mit Assembler möglich und einfach durchzuführen. Im vorliegenden Beispielprogramm der Übung 3 werden die beiden Zahlen
miteinander addiert. Die Summe ist: 51117 oder 0b1100_0111_1010_1101. Die rot markierten acht Bit stehen für das Highbyte, die blauen acht Bit für das Lowbyte. Dreht man das STK200-Board um 90° nach rechts, so dass die Bargraf-Anzeige horizontal liegt, kann man die entsprechende Bitkonfiguration unmittelbar ablesen (Abb. 6).
Im diesem Abschnitt wurden die Op-Codes
und die Direktiven
eingeführt.
Im folgenden Abschnitt wird gezeigt, wie man den Zustand eines Tasters abfragt. Interessiert? Dann geht es hier weiter mit AVR Studio - Teil 2.