Fachbereich VI - Informatik und Medien Technische Informatik Bachelor Prof. Dr.-Ing. Sven-Hendrik Voß

Maschinenorientierte Programmierung

(136012/3)

Skript zur Vorlesung

Autor: Prof. Dr. Sven-Hendrik Voß

14. Januar 2018 - vollst¨andige und korrigierte Version Vorwort und Erl¨auterungen

Vorwort Das vorliegende Skript dient als Grundlage fur¨ die Vorlesung Maschinenorientierte ” Programmierung“ im zweiten Semester des Bachelor-Studiengangs Technische Infor- ” matik Embedded Systems“ an der Beuth Hochschule fur¨ Technik Berlin. Es dient als Referenz fur¨ die in der Vorlesung behandelten Themenbereiche, deckt aber nicht alle pe- ripheren Themengebiete ab. Es ist eine reine Vorlesungsausarbeitung, kein Lehrbuch. Entsprechend ist es sprachlich eher knapp gehalten und inhaltlich sicher an einigen Stellen weit weniger umfangreich als es ein entsprechendes Lehrbuch. Ich hoffe, dass es trotzdem den Studierenden bei der Vor- und Nachbereitung des seminaristischen Unterrichts, sowie der Prufungsvorbereitung¨ hilfreich sein wird. Es gilt zu beachten, dass dieses Skript keinesfalls den Vorlesungsbesuch ersetzt. Dieses Skript stellt nur einen Teil der Unterlagen fur¨ die Vorlesung Maschinenorien- ” tierte Programmierung“ dar. Zus¨atzlich werden Kopien der Folien aus der Vorlesung, sowie ausgew¨ahlte Dokumente zum Labor (Befehlsliste 8051 Mikrocontroller, Hinwei- se zur Assembler-Programmierung, Datenbl¨atter, Schaltpl¨ane und Handbucher)¨ zur Verfugung¨ gestellt. Vorlesung und Laborubungen¨ sind aufeinander abgestimmt, wo- bei die praktischen Ubungen¨ der Vertiefung des im Unterricht vermittelten Wissens dienen. Die Laborubungen¨ werden in der Regel mit dem Simulator EdSim simuliert und mit Hilfe eines Software-Entwicklungssystems fur¨ Mikrocontroller der Serie 51 (MC- Tools) auf die Hardware gebracht. Die Handhabung der Software (z.B. EdSim, MC- Tools) muss der Studierende mit Eigenengagement bewerkstelligen. Im Internet gibt es dazu eine Vielzahl von Anleitungen. Viele der Tools beinhalten Kompendien und Ubungsbeispiele.¨ Die Vorlesung vermittelt Ihnen Fachwissen, keine Skills! Zum Inhalt: Die Vorlesung Maschinenorientierte Programmierung“ baut inhaltlich auf ” der Veranstaltung Grundlagen digitaler Systeme“ auf. So wird empfohlen, die dort ver- ” mittelten Stoffinhalte - insbesondere die der Zahlendarstellungen, Rechnerarithmetik und Booleschen Algebra - vor Teilnahme an dieser Veranstaltung zu wiederholen. Auch die empfohlene Fachliteratur ist zur Vertiefung heranzuziehen. Es sei auch noch auf einen weiteren Aspekt hingewiesen. Bei den Kenntnissen der technischen Informatik - insbesondere im Bereich der Digitaltechnik, Programmierung von Mikroprozessoren, Methoden der Algebra, etc. - kommt es fur¨ angehende Inge- nieurinnen und Ingenieure bzw. Informatiker(innen) nicht nur auf das Verst¨andnis der theoretischen Zusammenh¨ange an, sondern insbesondere auf das zuverl¨assige Verste- hen und Bearbeiten von Ubungsaufgaben.¨ Im Rahmen von Unterrichts-, Klausur-, so- wie Laborvor- und -nachbereitungen empfiehlt es sich, ausreichend Ubungsaufgaben¨ zu bearbeiten. So kann aktiv die Ubertragung¨ der Theorie auf die Anwendung geubt¨ und bearbeitungstechnische Routine erlangt werden. Zur Form: Es hat sich im Sprachgebrauch etabliert, die englischen Fachbegriffe zu ver-

Beuth Hochschule fur¨ Technik Berlin II Prof. Dr.-Ing. Sven-Hendrik Voß wenden. Teilweise macht eine deutsche Ubersetzung¨ keinen Sinn oder ist nicht m¨oglich. Sind deutsche Fachbegriffe vorhanden, so werden diese verwendet. Der englische Ter- minologie wird meist in Klammern erg¨anzt oder kursiv hervorgehoben. Das vorliegende Skript basiert auf Fachliteratur und teilweise auf im Internet verfugbaren¨ Unterlagen. Es ist nicht m¨oglich alle Quellen im Detail zu benennen. An dieser Stelle sei den Kol- legen, Autoren und Helfern gedankt, die benannt oder unbenannt zum Gelingen dieses Skriptes beigetragen haben.

Der Text des Skriptums wurde naturlich¨ mit LATEX geschrieben. Eingesetzt wurde die integrierte Benutzeroberfl¨ache TeXnicCenter 2.0 Alpha 3 zusammen mit TeX Live 2010 unter MS Windows, sowie die Editoren TeXShop und iTeXMac in Verbindung mit MacTeX unter Mac OS. Verbesserungsvorschl¨age, Hinweise auf Fehler und jedwede qualifizierte Kritik sind will- kommen. Berlin, im September 2012 Sven-Hendrik Voß

Hinweis Die Informationen in diesem Dokument werden ohne Rucksicht¨ auf einen eventuellen Patentschutz ver¨offentlicht. Die erw¨ahnten Soft- und Hardware-Bezeichnungen k¨onnen auch dann eingetragene Warenzeichen sein, wenn darauf nicht besonders hingewiesen wird. Sie geh¨oren den jeweiligen Warenzeicheninhabern und unterliegen gesetzlichen Bestimmungen. Das Skript wurde mit gr¨oßter Sorgfalt erstellt und korrigiert. Den- noch k¨onnen Fehler und Ungenauigkeiten nicht ausgeschlossen werden. Fur¨ fehlerhafte Angaben oder gar deren Folgen wird keine juristische Verantwortung oder irgendeine Haftung ubernommen.¨

Beuth Hochschule fur¨ Technik Berlin III Prof. Dr.-Ing. Sven-Hendrik Voß Voraussetzungen • Grundlagen digitaler Systeme • Programmieren I

Lehrinhalt und Lernziele Das vorliegende Skript erg¨anzt die Vorlesung Maschinenorientierte Programmierung“. ” In dieser Veranstaltung steht die Funktionsweise von Mikrocontrollern und ihren Schnittstellen, sowie der Entwurf und die Programmierung von Systemen mit Mikro- controllern im Mittelpunkt. Voraussetzungen fur¨ die Veranstaltung sind im wesentli- chen die Grundlagen digitaler Systeme, sowie Kenntnisse im Programmieren (und nicht zuletzt Ihr Interesse an der Thematik). Lehrinhalt: 1. Rechnerarchitektur, Harvard- und von-Neumann-Architektur 2. Architektur eines einfachen realen Prozessors anhand eines 8051 Mikrocontrollers 3. Instruktionsverarbeitung 4. Programmierung in Assembler 5. Befehlssatz - arithmetische und logische Befehle 6. Adressierungsarten 7. Steuerbefehle: Sprungbefehle und Unterprogrammaufrufe 8. Programmstrukturierung: Flussdiagramm, strukturierte Programmierung 9. Hardware-/Softwareschnittstellen 10. Assemblerdirektiven 11. Aufbau und Programmierung einfacher I/O-Schnittstellen (Parallele/Serielle Schnittstellen) 12. -Programmierung (Hard- und Software-, Interrupt-Vektor- Tabelle, Interrupt-Service-Routinen) 13. Einfuhrung¨ in die hardwarenahe Programmierung in C

Beuth Hochschule fur¨ Technik Berlin IV Prof. Dr.-Ing. Sven-Hendrik Voß Nach der Lehrveranstaltung sollten Sie in der Lage sein, reale Mikrocontrollerapplika- tionen auf Assemblerebene entwerfen, implementieren und testen zu k¨onnen. Sie ler- nen den Umgang mit g¨angiger Prozessorperipherie, I/O-Schnittstellen und Ans¨atze fur¨ Echtzeit- und Interrupt-Programmierung. Schließlich sollten Sie die Kompetenz erlangt haben, die Leistungsf¨ahigkeit einer Architektur und den Aufwand einer gegebenen Pro- blemstellung auf der Ebene der maschinennahen Programmierung abzusch¨atzen und zu beurteilen welchem Aufwand eine gegebene Implementierung in einer Hochsprache auf der Maschinenebene entspricht.

Skripte, Bucher¨ etc. Prof. Dr.-Ing. Sven-Hendrik Voß: Folien und Skript

1. M. Mazidi, J. Mazidi, R. McKinlay: The 8051 and Embedded Systems Using Assembly and C, Prentice Hall, ISBN 013119402X 2. I. Scott MacKenzie, Raphael Chung-Wei Phan: The 8051 Microcontroller (4th Edition), Pearson, ISBN 0132059754 3. Rolf Klaus: Die Mikrokontroller 8051, 8052 und 80C517, Vdf Hochschulverlag, ISBN 3728132594 4.J urgen¨ Walter: Mikrocomputertechnik mit der 8051-Controller-Familie, Springer, ISBN 354066758X 5. Thomas Flik: Mikroprozessortechnik und Rechnerstrukturen, Springer, ISBN 3540222707 6. Klaus Wust:¨ Mikroprozessortechnik, Vieweg und Teubner, ISBN 9783834804617 7. Uwe Brinkschulte: Mikrocontroller und Mikroprozessoren, Springer, ISBN 9783540430957 8. David A. Patterson, John LeRoy Hennessy: Rechnerorganisation und Rechner- entwurf, Oldenbourg, ISBN 3486591908 9. Helmut Malz: Rechnerarchitektur - Eine Einfuhrung¨ fur¨ Ingenieure und Informa- tiker, Vieweg und Teubner, ISBN 3528133791 10. Paul Herrmann: Rechnerarchitektur - Aufbau, Organisation und Implementie- rung, inklusive 64-Bit-Technologie und Parallelrechner, Vieweg und Teubner, ISBN 3834815128 11. Andrew S. Tanenbaum: Computerarchitektur, Pearson, ISBN 9783827371515 12. Klaus Beuth: Digitaltechnik, Vogel Buchverlag, ISBN 3834330841

Beuth Hochschule fur¨ Technik Berlin V Prof. Dr.-Ing. Sven-Hendrik Voß Links im Netz Im Netz finden sich zahlreiche Links zur Assemblerprogrammierung und dem 8051 Mikrocontroller. Hier nur eine kleine Auswahl: • http://www.self8051.de/ • http://www.8052.com • http://www.goblack.de/desy/mc8051chip/

• http://www.ipd.uka.de/~buchmann/microcontroller/ • http://mikrocontroller.rahm-home.de/8051.htm • http://www.controllersandpcs.de • http://et-tutorials.de/Mikrocontroller/ Empfohlene Hilfsmittel und Software: • EdSim51 (kostenloser 8051 Simulator) • Asem-51 (kostenloser Macro-Assembler) • MC-51 Vers. 5.5 (IDE fur¨ Asem-51) • Eclipse (IDE zur Entwicklung von Software) • PL2303 Prolific USB-Seriell-Adapter Treiber

Beuth Hochschule fur¨ Technik Berlin VI Prof. Dr.-Ing. Sven-Hendrik Voß Inhaltsverzeichnis

Abbildungsverzeichnis XV

Tabellenverzeichnis XVII

1 Einfuhrung¨ 1 1.1 Ubersicht¨ ...... 1 1.2 Technische und mathematische Grundlagen ...... 3 1.2.1 Zahlensysteme ...... 4 1.2.2 Komplementdarstellung ...... 6 1.2.3 Zahlencodierung ...... 8 1.2.4 Zeichencodierung ...... 9 1.2.5 Fehlererkennung ...... 12 1.2.6 Elementare Logikverknupfungen¨ ...... 13

2 Grundlagen der Rechnerarchitektur 16 2.1 Definition und Grundkonzept ...... 16 2.2 Aufbau und Struktur ...... 19 2.2.1 Speicherhierarchie ...... 20 2.2.2 Ein- und Ausgabewerk ...... 23 2.2.3 Operationswerk ...... 23 2.2.4 Steuerwerk ...... 24 2.2.5 Speicherwerk ...... 25 2.2.6 Bussysteme ...... 26 2.3 Architekturuberblick¨ ...... 27 2.3.1 Schema eines einfachen Rechners ...... 28 2.3.2 Architekturrealisierungen ...... 30

3 Befehlsausfuhrung¨ und Organisationsprinzipien 32 3.1 Typische externe Architekturen ...... 32 3.1.1 Akkumulator-Maschine ...... 33 3.1.2 Stack-Maschine ...... 34 3.1.3 Registersatz-Maschine ...... 35 3.2 Befehlsausfuhrung¨ ...... 38 3.3 Beschleunigung der Befehlssausfuhrung¨ ...... 42 3.4 Befehlsausfuhrung¨ bei Mikrocontrollern ...... 46

VII Inhaltsverzeichnis

4 Adressierungsarten und Maschinenprogrammierung 48 4.1 Speicherorganisation ...... 48 4.1.1 Alignment des Speichers ...... 48 4.1.2 Grundlagen der Adressraumverwaltung ...... 50 4.1.3 Adressraum bei von-Neumann ...... 52 4.1.4 Adressraum bei Harvard ...... 52 4.2 Adressierungsarten ...... 54 4.2.1 Unmittelbare Adressierung ...... 56 4.2.2 Register-Addressierung ...... 56 4.2.3 Direkte Adressierung ...... 56 4.2.4 Register-indirekte Adressierung ...... 57 4.2.5 Indizierte Adressierung ...... 58 4.3 Maschinenprogrammierung ...... 59 4.3.1 Rechnerarchitektur und Programmierung ...... 59 4.3.2 Maschinensprache und maschinennahe Sprache ...... 63 4.3.3 Abgrenzung zu h¨oheren Sprachen und PC-Programmierung . . . 64 4.3.4 Arbeiten mit Assembler ...... 65 4.3.5 Vom Assemblerprogramm zum Maschinenprogramm ...... 67 4.3.6 Platzierung von Programmen im Speicher ...... 71 4.3.7 Programmentwicklung ...... 73

5 8051 Mikrocontroller-System 76 5.1 Prozessorarten ...... 76 5.2 Controller- und Prozessorfamilien ...... 78 5.3 Eigenschaften der 8051 Architektur ...... 79 5.4 Aufbau des 8051 Mikrocontrollers ...... 80 5.5 Programmiermodell des 8051 Mikrocontrollers ...... 82 5.5.1 Abbildung der Register im internen RAM ...... 83 5.5.2 Software-bezogene Register des Programmiermodells ...... 87 5.5.3 Hardware-bezogene Register des Programmiermodells ...... 90 5.6 Speichermodell des 8051 Mikrocontrollers ...... 93 5.6.1 Programmspeicher des 8051 ...... 95 5.6.2 Datenspeicher des 8051 ...... 96 5.6.3 Stack-Konzept des 8051 ...... 97

6 Programmierung und Einsatz 100 6.1 Adressierungsmodi der 8051 CPU ...... 100 6.2 Assemblernotation fur¨ die 8051 CPU ...... 102 6.2.1 Transferbefehle ...... 105 6.2.2 Bitverarbeitungsbefehle ...... 108 6.2.3 Befehle zur logischen Verknupfung¨ ...... 109 6.2.4 Arithmetische Verarbeitungsbefehle ...... 112 6.2.5 Sprungbefehle ...... 114 6.2.6 Unterprogrammbefehle ...... 117 6.2.7 Sonstige Befehle ...... 121

Beuth Hochschule fur¨ Technik Berlin VIII Prof. Dr.-Ing. Sven-Hendrik Voß Inhaltsverzeichnis

6.2.8 Assemblerdirektiven ...... 121 6.3 Modi und Pinout des 8051 ...... 124 6.3.1 8051 im Prim¨armodus ...... 124 6.3.2 8051 im Sekund¨armodus ...... 125 6.3.3 Prozessorbus im Sekund¨armodus ...... 127

7 Funktionsgruppen der Peripherie und Steuerung 136 7.1 Interrupt-Programmierung ...... 136 7.1.1 Polling und Interrupt ...... 136 7.1.2 Prinzip der Interrupt-Behandlung ...... 139 7.1.3 Zeitlicher Ablauf eines Interrupt ...... 141 7.1.4 Interrupt-Vektortabelle ...... 142 7.1.5 Interrupt SFR ...... 145 7.1.6 Interrupt Priorit¨aten ...... 152 7.2 Timer-Programmierung ...... 154 7.2.1 Betriebsarten von Timer und Counter ...... 155 7.2.2 Funktionsweise ...... 155 7.2.3 Timer SFR ...... 158 7.2.4 Programmierung des Timers ...... 162 7.2.5 Beeinflussung der Zeitintervalle beim Timer ...... 165 7.3 Aufbau und Programmierung der seriellen Kommunikationsschnittstelle 169 7.3.1 Grundbegriffe der Datenkommunikation ...... 169 7.3.2 Ubertragungsmethoden¨ ...... 173 7.3.3 Betriebsarten der seriellen Schnittstelle ...... 177 7.3.4 SFR fur¨ die serielle Schnittstelle ...... 179 7.3.5 Empfangen und Versenden von Daten ...... 182 7.3.6 Programmierung des seriellen Schnittstelle ...... 184 7.3.7 Erzeugung der Baudrate ...... 185

8 Hardwarenahe Programmierung in C 193 8.1 Die Programmiersprache C ...... 193 8.1.1 Gegenuberstellung¨ von C und Assembler ...... 194 8.1.2 Systemn¨ahe von C ...... 194 8.1.3 Operatoren in C ...... 195 8.1.4 Datentypen in C ...... 197 8.1.5 C Programmaufbau fur¨ Mikrocontroller ...... 199 8.2 Programmierung des 8051 mit C ...... 201 8.2.1 Auswahl des richtigen Compilers ...... 201 8.2.2 Verwendung von Special Function Registern ...... 202 8.2.3 Ein- Ausgabeoperationen in C ...... 203 8.2.4 Timer-Programmierung ...... 205 8.2.5 Interrupt-Steuerung ...... 207 8.2.6 Ansteuerung der RS232-Schnittstelle ...... 209 8.2.7 Inline-Assembler ...... 210

Beuth Hochschule fur¨ Technik Berlin IX Prof. Dr.-Ing. Sven-Hendrik Voß Inhaltsverzeichnis

9 Multitasking mit dem 8051 212 9.1 Idee und Zweck des Multitasking ...... 212 9.1.1 Konzept des Multitasking ...... 213 9.1.2 Schedulingalgorithmen ...... 213 9.2 Multitasking auf dem 8051 ...... 215 9.3 Multitasking mit Kontextwechsel ...... 223

10 Ausblick 225 10.1 Mikrocontroller-Plattformvarianten ...... 225 10.1.1 Wahl der Zielplattform ...... 225 10.1.2 Ubersicht¨ g¨angiger Mikrocontroller ...... 226 10.2 Rekonfigurierbare Hardware als Alternative ...... 226 10.2.1 Unterschiede im Entwurf ...... 227 10.2.2 Designentscheidungen im Co-Design ...... 228

Literatur 230

Beuth Hochschule fur¨ Technik Berlin X Prof. Dr.-Ing. Sven-Hendrik Voß Abbildungsverzeichnis

2.1 Externe und interne Architektur eines Rechners ...... 17 2.2 Schlusselrolle¨ des Befehlssatzes ...... 18 2.3 Interne Architektur eines Rechners ...... 20 2.4 Speicherhierarchie in einem Rechner ...... 21 2.5 Ein- und Ausgabewerk ...... 23 2.6 Operationswerk ...... 24 2.7 Speicherwerk ...... 25 2.8 Zusammenwirken von CPU, Speicher und Peripherie ...... 27 2.9 Systemarchitektur mit Systembus ...... 28 2.10 Schema eines einfachen Rechners ...... 29 2.11 Vereinfachtes Rechnerschema ...... 30 2.12 von Neumann-Architektur ...... 30 2.13 Harvard-Architektur ...... 31

3.1 Einfache Addition in einer Akkumulator-Maschine ...... 34 3.2 Einfache Addition in einer Stack-Maschine ...... 35 3.3 Struktur einer Registersatz-Maschine ...... 36 3.4 CISC-Architekturprinzip ...... 37 3.5 RISC-Architekturprinzip ...... 38 3.6 Befehlsformat ...... 39 3.7 Zustand aller Operanden vor der Addition ...... 39 3.8 Zustand aller Operanden nach der Addition ...... 40 3.9 Struktur des Prozessors mit allen beteiligten Registern ...... 40 3.10 Phasen des Befehlszyklus ...... 42 3.11 Zyklushierarchien ...... 43 3.12 Befehlszyklus ...... 43 3.13 Befehlsverarbeitung ohne Optimierung ...... 44 3.14 Methoden zur Beschleunigung ...... 44

4.1 Struktur eines Speichers ...... 48 4.2 Alignment von Daten im Speicher ...... 49 4.3 Konventionen der -Reihenfolge ...... 49 4.4 von Neumann-Architektur im Detail ...... 50 4.5 Harvard-Architektur im Detail ...... 50 4.6 Organisation eines Stack ...... 51 4.7 Adressraum bei von Neumann ...... 52 4.8 Adressraum bei von Neumann mit Zeigern ...... 53

XI Abbildungsverzeichnis

4.9 Adressraum bei Harvard ...... 53 4.10 Harvard-Adressraum beim 8051 Mikrocontroller ...... 54 4.11 Beteiligte Komponenten fur¨ die Adressierung ...... 55 4.12 Unmittelbare Adressierung ...... 56 4.13 Register-Addressierung ...... 57 4.14 Direkte Addressierung ...... 57 4.15 Indirekte Addressierung ...... 58 4.16 Indizierte Addressierung ...... 58 4.17 Zusammenfassung zu Addressierungsarten ...... 59 4.18 Hierarchie von Programmiersprachen ...... 60 4.19 Programmierung auf verschiedenen Abstraktionsebenen ...... 60 4.20 Von der Hochsprache zum Maschinencode ...... 62 4.21 Programmbeschreibungen gegenubergestellt¨ ...... 63 4.22 Inhalt einer LST-Datei (List) ...... 66 4.23 Einfaches Assembler-Projekt ...... 66 4.24 Umfangreiches Assembler-Projekt ...... 67 4.25 Auszug aus Befehlsliste fur¨ den 8051 ...... 68 4.26 Beispiel Assemblerbefehl JB (Jump If Bit Is Set) ...... 69 4.27 Assemblerdirektiven im EdSim ...... 70 4.28 Ablauf der Programmentwicklung ...... 73 4.29 Elementare Konstrukte eines Flussdiagrams ...... 74 4.30 Praxisbeispiel eines Flussdiagrams ...... 75

5.1 Schematische Darstellung eines Mikroprozessors ...... 77 5.2 Schematische Darstellung eines Mikrocontrollers ...... 77 5.3 Verh¨altnis von Maschinen- zu Taktzyklen ...... 80 5.4 Aufbau des 8051 ...... 81 5.5 Programmiermodell des 8051 ...... 82 5.6 Einheitliche Darstellung von Registern ...... 83 5.7 Aufteilung des internen RAM ...... 84 5.8 Detailansicht Registerb¨anke im internen RAM ...... 84 5.9 Adressen der Registerbank-Register ...... 85 5.10 Detailansicht Special-Function-Register ...... 86 5.11 Adressen der Special-Function-Register ...... 87 5.12 Flags des Program Status Word ...... 88 5.13 Port-Bit-Zuordnung am Beispiel des Port 0 ...... 91 5.14 Interne Schaltung der Ports ...... 92 5.15 Uberlappende¨ Adressr¨aume des 8051 ...... 93 5.16 Adressr¨aume detailliert ...... 94 5.17 Adresszuordnung fur¨ bit- und byteweisen Zugriff ...... 95 5.18 Programmspeicher ...... 96 5.19 Externer Datenspeicher ...... 96 5.20 Internes RAM ...... 98 5.21 Beispiel einer Stackoperation mittel Stackpointer (SP) ...... 99

Beuth Hochschule fur¨ Technik Berlin XII Prof. Dr.-Ing. Sven-Hendrik Voß Abbildungsverzeichnis

6.1 Syntaxstruktur der 8051 Befehle ...... 103 6.2 Interne Repr¨asentation eines Befehls ...... 103 6.3 Dekodierungsschaltnetz fur¨ den Opcode ...... 104 6.4 Prinzipieller Aufbau von 8051 Assemblercode ...... 105 6.5 Beispiele fur¨ die Anwendung von MOV Befehlen ...... 106 6.6 Anwendung von MOV Befehlen ...... 107 6.7 Varianten der MOV-Befehle ...... 107 6.8 Gultigkeit¨ der Adressierungsformen ...... 108 6.9 Prinzip des Rotate Right (RR) Befehls ...... 109 6.10 Prinzip des Rotate Left (RL) Befehls ...... 110 6.11 Prinzip des Rotate Right Carry (RRC) Befehls ...... 110 6.12 Prinzip des Rotate Left Carry (RLC) Befehls ...... 111 6.13 Beispiel fur¨ die Anwendung des ANL Befehls ...... 111 6.14 Beispiel fur¨ die Anwendung des ORL Befehls ...... 111 6.15 Beispiel fur¨ die Anwendung des XRL Befehls ...... 112 6.16 Beispiel fur¨ die Anwendung des ADD Befehls ...... 112 6.17 Beispiel fur¨ die Anwendung des JZ Befehls ...... 115 6.18 Beispiel fur¨ die Anwendung des JNC Befehls ...... 116 6.19 Schleifen mit Sprungbefehlen ...... 116 6.20 Adressberechnung kurzer Sprunge¨ ...... 118 6.21 Partitionierung eines Programms in Haupt- und Unterprogramme . . . 119 6.22 Ablauf eines Unterprogrammaufrufs ...... 119 6.23 Speicherung der Rucksprungadresse¨ bei einem Unterprogrammaufruf . 120 6.24 Rolle des Stack bei einem Unterprogrammaufruf ...... 121 6.25 Pinbelegung im Prim¨armodus ...... 125 6.26 Pinbelegung im Sekund¨armodus ...... 126 6.27 Anschluß eines externen Programmspeichers beim 8051 ...... 129 6.28 Anschluß eines externen Datenspeichers beim 8051 ...... 130 6.29 Zugriff auf Codespeicher (fur¨ 2-Byte-Befehle) am 8051 ...... 131 6.30 Tats¨achliche Zugriffszeiten beim 8051 (vereinfacht) ...... 132 6.31 Zugriff auf Datenbyte aus externem RAM (Lesezugriff) ...... 133 6.32 Zugriff auf Datenbyte aus externem RAM (Schreibzugriff) ...... 134

7.1 Polling vs. Interrupt-Behandlung ...... 138 7.2 Unterbrechung eines Programms durch Interrupts ...... 141 7.3 Zeitlicher Ablauf eines Interrupt (1) ...... 141 7.4 Zeitlicher Ablauf eines Interrupt (2) ...... 142 7.5 Sprung in Vektortabelle bei aktivem externen Interrupt ...... 144 7.6 Partitionierung des Speichers und Auslagerung der Interrupt Routinen 144 7.7 Ubersicht¨ Interrupt-System des 8051 ...... 145 7.8 Flags des Interrupt Enable Register ...... 146 7.9 Eing¨ange fur¨ externe Interrupts ...... 148 7.10 Zeitliche Rahmenbedingungen fur¨ pegelgetriggerte Interrupts ...... 148 7.11 Triggeroptionen fur¨ die externen Interrupts ...... 149 7.12 Triggermodi fur¨ externe Interrupts ...... 150

Beuth Hochschule fur¨ Technik Berlin XIII Prof. Dr.-Ing. Sven-Hendrik Voß Abbildungsverzeichnis

7.13 Zeitliche Rahmenbedingungen fur¨ flankengetriggerte Interrupts . . . . . 150 7.14 Flags des erweiterten Interrupt Enable Register ...... 151 7.15 Flags des Interrupt Priority Register ...... 152 7.16 Funktion: Zeitgeber (Timer) - Interne Takt z¨ahlen ...... 156 7.17 Funktion: Z¨ahler (Counter) - Externe Pulse z¨ahlen ...... 156 7.18 Steuereing¨ange fur¨ Timer/Counter ...... 157 7.19 Flags des Timer Control Register (oberes Halbbyte hervorgehoben) . . 158 7.20 Flags des Timer Control Register (unteres Halbbyte hervorgehoben) . . 159 7.21 Flags des Timer Modus Register ...... 160 7.22 Konfiguration als 16-Bit Counter/Timer mit relevanten SFRs ...... 161 7.23 Konfiguration als Auto-Reload Counter/Timer mit relevanten SFRs . . 161 7.24 Registerzugeh¨origkeiten fur¨ die Programmierung von Timer/Counter . 162 7.25 Maximale Zeitintervalle mit einem 16-Bit Timer ...... 166 7.26 Erh¨ohung der Zeitintervalle durch Mehrfachaufruf eines 16-Bit Timers . 166 7.27 Generierung von asymmetrischen Rechtecksignalen ...... 167 7.28 Varianten der Datenubertragung¨ ...... 169 7.29 8-Bit breite parallele Datenubertragung¨ ...... 170 7.30 Bitserielle Datenubertragung¨ ...... 170 7.31 Schnittstellenimplementierung auf Controllerboard ...... 171 7.32 Pegelwandlung auf Controllerboard ...... 172 7.33 Physische Ausfuhrung¨ der Schnittstelle ...... 173 7.34 Technische Realisierung einer RS232-Verbindung ...... 174 7.35 Asynchrone Datenubertragung¨ mit einem Start Bit und zwei Stop Bits 175 7.36 Synchrone Ubertragung¨ von Datenbl¨ocken ohne Unterbrechung . . . . . 176 7.37 Beispiel fur¨ zeichenorientierte Ubertragung¨ ...... 176 7.38 Beispiel fur¨ bitorientierte Ubertragung¨ ...... 176 7.39 Modus 0: Schieberegister-Modus ...... 178 7.40 Modus 1: Asynchrone 8-Bit-Datenubertragung¨ ...... 178 7.41 Modus 2: Asynchrone 9-Bit-Datenubertragung¨ ...... 179 7.42 Datenrahmen der asynchronen 9-Bit-Datenubertragung¨ ...... 179 7.43 Flags des Serial Control Register ...... 180 7.44 Serial Buffer Register ...... 181 7.45 Aufbau und Steuerung des seriellen Ports ...... 182 7.46 Beispiel fur¨ Sendevorgang uber¨ seriellen Port ...... 183 7.47 Beispiel fur¨ Empfangsvorgang uber¨ seriellen Port ...... 184 7.48 Baudrate gleich Bitrate ...... 187 7.49 Baudrate ungleich Bitrate ...... 187 7.50 Beziehung zwischen Oszillatorfrequenz und Baudrate (Modi 1 und 3) . 189 7.51 Beziehung zwischen Oszillatorfrequenz und Baudrate mit SMOD Flag . 191 7.52 Flags des Power Control Register ...... 191

8.1 Programm mit eingebundener Header-Datei zur Ausgabe an P1 . . . . 203 8.2 Programm zum Tooglen eines Bits mittels XOR-Operator ...... 205

9.1 Rolle des Schedulers zur Taskumschaltung ...... 214

Beuth Hochschule fur¨ Technik Berlin XIV Prof. Dr.-Ing. Sven-Hendrik Voß Abbildungsverzeichnis

9.2 Beispielapplikation mit drei quasi-parallelen Aufgaben ...... 215 9.3 Task-Steuerung anhand von Ticks ...... 216 9.4 10ms Zeitscheibe mit mehreren Tasks ...... 216 9.5 Steuerung des LED Blinkens anhand von Ticks ...... 218 9.6 Aktualisierung der Zeit anhand von Ticks ...... 220 9.7 Abarbeitung von Tasks mit gespeichertem Kontext ...... 224

10.1 Flexibilit¨at vs. Leistung ...... 227 10.2 Design-Ebenen der unterschiedlichen Implementierungsvarianten . . . . 228 10.3 Design Flow eines HW/SW Co-Design ...... 229

Beuth Hochschule fur¨ Technik Berlin XV Prof. Dr.-Ing. Sven-Hendrik Voß Tabellenverzeichnis

1.1 Bitcodierung ...... 3 1.2 Zahlensysteme ...... 4 1.3 Nennwertzuordnung unterschiedlicher Zahlensysteme ...... 5 1.4 BCD-Code ...... 8 1.5 ASCII Tabelle (0-63) ...... 10 1.6 ASCII Tabelle (64-127) ...... 11 1.7 Bin¨arcode mit Parity ...... 13 1.8 AND-Verknupfung¨ ...... 14 1.9 OR-Verknupfung¨ ...... 14 1.10 XOR-Verknupfung¨ ...... 14

2.1 von-Neumann Rechnerstruktur ...... 29

4.1 Little Endian vs. Big Endian ...... 50 4.2 Adressierungsarten des 8051 Mikrocontrollers ...... 55 4.3 Programmplatzierung im ROM (Beispiel) ...... 71 4.4 Inhalt des ROMs (Beispiel) ...... 72

5.1 Prozessorarten ...... 76 5.2 8051 Derivate (Auswahl) ...... 78 5.3 Auswahl der Registerb¨anke ...... 85 5.4 Flags des PSW ...... 89

6.1 Eigenschaften der Multiplikation beim 8051 ...... 113 6.2 Eigenschaften der Division beim 8051 ...... 113 6.3 Berechnung der Zugriffszeiten ...... 132

7.1 Gegenuberstellung¨ Polling - Interrupts ...... 139 7.2 Interrupt-Vektortabelle des 8051 ...... 143 7.3 Flags des IE ...... 146 7.4 Flags des IEN1 ...... 152 7.5 Flags des IP ...... 153 7.6 Flags des TCON zur Steuerung von Timer/Counter 0 und 1 ...... 158 7.7 Flags des TCON zur Steuerung der externen Interrupts 0 und 1 . . . . 159 7.8 Flags des TMOD zur Steuerung von Timer/Counter 0 und 1 ...... 160 7.9 Pins des Port 3 zur Nutzung fur¨ Timer 0 und 1 ...... 160 7.10 Pinbelegung der DSUB-9 Buchse ...... 173 7.11 Flags des SCON ...... 181

XVI Tabellenverzeichnis

7.12 Auswahl der Schnittstellenmodi ...... 181 7.13 Zusammenhang zwischen Kennzust¨anden und verwendeten Bits . . . . 186 7.14 Programmierung von TH1 in verkurzter¨ Form ...... 189 7.15 Beispiele zur Darstellung mit und ohne Komplement ...... 190 7.16 Flags des PCON ...... 191

8.1 Gegenuberstellung¨ von Assembler und C ...... 194 8.2 Operatoren in C ...... 196 8.3 Operatoren in C (Fortsetzung) ...... 197 8.4 Anwendung logischer Operatoren in C ...... 197 8.5 Datentypen in C ...... 198

9.1 Verwendung von Registern im Programm ...... 217

10.1 Implementierungsvarianten bei unterschiedlicher Komplexit¨at ...... 225

Beuth Hochschule fur¨ Technik Berlin XVII Prof. Dr.-Ing. Sven-Hendrik Voß 1 Einfuhrung¨

1.1 Ubersicht¨

Trotz der Leistungsf¨ahigkeit heutiger Compiler und der Verfugbarkeit¨ der Sprache C ist die Darstellung von Programmen in maschinennaher Form fur¨ bestimmte Anwen- dungen auch heute noch unerl¨aßlich. Nach wie vor werden viele Programme in Assem- bler erstellt, so zum Beispiel im Bereich des Compilerbau, bei eingebetteten Systeme oder fur¨ systemnahe Programmierung in Teilen des Betriebssystems. Die Applikatio- nen reichen von Echtzeitanwendungen uber¨ Betriebssystemanwendungen wie Nach- richtenaustausch, low-level Speicherverwaltung, etc. bis hin zu Spezialanwendungen fur¨ eingebettete Systeme, an die oft harte Effizienzanforderungen gestellt werden, wie z.B. Minimierung von Energieverbrauch, Laufzeit und Speicherplatz und nicht zuletzt Erfullung¨ von Echtzeitbedingungen. Eingebettete Systeme, engl. Embedded Systems, sind in der Praxis nahezu allge- genw¨artig. Sie finden sich in Autos, Waschmaschinen, Fernsehger¨aten, MP3-Spielern, Navigationsger¨aten und Mobiltelefonen. Beispielsweise ist in modernen Autos bereits eine zwei- oder dreistelligen Anzahl von Prozessoren zu finden, die uber¨ einen inter- nen Bus miteinander verbunden sind. Allgemein definiert ist ein eingebettetes System ein elektronisches System, das aus Hardware und Software besteht und in komplexe technische Umgebungen eingebettet ist [Scholz 05]. Als Umgebung versteht man meist ein technisches oder maschinelles System, in dem oder fur¨ das das eingebettete System komplexe Steuerungs-, Regelungs- und Datenverarbeitungsaufgaben ubernehmen.¨ Es dient der Steuerung sowie der Interaktion des Produktes mit seiner Umgebung, sei es anderen technischen Systemen oder dem Benutzer. Das wesentliche Merkmal von ein- gebetteten Systemen ist die enge Verknupfung¨ des Mikrocontrollers/Mikroprozessors mit der umgebenden Maschine. Das Herzstuck¨ jedes eingebetteten Systems sind Mikrocontroller, da sie die Datenakqui- sition und Verarbeitung steuern, regeln oder zumindest unterstutzen.¨ Außerdem bilden sie eine flexible Schnittstelle zu jeder erdenklichen Kommunikation mit dem eingebet- teten System, stellen so z.B. direkt den Datenaustausch uber¨ eine Benutzerschnittstelle bereit oder dienen der Anbindung an ein ubergeordnetes¨ Datenverarbeitungssystem. Ein Mikrocontroller besteht aus mindestens einem Mikroprozessor und weiteren Kom- ponenten wie Speicher und Input/Output (Peripherie). Ein Mikroprozessor ist die mo- nolithisch integrierte Variante eines Prozessors. Unter einem Prozessor versteht man die (CPU) aus dem Von-Neumann-Modell. Bei der Vielzahl an Verwendungen in unterschiedlichsten Umgebungen wird deutlich,

1 KAPITEL 1. EINFUHRUNG¨ dass die Anzahl der Mikrocontroller in eingebetteten Systemen diejenige der Mikropro- zessoren in Rechnern bei weitem ubersteigt.¨ Doch nicht nur das Vorkommen, sondern auch die verbundene Entwurfsmethodik zur Programmierung dieser Prozessoren un- terscheidet sich von herk¨ommlichen Prozessoren, da die Anforderungen an sie vollkom- men anders gewichtet sind. Die in eingebetteten Systemen verwendeten Mikrocontroller verfugen¨ in der Regel uber¨ limitierte Ressourcen hinsichtlich Rechenleistung, Taktfre- quenz (damit Datendurchsatz) und Speicher. Hinzu kommt, dass durch das Einsatzum- feld Randbedingungen gestellt werden, die das eingebettete System erfullen¨ mus. In der Regel fallen darunter niedrige Stromaufnahmen und reduzierte Chipfl¨ache, aber auch Echtzeitverhalten und besondere Zuverl¨assigkeit. Dies stellt besondere Anforderungen an den Entwicklungsprozess und betrifft sowohl Hard- als auch Software. Um die dargelegten eingeschr¨ankten Ressourcen optimal auszunutzen, wird in der Re- gel die Programmierung in Assembler gew¨ahlt. Ein Assemblerprogramm ist in den meisten F¨allen wesentlich kurzer¨ als das entsprechende Pendant in einer Hochschpra- che, da dieses lediglich das Produkt eines Compilers ist. Heutige Compiler erzeugen zwar sehr guten optimierten Code und fur¨ viele Anwendungsf¨alle reicht das auch aus. Wenn jedoch absolute Geschwindigkeit oder die minimale Codegr¨oße gefordert sind gibt es nur eine L¨osung: Assembler. Ein in Assembler geschriebenes Programm ist ef- fizienter, schneller und nutzt die Hardware-Ressourcen besser aus. Ein Manko fur¨ den Einsteiger ist allerdings der Umgang mit dem jeweiligen Befehlssatz des eingesetzten Mikroprozessors / Mikrocontrollers. Jede Mikroprozessor-Architekutr hat ihre eigene Assemblersprache. Ein in Assembler geschriebenes Programm l¨auft nur auf einer Ar- chitektur und kann auf einer anderen nicht ohne weiteres wiederverwendet werden. Diese Vorlesung mit dem Titel Maschinenorientierte Programmierung“ ist als ” Einfuhrung¨ in die Assembler-Programmierung konzipiert und behandelt Grundlagen der Assemblerprogrammierung, die Methodik des Entwurfs solcher Programme und widmet sich schließlich exemplarisch dem Design kleiner Beispielanwendungen am Bei- spiel eines 8-Bit-Mikrocontrollers. 8-Bit-Mikrocontroller stellen die zahlenm¨aßig am h¨aufigsten eingesetzten Mikrocontroller dar und bewegen sich in einem Preissegment von 1 bis 10 e. Sie sind damit h¨aufig billiger als mechanische Komponenten wie Kabel, Steckverbinder usw. Die Angabe 8 Bit“ bezieht sich auf die zugrundegelegte interne ” Datenverarbeitungsbreite. Alle verarbeitungsrelevanten Komponenten, beispielsweise CPU, Register, Adreßbusse oder Datenbusse sind also auf h¨ochstens 8 Bits (1 Byte) ausgelegt. Somit definiert die Angabe 8 Bit“ auch diejenige Breite, die in einem Durch- ” gang berechnet werden kann. In der Vorlesung werden zum einen allgemeine Fakten behandelt, die fur¨ alle Mikro- controller gelten. Zum anderen wird schwerpunktm¨aßig eine konkrete Mikrocontrol- lerfamilie beleuchtet. Wegen der noch immer vorherrschenden großen Bedeutung fur¨ die industrielle Praxis und als typisches Beispiel fur¨ einen 8-Bit-Mikrocontroller wird hier der 8051 Mikrocontroller von herangezogen. Dieser wurde erstmals 1980 am Markt eingefuhrt.¨ Mittlerweile existiert auf dessen Basis eine ganze Familie unter- schiedlicher Mikrocontroller, auch von anderen Herstellern. Diese nennt man Derivate. Derivate sind verschiedene, eigenst¨andige Versionen dieses Original-Mikrocontrollers,

Beuth Hochschule fur¨ Technik Berlin 2 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 1. EINFUHRUNG¨ die sich befehlskompatibel verhalten. In der Klasse der 8-Bit-Mikrocontroller z¨ahlen die Derivate der Intel-8051-Baureihe heute noch zu den am h¨aufigsten eingesetzten. Aus diesem Grund - und weil der 8051 die wesentlichen Bestandteile eines Mikrocon- trollers enth¨alt aber noch nicht zu sehr mit zus¨atzlichen Funktionen uberfrachtet¨ ist, die das Verst¨andnis beeintr¨achtigen k¨onnten - stellt er die Basis fur¨ den Unterricht dar. Auf Grund des im Rahmen dieser Veranstaltung vermittelten Basiswissens bezogen auf den 8051 Mikrocontroller wird man in der Praxis feststellen, dass eine Einarbeitung in andere Typen rasch m¨oglich ist.

1.2 Technische und mathematische Grundlagen

In der Informatik ist das Bit (Abkurzung¨ fur¨ engl. binary digit) die kleinste dar- stellbare Dateneinheit. In der elektronischen Datenverarbeitung ist 1 Bit zugleich die kleinstm¨ogliche Speichereinheit, in der Daten abgelegt werden k¨onnen. Ein Bit kann zwei m¨ogliche Zust¨ande annehmen: Strom aus / an, Kondensator geladen / ungela- den, 0 oder 1. Ein Paket aus n Bits hat 2n Zust¨ande. Mit 2 Speichereinheiten sind 22 = 4 Zust¨ande m¨oglich (siehe Abschnitt 1.2). 8 Bits zusammen ergeben 1 Byte (die n¨achstgr¨oßere Einheit). In der ublichen¨ Schreibweise werden die einzelnen Bits von rechts nach links abgez¨ahlt. MSB“ (Abk. fur¨ engl.: Most Significant Bit) nennt man ” das h¨ochstwertige Bit (ganz links, Bit 7), LSB“ (Abk. fur¨ engl.: Least Significant Bit) ” das niederwertigste (ganz rechts, Bit 0). Mit 8 Bits sind bereits 28 = 256 Zust¨ande dar- stellbar. Heutzutage sind die kleinsten adressierbaren Speichereinheiten. Kleinere Einheiten mussen¨ aus einem Byte extrahiert werden.

Bit 1 Bit 0 0 0 Zustand 0 0 1 Zustand 1 1 0 Zustand 2 1 1 Zustand 3

Tabelle 1.1: Bitcodierung

In einem Rechnersystem kommen nur die Signale 0 und 1 vor. Das hat den Hintergrund, dass sich elektronische Rechner am einfachsten, am effizientesten und am preiswertes- ten aus bipolaren Elementen zusammenbauen, die gerade zwei elektrische Zust¨ande annehmen k¨onnen. Fur¨ die Datenverarbeitung bedeutet das, Signale 0 und 1 auf den Eing¨angen mussen¨ wieder in Signale 0 und 1 auf den Ausg¨angen abgebildet werden. Die- se Abbildungen heißen Schaltfunktionen. Jede Schaltfunktion ist eine Zusammenfugung¨ Boole’scher Funktionen. Jede Boole’sche Funktion f kann durch Kombination von AND, OR und NOT realisiert werden (alternativ: NAND bzw. NOR). Wesentliche Grund- bausteine zur Umsetzung dieser Funktionen mit bin¨aren Ein- und Ausgaben in einem Rechner sind bistabile Speicherelemente und bin¨are Schalter. Diese Grundlagen wurden

Beuth Hochschule fur¨ Technik Berlin 3 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 1. EINFUHRUNG¨ bereits ausfuhrlich¨ in der Veranstaltung Grundlagen digitaler Systeme“ behandelt. Die ” wichtigsten Begriffe und Techniken werden hier noch einmal kurz umrissen.

1.2.1 Zahlensysteme

Zu den elementaren logischen Grundlagen eines Rechners, insbesondere der zugrunde- liegenden Hardware, z¨ahlt eine geeignete Repr¨asentation der zu verarbeitenden Da- ten, und zwar eine, die eine m¨oglichst gute Abbildung auf die internen Vorg¨ange gew¨ahrleistet. Die differenzierbaren eindeutigen Zust¨ande in elektrotechnischen Um- setzungen, d.h. also von Relais, Dioden, Transistoren etc., beschr¨anken sich in der Regel auf zwei, und zwar leitend / nichtleitend“ oder an / aus“. ” ” Da liegt es nahe, ein Zahlensystem zugrundezulegen, das im wesentlichen auch nur zwei Zust¨ande kennt. Dies bezeichnet man als bin¨ares (oder auch duales) Zahlensystem, kurz Bin¨arsystem (oder Dualsystem). Es verwendet als elementare Ziffern nur die 0 und die 1 und stellt die darzustellende Zahl als Zahl der Basis 2 dar. Fur¨ interne Darstel- lungen in digitalen Rechnersystemen werden neben dem Bin¨arsystem auch solche auf der Basis der Zahl 8 (Oktalsystem) und der Zahl 16 (Hexadezimalsystem) verwendet. Abschnitt 1.2.1 stellt die soeben vorgestellten Zahlensysteme gegenuber.¨ Als Referenz (erste Spalte) dient das allt¨aglich gebr¨auchliche Dezimalsystem. Im Dezimalsystem ist die Basis 10. Dezimal Dual Oktal Hexadezimal 0 0 0 0 1 1 1 1 2 10 2 2 3 11 3 3 4 100 4 4 5 101 5 5 6 110 6 6 7 111 7 7 8 1000 10 8 9 1001 11 9 10 1010 12 A 11 1011 13 B 12 1100 14 C 13 1101 15 D 14 1110 16 E 15 1111 17 F 16 10000 20 10

Tabelle 1.2: Zahlensysteme

Alle hier gezeigten Zahlensysteme basieren auf einer Stellenwertcodierung. Bei dieser h¨angt die Wertigkeit einer Zahl h¨angt vom Stellenwert der Zahl ab, die diese in ei-

Beuth Hochschule fur¨ Technik Berlin 4 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 1. EINFUHRUNG¨ ner Reihe von Zahlen einnimmt. Allgemein dargestellt ordnet man einem Codewort (an−1, ..., ai, ..., a0) einen Wert nach folgender Definition zu:

n−1 X i W (an−1, ..., ai, ..., a0) = ai · b (1.1) i=0

Die zugrundegelegte Basis ist durch b (bei den gezeigten Zahlensystemen b = 2, 8, 10, 16), der Stellenwert durch ai mit 0 ≤ ai ≤ b − 1 gekennzeichnet. Wie bereits in Abschnitt 1.2.1 zu ersehen, weist jedes Zahlensystem einen unterschiedlichen Zahlen- vorrat auf. Im Dezimalsystem sind das die Zahlen 0 bis 9. Mehr Zahlen kennt das Dezimalsystem nicht. Das bedeutet, dass es zehn verschiedene M¨oglichkeiten gibt. Die Ziffern im Zahlensystem werden Nennwerte genannt. Die Basis beschreibt die An- zahl der M¨oglichkeiten. Die Anzahl der Nennwerte ergibt sich aus der Basis. Der gr¨oßte Nennwert entspricht der Basis minus 1. Wird der gr¨oßte Nennwert uberschritten,¨ ent- steht aus dem Ubertrag¨ der n¨achsth¨ohere Stellenwert, wie in Abschnitt 1.2.1 ersichtlich. Dieses Prinzip ist bei allen Zahlensystemen gleich. Das Wissen um diesen Umstand sollte es jedem erm¨oglichen, in allen Zahlensystemen z¨ahlen zu k¨onnen. Da unser Zah- lensystem gerade zehn Symbole zur Notation der Ziffern (0 bis 9) gebraucht, verwendet man beim Hexadezimalsystem zus¨atzlich die ersten sechs Buchstaben des Alphabets (A, B, C, D, E, F) zur Darstellung. Nicht nur der Zahlenvorrat, sondern auch die Wertigkeit ist in den verschiedenen Zah- lensystemen unterschiedlich. Im Dezimalsystem ist die Basis 10. Das bedeutet, die Zah- len werden von Position zu Position um den Faktor 10 multipliziert. Im Bin¨arsystem ist die Basis 2, somit nehmen die Zahlen von Position zu Position um den Multiplika- tionsfaktor 2 zu; analog dazu gestaltet es sich im Oktal- und Hexadezimalsystem. Das Prinzip kann auf alle Zahlensysteme angewandt werden.

Zahlensystem Basis b Zahlenalphabet Bin¨ar 2 {0,1} Oktal 8 {0,1,2,3,4,5,6,7} Dezimal 10 {0,1,2,3,4,5,6,7,8,9} Hexadezimal 16 {0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F}

Tabelle 1.3: Nennwertzuordnung unterschiedlicher Zahlensysteme

Der Umstand, dass sowohl 8 und 16 eine Potenz von 2 darstellen (und zwar 23 und 24), erm¨oglicht eine sehr einfache Umrechung. Damit entspricht jede oktale Ziffer drei bin¨aren Ziffern und jede hexadezimale Ziffer 4 bin¨aren Ziffern. Die Konvertierung vom Bin¨arsystem ins Oktalsystem ist so z.B. m¨oglich, wenn man die Bin¨arzahl in Gruppen von je drei Ziffern partitioniert. Es wird jeweils bei der unteren Stelle begonnen, bei rationalen Zahlen beim Komma und von dort nach links bzw. rechts. Es ist zu bemerken, dass die Zahlen in der Digitaltechnik grunds¨atzlich nicht immer eindeutig einem Zahlensystem zugeordnet werden k¨onnen. So k¨onnte die Zahl 100 dem

Beuth Hochschule fur¨ Technik Berlin 5 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 1. EINFUHRUNG¨ hexadezimalen, dem dualen und dem dezimalen Zahlensystem angeh¨orig sein. In allen Zahlensystemen h¨atte die Zahl 100 eine andere Wertigkeit. Deshalb muss zwingend darauf geachtet werden, in solch missverst¨andlichen Konstellationen die Zahlen mit einem Index zu versehen. Man schreibt 100d (fur¨ dezimal), 100h (fur¨ hexadezimal) und 100b (fur¨ bin¨ar). Die Arithmetik, also das Rechnen, im Bin¨arsystem (Oktal- und Hexadezimalsystem) gestaltet sich analog zum Dezimalsystem, allein die Ubertr¨ ¨age finden anders statt. Wie oben bereits erw¨ahnt sind Ubertrage¨ entscheidend fur¨ die Darstellung von Zahlen, die gr¨oßer sind als der Zahlenvorrat. W¨ahrend man beim Dezimalsystem jeweils Ubertr¨ ¨age an Zehnerstellen hat, tauchen diese beim Bin¨ar-, Oktal- und Hexadezimalsystem bei 2, respektive 8 und 16 auf. Ein Beispiel fur¨ das Bin¨arsystem ist hier gegeben:

012 + 012 = 102 (1.2)

Der Ubertrag¨ im Dualsystem funktioniert also nach dem gleichen Prinzip wie im Dezi- malsystem. Die Hardware eines Rechners realisiert ublicherweise¨ nur eine Arithmetik fur¨ eine feste Zahll¨ange n. Durch diese Arithmetik ist die maximale interne Daten- verarbeitungsbreite definiert, etwa 8 Bit (bei 8-Bit Mikrocontrollern) oder 16 Bit (bei 16-Bit Mikrocontrollern, usw.) oder 32 Bit. Mathematisch gesehen wird die Arithmetik Modulo-2n realisiert. Dies ist dann entscheidend, wenn man beispielsweise zwei Zahlen addiert und das Ergebnis zu groß wird. Ubertr¨ ¨age in die n+1-te Stelle fallen einfach weg und nur die niederwertigsten Bits des Ergebnisses werden gespeichert. Dies genau entspricht der Modulo-Operation.

1.2.2 Komplementdarstellung

Die im Folgenden dargelegten Sachverhalte beziehen sich ausschließlich auf das Bin¨arsystem, da dieses das fur¨ digitale Rechnersysteme entscheidende ist. Mit der oben gezeigten Bin¨ardarstellung lassen sich ohne weiteres positive ganze Zahlen darstellen. Anstatt aber nur positive Zahlen von 0 bis 2n−1 mit Bitmustern der L¨ange n darzustel- len und arithmetische Operationen darauf auszufuhren,¨ werden oftmals auch negative Zahlen ben¨otigt. Die Darstellung von negativen ganzen Zahlen ist m¨oglich mit Hilfe der Komplementbil- dung. Dabei werden zwei Arten von Komplementbildung unterschieden. Sei b wieder die Basis des Zahlensystems (also 2, 8, 10, 16), so unterscheidet man das Komplement bezuglich¨ (b-1) und das Komplement bezuglich¨ b. Bezogen auf Dualzahlen bedeutet dies, dass es ein 1er- und ein 2er-Komplement gibt. In der Praxis hat sowohl die Verwendung des Einerkomplements als auch die des 2er- Komplements spezifische Vorteile. Das Einerkomplement ist technisch sehr einfach um- zusetzen, da nur eine bitweise Invertierung aller Bits (0 nach 1, 1 nach 0) erforderlich ist. Gem¨aß der Bildungsvorschrift ist der Zahlenbereich des Einerkomplements symme- trisch und reicht bei einer n-stelligen Bin¨arzahl von −(2n−1−1) bis +(2n−1−1). Deshalb

Beuth Hochschule fur¨ Technik Berlin 6 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 1. EINFUHRUNG¨ hat die 0 zwei Darstellungen, eine positive und eine negative. Diese zwei unterschied- lichen Null-Kombinationen mussen¨ unterschieden werden, was Rechenoperationen auf Einerkomplementdarstellung kompliziert machen kann. Das Rechnen im Zweierkomplement ist dagegen sehr viel einfacher, die Generierung dagegen mit einem zus¨atzlichen Schritt verbunden. Zur bitweise Invertierung aller Bits kommt noch eine Addition einer 1 zum niederwertigsten Bit hinzu. Der Zahlenbereich des Zweierkomplements ist asymmetrisch und umfasst bei einer n-stelligen Bin¨arzahl den Bereich −(2n−1) bis +(2n−1 − 1). Das Zweierkomplement hat somit nur eine arth- metische Null. Ein Beispiel: Die Zweierkomplementdarstellung von −6 l¨asst sich erstellen, indem zu- erst die Bin¨ardarstellung von +6, also (0110)2, gebildet wird. Anschließend wird das Einerkomplement, also (1001)2, generiert und eine 1 addiert. Die Zahl (−6)10 wird im Zweierkomplement als die Bin¨arzahl (1010)2 ausgedruckt.¨ Das Rechnen in Zweierkomplementdarstellung ist simpel. So l¨asst sich eine Subtraktion auf eine Negation mit anschließender Addition zuruckf¨ uhren.¨ Um beispielsweise 210−610 zu berechnen, wird einfach die Addition 2 + (−6) durchgefuhrt.¨ In bin¨arer Darstellung sieht das folgendermaßen aus:

0010 (2)10 + 1010 Zweierkomplement von (−6)10 1100 Betrachtet man nun das Ergebnis dieser Rechnung, muss man bei der Interpretation schrittweise vorgehen. Zun¨achst zeigt das erste Bit 1xxx, dass es sich um eine negative Zahl handelt (vgl. Einheitskreis bei Komplementdarstellung). Der Betrag der Zahl l¨aßt sich durch erneute Bildung des Zweierkomplements ermitteln. Hier werden also wieder die einzelnen Bits vertauscht (Einerkomplement) und dann 1 dazuaddiert. Das Einerkomplement von 1100 ergibt 0011, das Zweierkomplement resultiert als 0011 + 0001 = 01002 = 410. Zusammen mit der Vorzeicheninformation ist das Ergebnis der Rechnung also (−4)10. Merke: Die Addition zweier positiver Dualzahlen und solcher in Zweierkomplementdar- stellung ergibt das gleiche Bitmuster. Das Komplement wird auch fur¨ logische Operationen benutzt (als bitweises NOT). Es ist eine einstellige Verknupfung,¨ die eine logische Negation jedes Bits durchfuhrt.¨ Ist in der Literatur nur von Komplement“ die Rede, so ist generell das Einerkomplement ” gemeint. Gleiches gilt auch fur¨ Komplementoperatoren bei C- oder Assembler-basierten Programmiersprachen. Auf die Darstellungsformen rationaler Zahlen wird hier nicht n¨aher eingegangen, da dies bereits Bestandteil des Unterrichts Grundlagen digitaler Systeme“ war und auch ” im hier behandelten Kontext nicht relevant ist.

Beuth Hochschule fur¨ Technik Berlin 7 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 1. EINFUHRUNG¨

1.2.3 Zahlencodierung

Alle Informationen in einem digitalen Rechnersystem werden bin¨ar codiert. Grund- element dieser bin¨aren Codierung ist ein Bit. Zur Darstellung digitaler Informationen reicht ein Bit naturlich¨ nicht aus. Daher fasst man mehrere Bits zu l¨angeren Paketen, sogenannten Codes, zusammen. Die Aufgabe von Codes ist es, Informationen (Zah- len, Buchstaben und Zeichen) in eine geeignete Darstellungsform zu bringen, die eine schnellere und einfachere Verarbeitung erm¨oglicht. Je nach Art und gewunschter¨ Ver- arbeitung der Information verwendet man unterschiedliche Codes. So werden Zahlen in der Regel anders dargestellt als Zeichen. Entscheidend beim Umgang mit bin¨aren Codes ist, dass die Zuordnung zwischen Bit-Werten und repr¨asentierten Zeichen oder Zahlenwerten nicht eindeutig ist. Eine spezielle Bitfolge kann, je nach gew¨ahlter Codie- rung, unterschiedlichen Zahlenwerten entsprechen. Daher ist stets zu beachten, welche Codierung zugrundeliegt. Fur¨ die Darstellung von naturlichen¨ Zahlen w¨ahlt man meist den reinen Bin¨arcode oder eine Darstellung im BCD-Format (engl. Binary Coded Decimal). Der BCD-Code (auch als 8-4-2-1-Code bezeichnet) weist Dezimalziffern einen Code im bin¨aren Zahlensystem zu. Dabei wird jede Dezimalziffer einzeln bin¨arcodiert. Wird also eine mehrstellige Dezimalzahl im BCD-Code dargestellt, so wird jede einzelne Ziffer bin¨arcodiert. Um die Ziffern 0 bis 9 bin¨ar darzustellen, werden 4 Bits ben¨otigt. Mittels dieser 4 Bits (bezeichnet als Tetrade, Nibble oder Halbbyte) ist die Darstellung von 24 = 16 verschiedenen Werten m¨oglich, von denen die ersten 10 Werte zur Darstellung der Ziffern 0 bis 9 genutzt werden (siehe Abschnitt 1.2.3). Die weiteren 6 Wertigkeiten werden als Pseudotetrade bezeichnet und bleiben ungenutzt.

Dezimalziffer BCD-Code 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111 8 1000 9 1001

Tabelle 1.4: BCD-Code

M¨ochte man beispielsweise die Dezimalzahl 418 mittels BCD codieren, so erh¨alt man als Ergebnis 0100 0001 1000. Durch Verschiebung der Pseudotetraden lassen sich aus dem BCD-Code weitere Codes ableiten, so der Aiken-Code und der Exzess-3-Code, die ebenso den BCD-Codes zuzuordnen sind. Diese Codes arbeiten mit einem Versatz gegenuber¨ dem BCD-Code, der in manchen mathematischen Operationen vorteilhaft

Beuth Hochschule fur¨ Technik Berlin 8 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 1. EINFUHRUNG¨ genutzt werden kann (vgl. Grundlagen digitaler Systeme“). Der praktische Einsatz ” des BCD-Systems zeigt sich beispielsweise in numerischen Anzeigemodulen, 7-Segment- Anzeigen.

1.2.4 Zeichencodierung

In fast allen Anwendungen digitaler Rechnersysteme werden heute nicht nur nume- rische, sondern auch alphanumerische Zeichen verarbeitet. Um eine Gruppe von 2n Elementen (z.B. die Zeichen eines Codes) darzustellen, werden bin¨ar n Bits ben¨otigt. Fur¨ das Alphabet wurden¨ z.B. mindestens 26 Zeichen (plus 3 Umlaute und ß“ in der ” deutschen Sprache) zu codieren sein (angenommen nur Großbuchstaben). Mit 25 = 32 wurden¨ also mindestens 5 Bits ben¨otigt. Um auch Kleinbuchstaben, Sonderzeichen, Ziffern, etc. darstellen zu k¨onnen, wird tats¨achlich mindestens ein 7-Bit-Code ver- wendet. Bei der Verwendung eines Codes mit fester Bitl¨ange kann es durchaus freie Bit-Kombinationen geben, die keinem Zeichen zugeordnet sind. Der fur¨ die Darstellung von Zeichen heute weitgehend verwendete ASCII-Code (Ameri- can Standard Code for Information Interchange) nutzt 7 Bits. Es ist ein vereinheitlichter Code, bei dem jedes Zeichen durch eine fest definierte Codierungsnummer dargestellt wird. Damit stellt der ASCII-Code die unterste Ebene dar, auf der man sinnvollerweise alphanumerische Information zwischen unterschiedlichen Systemen austauschen kann. Typischerweise kann man ASCII-Information immer noch lesen, bin¨ar codierte kaum noch. Durch die 7 Bits k¨onnen bis zu 127 Zeichen dargestellt werden. Beim ASCII-Code sind die ersten 32 Codes fur¨ Steuerzeichen, beispielsweise fur¨ den Zeilenvorschub, vorbehal- ten. Die nachstehenden zwei Tabellen geben eine Ubersicht¨ uber¨ die in ASCII-Code dargestellten Zeichen und Ziffern und deren Entsprechung in den gebr¨auchlichsten al- phanumerischen Codes.

Beuth Hochschule fur¨ Technik Berlin 9 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 1. EINFUHRUNG¨

Dez Hex Okt Zeichen Dez Hex Okt Zeichen 0 0x00 000 NUL 32 0x20 040 SP 1 0x01 001 SOH 33 0x21 041 ! 2 0x02 002 STX 34 0x22 042 “ 3 0x03 003 ETX 35 0x23 043 # 4 0x04 004 EOT 36 0x24 044 $ 5 0x05 005 ENQ 37 0x25 045 % 6 0x06 006 ACK 38 0x26 046 & 7 0x07 007 BEL 39 0x27 047 ’ 8 0x08 010 BS 40 0x28 050 ( 9 0x09 011 TAB 41 0x29 051 ) 10 0x0A 012 LF 42 0x2A 052 * 11 0x0B 013 VT 43 0x2B 053 + 12 0x0C 014 FF 44 0x2C 054 , 13 0x0D 015 CR 45 0x2D 055 - 14 0x0E 016 SO 46 0x2E 056 . 15 0x0F 017 SI 47 0x2F 057 / 16 0x10 020 DLE 48 0x30 060 0 17 0x11 021 DC1 49 0x31 061 1 18 0x12 022 DC2 50 0x32 062 2 19 0x13 023 DC3 51 0x33 063 3 20 0x14 024 DC4 52 0x34 064 4 21 0x15 025 NAK 53 0x35 065 5 22 0x16 026 SYN 54 0x36 066 6 23 0x17 027 ETB 55 0x37 067 7 24 0x18 030 CAN 56 0x38 070 8 25 0x19 031 EM 57 0x39 071 9 26 0x1A 032 SUB 58 0x3A 072 : 27 0x1B 033 ESC 59 0x3B 073 ; 28 0x1C 034 FS 60 0x3C 074  29 0x1D 035 GS 61 0x3D 075 = 30 0x1E 036 RS 62 0x3E 076  31 0x1F 037 US 63 0x3F 077 ?

Tabelle 1.5: ASCII Tabelle (0-63)

Beuth Hochschule fur¨ Technik Berlin 10 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 1. EINFUHRUNG¨

Dez Hex Okt Zeichen Dez Hex Okt Zeichen 64 0x40 100 @ 96 0x60 140 ‘ 65 0x41 101 A 97 0x61 141 a 66 0x42 102 B 98 0x62 142 b 67 0x43 103 C 99 0x63 143 c 68 0x44 104 D 100 0x64 144 d 69 0x45 105 E 101 0x65 145 e 70 0x46 106 F 102 0x66 146 f 71 0x47 107 G 103 0x67 147 g 72 0x48 110 H 104 0x68 150 h 73 0x49 111 I 105 0x69 151 i 74 0x4A 112 J 106 0x6A 152 j 75 0x4B 113 K 107 0x6B 153 k 76 0x4C 114 L 108 0x6C 154 l 77 0x4D 115 M 109 0x6D 155 m 78 0x4E 116 N 110 0x6E 156 n 79 0x4F 117 O 111 0x6F 157 o 80 0x50 120 P 112 0x70 160 p 81 0x51 121 Q 113 0x71 161 q 82 0x52 122 R 114 0x72 162 r 83 0x53 123 S 115 0x73 163 s 84 0x54 124 T 116 0x74 164 t 85 0x55 125 U 117 0x75 165 u 86 0x56 126 V 118 0x76 166 v 87 0x57 127 W 119 0x77 167 w 88 0x58 130 X 120 0x78 170 x 89 0x59 131 Y 121 0x79 171 y 90 0x5A 132 Z 122 0x7A 172 z 91 0x5B 133 [ 123 0x7B 173 { 92 0x5C 134 \ 124 0x7C 174 | 93 0x5D 135 ] 125 0x7D 175 } 94 0x5E 136 ˆ 126 0x7E 176 - 95 0x5F 137 127 0x7F 177 DEL

Tabelle 1.6: ASCII Tabelle (64-127)

IBM erweiterte den ASCII-Code fur¨ die Verwendung mit dem PC auf einen Werteum- fang von 8 Bit (Zahlen von 0 bis 255), um weitere Sonderzeichen und Blockgrafikzeichen darstellen zu k¨onnen. Dieser erweitere ASCII-Code wird auch 8-Bit-ASCII oder IBM- PC-Zeichensatz genannt.

Beuth Hochschule fur¨ Technik Berlin 11 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 1. EINFUHRUNG¨

1.2.5 Fehlererkennung

Neben der internen Darstellung von Daten in digitalen Rechnersystemen ist auch die Ubertragung¨ der Daten von Bedeutung. Insbesondere fur¨ die Datenubertragung¨ kann eine weitere Codierung erforderlich sein, um z.B. leicht prufbare¨ und korrigierende Darstellungen zu erhalten. St¨orungen auf den Ubertragungswegen¨ ¨außern sich meist in auftretenden Bitfehlern. Ursachen dafur¨ k¨onnen St¨orsignale von außen, Spannungsspitzen aus dem Rauschen aktiver Bauelemente oder auch statische oder dynamische Fehler in digitalen Spei- chern sein. Zur Erkennung solcher Bitfehler (und sogar zur direkten Korrektur solch fehlerhafter Information) k¨onnen spezielle Codes verwendet werden, die man - je nach Komplexit¨at und Verhalten - fehlererkennende oder fehlerkorrigierende Codes nennt. Ein fehlererkennender Code beinhaltet in den Codew¨ortern des Zielalphabets redun- dante Zeichen (Prufzeichen)¨ als Zusatzinformation. Diese Zusatzinformation ist so be- schaffen, dass sie die Erkennung eines Ubertragungsfehlers¨ erm¨oglicht. Ist dieser Fehler dann erkannt, so kann die Ubertragung¨ einfach wiederholt werden. Die einfachste und am weitesten verbreitete Methode ist die Erweiterung der Datenbits einer Bitfolge um ein weiteres Bit (Prufbit),¨ das sogenannte Parit¨atsbit (Parity Bit). Mit dem Parit¨atsbit wird die Anzahl der in der Bitfolge vorkommenden Bits auf eine gerade oder ungerade Anzahl erg¨anzt. Je nachdem spricht man von einer geraden Parit¨at (even parity) oder einer ungeraden Parit¨at (odd parity). Bei der geraden Parit¨at wird die Anzahl der in der Bitfolge auftretenden Einsen durch das Parity Bit zu einer geraden Anzahl von Einsen erg¨anzt. Bei der ungeraden Parit¨at wird dagegen eine ungerade Anzahl von Einsen hergestellt. In Abschnitt 1.2.5 ist als Beispiel eine Liste von Bin¨arzahlen (von 0 bis 15) mit den Parit¨atsbits fur¨ gerade (even) und ungerade (odd) Parit¨at aufgefuhrt.¨

Beuth Hochschule fur¨ Technik Berlin 12 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 1. EINFUHRUNG¨

Bin¨arcode Parity Bit ungerade Parity Bit gerade 0000 1 0 0001 0 1 0010 0 1 0011 1 0 0100 0 1 0101 1 0 0110 1 0 0111 0 1 1000 0 1 1001 1 0 1010 1 0 1011 0 1 1100 1 0 1101 0 1 1110 0 1 1111 1 0

Tabelle 1.7: Bin¨arcode mit Parity

Mithilfe des Parity Bits k¨onnen Einbitfehler bei einer Datenubertragung¨ erkannt wer- den. Das Auftreten von Zweibitfehlern wurde¨ allerdings nicht erkannt werden, weil diese sich in der Erkennung aufheben wurden.¨ Die Erkennung von drei fehlerhaften Bits (oder allgemein: ungeraden Mehrfachfehlern) ist dagegen m¨oglich. Eine einfache Erweiterung erm¨oglicht auch die Erkennung gerader Mehrfachfehler. Die- se Erweiterung besteht in einer blockweisen Absicherung mehrerer Bin¨arw¨orter zusam- men, wobei einzelne Bin¨arw¨orter als Zeilen und die jeweiligen Bitstellen als Spalten aufgefasst werden. Bildet man nun ein Parit¨atsbit bezuglich¨ der Spalten und eines bezuglich¨ der Spalten, so kann man zwei gleichzeitig auftretende Fehler erkennen. Naturlich¨ l¨aßt sich der Aufwand in der Codierung beliebig ausbauen bis hin zur Feh- lerkorrektur. Fehlerkorrigierende Codes sind ¨ahnlich aufgebaut wie fehlererkennende Codes, mit dem Unterschied, dass die Zusatzinformation so beschaffen ist, dass sie eine eindeutige Bestimmung der Position des aufgetretenen Fehlers erm¨oglicht. Nur so l¨aßt sich dieser schließlich korrigieren. Ein Beispiel fur¨ einen fehlerkorrigierenden Code ist der sog. Hamming-Code (vgl. Grundlagen digitaler Systeme“). ”

1.2.6 Elementare Logikverknupfungen¨

Logische Verknupfungen¨ sind in der Aussagenlogik bzw. Booleschen Algebra sehr wich- tig. Aber auch im hier behandelten Kontext spielen sie eine große Rolle. Logische Ver- knupfungen¨ (z.B. zwischen zwei Operanden) lassen sich mit sog. logischen Operatoren durchfuhren.¨ Mit logischen Operatoren werden Wahrheitswerte nach definierten Mus- tern verknupft.¨ Auch dies ist aus den Grundlagen digitaler Systeme“ bereits bekannt. ”

Beuth Hochschule fur¨ Technik Berlin 13 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 1. EINFUHRUNG¨

Warum hier erneut darauf Bezug genommen wird, ergibt sich aus dem Umstand, dass die meisten Assembler - so auch der 8051 Befehlssatz - die logischen Befehle kennen und direkt implementiert haben. Das macht auch Sinn, da beispielsweise die Abar- beitung von Programmcode oft an Bedingungen geknupft¨ ist. Diese Bedingungen sind oftmals komplex zusammengesetzt, lassen sich aber auf die elementaren Operatoren AND, OR, XOR und NOT zuruckf¨ uhren.¨ Im Folgenden seien diese Operatoren noch einmal zusammenfassend dargestellt. Bei der AND-Verknupfung¨ (Konjunktion) wird jedes Bit der Operanden uberpr¨ uft.¨ Nur wenn beide Bits gesetzt sind, erh¨alt das Ergebnis den Wert 1.

X1 X2 AND 0 0 0 0 1 0 1 0 0 1 1 1

Tabelle 1.8: AND-Verknupfung¨

Bei der OR-Verknupfung¨ (Disjunktion) wird das Ergebnis auf 1 gesetzt, falls eines der Eingangsbits den Wert 1 besitzt

X1 X2 OR 0 0 0 0 1 1 1 0 1 1 1 1

Tabelle 1.9: OR-Verknupfung¨

Bei der XOR-Verknupfung¨ (Antivalenz) wird ebenfalls jedes Bit der Operanden uberpr¨ uft.¨ Nur wenn beide Bits unterschiedliche Werte besitzen, erh¨alt das Ergebnis den Wert 1.

X1 X2 XOR 0 0 0 0 1 1 1 0 1 1 1 0

Tabelle 1.10: XOR-Verknupfung¨

Bei der NOT-Operation (Negation) wird einfach der Wert des Eingangsbits im Ergebnis invertiert weitergegeben.

Beuth Hochschule fur¨ Technik Berlin 14 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 1. EINFUHRUNG¨

Weitere Hinweise zu Logikoperationen finden sich in den Abschnitten zum Befehls- satz des 8051 Mikrocontrollers. Die bis hierhin dargestellten Sachverhalte sollten Ihnen einen Zugang zu Grundlagen und Hintergrundinformationen geben, die zum fundier- ten Verst¨andnis und zur sicheren Anwendung in den nun folgenden Themenkomplexen rund um die Assemblerprogrammierung von Mikrocontrollern beitragen sollen.

Beuth Hochschule fur¨ Technik Berlin 15 Prof. Dr.-Ing. Sven-Hendrik Voß 2 Grundlagen der Rechnerarchitektur

2.1 Definition und Grundkonzept

Eine Rechnerarchitektur beschreibt das Design und die Organisation eines Rechners. Sie bestimmt den externen und internen Aufbau. Konkret z¨ahlen dazu die physikalische Struktur (und mit ihr die tats¨achlichen elektrischen Verbindungen), die Organisation, sowie eine definierte Schnittstelle zwischen Software und Hardware. Als Hardware wer- den alle physischen Komponenten eines Rechners bezeichnet, also alles, was materiell vorhanden ist (z.B. der Mikroprozessor als Silizium-Chip). Unter Software versteht man Programme, die auf Rechnern ablaufen. Die heute etablierte Definition einer Rechner- architektur ist auf Patterson und Hennessy zuruckzuf¨ uhren¨ [Hennessy 03]. Die externe Architektur legt durch den Maschinenbefehlssatz fest, wie ein Rechner von der Seite der Software her angesprochen werden kann. Dies ist die fur¨ die Codegene- rierung maßgebliche Schnittstelle. Der Maschinenbefehlssatz enth¨alt die elementaren Befehle und spiegelt als Befehlsschnittstelle die Sicht des Programmierers auf den Pro- zessor wieder. Usprunglich¨ bezeichnete man nur diesen Teil, also denjenigen Teil eines Rechners, der fur¨ einen Maschinensprachenprogrammierer sichtbar ist und von ihm verwendet werden kann, als Rechnerarchitektur [Amdahl 64]. Nach M¨artin bezeich- net man diesen Teil heute auch als Befehlssatzarchitektur oder ISA (Instruction Set Architecture) [Maertin 03]. Die interne Architektur beschreibt die interne Realisierung und bezieht sich auf den internen Aufbau und das Organisationsprinzip eines Rechners. Sie definiert den inneren Hardwareaufbau eines Rechners, also die Hardware selbst (bzw. eine mittels Softwa- re modellierte Hardwareschnittstelle). Hinter der internen Architektur verbirgt sich die sog. Rechnerorganisation (auch Mikroarchitektur), die wiederum auf eine konkrete Realisierung mit Register-Transfer-Strukturen zuruckzuf¨ uhren¨ ist. Die Rechnerorganisation beschreibt wie die im Rechner enthaltenen Komponenten zu- sammenh¨angen bzw. zusammenarbeiten, um die externe Architektur, also die Befehls- satzarchitektur, zu implementieren. Die Rechnerorganisation enth¨alt high-level Aspekte des Computerdesign, wie z.B. das Speichersystem, die Struktur des Busses, und das Design der CPU [Hennessy 03]. Auf Register-Transfer-Ebene ist u.a. exakt definiert welcher Inhalt welches Regis- ters in welches andere Register zu welchem Zeitpunkt transferiert wird. Der Begriff Register-Transfer-Ebene (engl. Register Transfer Level, kurz: RTL) ist aus der Vorle- sung Grundlagen digitaler Systeme“ bekannt und wird uns im Rahmen einer weiteren ”

16 KAPITEL 2. GRUNDLAGEN DER RECHNERARCHITEKTUR

Vorlesung ( Digitaltechnik“) noch einmal begegnen und dort vertieft werden. Kom- ” ponenten von RT-Strukturen sind u.a. Dekoder, Multiplexer, Register, Speicher und ALUs. Aus diesen Sachverhalten l¨asst sich der in Abbildung 2.1 dargestellte Aufbau ableiten. Insbesondere die Rolle der externen Architektur als Schnittstelle zwischen Software und Hardware, also als Schnittstelle zur Programmierung per Software wird deutlich. Unter Software wird hier das Maschinenprogramm verstanden. Die interne Rechnerar- chitektur ist die auf RT-Ebene definierte Hardware.

Software

Befehlssatz externe Architektur

Hardware interne Architektur

Universalprozessor

Abbildung 2.1: Externe und interne Architektur eines Rechners

Abbildung 2.1 zeigt eine sehr allgemein gehaltete Architektur eines Rechnermodells mit den wesentlichen Komponenten. Interne und externe Architektur sind hier Bestandteil eines beispielhaften, programmierbaren Universalprozessors (Von-Neumann-Rechner). Die Programmierbarkeit setzt voraus, dass die zugrundeliegende Hardware in jedem Fall ein Programm in Form eines maschinenlesbaren Textes ben¨otigt, um eine Aufgabe erfullen¨ zu k¨onnen. Die Programmierbarkeit ist die praktische Auspr¨agung der Universalit¨at. Der Uni- versalprozessor ist theoretisch fur¨ alle Anwendungen vom einfachen Assembler- / C- Programm bis zum Compiler, Betriebssystem, Datenbank, Textverarbeitung geeignet und l¨asst sich per Programmierung auf die jeweilige Problemstellung (und damit auch wechselnd auf viele Problemstellungen) anpassen. Das Geniale an diesem Universalan- satz ist auch, dass die Programmierung sich gegenuber¨ der Bauzeit in einem wesentlich kleineren Zeitrahmen durchfuhren¨ l¨aßt. In der Praxis ist die Universalit¨at letztlich nur durch beschr¨ankten Speicherplatz begrenzt. Alle in der Theorie berechenbaren Proble- me k¨onnen also nur daran scheitern. Die Programmierung kann auf verschiedenen Abstraktionsebenen geschehen. Beispiels- weise kann das Programm in einer h¨oheren Programmiersprache (z.B. in C), oder als Assemblerprogramm oder sogar direkt als Maschinenprogramm erstellt werden. Unge- achtet der gew¨ahlten Abstraktionsebene bei der Programmerstellung erfolgt letztlich die eigentliche Programmierung einer CPU immer in Maschinensprache. Alle Program- me, die existieren, sind im Endeffekt reine Maschinenprogramme. Der Grund dafur¨

Beuth Hochschule fur¨ Technik Berlin 17 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 2. GRUNDLAGEN DER RECHNERARCHITEKTUR besteht darin, dass eine CPU nur die Maschinensprache versteht. Programmiert man beispielsweise in C, ubersetzt¨ der C-Compiler den C-Quelltext vor dem eigentlichen Laden auf die CPU in Maschinensprache. Aufgrund der in Kapitel 1 dargelegten Schw¨achen ist es hin und wieder sinnvoll direkt in Assembler zu arbeiten. Die Assembler-Befehle nennt man Mnemonics. Ein Assembler-Befehl entspricht genau einem echten Maschinenbefehl, also ist ein Assemblerprogramm immer eine Eins-zu- eins-Ubersetzung¨ in Maschinensprache. Der Prozessor l¨adt die in Maschinensprache vorliegenden Programme aus dem Speicher in seine Dekodierlogik und fuhrt¨ sie dann aus. Die Befehle sind meist recht primitiv. Typisch sind das Laden und Speichern von Werten, Programmsprunge¨ und einfache Rechenoperationen. Darauf wird sp¨ater noch genauer eingegangen.

c := a + b

LAC a ADD b SAC c

1110000000100001 1010000000100010 0010000000100011 Software

Befehlssatz externe Architektur

Hardware interne Architektur

Abbildung 2.2: Schlusselrolle¨ des Befehlssatzes

Fur¨ die Programmierung nimmt der Befehlssatz eine Schlusselrolle¨ ein, legt er doch schließlich fest welche Maschinenbefehle als Elementaroperationen zur Verfugung¨ ge- stellt werden, auf die bei der generellen Funktionsimplementierung zuruckgegriffen¨ wer- den kann. Im Idealfall sorgt ein geschickt gew¨ahlter Befehlssatz dafur,¨ dass alle An- wendungen vom C-Programm bis zur Datenbankimplementierung effizient unterstutzt¨ werden. In [Parnas 75] wurde einst eine anschauliche Analogie dargestellt, nach der der Maschinenbefehlssatz der Lenkung eines Autos enspricht. Bei starrer Hinterachse und beweglich aufgeh¨angten Vorderr¨adern gibt es fur¨ die Vorderr¨ader viele M¨oglichkeiten. Bezogen auf eine Mikrocontroller-Realisierung als Siliziumchip l¨aßt sich dies als freie Gestaltungsm¨oglichkeit der Siliziumfl¨ache verstehen. Durch die Lenkung - also den Befehlssatz - sind nur noch sinnvolle“ Positionen benutzbar. ” Ein erfolgreicher Befehlssatz (externe Architektur) bindet die Software-Entwicklung fur¨ diesen Befehlssatz meist uber¨ Jahrzehnte und hat ein erhebliches Beharrungsverm¨ogen. Hintergrund ist, dass mitunter teure Software fur¨ den einen spezifischen Befehlssatz ent- wickelt wurde, die auch auf neueren Rechnern in Maschinencode ohne Recompilierung

Beuth Hochschule fur¨ Technik Berlin 18 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 2. GRUNDLAGEN DER RECHNERARCHITEKTUR ablauff¨ahig sein soll. Historische Beispiele hierfur¨ sind die IBM 360 Rechnerfamilie oder die Intel x86 Familie. Schließlich bedingt dies auch das Ph¨anomen der Prozessorklo- ” ne“: Darunter versteht man Maschinencode-kompatible Prozessoren anderer als der Original-Hersteller. Dieses Konzept funktioniert einzig und allein deswegen, weil sich die Prozessoren auf Befehlssatzebene in keiner Weise unterscheiden. Dank der Befehlssatzarchitektur k¨onnen Rechnerarchitekten Funktionen unabh¨angig von der diese Funktionen ausfuhrenden¨ Hardware betrachten. So gibt es z.B. meh- rere Prozessoren, die die x86-Befehlssatzarchitektur implementieren, jedoch z.B. mit v¨ollig unterschiedlicher Cache-Organisation arbeiten. Daruber¨ hinaus gibt es Archi- tekturen, die sowohl die gleichen Befehlssatzarchitekturen unterstutzen,¨ als auch eine sehr ¨ahnliche Organisation aufweisen, sich jedoch bei der Verwendung der Hardwa- re stark unterscheiden. So sind z.B. der Pentium II und der Celeron nahezu iden- tisch, bieten jedoch unterschiedliche Taktraten und unterschiedliche Speichersysteme [Hennessy 03].

2.2 Aufbau und Struktur

Nachdem nun die Rolle der externen Architektur (Befehlssatz) erl¨autert wurde, soll nun die interne Architektur (Hardware) etwas genauer betrachtet werden. Abbildung 2.3 zeigt die interne Architektur, die aus den drei Grundbestandteilen • Prozessor (Central Processing Unit, CPU) • Speicher (Memory) • Ein-/Ausgabeeinheit (Input/Output Unit) aufgebaut ist (nach dem Von-Neumann-Prinzip [Oberschelp 00]). Neben diesen drei Teileinheiten existieren noch Verbindungen zwischen den Einheiten, die als Busse be- zeichnet werden. Die CPU ubernimmt¨ innerhalb dieser Struktur die Ausfuhrung¨ von Befehlen, die im Speicher gespeichert sind, und enth¨alt die dafur¨ notwendige Ablaufsteuerung. Die Ein- /Ausgabeeinheit stellt die Verbindung zur Außenwelt in Form des Austausches von Programmen und Daten her und bietet so uberhaupt¨ erst die M¨oglichkeit, mit der CPU zu kommunizieren. Im Prozessor, der zentralen Einheit, sind Rechenwerk (auch Operationswerk) und Steu- erwerk (auch Leitwerk) untergebracht. Darauf wird sp¨ater noch genauer eingegangen. Speicher sind Komponenten, welche Daten aufbewahren. Im Speicher werden sowohl die Daten, als auch die Programme in Form von Bitfolgen abgelegt. Daten k¨onnen im Allgemeinen in den Speicher geschrieben und wieder ausgelesen werden. Es gibt eine Vielzahl an M¨oglichkeiten wie man Speicher klassifizieren kann, so z.B. uber¨ die Art des Zugriffs, uber¨ den physikalischen Aufbau, uber¨ Gr¨oße und Verwendungsart. Im Hinblick auf Mikrocontroller, die im Folgenden im Mittelpunkt stehen werden, ist

Beuth Hochschule fur¨ Technik Berlin 19 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 2. GRUNDLAGEN DER RECHNERARCHITEKTUR

Prozessor Operations- Ein- / werk Speicher Ausgabe Steuerwerk

CPU (Central Processing Unit)

Abbildung 2.3: Interne Architektur eines Rechners eine Unterscheidung nach fluchtigem¨ und permanentem bzw. nicht-fluchtigem¨ (engl. nonvolatile memory) Speicher besonders interessant. • RAM (Random Access Memory) - tempor¨are Speicherung von Anwendungsdaten und Programmen, die auf dem laufen → Daten gehen bei Power-Down verloren (fluchtig)¨ • ROM (Read Only Memory) - beinhaltet Programme und Informationen, die es- sentiell fur¨ das Funktionieren des Rechners sind → dort gespeicherte Informatio- nen k¨onnen nicht durch Nutzung ver¨andert werden, gehen bei Power-Down nicht verloren (nicht-fluchtig)¨ Auf weitere Merkmale, wie z.B. den wahlfreien Zugriff beim Random Access Memory wird hier nicht n¨aher eingegangen und auf entsprechende Sekund¨arliteratur verwie- sen.

2.2.1 Speicherhierarchie

In einem Rechnersystem gibt es unterschiedlichste Arten von Speichern, die hierarchisch organisiert sind und sich in ihren Charakteristika unterscheiden. Eine grobe Einteilung ist in Abbildung 2.4 aufgezeigt. Die Speicherhierarchie ist in den meisten Rechnern noch weiter unterteilt. Folgenden Merkmale charakterisieren Speicher: • Zugriffsgeschwindigkeit: Zeit, um eine Speicherzelle zu lokalisieren und aus ihr zu lesen bzw. sie zu beschreiben • Kapazit¨at: Anzahl der Speicherzellen, typischerweise angegeben in Bit, Byte oder Worten • Speicherzykluszeit: setzt sich zusammen aus der Zugriffszeit und einer eventuellen Regenerierungszeit1

1Regenerierungszeit ist je nach Speicher n¨otig, wenn die Speicherzelle durch den Lesevorgang gel¨oscht wird und diese anschließend wieder mit demselben Inhalt beschrieben werden muss, bevor der n¨achte Zugriff m¨oglich ist.

Beuth Hochschule fur¨ Technik Berlin 20 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 2. GRUNDLAGEN DER RECHNERARCHITEKTUR

r[0] ... Cache RAM HDD r[31] Register des Prozessors

Zugriffsgeschwindigkeit

Preis

Kapazität

Entfernung zum Prozessor

Abbildung 2.4: Speicherhierarchie in einem Rechner

Die in Abbildung 2.4 gezeigte Unterteilung folgt dem Prinzip, Daten bzw. Befehle von der niedrigsten (schnellsten) Ebene verfugbar¨ zu machen. Die soeben erw¨ahnten Charakteristika spielen dafur¨ eine entscheidende Rolle. Die Speicherhierarchie in einem Rechner spiegelt die Beziehung der CPU zu RAM und ROM wieder. Damit die CPU Daten verarbeiten kann, mussen¨ diese erst im RAM oder ROM gespeichert werden. RAM und ROM sollen einen m¨oglichst schnellen Zu- griff der CPU auf Daten und Befehle gestatten, sind aber relativ teuer. Sie werden auch als Prim¨arspeicher bezeichnet. Das ROM stellt Daten bereit, die fest und dau- erhaft sind (Tabellen oder Initialisierungsprogramme), das RAM speichert dagegen Daten, die tempor¨ar sind und sich mit der Zeit ¨andern k¨onnen (Anwendungsdaten, Betriebssystemdateien sofern vorhanden). Zur Verarbeitung bekommt die CPU Daten zuerst vom RAM (oder ROM). Wenn die ben¨otigten Daten dort nicht vorhanden sind, sucht die CPU die Daten an einem Massenspeicherger¨at (Sekund¨arspeicher) und ubertr¨ ¨agt diese an das RAM. Allgemein ausgedruckt¨ wird immer versucht die Daten von der schnellsten Ebene zu holen. Falls die Daten dort nicht verfugbar¨ sind, wird versucht, diese von der n¨achsten Ebene zu holen, usw. Innerhalb der CPU k¨onnen Daten (wie Adressen, Zahlen, Operationscode) in Registern kurzfristig zur Verarbeitung vorgehalten bzw. gespeichert werden. Registerspeicher ist ein sehr schneller Speicher mit sehr kleiner Kapazit¨at, der u.a. direkt auf dem Prozessor vorhanden ist. Cache ist ein schneller Zwischenspeicher, um Daten schneller verarbeiten bzw. auf diese zugreifen zu k¨onnen. So gibt es beispielsweise auf einigen Prozessoren2 einen Cache, der die zuletzt benutzten Daten des Hauptspeichers enth¨alt. Die zuletzt verwendeten Daten (oder nahgelegene) werden h¨aufig nochmals verwendet (Lokalit¨atsprinzip). Wer- den diese im Cache zwischengespeichert, muss der Prozessor sie nicht erneut uber¨ den

2Der 8051 geh¨ort nicht dazu, er hat keinen Cache.

Beuth Hochschule fur¨ Technik Berlin 21 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 2. GRUNDLAGEN DER RECHNERARCHITEKTUR

Systembus vom langsameren Arbeitsspeicher anfordern. So vermeidet man unn¨otige Wartezeiten, denn das Abholen eines Befehls aus dem Speicher dauert erheblich l¨anger als die eigentliche Ausfuhrung¨ des Befehls. Der Cache befindet sich als Level-1 Cache (extrem schnell und klein, vollassoziativ und doppelt ausgelegt fur¨ Daten und Befehle) direkt auf dem Prozessor und als Level-2 Cache (gr¨oßere Kapazit¨at aber langsamer, nichtassoziativ oder teilassoziativ, keine Trennung zwischen Daten und Befehlen) ent- weder ebenfalls auf dem Prozessorchip oder extern (Off-Chip Cache). Die Rolle des RAM als Arbeitsspeicher wurde bereits erl¨autert. Es wird gemeinhin eine Unterscheidung getroffen, ob Daten und Programme in gemeinsamen oder unterschied- lichen Speichern aufbewahrt werden (Harvard- vs. von-Neumann-Architektur). Darauf wird sp¨ater noch genauer eingegangen. Massenspeicher oder Peripheriespeicher (wie Festplatten, Floppy, CDs, etc.) dient zur Speicherung von Daten und Programmen, auf die selten zugegriffen wird. Sie sind meist langsamer als der Arbeitsspeicher, k¨onnen aber Daten langfristig aufbewahren. Ihr Speicherinhalt ist nicht fluchtig.¨ Im Embedded-Bereich ist diese Art von Speicher eher selten. Mikrocontrollersysteme verfugen¨ in der Regel nicht uber¨ einen Massenspei- cher. Bevor mit den weiteren Komponenten der internen Architektur eines Rechners fortge- fahren wird, sollen hier noch einmal die Grundlagen der Speicheradressierung aufge- griffen werden. Die Adressen vom RAM (und auch ROM) werden uber¨ einen Adressbus direkt adressiert, wobei die Busbreite des Adressbus dabei die maximale Anzahl der ansprechbaren Speicherzellen bestimmt. Die Speicherzellen sind linear geordnet und nummeriert, wobei die Nummerierung mit Null beginnt. Jede Speicherzellen kann ein Datum fester L¨ange aufnehmen. In der Regel hat eine Speicherzelle die Gr¨oße 1 Byte, also 8 Bit. Die Speicherzellen k¨onnen mit ihrer Nummer identifiziert und angesprochen werden. Die Nummer der Speicherzelle wird als ihre Adresse bezeichnet. Wie alle Zahlen zur besseren elektrotechnischen Umsetzung in digitalen Systemen dual- codiert sind, so werden auch Adressen ebenso repr¨asentiert, und zwar als ganze positive Zahlen. Je nachdem wieviele Bits zur Adressierung zur Verfugung¨ stehen, ergibt sich die Anzahl der m¨oglichen ansprechbaren Speicherzellen. Stehen beispielsweise 32 Bit zur Adressierung zur Verfugung,¨ berechnet sich die Anzahl an Speicherzellen wie folgt:

232 = 4.294.967.296 (2.1)

Das bedeutet, es sind mit 32 Bit Adressen 4.294.967.296 Speicherzellen prinzipiell an- sprechbar. Der Adressraum ist die Menge aller m¨oglichen Adressen, allerdings nicht mit der Speicherkapazit¨at zu verwechseln. Die Speicherkapazit¨at gibt den wirklich vorhan- denen Speicherplatz an, ist also ein Maß fur¨ den pysikalisch vorhandenen Speicher.

Beuth Hochschule fur¨ Technik Berlin 22 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 2. GRUNDLAGEN DER RECHNERARCHITEKTUR

2.2.2 Ein- und Ausgabewerk

Das Ein- und Ausgabewerk, schematisch dargestellt in Abbildung 2.5, dient zur Kom- munikation mit der Umwelt, z.B. dem Benutzer. Hieruber¨ werden Eingangs- und Aus- gabedaten ausgetauscht, zu verarbeitende Daten z.B eingegeben und das Ergebnis der Berechnung ausgegeben.

Daten- verarbeitung

Eingabe Ausgabe E / A

Abbildung 2.5: Ein- und Ausgabewerk

Die Eingabe dient der • Ubernahme¨ von Daten von extern angeschlossenen Ger¨aten • Umsetzung in eine geeignete, normierte Darstellung zur weiteren Verarbeitung Die Ausgabe erfullt¨ den Zweck der • Aufbereitung der Daten (Datenformat, Signalpegel) • Weiterleitung an externe Ausgabeger¨ate • eventuellen Auswahl des Ausgabeger¨ates Da Daten ubertragen¨ werden, muss das Ein- und Ausgabesystem (E/A-System, auch engl. I/O) an den Datenbus angeschlossen sein. Der Datentransport kann auf ver- schiedene Arten gesteuert werden. Man unterscheidet befehls- und speicherbezoge- ne Ein- und Ausgabe, sowie die unterbrechungsgesteuerte. Bei befehlsbezogener E/A wird der Peripherie uber¨ eine spezifische Adresse ein Funktionscode ubermittelt.¨ Bei der speicherbezogenen E/A (engl. memory mapped input/output) werden Bereiche des Arbeitsspeichers fur¨ die Peripherieger¨ate reserviert. So k¨onnen diese direkt, wie Spei- cheradressen, angesprochen werden. Bei der unterbrechungsgesteuerten E/A l¨ost die Peripherie von sich aus eine Unterbrechnung (engl. interrupt) des aktiven Programms auf dem Prozessor aus. Damit wird der Prozessor nicht durch unn¨otige Wartezeiten und Statusabfragen zeitlich belastet. Darauf wird sp¨ater noch genauer eingegangen.

2.2.3 Operationswerk

Es wurde bereits erw¨ahnt, dass der Prozessor ein Operations- und ein Steuerwerk umfasst. Das Operationswerk stellt den ausfuhrenden,¨ also den datenverarbeitenden Teil, das Steuerwerk (wie der Name schon vermuten l¨asst) den steuernden Teil dar.

Beuth Hochschule fur¨ Technik Berlin 23 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 2. GRUNDLAGEN DER RECHNERARCHITEKTUR

Die Aufgabe des Operationswerks ist es, arithmetische (Addieren, Subtrahieren, Multi- plizieren, Dividieren) und logische (AND, OR, NOT) Operationen auf Daten anzuwen- den, um diese Daten zu manipulieren, zu verarbeiten. Dazu stellt es einen Satz von Ba- sisfunktionen aus dem Bereich der numerischen und logischen Verknupfungen¨ anhand einer arithmetischen und logischen Einheit (engl. arithmetic logic unit, kurz: ALU) und geeigneten Registern zur Zwischenspeicherung der Operanden zur Verfugung.¨ Ublicherweise¨ beschr¨ankt sich das Operationswerk auf Funktionen mit zwei Operan- den bei gegebener maximaler Stellenzahl. Dies bedingt letztlich die Genauigkeit bei der Verarbeitung der Daten. Eine schematische Darstellung des Operationswerkes findet sich in Abbildung 2.6.

Operand 1 Operand 2

Bedingungs- Art der Operation vektor ALU (Operationscode)

Ergebnis

Abbildung 2.6: Operationswerk

Einzelne Merkmale eines Operanden oder Ergebnisses (z.B. Wert gleich Null) k¨onnen als Bin¨arwerte in einem sogenannten Bedingungsvektor ( flags“) zur Verfugung¨ gestellt ” werden. Normalerweise kann die ALU als arithmetische Operation nur addieren, da die anderen arithmetischen Operationen (Subtraktion, Multiplikation und Division) auf eine Addition zuruckgef¨ uhrt¨ werden k¨onnen (vgl. Addiererschaltungen).

2.2.4 Steuerwerk

W¨ahrend das Operationswerk Daten aus dem Speicher verarbeitet, dient das Steuer- werk der Abarbeitung von Befehlen. Es dient der Koordination der Komponenten des Prozessors, z.B. Versorgung mit Daten und Adressen, Selektion von Ger¨aten, Auswahl von Operanden und Operationen. Dies wird erm¨oglicht, indem das Steuerwerk folgende Aufgaben leistet: • Steuerung des Ablaufs der Befehlszyklen in der CPU (Steuerung des Program- mablaufs) • Befehle holen und decodieren • Operanden holen/speichern • Steuerung der Befehlsausfuhrung¨ • Koordination und Steuerung aller ubriger¨ Einheiten der CPU

Beuth Hochschule fur¨ Technik Berlin 24 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 2. GRUNDLAGEN DER RECHNERARCHITEKTUR

Das Steuerwerk koordiniert die Komponenten des Prozessors, wobei es die Maschi- nenbefehle schrittweise interpretiert. So liest es w¨ahrend eines Befehlszyklus einen Be- fehl aus dem Speicher des Mikrocontrollers aus, interpretiert ihn und bringt ihn zur Ausfuhrung.¨ Die Ausfuhrung¨ geschieht ganz oder teilweise im Operationswerk. Um das Steuerungprinzip zu realisieren, bedarf es bestimmter Festlegungen. So ist zun¨achst ei- ne Formalisierung fur¨ die Anweisung n¨otig [Lipp 08]. Der Begriff Befehl“ ist bereits ” verwendet worden, jedoch bisher nicht n¨aher erl¨autert worden. • Befehl: (Maschinenlesbare) Anweisung, aus der hervorgeht, welche Operation mit welchen Operanden durchgefuhrt¨ werden soll • Befehlsformat: Festlegung, wie die fur¨ einen Befehl notwendigen Angaben darge- stellt werden Auf die n¨ahere Erl¨auterung der Begrifflichkeiten Befehlszyklus, Decodierung, usw. wird an dieser Stelle verzichtet. Die genaue Bedeutung ergibt sich aus dem Kontext des nachfolgenden Kapitels, in dem die genaue Abfolge der n¨otigen Schritte erl¨autert wird, die der Ausfuhrung¨ eines Befehls dienen.

2.2.5 Speicherwerk

Das Speicherwerk (Abbildung 2.7) dient der Aufbewahrung von Operanden, Be- dingungsvektoren und Ergebnissen. Es kann eine große Zahl von Operanden und (Zwischen-)Ergebnissen w¨ahrend der Verarbeitung bereithalten. Dies hat den Vorteil, dass so nicht fur¨ jede Operation das Ein-/ Ausgabewerks bemuht¨ werden muss. Wie bereits im Kontext der Speicherhierarchie dargelegt wurde, dienen zur Speicherung im einfachsten Fall nur eine Reihe von Registern. Im Allgemeinen gilt: Je mehr und je gr¨oßer die Register sind, desto besser die CPU. Register k¨onnen 8-, 16-, 32- oder 64- Bit groß sein, dies richtet sich in der Regel nach der Auslegung des Prozessors (8-Bit, 16-Bit, usw.). Der Nachteil einer großen Anzahl von Registern liegt in einer teureren CPU. Daher wird meist umfangreicher adressierbarer Schreib/Lese-Speicher (RAM) fur¨ genau die- sen Zweck benutzt. Im allgemeinen enth¨alt das Speicherwerk mehrere (u. U. unter- schiedliche) Speicherbausteine. Die Zahl der verfugbaren¨ Speicherzellen richtet sich nach Breite des Adressvektors. Die Zusammenh¨ange wurden bereits erl¨autert.

Adresse Speicher

Schreiben / Datenein- / Lesen ausgabe

Abbildung 2.7: Speicherwerk

Beuth Hochschule fur¨ Technik Berlin 25 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 2. GRUNDLAGEN DER RECHNERARCHITEKTUR

Das Speicherwerk besteht aus den eigentlichen Speichereinheiten, sowie der Ankoppel- schaltung an CPU und Ein- und Ausgabewerk. Die Ankoppelung an den Systembus geschieht mit Hilfe von • Registern zur Zwischenspeicherung von Daten und Adressen zur Sicherstellung der definierten Zugriffszeit • einem Adressdecoder zur Generierung von Ansteuersignalen fur¨ den entsprechen- den Baustein innerhalb eines vorbestimmten Adressbereichs • Steuerleitungen zur Festlegung Lesen/Schreiben, Taktleitungen (Zeitpunkt des Zugriffs), Speicheraktivierung

2.2.6 Bussysteme

Zur Steuerung, der Adressierung und der Ubertragung¨ von Daten werden Bussysteme eingesetzt. Unter einem Bus (Binary Unit System) versteht man eine Anzahl von Lei- tungen, an die mehrere Funktionseinheiten parallel angeschlossen sind. Ein Bus ist also eine Sammelleitung zur Ubertragung¨ von Daten zwischen verschiedenen Komponenten. Durch die gemeinsamen Verbindungsleitungen kann die Anzahl der Verbindungsleitun- gen klein gehalten werden gegenuber¨ der Variante, dass alle Komponenten durch eigene Leitungen miteinander verbunden sind. Man unterscheidet zwischen unidirektionalen und bidirektionalen Bussen. Bei Erstgenannten erfolgt die Ubertragung¨ immer nur in eine Richtung. Uber¨ bidirektionale Busse kann die Ubertragung¨ dagegen in beide Richtungen erfolgen. Der Systembus eines Rechnersystems verbindet die Hauptkomponenten Prozessor, Speicher und Ein/Ausgabesysteme. Dieser teilt sich in Datenbus, Adressbus und Steu- erbus. Uber¨ den Datenbus werden Daten zwischen CPU und Peripherie (Speicher oder E/A- Komponenten) ubertragen.¨ Dieser Bus ist bidirektional, da Daten sowohl empfangen als auch gesendet werden mussen,¨ z.B. wird in Speicherzellen gelesen und geschrieben. Prinzipiell gilt Folgendes: je mehr Datenbusse verfugbar¨ sind, desto besser ist die CPU. Eine Analogie zum Verstehen und Merken dieser doch sehr einfach dargestellten und plakativen Aussage ist den Datenbus wie Fahrspuren auf einer Autobahn zu betrachten. Je breiter der Bus, desto mehr Daten (oder im ubertragenen¨ Sinne Fahrzeuge auf einer Autobahn) k¨onnen zur gleichen Zeit ubertragen¨ werden. Mehr Datenbusse bedeuten eine teurere CPU. Die durchschnittliche Breite von Datenbussen variiert zwischen 8 und 64 Bit (Anzahl Busleitungen). Die Leistung eines Rechners ist schließlich mit der Gr¨oße seiner Busse verbunden. Damit die Peripherie von der CPU erkannt werden kann, muss eine eindeutige Adresse zugewiesen werden. Uber¨ den Adressbus werden die Komponten, die an den System- bus angeschlossen sind, und die Adressen der Speicherzellen oder Register ausgew¨ahlt. Der Adressbus ist unidirektional. Je gr¨oßer der Adressbus, desto h¨oher die Anzahl der

Beuth Hochschule fur¨ Technik Berlin 26 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 2. GRUNDLAGEN DER RECHNERARCHITEKTUR

Einheiten die adressiert werden k¨onnen. Gibt es n Adressleitungen auf dem Adress- bus so k¨onnen 2n Speicherzellen adressiert werden - unabh¨angig von der Gr¨oße des Datenbusses. Beispiel: Eine CPU mit 24 Adressleitungen und 8 Datenleitungen kann 224 = 16777216 = 16 · 1048576 = 16 · 220 = 16 MB Speicher adressieren. Merke: In der Informatik wird mit kilo meist 1024 = 210 gemeint. 1 kByte entsprechen also 1024 Byte. Die Angabe Mega steht fur¨ 1024 · 1024 = 220, also sind 1 MByte gleich 1024 kByte. Giga bezeichnet folglich 1024 · 1024 · 1024 = 230 und 1 GByte umfasst demnach 1024 MByte. Entsprechend ist dieser Zusammenhang auch auf die Angabe kBit und MBit anwendbar. Dieser Sachverhalt ist wichtig zu erw¨ahnen, da er eigentlich dem normierten Sprachgebrauch, in dem k immer 1000, und M immer 1000000 bezeichnen muss, widerspricht. Jede Speicherzelle kann ein Maximum von 1 Byte Daten haben, denn alle Mehrzweck- CPUs sind Byte-adressierbar. Die CPU legt eine Adresse auf den Adressbus, die Deco- dierschaltkreise finden die entsprechende Peripheriekomponente und w¨ahlen diese fur¨ die nachfolgenden Aktionen aus. Der Steuerbus dient zur Ubertragung¨ von Steuersignalen und ist teilweise unidirek- tional und bidirektional. Diese Steuersignale sind u.a. Lese- und Schreibsignale zur Angabe, ob die CPU Informationen erhalten oder senden m¨ochte.

2.3 Architekturuberblick¨

Die Funktionseinheiten eines und ihre Verbindungen sind in Abbildung 2.8 grob schematisch dargestellt.

Adressbus

Speicher CPU Peripherie (RAM, ROM)

Datenbus

Abbildung 2.8: Zusammenwirken von CPU, Speicher und Peripherie

Abbildung 2.9 zeichnet ein genaueres Bild vom Zusammenwirken der bereits vorgestell- ten einzelnen Bustypen. Soll beispielsweise der Inhalt einer Adresse ausgelesen werden, so wird uber¨ den Steuerbus (vom Prozessor) ein Signal angelegt, welches dem ent- sprechenden Speicherbaustein signalisiert, dass eine Speicherzelle ausgelesen werden soll. Auf dem Adressbus wird die entsprechende Adresse der Speicherzelle angelegt.

Beuth Hochschule fur¨ Technik Berlin 27 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 2. GRUNDLAGEN DER RECHNERARCHITEKTUR

Der Inhalt der Adresse wird dann uber¨ den Datenbus vom Speicher zum Prozessor ubertragen.¨

Addressbus

CPU RAM ROM DAC UART VGA GPIO

Lesen/ Schreiben Datenbus Steuerbus

Abbildung 2.9: Systemarchitektur mit Systembus

2.3.1 Schema eines einfachen Rechners

Im vorangegangenen Teil wurden nun schon die wesentlichen Komponenten eines Uni- versalrechners nach von Neumann vorgestellt. Der Rechner besteht aus funf¨ Funki- onseinheiten: Steuerwerk, Rechenwerk, Speicher, Eingabewerk und Ausgabewerk. Die Struktur des Rechners ist unabh¨angig vom zu bearbeitenden Problem. Zur L¨osung ei- nes Problems muß ein Programm im Speicher abgelegt werden. Beim von-Neumann Modell werden Programme, Daten und Ergebnisse im selben Speicher abgelegt. Sp¨ater wird sich zeigen, dass das nicht immer so sein muss. Alle Daten (Befehle, Adressen usw.) werden bin¨ar codiert. Der Speicher besteht aus einzelnen Speicherzellen, die fortlaufend numeriert sind. Uber¨ die Adresse einer Spei- cherzelle kann deren Inhalt abgerufen werden. Aufeinanderfolgende Befehle eines Pro- gramms werden in aufeinanderfolgenden Speicherzellen abgelegt. Die Umsetzung dieser Prinzipien fuhrt¨ zu der in Abbildung 2.10 dargestellten Rech- nerstruktur (nach [Lipp 08]). Das Steuerwerk (Leitwerk) holt Befehle (Bitmuster) aus dem Speicher und interpretiert sie. Diese Interpretation fuhrt¨ zu einer Umsetzung in elektrische Signale, die die ALU und den Datentransport im Prozessor steuern. Wie schon erw¨ahnt, gibt es hier auch eine Reihe von Registern, also Speicherpl¨atze mit sehr schnellem Zugriff zur lokalen tempor¨aren Zwischenspeicherung von Daten. Das k¨onnen Werte sein, die verarbeitet werden sollen oder Adressen von Werten, die aus dem Speicher geholt werden sollen. Neben dem Akkumulator, einem zentralen Register zum Rechnen und fur¨ den Daten- transfer sind vor allem das Befehlsregister (BR) zur Speicherung des aktuellen aus- zufuhrenden¨ Befehls und der Befehlsz¨ahler (BZ, auch Programmz¨ahler oder engl. pro- gram counter genannt) zur Speicherung der Adresse des aktuellen Befehls von Bedeu- tung. Die Bedeutung aller beteiligten Register, sowie der fundamentale Instruktions- zyklus wird in einem sp¨ateren Kapitel dargelegt. Eine kurze Ubersicht¨ der beteiligten Register ist in Abschnitt 2.3.1 gegeben.

Beuth Hochschule fur¨ Technik Berlin 28 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 2. GRUNDLAGEN DER RECHNERARCHITEKTUR

Abbildung 2.10: Schema eines einfachen Rechners

Abkurzung¨ Bedeutung BR Befehlsregister BRC Codeteil von BR BRA Adressteil von BR ST Register fur¨ Steuerbits BZ Befehlsz¨ahler AR Adressregister SR Speicherregister AK Akkumulator

Tabelle 2.1: von-Neumann Rechnerstruktur

Eine vereinfachte Darstellung der internen Struktur zeigt Abbildung 2.11. Alle darge- stellten Komponenten sind bereits erl¨autert worden. Die Flags dienen als Zustandsan- zeigen der ALU. Der Programmz¨ahler zeigt auf die Adresse des aktuellen, abzuarbei- tenden Befehls und wird inkrementiert (um 1 erh¨oht), sowie ein Befehl abgearbeitet wurde. Damit zeigt dieser dann auf die Adresse des n¨achsten abzuarbeitenden Befehls. Der Befehlsdecoder interpretiert den Befehl, der in die CPU geladen wurde. Eine CPU, die mehr Befehle verstehen und ausfuhren¨ kann, ben¨otigt mehr Transistoren.

Beuth Hochschule fur¨ Technik Berlin 29 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 2. GRUNDLAGEN DER RECHNERARCHITEKTUR A d r e s

Programmzähler s b u s

Befehlsregister S t e u

ALU e

Flags Befehlsdekoder, r b

Timing und Steuerung u s D a t Interne e n

Busse b Register A u s Register B Register C

Register D

Abbildung 2.11: Vereinfachtes Rechnerschema

2.3.2 Architekturrealisierungen

Es gibt grunds¨atzlich mehrere M¨oglichkeiten einen Rechner aufzubauen. In der Praxis haben sich zwei Architekturen durchgesetzt, die sich in erster Linie darin unterschei- den, wie mit Daten (Variablen) und Code (Programme) umgegangen wird, d.h. auf welche Art diese angesprochen werden. Es gibt die M¨oglichkeit diese zu trennen oder zusammenzulegen. Gleichermaßen gibt es fur¨ beide Varianten Vor- und Nachteile. Die von Neumann-Architektur (benannt nach dem Mathematiker John von Neumann, 1903 - 1957) zeichnet sich durch einen gemeinsamen Programm- und Datenspeicher (gemeinsame Busse) aus, zu erkennen in Abbildung 2.12. Es herrscht keine Unter- scheidung zwischen Code- und Datenbereichen. Der Vorteil liegt im relativ einfachen Aufbau, der Nachteil ¨außert sich darin, dass Befehle und Daten nur nacheinander ge- holt werden k¨onnen. Vertreter sind die Freescale 68HC08-Familie (68HC11, etc.) und die Intel x86-Familie.

Adressen Prozessor Speicher Daten, Befehle

Abbildung 2.12: von Neumann-Architektur

Die Harvard-Architektur (benannt nach der Harvard-Universit¨at (Cambridge, Massa- chusetts), an der der erste nach diesem Konzept arbeitende Rechner Mark I entwickelt wurde) ist gegenuber¨ der von Neumann-Architektur durch einen getrennten Programm- und Datenspeicher (getrennte Busse) gekennzeichnet. Dargestellt ist dies in Abbil-

Beuth Hochschule fur¨ Technik Berlin 30 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 2. GRUNDLAGEN DER RECHNERARCHITEKTUR dung 2.13. Dadurch kann auf Daten- und Programmspeicher gleichzeitig zugegriffen werden. Dies ist zugleich ein Vorteil gegenuber¨ der von Neumann-Architektur. Der Fakt, dass Daten und Befehle gleichzeitig geholt werden k¨onnen, erm¨oglicht einen schnelleren Programmablauf. Code im Datenspeicher kann nicht ausgefuhrt¨ werden. Vetreter sind die Atmel AVR-Plattform und die meisten DSPs (Digitale Signal Prozes- soren).

Adressen Adressen Programm- Daten- Prozessor speicher Befehle Daten speicher

Abbildung 2.13: Harvard-Architektur

Die Begriffe von Neumann-Architektur und Harvard-Architektur bezeichnen allgemei- ne Architekturkonzepte, die sich darin unterscheiden, wieviele Speicheradressr¨aume bzw. Speicherzugriffswege grunds¨atzlich vorgesehen sind. Die Unterscheidung anhand getrennter“ oder gemeinsamer“ Busse gestaltet sich in der Praxis schwierig, da es ” ” durchaus Realisierungen gibt, bei denen mehrere getrennte Adressr¨aume uber¨ den glei- chen Bus angesprochen werden. Daher ist eine Differenzierung uber¨ Adressr¨aume, d.h. ob Programm- und Datenspeicher in einem gemeinsamen Adressraum liegen oder ge- trennt adressiert werden, zweckm¨aßiger. Letztlich ist dies auch fur¨ den Programmierer entscheidend, da es die Implementierungsm¨oglichkeiten grundlegend beeinflußt. Beide Architekturen haben einige wesentliche Prinzipen gemeinsam. Es gibt einen ein- zigen Befehlsstrom, wobei Befehl fur¨ Befehl nacheinander ausgefuhrt¨ wird. Die Be- fehlsadressierung erfolgt in der Regel durch fortlaufende Inkrementierung der Befehls- adresse. Ausnahmen davon sind Verzweigungen, Unterprogrammrufe, Unterbrechungen usw. Moderne Mikroprozessoren verwenden Mischformen aus von Neumann- und Harvard- Architektur (z.B. getrennte Daten- und Befehlsbereiche, getrennte Caches, getrennte Busse, extern gemeinsamer Speicher). N¨aher wird an dieser Stelle nicht mehr auf den Themenkomplex eingegangen. Die Grundlagen der Rechnerarchitektur wurden hier insofern knapp dargelegt, als dass sie dem Verst¨andnis und der Einordung der im Folgenden behandelten Details zu Mikro- controllern und der 8051 Architektur im Besonderen in einen gr¨oßeren Kontext dienen. Fur¨ eine ausfuhrlichere¨ Darstellung sei hier auf die eigenst¨andige Vorlesung Rechner- ” architektur“, sowie entsprechende Sekund¨arliteratur verwiesen.

Beuth Hochschule fur¨ Technik Berlin 31 Prof. Dr.-Ing. Sven-Hendrik Voß 3 Befehlsausfuhrung¨ und Organisationsprinzipien

3.1 Typische externe Architekturen

Im Rahmen der Grundlagen zu Rechnerarchitekturen wurden die externe und interne Architektur eines Rechnersystems erl¨autert. Entscheidend fur¨ eine erfolgreiche Rech- nerarchitektur ist das Zusammenspiel der externen und internen Architektur. Die ex- terne Architektur legt durch den Maschinenbefehlssatz fest, wie ein Rechner von der Seite der Software her angesprochen werden kann. Dies ist die fur¨ die Codegenerierung maßgebliche Schnittstelle. Einzelne Maschinenbefehle stellen maschinennahe Elemen- taroperationen von Rechnersystemen dar. Die Implementierung des Maschinenbefehlssatzes erfolgt durch die interne Architektur. Die interne Architektur definiert den inneren Hardwareaufbau eines Rechners, sowie dessen Organisationsprinzip. Vereinfacht dargestellt bildet die interne Architektur den Maschinenbefehlssatz auf eine reale Schaltung auf Siliziumebene ab. Der Maschinen- befehlssatz hat einen entscheidenden Einfluß auf Effizienz und Kosten, schließlich geht es darum diesen m¨oglichst kostengunstig¨ - d.h. mit wenig Hardware - zu implemen- tieren. Ferner muss er auch m¨oglichst effizient - d.h. durch eine geringe Rechenzeit gekennzeichnet - implementiert werden. Externe Architekturen (Befehlssatzarchitekturen) lassen sich auf unterschiedliche Ar- ten klassifizieren. Beispielsweise durch: • Anzahl der Operanden pro Befehl (Zweiadress-, Dreiadress-Befehle) • Lage der Operanden (Register, Speicher, Stack) • Typ und L¨ange der Operanden • Operationsvorrat Die Lage der Operanden bestimmt die Form des Operandenzugriffs fur¨ eine Operation und damit die Art der prozessorinternen Speichernutzung. Sie trifft also Aussagen daruber,¨ wie die fur¨ Datenoperationen, etwa eine Addition, notwendigen Operanden vor und nach der Operation im Zugriffsbereich des Prozessors liegen. Aus diesem Grund wird diese Klassifizierung h¨aufig genutzt. Sie umfasst: • Akkumulator-Maschinen

32 KAPITEL 3. BEFEHLSAUSFUHRUNG¨ UND ORGANISATIONSPRINZIPIEN

• Stack-Maschinen • Registersatz-Maschinen

3.1.1 Akkumulator-Maschine

Die Akkumulator-Architektur ist das Organisationsprinzip vieler einfacher fruher¨ Rech- ner aber auch vieler Mikrocontroller (z.B. 6809). Sie zeichnet sich durch einen Akkumulator (ggf. auch zwei Akkumulatoren) als zentrales Register aus. Rechenergeb- nisse werden in diesem Register akkumuliert“ (daher der Name). Rechenoperationen ” beziehen sich auf einen Operanden und implizit den Akkumulator. In der Befehlscodie- rung ist somit bereits die Information enthalten welches Register als Quelle und ggf. Ziel zur Operation genutzt wird. Typische Befehle einer Akkumulator-Maschine sehen in etwa so aus: LAC m lade den Wert unter der Adresse m in den Akkumulator SAC m speichere den Inhalt vom Akkumulator nach Adresse m ADD m addiere den Inhalt vom Akkumulator mit dem Wert unter Adresse m und speichere das Resultat wiederum in den Akkumulator

Beispiel c = a + b in einer Akkumulator-Maschine

LAC a ADD b SAC c

Im Folgenden ist die Befehlsausfuhrung¨ in einer Akkumulatormaschine anhand des Bei- spiels dargestellt. Das Akkumulator-Register ist mit dem Kurzel¨ AC bezeichnet. Die roten Pfeile kennzeichnen den in der jeweiligen Phase stattfindenden bzw. mit dem je- weiligen Befehl verbundenen Datentransport. Anhand der Bedeutung der oben genann- ten typischen Befehle einer Akkumulator-Maschine lassen sich die einzelnen Schritte einfach nachvollziehen.

Adressen Adressen ac ac Daten, Befehle Daten, Befehle a

Prozessor Speicher Prozessor Speicher LAC a ADD b SAC c

Beuth Hochschule fur¨ Technik Berlin 33 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 3. BEFEHLSAUSFUHRUNG¨ UND ORGANISATIONSPRINZIPIEN

Adressen Adressen c ac b ac b Daten, Befehle Daten, Befehle a a

Prozessor Speicher Prozessor Speicher LAC a LAC a ADD b ADD b SAC c SAC c

Abbildung 3.1: Einfache Addition in einer Akkumulator-Maschine

3.1.2 Stack-Maschine Die Stack-Architektur ist dadurch gekennzeichnet, dass alle Quell- und Zieloperanden auf dem Stack (auch Stapelspeicher genannt) gespeichert und nur von dort aus auf sie zugegriffen wird. Der Zugriff seitens des Prozessors auf die Operanden erfolgt da- her implizit und in einer exakt festgelegten Reihenfolge. Diese Reihenfolge ergibt sich aus dem Funktionsprinzip eines Stack. Die Speicherung auf einem Stack erfolgt nach dem Last-In-First-Out-Prinzip (LIFO). Dabei k¨onnen Werte jeweils nur an die aktuell oberste Speicherposition geschrieben werden (mit dem Befehl push“) und auch nur ” von dieser obersten Speicherposition gelesen werden (mit dem Befehl pop“ oder sto- ” ” re“). Auf andere Speicherstellen kann nicht zugegriffen werden. Physikalisch wird der Stack typischerweise uber¨ Register (z.B. die beiden obersten Elemente) und Speicher (Rest) verteilt. Typische Befehle einer Stack-Maschine sehen in etwa so aus: PUSH m lege den Wert unter Adresse m auf den Stack ADD addiere die beiden obersten Werte des Stacks, entferne sie und lege die Summe als oberstes Element auf den Stack STORE m speichere das oberste Element auf dem Stack nach der Adresse m Beispiel c = a + b in einer Stack-Maschine

PUSH a PUSH b ADD STORE c Aufgrund des oben beschriebenen festen Schemas k¨onnen alle arithmetischen und lo- gischen Operationen nur auf den beiden obersten gespeicherten Werten ausgefuhrt¨ werden. Das bereits bekannt Beispiel der Addition von a und b verdeutlicht dies im Folgenden. Da ein Stack immer eine dynamische Strukur ist, muss der Fullstand¨ kon- tinuierlich beobachtet und identifiziert werden. Dazu dient der sog. Stackpointer. Der Stackpointer zeigt dabei immer auf den aktuellen Speicherplatz, also auf das zuletzt gepushte“ Element. Bei diesem obersten Element spricht man vom Top of Stack“ ” ” (tos).

Beuth Hochschule fur¨ Technik Berlin 34 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 3. BEFEHLSAUSFUHRUNG¨ UND ORGANISATIONSPRINZIPIEN

Adressen a Adressen tos tos Stack Stack Daten, Befehle Daten, Befehle a

Prozessor Speicher Prozessor Speicher PUSH a PUSH b ADD STORE c

b b a Adressen a Adressen tos tos Stack b Stack b Daten, Befehle Daten, Befehle a a

Prozessor Speicher Prozessor Speicher PUSH a PUSH a PUSH b PUSH b ADD ADD STORE c STORE c

c c Adressen Adressen c tos tos Stack b Stack b Daten, Befehle Daten, Befehle a a

Prozessor Speicher Prozessor Speicher PUSH a PUSH a PUSH b PUSH b ADD ADD STORE c STORE c

Abbildung 3.2: Einfache Addition in einer Stack-Maschine

3.1.3 Registersatz-Maschine Die Registersatz-Architektur basiert auf mehreren, ublicherweise¨ 16 oder 32 gleich- berechtigten Universalregistern. Abbildung 3.3 zeigt die allgemeine Struktur einer Registersatz-Maschine. Mindestens ein Operand wird aus einem der internen Prozes- sorregister bezogen, wobei dieses Register im Befehl explizit angegeben werden muss. Uberhaupt¨ kennen Registersatz-Architekturen nur explizite Operanden, entweder Re- gister oder Speicheradressen. Dass die Registersatz-Maschine - wie der Name schon sagt - auf einem Satz von Regis- tern basiert, liefert einige Vorteile. Register sind schneller als RAM-Speicher. Dadurch dass die Register als Variablenspeicher verwendet werden, kann der Speicherverkehr verringert und so die Programmausfuhrung¨ beschleunigt werden (da Register flexibler

Beuth Hochschule fur¨ Technik Berlin 35 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 3. BEFEHLSAUSFUHRUNG¨ UND ORGANISATIONSPRINZIPIEN

32x32 Bit Adressen Register- satz Daten, Befehle

Prozessor Speicher

Abbildung 3.3: Struktur einer Registersatz-Maschine und schneller sind als Speicher). Letztlich wird im Gegensatz zur Verwendung von Spei- chervariablen auch die Codierung kompakter, da Register mit weniger Bits adressierbar sind als Speicherstellen. Zwei Kriterien unterteilen die Klasse der Registersatz-Architekturen: 1. Wieviele Operanden kann ein typischer ALU-Befehl haben? 2. Wieviele Operanden durfen¨ Speicheradressen sein? Bei einem 3-Operanden Format gibt es zwei Quelloperanden und einen Zieloperan- den. OP DEST, SRC1, SRC2 d.h. DEST:= SRC1 OP SRC2 SCR1 und SCR2 (fur¨ engl.: source) bezeichnen die Quelloperanden, DEST (fur¨ engl.: destination) bezeichnet den Zieloperanden. Bei einem 2-Operanden Format muß ein Operand als Quelle und Ziel dienen, d.h. er wird durch die Operation uberschrieben.¨ OP DEST, SRC d.h. DEST:= DEST OP SRC Beispiel: ADD R5, R6 R5:= R5+R6 In der Klasse der Registersatz-Maschine macht man folgende Unterklassifizierungen: CISC- und RISC-Architekturen. Die Abkurzung¨ CISC steht fur¨ Complex Instruction Set Computer. Diese Architektur zeichnet sich durch einen sehr umfangreichen Maschinenbefehlssatz mit bis zu 500 Instruktionen aus. Es handelt sich dabei um sehr leistungsstarke Befehle mit variabler L¨ange (1-15 Bytes). Bezogen auf die hardwaretechnische Realisierung bedeutet dies jedoch einen hohen schaltungstechnischen Aufwand fur¨ die interne Ablaufsteuerung. Konstrukte h¨oherer Programmiersprachen werden durch teilweise sehr komplizier- te High-Level-Instruktionen unterstutzt.¨ Jeder Befehl kann aus mehreren Low- Level-Operationen wie Memory-Access, arithmetische Operationen oder Adress- Berechnungen durchfuhren.¨ Dies fuhrt¨ dazu, dass i.a. kurzere¨ und elegantere Program- me als bei RISC m¨oglich sind, diese jedoch mit einer l¨angeren Ausfuhrungszeit¨ (zehn und mehr Taktzyklen) einhergehen. Verglichen mit RISC werden fur¨ CISC weniger Register ben¨otigt, jedoch ist die Ar- chitektur durch komplizierte Adressiermodi (Anzahl 8-20) gekennzeichnet. Operanden k¨onnen Register und/oder Speicheradressen sein. Abbildung 3.4 verdeutlich das Prin- zip der CISC-Architektur, wobei vor allem dem letztgenannten Umstand Beachtung geschenkt werden soll, n¨amlich dass sowohl Register des Rechenwerks, als auch Spei-

Beuth Hochschule fur¨ Technik Berlin 36 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 3. BEFEHLSAUSFUHRUNG¨ UND ORGANISATIONSPRINZIPIEN cherpl¨atze die Operanden bereitstellen k¨onnen. Bekannte Vertreter der CISC-Architektur sind sie VAX 11/780-Famile (1978) und die Intel x86-Famile (1981).

Registersatz

ALU Prozessor- Prozessor speicher

Abbildung 3.4: CISC-Architekturprinzip

Beispiel c = a + b in einer CISC-Maschine

MOVE R1, a ADD R1, b MOVE c, R1 RISC-Architekturen grenzen sich elemenatar von CISC-Architekturen ab. Die Abkurzung¨ RISC steht fur¨ Reduced Instruction Set Computer. Die Entwicklung die- ser Architektur geht auf von IBM durchgefuhrte¨ Untersuchungen existenter CISC- Befehlss¨atze in den 1970ern zuruck.¨ Die Ergebnisse dieser Untersuchungen zeigten, dass nur etwa 20% des gesamten Befehlssatzes fur¨ ca. 80% der Programmlaufzeit in Anspruch genommen werden. In einer ganzen Reihe von F¨allen l¨auft die Ausfuhrung¨ einer Folge einfacherer Maschinenbefehle schneller ab als ein komplexerer Befehl mit derselben Wirkung. Dies zog die Entwicklung der RISC-Architektur in Stanford / Ber- keley nach sich [Oberschelp 00]. Die RISC-Architektur zeichnet sich durch einfachen Befehlssatz mit wenigen, i.a. gleich- langen (2-4 Bytes), einfachen Instruktionen aus. Die Anzahl der Instruktionen liegt fur¨ gew¨ohnlich bei 40-80. In der Anwendung fuhrt¨ dies dazu, dass Programme i.a. gr¨oßer sind als bei CISC, durch die Architekturunterschiede jedoch eine zwei- bis funffache¨ Leistung bei gleicher Technologie erreicht werden kann. Dies ist letztlich u.a. dem ein- heitlichen horizontalen Befehlsformat geschuldet, das ein effizientes Befehlspipelining mit gleich langen und eintaktigen Pipeline-Stufen erm¨oglicht. Zum Pipelining und des- sen Bedeutung folgen weitere Ausfuhrungen¨ zu einem sp¨ateren Zeitpunkt. Als Operanden von Verknupfungen¨ sind nur Register zul¨assig. Dies ist darauf zuruckzuf¨ uhren,¨ dass die RISC-Architektur eine Load-Store-Architektur ist, d.h. es existiert eine Aufteilung in Load/Store-Befehle fur¨ den Datentransport zwischen CPU und Speicher und arithmetische Befehle, die nur auf Registern arbeiten. Daher mussen¨ im Speicher stehende Werte immer erst in Register geladen bzw. zuruckgeschrieben¨ werden. Letztlich erm¨oglicht dies relativ einfache Adressiermodi (Anzahl 2-5). Abbildung 3.5 illustriert das Prinzip der RISC-Architektur, wobei wiederum die Resi- denz m¨oglicher Operanden beachtet werden soll. Hier werden die Operanden in Regis- tern des Rechenwerks vorausgesetzt.

Beuth Hochschule fur¨ Technik Berlin 37 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 3. BEFEHLSAUSFUHRUNG¨ UND ORGANISATIONSPRINZIPIEN

Bekannte Vertreter der RISC-Architektur sind das IBM-801-Projekt (1975), die SPARC (Scalable Processor Architecture) Maschinen (1987), sowie der PowerPC (1991).

Registersatz

ALU Prozessor- Prozessor speicher

Abbildung 3.5: RISC-Architekturprinzip

Beispiel c = a + b in einer RISC-Maschine

LOAD R1, a LOAD R2, b ADD R3, R2, R1 STORE c, R3

3.2 Befehlsausfuhrung¨

Zur Verarbeitung von Daten mussen¨ Rechnersysteme Anweisungen erhalten, wie die Daten zu bearbeiten sind. Diese maschinennahen Anweisungen werden Befehle genannt. Eine Abfolge von Befehlen ergeben ein Programm. Dieses Programm befindet sich im Speicher. Der Speicher ist ein Bereich innerhalb eines Rechnersystems, der zur Aufnahme, Aufbewahrung und Abgabe von Befehlen und Daten dient. Hier sollen nun die einzelnen Verarbeitungsphasen eines Befehls am Beispiel erl¨autert werden. Als Beispiel dient die Aufuhrung¨ einer einfachen Addition. Fur¨ die folgenden Ausfuhrungen¨ werden die Prinzipien der von-Neumann Architektur zugrundegelegt, d.h. alle beteiligten physischen Komponenten sind nach der von-Neumann Struktur zu- sammengesetzt und funktionieren nach dem von-Neumann Prinzip (vgl. Abschnitt 2.2). Der Speicher beherbergt sowohl das Programm, als auch die Daten. Ferner gilt fur¨ das im Folgenden Erl¨auterte die Annahme, dass es sich hier um ei- ne einfache Akkumulator-Maschine handelt, d.h. alle arithmetischen oder logischen Operationen basieren auf Verwendung des Akkumulator-Registers. Am Ende der Ope- rationen enth¨alt dieses auch das Ergebnis und bei Beginn einen Eingangsoperanden, falls mehr als ein Operand verarbeitet wird. Fur¨ das Beispiel der Addition bedeutet dies, dass ein Ein-Operanden Befehl den Operanden zum Akkumulator addiert und das Ergebnis wiederum im Akkumulator speichert. Hier wird davon ausgegangen, dass der Eingangsoperand, also der Wert, auf den ein anderer addiert werden soll, bereits im Akkumulator steht. Ein Befehl setzt sich zusammen aus einem Operator und einem (oder mehreren) Ope- randen3. Der Operator beschreibt die T¨atigkeit, die ausgefuhrt¨ werden soll (hier z.B.

3Es gibt auch den Sonderfall, dass keine Operanden angegeben werden, beispielsweise beim NOP-

Beuth Hochschule fur¨ Technik Berlin 38 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 3. BEFEHLSAUSFUHRUNG¨ UND ORGANISATIONSPRINZIPIEN

Addition). Dieser wird durch eine bin¨are Zahl codiert (fur¨ die Addition hier 0111 bin¨ar bzw. 7 dezimal) und Operationscode (kurz: Opcode) genannt. Der Operand ist das Element, auf dem die Operation ausgefuhrt¨ werden soll, und kann entweder eine Spei- cheradresse (wie hier z.B. Adresse 24 dezimal) oder ein Direktoperand (also eine direkt angegebene Zahl) sein. Je nachdem unterscheidet sich auch der Operationscode, so dass dadurch feststeht, ob es sich bei dem Operanden um eine Adresse oder einen Direktoperanden handelt.

Maschinenbefehl 7 24

Befehlscode Adresse 24 Addiere- Befehl à 7

Abbildung 3.6: Befehlsformat

Da das hier gezeigte Beispiel auf einer Akkumulator-Maschine basiert, ist fur¨ die Addi- tionsoperation nur die Angabe einer Adresse fur¨ den zweiten Operanden erforderlich. Der erste Operand befindet sich ja bereits im Akkumulator. Abbildung 3.6 zeigt das Befehlsformat und illustriert die Bedeutung der Felder im Maschinenbefehl gem¨aß der soeben dargelegten Grundlagen anhand des Beispiels der Addition. Der Addiere-Befehl holt den Wert unter der im Befehl angegebenen Adresse (im Beispiel Adresse 24) und addiert ihn zum Inhalt des Akkumulators. Alle folgenden Zahlenangaben beziehen sich auf die Dezimaldarstellung. Unter der An- nahme, dass der bereits im Akkumulator gespeicherte Wert 25 und der unter Adresse 24 im Speicher abgelegt Wert 200 ist, l¨aßt sich das Szenarion fur¨ den Zeitpunkt vor (Abbildung 3.7) und nach (Abbildung 3.8) Durchfuhrung¨ der Additionsoperation fol- gendermaßen skizzieren.

Adressen ac 25 Daten, Befehle 24 200

Prozessor Speicher

Abbildung 3.7: Zustand aller Operanden vor der Addition

Wie bereits in Abschnitt 2.2 beschrieben, werden die Daten zwischen Prozessor und Speicher (oder Peripherie im Allgemeinen) grunds¨atzlich uber¨ ein Bussystem transpor- tiert. Der Adressbus ist fur¨ die Ubertragung¨ der Speicheradressen vom Prozessor an

Befehl, der als Platzhalter oder zum Einfugen¨ von Wartetakten dient.

Beuth Hochschule fur¨ Technik Berlin 39 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 3. BEFEHLSAUSFUHRUNG¨ UND ORGANISATIONSPRINZIPIEN

Adressen ac 225 Daten, Befehle 24 200

Prozessor Speicher

Abbildung 3.8: Zustand aller Operanden nach der Addition den Speicher zust¨andig. Uber¨ den Datenbus erfolgt der Austausch von Daten vom und zum Prozessor. Im Rahmen der Erl¨auterung der einzelnen Verarbeitungsphasen sei den Signalwegen uber¨ die unterschiedlichen Busverbindungen Beachtung zu schenken.

pc ir Adressen or ac Daten, Befehle

Prozessor Speicher

Abbildung 3.9: Struktur des Prozessors mit allen beteiligten Registern

Fur¨ die Befehlsabarbeitung sind im Prozessor, genauer im Steuerwerk, spezielle Regis- ter vorgesehen, die je nach Phase Inhalte speichern und diese fur¨ die weiteren Aktionen interpretieren. Die Bedeutung der einzelnen Register wird deutlich, wenn die einzelnen Schritte der Befehlsabarbeitung erl¨autert werden. Abbildung 3.9 zeigt die Struktur des Prozessors mit allen beteiligten Registern. Im Einzelnen sind das, wie bereits in Abschnitt 2.3.1 vorgestellt, Folgende: • pc (, auch ip: instruction pointer): Befehlsz¨ahler • ir (instruction register): Befehlsregister • or (operand register): Speicheradressregister • ac (): Arbeitsregister Das Programm, d.h. eine Abfolge von Befehlen, befindet sich im Speicher, wobei die Befehle in der Regel hintereinander ausgefuhrt¨ werden (implizite Sequentialit¨at). Die Befehlsablauf (auch: Befehlszyklus) folgt genau dieser sequentiellen Befehlsfolge und ist streng seriell. Mikroprozessoren (zumindest jene, die dem von-Neumann Schema folgen) gehen allgemein nach nach folgendem Schema vor: Befehl holen (Interpretati- onsphase, engl.: fetch phase), Befehl abarbeiten (Ausfuhrungsphase,¨ engl.: execution phase). Dieses Schema l¨aßt sich in 4 - 5 Teilschritte gliedern. 1. Befehlsholphase (instruction fetch, IF) An welcher Speicherstelle des Programms sich der Rechner aktuell befindet, ist in dem Befehlsz¨ahler vermerkt. Dieser zeigt die Speicheradresse des n¨achsten auszufuhrenden¨ Befehls an. Von dieser Adresse wird der Befehl aus dem Speicher

Beuth Hochschule fur¨ Technik Berlin 40 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 3. BEFEHLSAUSFUHRUNG¨ UND ORGANISATIONSPRINZIPIEN

geholt und in das Befehlsregister geladen. 2. Befehlsdekodierphase (instruction decode, ID) Der aktuelle, im Befehlsregister gespeicherte Befehl wird decodiert, d.h. inter- pretiert, um weitere Aktionen entsprechend einleiten zu k¨onnen. Aus der In- terpretation des Befehls ergeben sich Informationen zur Befehlsklasse, sowie zu Art und Anzahl der ben¨otigten Operanden und deren Adressierungsformat. In Abh¨angigkeit vom Befehlsregister verzweigt die Ablaufsteuerung zur weiteren Be- fehlsverarbeitung. 3. Operandenholphase (operand fetch, OF) Der Operand (oder die Operanden, falls mehrere involviert sind), der zur Ausfuhrung¨ des Befehls notwendig ist, wird in das Speicheradressregister ubertragen¨ und abgelegt. Dabei wird unterschieden, ob Operanden aus Regis- tern geholt werden oder die Berechnung einer effektiven Adresse gem¨aß der im Befehl enthaltenen Adresse notwendig ist. Die Phase ist wesentlich von der vor- angegangenen Interpretation des Befehls abh¨angig. 4. Ausfuhrungsphase¨ (instruction execute, EX) Nach dem Laden des oder der Operanden kann der Befehl ausgefuhrt¨ werden. Maßgebend hierfur¨ ist der geladene Operationscode im internen Befehlsregister. Je nach Operationscode wird der Operand im Akkumulator ver¨andert. Im vor- liegenden Beispiel der Addition wird der Operand wird mit dem Akkumulato- rinhalt addiert und in eben diesem gespeichert. Ggf. ist dieser Phase noch das Zuruckschreiben¨ des Ergebnisses in andere interne Register oder in den externen Speicher zuzuordnen. Des weiteren muss der Befehlsz¨ahler inkrementiert werden, damit er auf den n¨achsten Befehl zeigt. Dies geschieht entweder als separater Schritt oder parallel. 1. Befehlsholphase 2. Befehlsdekodierphase

pc 73 pc 73 ir 7 24 Adressen 7 24 ir 7 24 Adressen 7 24 or ac 25 Daten, Befehle or Daten, Befehle ac 25

Prozessor Speicher Prozessor Speicher 3. Operandenholphase 4. Ausfuhrungsphase¨

pc 73 pc 73 ir 7 24 Adressen 7 24 ir 7 24 Adressen 7 24

24 24 or 200 Daten, Befehle 200 or 200 Daten, Befehle 200 ac 25 ac 225

Prozessor Speicher Prozessor Speicher

Beuth Hochschule fur¨ Technik Berlin 41 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 3. BEFEHLSAUSFUHRUNG¨ UND ORGANISATIONSPRINZIPIEN

Befehlsz¨ahler-Update Resultat

pc 74 pc 74 ir 7 24 Adressen 1 Adressen 7 24 7 24 ir 7 24 24 24 or 200 Daten, Befehle 200 or 200 Daten, Befehle 200 ac 225 ac 225

Prozessor Speicher Prozessor Speicher

Abbildung 3.10: Phasen des Befehlszyklus Dieser Befehlszyklus wird von der CPU st¨andig durchlaufen und kann in eine Reihe von Maschinenzyklen zerlegt werden. Der erste Maschinenzyklus jeder Anweisung besteht aus dem Abruf des Opcodes. Ein weiterer Maschinenzyklus wird dann ben¨otigt, wenn es sich um einen Speicherzugriff oder um eine Ein/Ausgabe handelt, damit die Da- tenubertragung¨ stattfinden kann, usw. Typische Maschinenzyklen, die innerhalb eines Befehlszyklus auftreten k¨onnen, sind: 1. Befehlsaufruf (Opcode-Fetch) 2. Speicher lesen (Memory Read) 3. Speicher schreiben (Memory Write) 4. Stack lesen (Stack Read / Stack pop) 5. Stack schreiben (Stack Write / Stack push) 6. Eingabe (Input) 7. Ausgabe (Output) 8. Unterbrechung (Interrupt) 9. Halt Die Anzahl der Maschinenzyklen variiert fur¨ unterschiedliche Befehle, so auch die Zeit- dauer einzelner Befehle. Die Befehlszyklen unterschiedlicher Befehle k¨onnen also auch unterschiedlich lang sein. Der gesamte Ablauf in der CPU wird durch einen zentralen Takt (Arbeitstakt des Prozessors) gesteuert. Jeder Maschinenzyklus besteht aus einem oder mehreren Taktperioden, deren L¨ange konstant ist und von einem Referenztaktge- ber (Quarz) abgeleitet wird. Uber¨ den Zusammenhang der Maschinenzyklen h¨angt die tats¨achliche Dauer eines Befehlszyklus also direkt auch von der Taktfrequenz der CPU ab. Die Organisation des Ablaufs in Taktzyklen, Maschinenzyklen und Befehlszyklen wird symbolisch in Abbildung 3.11 gezeigt. Der ursprungliche¨ 8051 Mikrocontroller von Intel ben¨otigte typischerweise 12 Takte pro Maschinenzyklus, neuere kompatible Nachfolger kommen mit einem Takt pro Zyklus aus. Sie sind also auch ohne h¨ohere Taktrate, allein durch Modifikation der internen Implementierung der Befehlsabarbeitung schneller.

3.3 Beschleunigung der Befehlssausfuhrung¨

Es existieren ein paar grundlegende Methoden, um die Befehlssausfuhrung¨ in einem Rechnersystem zu beschleunigen. Dies ist sicher kein thematischer Schwerpunkt im hier behandelten Umfeld, sei jedoch der Vollst¨andigkeit halber erw¨ahnt und anhand

Beuth Hochschule fur¨ Technik Berlin 42 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 3. BEFEHLSAUSFUHRUNG¨ UND ORGANISATIONSPRINZIPIEN

Programm

Befehl n-1 Befehl n Befehl n+1 Befehlszyklus Befehlszyklus Befehlszyklus

Maschinenzyklus Maschinenzyklus Maschinenzyklus

(Operationszyklus) Takt Takt Takt Takt

Abbildung 3.11: Zyklushierarchien einiger Ausfuhrungen¨ dargelegt. Als (eingeschr¨anktes) Maß fur¨ die Effizienz einer Ar- chitektur gilt die Angabe eines CPI-Wertes (Cycles per Instruction). CPI beschreibt die Anzahl der fur¨ eine Befehlsabarbeitung notwendigen Taktzyklen und damit die Per- formance eines getakteten Prozessors. Ziel der Beschleunigung einer Befehlsausfuhrung¨ muss demnach die Minimierung der Cycles per Instruction (CPI) sein. Das Problem dabei ist jedoch, dass die uberwiegende¨ Anzahl an Befehlen, wie bereits im Zusam- menhang mit den Erl¨auterungen zum Befehlszyklus erw¨ahnt wurde, nicht in einem Takt ausfuhrbar¨ sind, da sie zu komplex sind. Daher mussen¨ spezielle Techniken zur Beschleunigung der Befehlssausfuhrung¨ zur Anwendung kommen.

Befehl holen IF

Befehl decodieren ID

Operanden holen OF

Befehl ausführen EX

Abbildung 3.12: Befehlszyklus

Alle Techniken zur Beschleunigung der Befehlssausfuhrung¨ haben eine Grundidee ge- mein. Die Befehlsbearbeitung wird durch Aufspaltung in mehrere Einzelstufen (Fließ- bandprinzip) parallelisiert. Zugrundegelegt wird wiederum der bereits bekannte und in Abbildung 3.12 verkurzt¨ dargestellte Befehlszyklus. Jede Maschinenoperation wird dazu in eine Folge von Phasen zerlegt. Jede Phase deckt eine spezielle Teiloperation ab und braucht genau einen Taktzyklus (oder zumindest eine feste und determinstische Anzahl von Taktzyklen), um von einer funktionalen Verarbeitungseinheit abgearbeitet zu werden. Die funktionalen Einheiten k¨onnen mehrfach pro Zyklus benutzt werden, so

Beuth Hochschule fur¨ Technik Berlin 43 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 3. BEFEHLSAUSFUHRUNG¨ UND ORGANISATIONSPRINZIPIEN dass nicht die Notwendigkeit besteht, die Hardware zu duplizieren. Unter Einsatz se- parater, hintereinander geschalteter Funktionseinheiten ist somit also die Verarbeitung mehrerer unabh¨angiger Instruktionen in einem Takt m¨oglich. Konkret gibt es mehrere Methoden das Konzept der Fließbandverabeitung umzusetzen, n¨amlich: • Parallelisierung von Teiloperationen derselben Instruktion (Pipelining) • Parallelisierung von Teiloperationen verschiedener Instruktionen (Superpipeli- ning) • Verwendung mehrerer abgeschlossener Funktionseinheiten parallel • Verarbeitung mehrerer Instruktionen parallel durch mehrere skalare Einheiten (superskalar) • Parallelisierung von Instruktionen unterschiedlicher Prozesse/Threads (Multi- threading), Realisierung mehrerer Befehlsstr¨ange Ohne Anwendung von Maßnahmen zur Performance-Steigerung erfolgt die Verarbei- tung mehrerer Befehle nacheinander, im Prinzip in einer Schleife wie in Abbildung 3.13 dargestellt.

IF ID OF EX IF ID OF EX IF ID OF EX

Abbildung 3.13: Befehlsverarbeitung ohne Optimierung

Die vier unterschiedlichen Phasen werden pro Phase jeweils in einem Takt abgearbeitet. Es werden also pro Instruktion vier Takte ben¨otigt, d.h. der CPI-Index ist hier 4. Diese Schleife kann nun auf verschiedene Arten parallelisiert werden. Pipelining Superskalarit¨at IF ID OF EX IF ID OF EX IF ID OF EX IF ID OF EX IF ID OF EX IF ID OF EX IF ID OF EX IF ID OF EX IF ID OF EX IF ID OF EX Superpipelining Superskalarit¨at mit Superpipelining IF ID OF EX IF ID OF EX IF ID OF EX IF ID OF EX IF ID OF EX IF ID OF EX IF ID OF EX IF ID OF EX IF ID OF EX IF ID OF EX

Abbildung 3.14: Methoden zur Beschleunigung Das Pipelining ist eine Implementierungstechnik, die eine zeitlich uberlappende¨ Ver- arbeitung von Befehlen durch parallele Aktivit¨at aller Phasen erm¨oglicht. Nach Einschwingen“ der Pipeline, d.h. anf¨angliches Fullen,¨ ist durch Uberlappung¨ der ”

Beuth Hochschule fur¨ Technik Berlin 44 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 3. BEFEHLSAUSFUHRUNG¨ UND ORGANISATIONSPRINZIPIEN

Ausfuhrungsphase¨ (EX) eine Reduktion der Latenzzeiten m¨oglich4. Dies resultiert in einer h¨oheren Verarbeitungsgeschwindigkeit, bzw. erh¨ohtem Durchsatz von abgearbei- teten Befehlen pro Zeiteinheit. Im Idealfall wird pro Takt eine Instruktion fertig, d.h. der CPI-Index ist hier 1. Das Prinzip der Superskalarit¨at bewirkt im Idealfall eine Vervielfachung der Leistung durch mehrere parallele Funktionseinheiten, die derselben Phase der Befehlsabarbei- tung angeh¨oren. So ist zus¨atzlich zum Pipelining ein paralleles Ausfuhrung¨ von mehre- ren Befehlen m¨oglich, da mehr als eine Instruktion auf einmal an die Verarbeitungsein- heiten ausgegeben und abgearbeitet werden kann. Dies ist der wesentliche Unterschied zum einfachen Pipelining, bei dem immer nur eine Instruktion gleichzeitig an die Ver- arbeitung ubergeben¨ (skalar). Da pro Takt mehr als eine Instruktion abgeschlossen werden kann, ist CPI < 1 m¨oglich, theoretisch CPI = 1/k (k: Anzahl von parallelen Befehlen). Trennt man sich beim konzeptionellen Ansatz des Pipelinings von der Zuordnung, dass jede Phase genau einen Taktzyklus zur Verarbeitung durch die Verarbeitungseinheit ben¨otigt, so kommt man zum Konzept des Superpipelining. Hier wird eine zeitliche Uberlappung¨ der Befehlsabarbeitung durch Unterteilung der Befehlspipeline in mehre- re Stufen erreicht. Es entsteht somit eine feinere Unterteilung im Fließbandprinzip. Die Stufen der Pipeline haben so bereits eine kurzere¨ Durchlaufzeit, eine gr¨oßere Anzahl an Stufen erm¨oglicht zudem einen schnelleren Takt, was in einem h¨oheren Instrukti- onsdurchsatz resultiert. Verbindet man dieses Prinzip letztlich mit der Idee der Superskalarit¨at, so kann ein noch gr¨oßerer Nutzen im Hinblick auf die Befehlsbeschleunigung erreicht werden. Bei der Implementierungsvariante Superskalarit¨at mit Superpipelining ist zus¨atzlich zum Superpipelining eine parallele Ausfuhrung¨ von mehreren Befehlen durch mehrere paral- lel arbeitende Funktionseinheiten m¨oglich. Im Idealfall fuhrt¨ dies zu einer noch h¨oheren Vervielfachung der Verarbeitungsleistung. Die Voraussetzungen fur¨ eine effiziente Ausfuhrung¨ basierend auf dem Konzept der Parallelisierung k¨onnen leicht abgeleitet werden. • alle Befehle sind gleich lang (in Ausfuhrungsdauer)¨ • alle Befehle benutzen alle Phasen • jede Phase ben¨otigt in etwa die gleiche Ausfuhrungszeit¨ • pro Phase ist jeweils ein Befehl in Bearbeitung, d.h. Pipeline immer voll Es mag auf der Hand liegen, dass ein m¨oglicher Geschwindigkeitsgewinn durch Erh¨ohung der Anzahl der Pipeline-Stufen erreicht werden kann. Der Durchsatz w¨achst zun¨achst mit der Anzahl der Pipeline-Stufen. Bei gleicher Semantik und mehr Phasen wird zudem die ben¨otigte Zeit pro Phase theoretisch kleiner. Dies wird bereits beim Superpipelining ausgenutzt. Wichtig fur¨ die Entwicklung einer Pipeline ist, dass je- de Stufe die gleiche Zeit ben¨otigt, um Leerlauf zu vermeiden. Dabei muss man sich an der langsamsten Stufe orientieren, da die Taktdauer ja abh¨angig von der l¨angsten Ausfuhrungszeit¨ in einer Phase (Worst Case) ist. Ferner muss beachtet werden, dass der Zeitgewinn bei einer l¨angeren Pipeline durch Fullen¨ und Leeren der Pipeline gemindert wird. Dies gilt insbesondere bei einem Abbruch (engl.: stall, z. B. bei Sprunganweisun-

4Die Latenzzeit eines einzelnen Befehls wird nicht verringert, jedoch die Latenz der Befehle in Summe. Die Latenz des einmaligen Fullens¨ bleibt stets bestehen.

Beuth Hochschule fur¨ Technik Berlin 45 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 3. BEFEHLSAUSFUHRUNG¨ UND ORGANISATIONSPRINZIPIEN gen), der letztendlich zu l¨angeren Wartezeiten fuhrt¨ bis die Pipeline wieder gefullt¨ werden kann. Unter diesen Voraussetzungen gilt es einen sinnvollen Kompromiss zu finden. Bei Pipelining spielt auch die zugrundeliegende Prozessorarchitektur eine Rolle, da die Aufteilung der Pipeline abh¨angig von dieser ist. Pipelining bei CISC-Prozessoren ist theoretisch m¨oglich (insbesondere bei jungeren¨ CISC-Prozessoren), erfordert jedoch einen hohen Aufwand aufgrund der unterschiedlich langen und komplexen Befehle. Die Befehlsstruktur fuhrt¨ letztlich zu schlechter Auslastung der Phasen, da diese fast nie gleichzeitig ausfuhrbar¨ sind. Bei RISC-Prozessoren dagegen sind Pipelines gut reali- sierbar, nicht zuletzt wegen dem einheitlichen Befehlssatz. Schon konzeptionell ist ja jeder Befehl etwa gleich m¨achtig. Probleme k¨onnen in jedem Fall durch unausgewogene Pipeline-Fullung¨ aufgrund von Konflikten auftreten. Ein Konflikt, der zu inkorrekten Ergebnissen fuhren¨ wurde,¨ wird als Hazard, dem englischen Begriff fur¨ Gefahr, Risiko, bezeichnet. Es existieren unter- schiedliche Typen von Hazards, abh¨angig von der Charakteristik des Prozesses. Structural Hazard Versuch, dieselbe Hardware gleichzeitig fur¨ zwei verschiedene Zwecke zu verwenden Bsp: Zugriff auf gleiches Rechenwerk oder gleichzeitiger Spei- cherzugriff Data Hazard Instruktion ist abh¨angig von Resultat einer anderen, die noch in der Pipeline ist Control Hazard Entsteht durch Zeitversatz zwischen Instruktion-Fetch und Entscheidungen uber¨ den Control-Fluss (bedingte oder un- bedingte Sprunge:¨ Branches, Jumps) Hintergrund: Sprungbefehle ver¨andern Program Counter und damit Instruction-Fetch-Phase Je tiefer die Pipeline ist, desto schlimmer wirken sich Pipelinekonflikte aus. Die Ver- meidung und Aufl¨osung der vielfachen Konflikte nimmt eine zentrale Bedeutung in der Prozessorarchitektur ein, beispielsweise kann dies geschehen durch Vermeidung von Sprungen,¨ Einfugen¨ von Leerlauf, etc. Letztlich fuhrt¨ dies allerdings wiederum zu einer reduzierten Performance der Pipeline (durch die zus¨atzlichen Verz¨ogerungen).

3.4 Befehlsausfuhrung¨ bei Mikrocontrollern

Die bis hier vorgelegten Betrachtungen von Befehlss¨atzen und den Abl¨aufen von Befehlsausfuhrungen¨ haben ein Fundament geschaffen, auf dem aufbauend sich die Grundzuge¨ der Assemblerprogrammierung entwickeln lassen. Da Assemblerprogram- me faktisch auf Maschinencode-Ebene arbeiten, sei hier noch abschließend auf die Ei- genarten der Befehlssausfuhrung¨ bei Mikrocontrollern eingegangen. Diese Eigenarten werden sp¨ater noch vertieft, wenn es um die Betrachtung des internen Aufbaus und des Programmiermodells geht. Mikrocontroller beinhalten meist relativ einfach aufgebaute Rechner-Kerne. Sie sind entweder als simple von-Neumann-Maschine oder simple Harvard-Maschine. Vor allem 8-Bit und 16-Bit-Architekturen werden in großer Anzahl eingesetzt, in den letzten Jah-

Beuth Hochschule fur¨ Technik Berlin 46 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 3. BEFEHLSAUSFUHRUNG¨ UND ORGANISATIONSPRINZIPIEN ren auch verst¨arkt 32 Bit-Mikrocontroller. Der Grund ist, dass die 32-Bit-Architekturen in der Fertigung nicht viel teurer und aufwendiger sind, der Leistungsvorteil gegenuber¨ 8-Bit- und 16-Bit-Architekturen aber erheblich ist. Bei der Auswahl eines Mikrocon- trollers fur¨ eine gegebene Applikation (insbesondere im Embedded-Bereich) muss man jedoch genau abw¨agen, da die Architekturen geringerer Bitbreite in der Regel mit weniger Verlustleistung aufgrund der geringeren Hardware-Komplexit¨at auskommen. Zudem gibt es nur wenige Anwendungen, die 32 Bit ben¨otigen. Mikrocontroller besitzen keine oder meist nur zweistufige Pipelines. Dies ist nicht zu- letzt auch durch das Konzept und die Anwendungsbreite von Mikrocontrollern be- dingt. Mikrocontroller finden gr¨oßtenteils Einsatz in der Steuerung und Regelung. Diese Steuerungs- und Regelungsaufgaben werden dominiert von Interrupt-getriebenen An- wendungen. Die effiziente Bearbeitung von Interrupt-getriebenen Anwendungen wird allerdings durch Pipelining erschwert. Daher ist Pipelining im Bereich der Mikro- controller oft gar nicht wunschenswert.¨ Nachdem am Anfang dieses Kapitels nun alle g¨angigen externen Architekturen vorge- stellt wurden, stellt sich letztlich die Frage: Nach welchem Prinzip l¨auft das uberhaupt¨ bei Mikrocontrollern ab, Akkumulator-Maschine, Register-Maschine, ...? Diese Frage l¨aßt sich pauschal gar nicht beantworten. Auch hier existiert eine Vielfalt, wenn auch eingeschr¨ankt. Ursprung einer ganzen Familie von Bausteinen, so zum Beispiel der Ar- chitektur des 8051 von Intel, ist die erweiterte Akkumulator-Maschine. Die Architektur nach Art einer Register-Maschine ist ebenfalls ublich,¨ als Beispiel seien hier die Atmel AVR RISC-Architekturen genannt. Im Fokus dieser Veranstaltung steht, wie bereits in Abschnitt 1.1 erw¨ahnt, ein 8051 Derivat als typischer Low-Cost-Mikrocontroller, dessen Einsatzgebiete sich vom Steue- rungsbereich, uber¨ Automobilelektronik, der Anwendung als Kern von Chipkarten, dem Einsatz in der Computerperipherie bis hin zu Verwendung in Spielzeug erstrecken.

Beuth Hochschule fur¨ Technik Berlin 47 Prof. Dr.-Ing. Sven-Hendrik Voß 4 Adressierungsarten und Maschinenprogrammierung

4.1 Speicherorganisation

Wie bereits in Abschnitt 2.2 erw¨ahnt, sind Speicher Komponenten zur Aufbewahrung von Daten. Speicher werden ublicherweise¨ in Bytes organisiert, die Adressen des Spei- chers uber¨ den Adressbus direkt angegeben. Die Busbreite des Adressbus definiert die maximale Anzahl ansprechbarer Speicherzellen. Abbildung 4.1 zeigt die Struktur ei- nes Speichers der Gr¨oße 216 Bytes. Um diese 216 Bytes zu adressieren, ist eine 16-Bit Adresse n¨otig.

21 6-1

…….... …….... ……....

0 Speicher

Abbildung 4.1: Struktur eines Speichers

Der Speicher l¨aßt sich vereinfacht als einzeln direkt adressierbare Bytes betrachten. Die Adressen sind - auf das vorliegende Beispiel mit 16 Bit bezogen - vorzeichenlose 16-Bit-Zahlen, der Adressraum umfaßt daher 216 einzelne Bytes, das erste Byte hat die Adresse 0, das letzte 216 − 1 .

4.1.1 Alignment des Speichers Im Folgenden soll betrachtet werden wie Operanden im Hauptspeicher adressiert wer- den k¨onnen. Operanden k¨onnen Bytes (8 Bit), Words (16 Bit), Longwords (32 Bit), Quadwords (64 Bit) sein. Entsprechend ihres Formats mussen¨ Daten ausgerichtet (engl.: aligned) werden. Das heißt, dass ein Datum, das eine bestimmte Anzahl an Bytes lang ist, nur beginnend mit festen Positionen im Speicher abgelegt werden darf, z.B. Longwords nur an Adressen, die ein Vielfaches von 4 sind. Die Byte-Adresse muss also jeweils um 4 erh¨oht werden, um das n¨achste Datum ansprechen zu k¨onnen. Abbil- dung 4.2 veranschaulicht diesen Sachverhalt. Hier sind die Speicheradressen, die durch 4 teilbar sind, die naturlichen¨ Grenzen fur¨ das Ablegen von Longwords.

48 KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

16 21 6-1 2 -1 ….. ….. …….... ….. …….... 68 67 +4 64 64 …….... …….... …….... …….... 0 0 Speicher Speicher

Abbildung 4.2: Alignment von Daten im Speicher Es gibt unterschiedliche Konventionen wie die Bytes eines Datentypen anzuordnen sind. Die Byte-Reihenfolge definiert die Speicherorganisation fur¨ Daten der L¨ange ei- nes Vielfachen eines Bytes (Word, Longword, etc.) im Speicher. Man unterscheidet, ob das niedrigstwertige Byte an der h¨ochsten Adresse ( big endian“) oder der niedrigsten ” Adresse ( little endian“) gespeichert wird. In Big-Endian-Darstellung ist die Adresse ” eines Datums vom Datentyp Word (16 Bit) die des h¨ochstwertigsten ( linken“) By- ” tes, in Little Endian die des niederwertigsten ( rechten“) Bytes. Abbildung 4.3 zeigt ” die unterschiedlichen Speicherungsvarianten fur¨ die Hexadezimalzahl 1234h in einem Word.

21 6-1 21 6-1 …….... …….... …….... …….... …….... …….... 65 34 65 12 64 12 64 34 …….... …….... …….... …….... …….... …….... 0 0 Speicher Speicher „big endian“ „little endian“

Abbildung 4.3: Konventionen der Byte-Reihenfolge

Die unterschiedlichen Konventinen sind insbesondere dann zu beachten, wenn Daten byteweise zwischen verschiedenen Rechnersystemen ubermittelt¨ werden oder Speicher- bereiche als Folge von Bytes in einem Debugger betrachtet werden.

Beuth Hochschule fur¨ Technik Berlin 49 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

Name Little Endian Big Endian ( Intel-Notation“) ( Motorola-Notation“) ” ” Reihenfolge niedrigstes Byte zuerst h¨ochstes Byte zuerst Vorteil kleinerer Datentyp liegt auf Hex-Dump problemlos lesbar gleicher Adresse Nachteil Hex-Dump byteweise verdreht Adress-Offset bei Zugriff auf kleineren Datentyp Vertreter Intel i8080, Z80, 80x86, Pen- MIPS, Motorola 6502, SPARC, tium; Siemens C166; Atmel 68x00; Intel 8051 und Deri- AVR, ATmega, ATtiny; Texas vate, z.B. Cypress AN2131, Instruments MSP430, VAX, CY7C68013 Alpha

Tabelle 4.1: Little Endian vs. Big Endian

4.1.2 Grundlagen der Adressraumverwaltung Der Adressraum ist eine Abstraktion des physikalischen Speichers und stellt eine zu- sammenh¨angende Menge von Adressen plus deren Inhalte dar. Er umfasst Bereiche fur¨ Daten, Programmcode und ggf. Peripherie. Analog zur Abh¨angigkeit der physischen Gr¨oße des Speichers ist auch die maximale Gr¨oße des Adressraumes definiert durch die Breite des Adressbusses.

Adressen Prozessor Speicher Daten, Befehle

Abbildung 4.4: von Neumann-Architektur im Detail

Adressen Adressen Programm- Daten- Prozessor speicher Befehle Daten speicher

Abbildung 4.5: Harvard-Architektur im Detail In diesem Zusammenhang sollten noch einmal die Unterschiede von von-Neumann- Architektur und Harvard-Architektur aufgegriffen werden. Beides sind Architektur- konzepte, die sich darin unterscheiden, wieviele Speicheradressr¨aume bzw. Speicher- zugriffswege grunds¨atzlich vorgesehen sind. Adressr¨aume sind also jeweils von dem eingesetzten Konzept abh¨angig. Abbildung 4.4 und Abbildung 4.5 zeigen beide Archi- tekturen im Detail. Bevor auf die Besonderheiten der Adressraumgestaltung im Hinblick auf die zugrun-

Beuth Hochschule fur¨ Technik Berlin 50 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG deliegende Architektur n¨aher eingegangen wird, sei zun¨achst ganz allgemein auf die unterschiedlichen Bereiche eines Adressraumes verwiesen. Der Adressraum ist typi- scherweise in vier Bereiche aufgeteilt: 1.f ur¨ das in Maschinencode ubersetzte¨ Programm (Programmcode) 2.f ur¨ statische Daten, z.B. in einem Hauptprogramm deklarierte global verfugbare¨ Arrays 3. einen Stackbereich zur Unterstutzung¨ u.a. von Funktionsaufrufen aus einem Hauptprogramm 4.f ur¨ dynamische Daten, die w¨ahrend der Laufzeit entstehen, z.B. Parameter, Va- riablen, Zwischenergebnisse, ... Nur die Bereiche fur¨ das Programm und die statischen Daten sind zum Zeitpunkt der Programmierung der Hardware in ihrer Gr¨oße bekannt. Die anderen Bereiche k¨onnen theoretisch beliebig wachsen.

push a push b pop b pop a

b wie Stack- vorher pointer a a a

vorheriger Inhalt

Abbildung 4.6: Organisation eines Stack

In Abbildung 4.6 ist das bereits aus Abschnitt 3.1 bekannte Stack-Prinzip aufgegriffen und allgemeingultig¨ dargestellt. Der Stack spielt in der Mikroprozessortechnik eine besondere Rolle. Die prim¨aren Anwendungsbereiche des Stacks sind Folgende: • Unterprogrammsprunge:¨ Rucksprungadresse¨ landet auf dem Stack, wird bei Rucksprung¨ wieder in den Programmz¨ahler geladen; Ubergabe¨ von Parametern an Unterprogrammaufrufe • Lokale Variablen (mit beschr¨anktem Gultigkeitsbereich):¨ werden auf Stack ab- gelegt und bei Rucksprung¨ aus der Routine wieder verworfen (in funktionalen Sprachen wie C, Pascal, etc.) • Interrupt Requests: Rucksprungadresse¨ fur¨ die Behandlung von Interrupts, ge- rettete Registerinhalte, Prozessorstatusregister werden auf dem Stack gelagert Nahezu jeder aktuelle Mikrocontoller verfugt¨ uber¨ einen Stackbereich. Der Stack ist eine spezielle Speicherstruktur (LIFO), die meistens nicht eigenst¨andig physikalisch implementiert ist. Stattdessen wird ein Teil des RAM-Speichers entsprechend betrie- ben, dass er sich wie ein Stack verh¨alt. Es wurde bereits darauf hingewiesen, dass immer ein sogenannter Stack-Pointer ben¨otigt wird, der die aktuelle Speicherplatzadresse ver- waltet. Der Inhalt eines Stacks kann dynamisch wachsen und schrumpfen. Nach dem LIFO- Prinzip beziehen sich Lese- und Schreibzugriffe immer auf den obersten Teil des Stacks (Top-of-Stack). Abbildung 4.6 verdeutlicht dies anschaulich. Die Schreibzugriffe betref- fen dabei immer das n¨achste freie Element, Lesezugriffe dagegen das oberste besetzte Element, das gleichzeitig fur¨ neue Schreibzugriffe freigegeben wird.

Beuth Hochschule fur¨ Technik Berlin 51 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

4.1.3 Adressraum bei von-Neumann Je nach Auslegung der Architektur gestaltet sich die Adressraum-Verwaltung. Bei von Neumann-Architektur gibt es nur einen einzigen Speicheradressraum und einen einzi- gen Zugriffsweg. Daten- und Codespeicher werden daher mit derselben Befehlsgruppe abgearbeitet. Vereinfacht ausgedruckt:¨ Es gibt aus der Sicht des Programmierers nur einen einzigen, von Adresse 0 an fortlaufend adressierbaren Speicher, der alle Program- me, Daten, deskriptive Angaben usw. aufnimmt, die fur¨ die laufende Arbeit ben¨otigt werden. Der Vorteil besteht in der Flexibilit¨at mit der Speicherkapazit¨at bzgl. Pro- grammcode und Daten. Programme lassen sich als Daten behandeln, d.h. mit ublichen¨ Maschinenbefehlen transportieren, ¨andern usw.) Abbildung 4.7 zeigt ein Beispiel fur¨ ein Speicherlayout fur¨ die obengenannten vier Adressraumbereiche.

16 2 -1 Dynamische Daten

Stack Statische Daten 0 Programm Speicher

Abbildung 4.7: Adressraum bei von Neumann

Wichtige Kriterien fur¨ die Zuordnung von Adressen (zu Befehlen und Variablen) im Speicherbereich sind Relozierbarkeit, d.h. Verschiebbarkeit der Bereiche im Adress- raum, und Geschwindigkeit. Befehle und Daten werden nicht absolut adressiert. Statt- dessen findet die Addressierung relativ zu in Registern (Referenzzeigern) gehaltenen Referenzadressen statt. Der Zugriff auf Variablen wird uber¨ die register-relative Adres- sierung realisiert. Was das bedeutet, wird im Abschnitt uber¨ die verschiedenen Adres- sierungsarten erl¨autert. Ein Referenzzeiger fur¨ globale Daten gibt die Anfangsadresse des statischen Datenbereichs an, von der ausgehend relativ addressiert wird. Bezuglich¨ der Geschwindigkeit als zweites Kriterium sei anzumerken, dass die schnellste M¨oglichkeit fur¨ die Ubergabe¨ von Parametern und Resultaten die Benutzung von Regis- tern ist. Zudem ist bei Verzweigungen, Mehrfachaufrufe und ¨ahnlichem die Rettung der Registerinhalte notwendig. Dafur¨ ist u.a. der Stackbereich erforderlich. Abbildung 4.8 zeigt ein durch Zeiger zur Zuordnung der Speicherbereiche erg¨anztes Speicherlayout.

4.1.4 Adressraum bei Harvard Betrachtet man nun die Adressraum-Verwaltung bei der Harvard-Architektur, so er- gibt sich der wesentliche Unterschied darin, dass es zwei Speicheradressr¨aume gibt: einen fur¨ Daten, einen fur¨ Befehle. Daten- und Codespeicher werden daher mit eigenen Befehlsgruppen verarbeitet. Aufgrund der Trennung von Daten und Code k¨onnen der Daten- und der Codespeicher jeweils denselben Adressraum verwenden. Man unter-

Beuth Hochschule fur¨ Technik Berlin 52 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

16 2 -1 Dynamische Daten

stack pointer Stack data pointer Statische Daten pc Programm 0 Speicher

Abbildung 4.8: Adressraum bei von Neumann mit Zeigern scheidet zwischen echten Harvard-Maschinen und Maschinen mit Harvard-Architektur gem¨aß der technischen Auslegung. Bei echten Harvard-Maschinen gibt es eine gesonderte Speicheranordnung je Adress- raum (d.h. getrennten Programmspeicher und Datenspeicher). Beide Speicheranord- nungen sind uber¨ unabh¨angige Zugriffswege (Speicherbusse) erreichbar. Ein Archi- tekturbeispiel fur¨ eine echte Harvard-Maschine ist die Atmel AVR Mikrocontroller- Reihe. Bei Maschinen mit Harvard-Architektur gibt es zwar beide, logisch getrennte Adressr¨aume, jedoch nur einen einzigen gemeinsamen Speicherzugriffsweg. Als Archi- tekturbeispiel kann der Intel 8051 Mikrocontroller herangezogen werden. Durch diese Art der Adressraum-Verwaltung lassen sich mehrere Vorteile ableiten. Der gleichzeitige Zugriff auf Daten und Befehle erm¨oglicht eine h¨ohere Performance. Durch die physische Trennung ist zudem eine gezielte Aufwandsoptimierung m¨oglich, d.h. beide Speicher lassen sich gezielt hinsichtlich Zugriffsbreite, Technologie (RAM / ROM) optimal auslegen. Die zwei Adressr¨aume bieten zudem ein h¨oheres Adres- sierungsverm¨ogen, genau genommen eine Verdopplung des Adressierungsverm¨ogens. Abbildung 4.9 zeigt ein Beispiel fur¨ ein Speicherlayout fur¨ die bereits bekannten vier Adressraumbereiche nach Harvard-Organisation.

Datenadressen Befehlsadressen

16 16 2 -1 Dynamische 2 -1 Daten data pointer Statische Daten

pc Programm stack pointer Stack 0 0 Daten- Programm- speicher speicher

Abbildung 4.9: Adressraum bei Harvard

Um dieses Schema praxisrelevanter zu verdeutlichen, wird ein konkretes Beispiel fur¨

Beuth Hochschule fur¨ Technik Berlin 53 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG einen realen Mikrocontroller herangezogen (Abbildung 4.10). Aus gegebenem Anlaß sei hier der Intel 8051 Mikrocontroller dargestellt. Dessen Handhabung ist nach dem Harvard-Prinzip ausgelegt, d.h. es werden getrennte Adressr¨aume fur¨ Programm und Daten verwendet. Allerdings sind beide Speicher physisch nicht getrennt, d.h. der 8051 hat nur einen einzigen Speicherbus.

getrennte Adressräume

16 16 2 -1 Dynamische 2 -1 Daten data pointer Statische Daten

pc Programm stack pointer Stack 0 0 Speicher Speicher

aber: gemeinsamer Speicherbus

Abbildung 4.10: Harvard-Adressraum beim 8051 Mikrocontroller

Die Adressr¨aume teilen sich beim 8051 wiederum jeweils in internen und externen Speicherbereich. So kommt es vor, dass mehrere Adressr¨aume dieselbe Adresse haben. Dies macht den Umgang in der Praxis recht anspruchvoll, da eine eindeutige Zuordnung erforderlich ist. Mehr dazu wird sp¨ater im Rahmen der Erl¨auterungen zum Speicher- modell des 8051 Mikrocontrollers vermittelt. Nachdem nun die unterschiedlichen Adressraum-Gestaltungsvarianten erl¨autert wur- den, sei nun auf die Bedeutung in der Praxis hingewiesen. Die meisten Prozessoren und gr¨oßere Mikrocontroller sind zumindest vom Verhalten her von-Neumann-Maschinen. Im internen Aufbau zeichnet sich jedoch die Tendenz ab, die Vorteile beider Archi- tekturen zu vereinigen. Harvard-Architekturen finden sich bei den meisten DSPs und kleinen Mikrocontrollern.

4.2 Adressierungsarten

Eine CPU bietet eine Reihe von M¨oglichkeiten, die Operanden fur¨ eine Rechenoperation zu bestimmen, zu adressieren. Diese M¨oglichkeiten bezeichnet man als Adressierungs- arten. Adressierungsarten legen die Art des Datenzugriffs fest. Mit deren Hilfe wird die Adresse eines Objektes spezifiziert, auf die zugegriffen werden soll. Das kann eine Konstante, ein Register oder ein Speicherplatz im Hauptspeicher sein. Wie der Befehlssatz, die Anzahl und Art der vorhandenen Register, ist auch die Spei- cheradressierung von Mikroprozessor zu Mikroprozessor unterschiedlich und in der Re- gel nicht auf andere Typen anwendbar. So unterstutzt¨ der x86 beispielsweise andere Adressierungsarten als ein 8051 oder AVR, MSP430, M16C oder HC08. Hinzu kommen abh¨angig vom Prozessortypen spezifische Erweiterungen und Segmentierungen, sowie

Beuth Hochschule fur¨ Technik Berlin 54 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG v¨ollig unterschiedliche Syntax-Konventionen fur¨ die Notation der Adressierungen. Eine allgemeine Betrachtung macht daher in diesem Zusammenhang keinen Sinn. Bezuglich¨ der Adressierungsarten wird gleich auf den 8051 Mikrocontroller Bezug genommen. Im Folgenden werden die wesentlichen Adressierungsarten des 8051 Mikrocontrollers (Akkumulatormaschine) betrachtet. Beim 8051 gibt es folgende Adressierungsm¨oglichkeiten: • Unmittelbare (Immediate) Adressierung (Direkt-Wert) • Register-Adressierung • Direkte Adressierung • Register-indirekte Adressierung • Indizierte Adressierung Sie unterscheiden sich in • der Anzahl ben¨otigter Befehls-Bytes • der Befehlsausfuhrungszeit¨ • der m¨oglichen Zugriffszielen Abschnitt 4.2 zeigt eine Ubersicht¨ der Adressierungsarten des 8051 Mikrocontrollers. Als Hinweis sei angemerkt, dass in vielen Assemblern als ubliche¨ Notation # fur¨ Kon- stante und @ fur¨ indirekte Adressierung steht. In den hier aufgefuhrten¨ Beispiele findet diese Konvention ebenfalls Anwendung. Abbildung 4.11 zeigt ein Prinzipschema fur¨ die beteiligte Komponenten an den im Folgenden dargestellen Adressierungsvarianten.

Adressierungsart Beispiel Unmittelbare Adressierung MOV R1, #15 Register-Adressierung MOV A, R0 Direkte Adress. MOV R0, 35h MOV R0, symb Adr Register-indirekte Adressierung MOV A, @R0 Indizierte Adressierung MOVC A,@A+DPTR

Tabelle 4.2: Adressierungsarten des 8051 Mikrocontrollers

A ... R1 R0

Prozessor Speicher

Abbildung 4.11: Beteiligte Komponenten fur¨ die Adressierung

Bevor die unterschiedlichen Adressierungsarten im Detail beleuchtet werden, vorab noch ein paar Hinweise zur Darstellung: Die Adressierungsarten werden hier an dem Befehl mov (engl.: move, also bewege nach...“) beispielhaft erl¨autert. Es wird die ”

Beuth Hochschule fur¨ Technik Berlin 55 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

Intel-Assemblernotation MOV Ziel, Quelle“ verwendet, mehr zu den Kurznamen fur¨ ” Befehle (genannt Mnemonics) in Kurze.¨ Beim 8051 k¨onnen A (Akkumulator), R0...R7 (Speicher der Registerb¨anke), DPTR (16 Bit Datenpointer) u.a. als Register der CPU bezeichnet werden (vgl. Abbildung 4.11 und nachfolgende Abbildungen). Eigentlich sind diese Register physisch im internen RAM untergebracht (mehr dazu sp¨ater unter Speichermodell des 8051 Mikrocontrollers“). ” 4.2.1 Unmittelbare Adressierung Bei der unmittelbaren Adressierung ist der Operand Teil des Maschinenbefehls und befindet sich zusammen mit ihm als Konstante im Programmspeicher (unver¨anderlich). Da keine Referenzierung auf einen Wert z.B. im Speicher oder Register stattfindet, ist die Adresse der Befehl selbst (Laden von Konstanten). Damit ein ubergebener¨ Zahlwert als konstanter Operand interpretiert wird, muss das Zeichen # vorangestellt werden. Darauf wurde bereits hingewiesen. Abbildung 4.12 veranschaulicht die unmittelbare Adressierung mit einer Konstanten als Operand.

Befehl Opcode Operand

A ... R1 „#15" R0

Prozessor

Abbildung 4.12: Unmittelbare Adressierung

4.2.2 Register-Addressierung Bei der Register-direkten Adressierung ist der Operand ein Register im Prozessor. Der Name des Registers wird direkt angegeben. Beim 8051 k¨onnen folgende Register verwendet werden: A, B, R0 bis R7 und DPTR (16 Bit). Abbildung 4.13 illustriert die Register-Addressierung.

4.2.3 Direkte Adressierung Die direkte Adressierung ist dadurch gekennzeichnet, dass die effektive Speicheradresse direkt als Operand einer Operation angegeben wird. Die Adresse der Speicherzelle steht also direkt und vollst¨andig zusammen mit dem Maschinenbefehl im Progammspeicher.

Beuth Hochschule fur¨ Technik Berlin 56 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

Befehl Opcode Registerbezeichner

A ... R1 R0 Operand

Prozessor

Abbildung 4.13: Register-Addressierung

Die Gesamtheit der m¨oglichen Adressen bildet den Adressbereich dieser Adressierungs- art. Beim 8051 umfasst dieser alle Adressen im internen Speicher (0..7Fh und SFR). Die bei der direkten Adressierung stattfindende Referenzierung auf den Speicher stellt Abbildung 4.14 anschaulich dar.

Befehl Opcode Speicheradresse

…….... …….... Operand

……....

Speicher

Abbildung 4.14: Direkte Addressierung

4.2.4 Register-indirekte Adressierung Bei der Register-indirekten Adressierung zeigt der Inhalt eines Adressregisters auf die Speicheradresse eines Operanden. Der Inhalt des angegebenen Registers, hier als Adressregister bezeichnet, wird also einfach als Adresse interpretiert. Ziel der Adres- se ist eine Speicherzelle im Speicher. Das Register fungiert also als Zeiger auf diese Speicherzelle. Fur¨ Zugriffe ins interne RAM (Adressen 0..FFh) dienen beim 8051 die Register R0 bis R7, fur¨ Zugriffe ins externe RAM (Adressen 0..FFFFh) dient das DP- TR Register. Abbildung 4.15 veranschaulicht die indirekte Adressierung mittels eines in einem Register verwalteten Zeigers.

Beuth Hochschule fur¨ Technik Berlin 57 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

Befehl Opcode Registerbezeichner

…….... A ……...... Operand R1 R0 Adresse ……....

Prozessor Speicher

Abbildung 4.15: Indirekte Addressierung

4.2.5 Indizierte Adressierung Die indizierte Adressierung bildet die Summe eines Registerinhaltes und eines weiteren Indexregister, um die Adresse des Operanden zu bilden.

Befehl Opcode Registerbezeichner

…….... A Index + ……...... Operand R1 R0 …….... DPTR Basisadresse Prozessor Speicher

Abbildung 4.16: Indizierte Addressierung

Ziel der Adresse ist wiederum eine Speicherzelle im Speicher. Dabei verweist ein Re- gister auf den Ort, an dem der erste Wert abgelegt ist. Der Wert des zweiten Registers wird als Offset zur ersten Adresse hinzuaddiert, das Ergebnis ist schließlich die Adresse des Ziels im Speicher. Damit sind Datenstrukturen beliebiger Gr¨oße und mit beliebigem Abstand m¨oglich. Die Adresse berechnet sich aus den Prozessorregistern A + DPTR oder A + PC.

Beuth Hochschule fur¨ Technik Berlin 58 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

Programm- Register des Datenspeicher speicher (Code) Prozessors

Unmittelbare Operand Adressierung

Register- Register- Operand Adressierung bezeichner

Direkte ganze Operand Adressierung Adresse

Register-indirekte Register- Adresse Operand Adressierung bezeichner

Abbildung 4.17: Zusammenfassung zu Addressierungsarten

Im in Abbildung 4.16 gezeigten Beispiel wird das DPTR Register mit A als Indexre- gister verwendet. Genutzt wird diese Adressierungsart vornehmlich fur¨ den Zugriff auf Programmspeicher oder fur¨ absolute Sprunge.¨ Abschließend sei in Abbildung 4.17 eine Zusammenfassung zu den Adressierungsarten gegeben.

4.3 Maschinenprogrammierung

Die Lehrgebiete der Rechnerarchitektur und der maschinennahen Programmierung sind eng miteinander verbunden. Das Verst¨andnis der grundlegenden Rechnerarchitektur ist essentiell zum Verstehen und Erlernen der systemnahen Programmierung in Assembler, denn zum Programmieren auf blanker Hardware muss deren Wirkprinzipien verstanden sein. Daher wurde im vorliegenden Skript zun¨achst ausgiebig auf die Grundlagen der Rechnerarchitektur eingegangen. Der grunds¨atzliche Aufbau eines Universalrechners wurde behandelt und die einzelnen Funktionseinheiten diskutiert. Nun wird schließlich die Brucke¨ zur Maschinenprogrammierung geschlagen.

4.3.1 Rechnerarchitektur und Programmierung Was versteht man unter dem Begriff Programmierung uberhaupt?¨ Die Anwort ist ebenso knapp wie die Frage. Es ist die Uberf¨ uhrung¨ einer algorithmisch formulierten L¨osungsidee in ein Programm einer Programmiersprache. Das Programm selbst besteht aus einzelnen Schritten, den (Programm-)Anweisungen oder Befehlen (vgl. Kapitel 3). Es gibt eine ganze Hierarchie von Programmiersprachen, die von der direkten Program- mierung auf Maschinenebene uber¨ die maschninennahe Sprache bis zum hohen Niveau der h¨oheren Sprachen reicht, illustriert in Abbildung 4.18.

Beuth Hochschule fur¨ Technik Berlin 59 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

Höhere Sprachen Maschinennahe Abstraktion Sprachen Maschinen- sprachen

Abbildung 4.18: Hierarchie von Programmiersprachen

In Abbildung 4.19 ist eine detailliertere Sicht auf die Hierarchie der Programmier- sprachen gegeben. Erg¨anzt wird die Darstellung durch Beispiele fur¨ die jeweilige, die einzelne Abstraktionsebene charakterisierende Programmiersprache, sowie durch spezi- fische Eigenschaften des Programmieransatzes. Eine hierarchische Einteilung der Pro- grammiersprachen l¨asst sich sowohl klassisch nach Generationen (gem¨aß der Entste- hungsfolge), als auch nach weiteren Einteilungsmerkmalen durchfuhren,¨ beispielsweise ob es sich um eine ablauf- oder inhaltsorientierte oder eine objektorientierte Sprache handelt.

Objektorientierte Sprachen der Objekte - Attribute, Methoden, Sprache Klassen, Klassenhierarchien, (C++, C#, Java, ...) 5. Generation Vererbung n e h

c Deklarative Sprache inhaltsorientiert, nicht ablauf- a Sprachen der r (SQL, Prolog, ... ) orientiert, anwendernah, p

s SELECT * FROM Tabelle 4. Generation Berichtsgeneratoren, ... h c o H Prozedurale/Imperative Sprachen der ablauforientiert, Kontroll- Sprache (Pascal, C, ...) strukturen, Unterprogramme, IF a > 0 THEN ... 3. Generation komplexe Datentypen, ...

Maschinennahe Sprache Sprachen der (Assembler) prozessorspezifisch, Einzelbefehle ADDL R0,R1 2. Generation

Maschinensprache Sprachen der prozessorspezifisch, 01000111100011... 1. Generation Kombination aus Bits

Abbildung 4.19: Programmierung auf verschiedenen Abstraktionsebenen

Bei der Programmierung in Maschinensprache (1. Generation) werden Befehle di- rekt in einer Maschinensprache angegeben, d.h. als Folge von Nullen und Einsen (Bin¨arcode). Diese Programmdarstellung ist unubersichtlich,¨ aufw¨andig zu schreiben und fehleranf¨allig bei der Eingabe. Da die Darstellung in Bin¨arcode verh¨altnism¨aßig viel Platz einnimmt, ist es deshalb ublich,¨ die gleichen Daten in hexadezimaler Dar- stellung aufzulisten. Da sich der Befehlssatz von Rechner mit unterschiedlichen Pro- zessoren im allgemeinen deutlich unterscheidet, sind in Maschinensprache geschriebene

Beuth Hochschule fur¨ Technik Berlin 60 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

Programme nur sehr schwer ubertragbar.¨ Sie sind hardwareabh¨angig, d.h. prozessor- spezifisch. Die direkte Programmierung in einer Maschinensprache wird heute kaum noch verwendet. Um die Programmierung zu vereinfachen, wurden Abkurzungen,¨ d.h. symbolische Be- zeichner fur¨ die Gruppen von Einsen und Nullen verwendet, aus denen die Maschi- nensprache besteht. Die Verwendung dieser symbolischen Bezeichner, auch Mnemonics genannt, kennzeichnet die Assemblerprogrammierung als Vertreter der maschinenna- hen Sprache (2. Generation). Eine Assembleranweisung wird in genau einen Maschi- nenbefehl umgesetzt, d.h. es werden zur Programmerstellung nur elementare Opera- tionen genutzt, die eine Eins-zu-Eins-Entsprechung in der Maschinensprache haben. Daher sind auch Assemblerprogramme an einen bestimmten Prozessortyp gebunden, also prozessorspezifisch. Aus diesem Grund werden sowohl Sprachen der 1., als auch der 2. Generation als maschinenorientierte Sprachen bezeichnet. Ab Sprachen der dritten Generation spricht man von h¨oheren Programmiersprachen (auch Hochsprachen). Erste h¨ohere Programmiersprachen entstanden ab Mitte der funfziger¨ Jahre. Prozedurale bzw. imperative Sprachen als Sprachen der dritten Genera- tion (z.B. Fortran, Cobol, Pascal, Basic, C) unterstutzen¨ unmittelbar die Notation von Algorithmen, sie sind weitgehend anwendungsneutral und nicht mehr prozessorspezi- fisch. Durch das h¨ohere Abstraktionsniveau sind Programme besser lesbar, mussen¨ aber vor der Ausfuhrung¨ mittels eines Compilers in Maschinensprache ubersetzt¨ werden. Programme sind weitgehend portabel, d.h. dasselbe Programm kann auf unterschied- lichen Maschinen laufen. Dies macht eine Neu-Compilation fur¨ die jeweilige Maschine erforderlich. Typischerweise sind Programme in Sprachen ab der dritten Generation weniger effizient als optimierte Programme in Assemblersprache. Sprachen der 4. Generation, auch deklarative Sprachen genannt (z.B. SQL, Prolog), sind anwendungsbezogen (applikative Sprachen). Sie stellen im Allgemeinen die wich- tigsten Gestaltungsmittel von Sprachen der 3. Generation zur Verfugung,¨ zus¨atzlich jedoch Sprachmittel zur Ausl¨osung von relativ komplexen, anwendungsbezogenen Ope- rationen, beispielsweise zum Zugriff auf Datenbanken und zur Gestaltung von Benut- zeroberfl¨achen. Objektorientierte Sprachen (C++, C#, Java, ...) versuchen schließlich, die in traditio- nellen Programmen ubliche¨ Trennung von Daten und Funktionen aufzuheben. Daten und die auf sie zugreifenden Funktionen werden zu Einheiten, den Objekten, zusam- mengefasst, die dann uber¨ den Austausch von Nachrichten miteinander kommunizie- ren. Mit den Sprachen der 3. bis 5. Generation wird eine weitgehende Hardwareun- abh¨angigkeit angestrebt. Die Darstellung der Probleml¨osung (3. Generation) bzw. des Problems selbst (4. und vor allem 5. Generation) ruckt¨ st¨arker in den Mittelpunkt. Diese Sprachen lassen sich auch als problemorientierte Sprachen kennzeichnen. Programme in h¨oheren Programmiersprachen k¨onnen nicht direkt durch das Rech- nersystem interpretiert werden, sondern mussen¨ durch Ubersetzungsprogramme¨ in die Maschinensprache uberf¨ uhrt¨ werden. Dazu wird ein Programm in einer Hochsprache vom Compiler (Ubersetzer)¨ in ein Programm in Assemblersprache fur¨ die spezifische Prozessorarchitektur ubersetzt.¨ Anschliessend wandelt der Assembler dieses in einen Objektcode um. Das ist eine Art Maschinencode, der aber noch nicht auf spezifische Adressen im Prozessor bezogen ist. Er enth¨alt also noch keine absoluten Adressen.

Beuth Hochschule fur¨ Technik Berlin 61 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

Man spricht von relocatable code. Anschließend legt der Linker (auch Binder genannt) fest, wo dieser Objektcode im Programmspeicher des Prozessors stehen soll, und er- setzt die relativen Adressen des Objectcodes durch absolute Adressen des Prozessors. Abbildung 4.20 verdeutlicht dies anschaulich. Erst ab diesem Schritt ist der Code im Prozessor lauff¨ahig. Dieses Stadium nennt man nun executable code. Sodann kann das Maschinenprogramm in den Speicher des Mikrocontrollers geladen werden. Der Weg auf die Hardware geht also immer uber¨ die Assembler-Ebene.

… for (i=0; i<=7; i++) Hochsprache PortB = (1 <<); _delay(200); PortB = 0x00; ... Compiler

… Assembler-Code mov A,#00000001b schleife: mov P0, A rl A jmp schleife ... Assembler

Objekt-Code … 34 4A 55 58 14 9A 91 45 7A 94 34 14 29 61 88 19 FE FB BA 11 37 ... … 58 14 9A 91 88 DD CB 34 14 29 61 56 CC DA Linker 88 19 FE FB BA 11 37 ...

Abbildung 4.20: Von der Hochsprache zum Maschinencode

Wie bereits in Abschnitt 1.1 erl¨autert, ist ein in Assembler geschriebenes Programm stets effizienter, schneller und optimal auf die unterliegende Hardware abgestimmt. Dies ist der Grund warum eine maschinennahe Programmierung - gerade im Hinblick auf die limitierten Ressourcen eines Mikrocontrollers - von so großer Bedeutung und hier das Mittel der Wahl ist. Mit der Programmierung in Assembler k¨onnen maschinenspe- zifische Besonderheiten genutzt werden, auf die ein Zugriff mit h¨oheren Programmier- sprachen gar nicht m¨oglich w¨aren. Da ein Assemblerprogramm auch nicht von einem Compiler interpretiert oder ubersetzt¨ werden muss, ist eine maximale Ausnutzung der Hardware m¨oglich, die h¨ochste Performance oder geringsten Aufwand in der Implemen- tierung eines gegebenen Algorithmus erm¨oglicht. Aus dem gleichen Grund lassen sich Unzul¨anglichkeiten sehr effizient umgehen (Workarounds) und beheben, beispielsweise Schwierigkeiten bei der Erreichung deterministischen Zeitverhaltens. In Assembler hat man ein bis auf den einzelnen Maschinentakt exaktes Zeitverhalten. Letztlich vermittelt die maschinennahe Programmierung grundlegendes Erfahrungswissen zum Verstehen, Beurteilen und Ausw¨ahlen von Prozessorarchitekturen. Dies l¨aßt sich nur durch den praktischen Umgang mit Assembler erreichen, nicht durch theoretische Betrachtungen auf h¨oherem Level.

Beuth Hochschule fur¨ Technik Berlin 62 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

4.3.2 Maschinensprache und maschinennahe Sprache Im Rahmen der Ubersicht¨ uber¨ die Hierarchie von Programmiersprachen wurde bereits erl¨autert, dass die Maschinensprache eine Sprache ist, die ein Prozessor direkt ausfuhren¨ kann. Die Maschinensprache umfasst nur sehr einfache Befehle zur Ausfuhrung¨ von elementaren Operationen: • Arithmetische Operationen • Vergleichsoperationen • Speicheroperationen • Steueroperationen Das Maschinenprogramm besteht aus einer Folge von Bytes. Eine fur¨ den Menschen besser handhabbare Form ist die Repr¨asentation der Maschinensprache in lesbarer Form, die durch die maschinennahen Sprachen (Assemblersprachen) erreicht wird. Statt Bytefolgen verwendet man mnemonische Symbole (Mnemonics). Assemblerspra- chen bestehen aus Befehlen unter Verwendung von mnemonischen Symbolen und dazu- geh¨origen Daten. Im Gegensatz zum Maschinenprogramm unterstutzen¨ sie zus¨atzlich Kommentare, symbolische Operationscodes, symbolische Registernamen, symbolische Marken (Kennzeichnung von Zeilen im Assemblerprogramm), sowie Makros (Erset- zung oft vorkommender Programmteile). Im Folgenden ist eine beispielhafte Auswahl an Mnemonics und ihren jeweiligen Bedeutungen aufgelistet. Mnemonic Beschreibung INC B erh¨oht das Register B um 1 (engl. increment) DEC A vermindert das Register A um 1 (engl. decrement) ADD A,B addiert Wert von Register B zu Register A MOV A,B kopiert Inhalt von Register B nach Register A Dass Assemblerprogramme stets umfangreicher sind als ihr Pendant in einer h¨oheren Programmiersprache, zeigt das folgende Beispiel.

A :=2; MOV 0h, #2 ;R0 FOR I:=1 TO 20 LOOP MOV 1h, #0 ;R1 A:=A*I; LOOP: ENDLOOP; INC R1 MOV A, R0 MOV B, R1 MULAB MOV 0h, A CJNE R1,#20,LOOP END

Abbildung 4.21: Programmbeschreibungen gegenubergestellt¨ Das gleiche Programm ist einmal in einer h¨oheren Sprache (links) und einmal in As- semblersprache (8051 Syntax) aufgelistet. Da die Assemblerbefehle eine Eins-zu-Eins- Entsprechung in der Maschinensprache haben, mussen¨ alle Problemstellungen in die elementaren Operationen der Maschinensprache heruntergebrochen werden. Dies macht den Code u.U. sehr umfangreich.

Beuth Hochschule fur¨ Technik Berlin 63 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

4.3.3 Abgrenzung zu h¨oheren Sprachen und PC-Programmierung Die Programmierung einer Anwendung fur¨ einen Mikrocontroller ist nicht zu verglei- chen mit der Programmierung fur¨ den Einsatz auf einem PC. Der wesentliche Unter- schied besteht allein schon darin, dass man nicht auf dem Zielsystem entwickelt, auf dem die Anwendung dann sp¨ater laufen soll. Man generiert z.B. auf einem PC den Ma- schinencode fur¨ eine Mikrocontroller-Plattform, wohlwissend, daß auf der Zielplattform andere Ressourcen und andere Periphere zur Verfugung¨ stehen als auf dem System, auf dem man entwickelt (PC). Bezuglich¨ des Ressourcen ist der Speicherbedarf ein entscheidender Unterschied zur Programmentwicklung auf dem PC. Bei Mikrocontrollern ist Speicher eine sehr knappe Ressource (z.B. 6KB RAM, 128KB FLASH). W¨ahrend die Programmentwicklung auf dem PC eher auf Geschwindigkeit optimiert ist, ist sie bei Mikrocontrollern klar auf minimalen Speicherplatz ausgerichtet. Daher sind vor allem speicherplatzschonende Algorithmen gefragt, vergleichbar mit den Anforderungen an PC-Programme vor 25 Jahren. Diesem Anspruch kommt wieder die Assemblerprogrammierung zugute, da ein Assembler-Programm verglichen mit C u.U. mit einem Bruchteil des Speicherbedarfs auskommt. Ein weiterer Punkt, der auch mit dem Umgang mit Speicher zusammenh¨angt, ist die Adressfestlegung. Beim PC k¨onnen Programme adressunabh¨angig entwickelt werden. Zur Laufzeit findet dann eine dynamische Adressfestlegung statt. Dies ist uberhaupt¨ auch die Voraussetzung, daß mehrere Programme gleichzeitig ausgefuhrt¨ werden k¨onnen. Bei Mikrocontrollern sieht das anders aus. Beim Vorgang des Linkens werden die Adressen statisch festgelegt. Die Adressen mussen¨ an das Speicherabbild (Memo- ry Map) des Mikrocontrollers angepasst werden. Das Programm wird nur-lesbar im ROM, die Daten lesbar und schreibbar im RAM platziert. Es ist insbesondere darauf zu achten, das Programm-Instruktionen, Interrupttabellen, etc. an der richtigen Stelle abgelegt werden. Dazu wird sp¨ater noch genauer eingegangen. Auch die Art der Anwendung ist in der Regel fur¨ den Mikrocontroller-Einsatz eine andere. Im Gegensatz zum PC geht es aber bei der Controllerprogrammierung meist weniger um die Ein- oder Ausgabe bzw. Bearbeitung von Texten. Im Vordergrund steht hier ublicherweise¨ die Erfassung, Manipulation und Ausgabe von Messwerten oder Ansteuerungssignalen, die Abfrage von Tasten oder Schaltern, die Realisierung von Zeitschleifen oder Verz¨ogerungen, die Erzeugung bestimmten Signalformen oder Frequenzen und die Bereitstellung von Bitmustern. Fur¨ die Entwicklung eines Mikrocontroller-Programms sind also vorab weitreichen- de Uberlegungen¨ zu t¨atigen, u.a. wieviel Programm- und Datenspeicher ben¨otigt die Anwendung? Reicht die Gr¨oße des internen Daten- und Programmspeichers? Ist ein ex- terner Busanschluss (I/Os) vorhanden? Wie wird auf die I/Os zugegriffen? Maximale externe Speichergr¨oße? Die Liste l¨aßt sich je nach Anwendung und Mikrocontroller- Modell beliebig fortfuhren.¨

Beuth Hochschule fur¨ Technik Berlin 64 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

4.3.4 Arbeiten mit Assembler Die Begriffe Assembler, Assemblerprogrammierung und Assembleranweisungen sind be- reits an einigen Stellen gefallen. Bevor n¨aher darauf eingegangen wird, sei hier zun¨achst erst einmal die formale Definition des Begriffs gegeben. Dieser hat zwei Bedeutungen. Definition: Assembler 1. Programmiersprache; geschriebene Programme sind Assembler-Programme, die als Quellcode bezeichnet werden 2. Codewandler zur Umwandlung des menschenlesbaren Assembler-Programms in ein maschinenlesbares Objekt- bzw. HEX-File; Vorgang wird assemblieren“ ge- ” nannt Bei h¨oheren Programmiersprachen (z.B. C) heißt der Vorgang des Umwandelns com- ” pilieren“ und wird vom Compiler vorgenommen. Der Assembler kann also als Compiler fur¨ ein Assembler-Programm betrachtet werden. Im Folgenden wird die prinzipielle Vorgehensweise bei der Assembler-Programmierung aufgezeigt. Der Ablauf bei der Entwicklung eines Assembler-Programms ist immer der gleiche. • Schreiben des menschenlesbaren Programmtextes (Quellcode in Assemblermne- monik der verwendeten Mikrocontrollerfamilie) in einem Text-Editor • Assemblieren des Quellcodes in ein maschinenlesbares Programm mit dem As- sembler (Ubersetzer)¨ • Zusammenstellung (Verbindung) einzelner Programmmodule zu einem ausfuhrbaren¨ Programm mit einem Linker (Binder von Programmteilen) • Resultat: HEX-Datei, die man dann mit einem Programmierger¨at in den Con- troller brennen kann • ebenfalls: Protokolldateien, z.B. LST-Datei (List): mit Adressen und Maschinen- code angereicherter Assembler-Quellcode (fur¨ Fehlersuche) Die optionale LST-Datei ist sehr hilfreich fur¨ Programmierer. In ihr sind alle Opcodes und Adressen, sowie Fehler aufgelistet, die der Assembler entdeckt hat. So kann sie vom Programmierer benutzt werden, um Syntaxfehler zu finden oder zu debuggen. Abbil- dung 4.22 zeigt den Inhalt einer typischen LST-Datei. Die enthaltenen Informationen sind auf mehrere Spalten verteilt. Die erste Spalte zeigt die Zeilennummer, danach folgt die Adresse im Programm-Speicher, an der der jeweilige Befehl abgelegt wurde. Spalte 3 zeigt den Hexadezimalcode des Maschinenprogramms, dessen Entsprechung in Spalte 4 als mnemonischer Ausdruck zu finden ist. Die letzte Spalte, also ganz rechts, zeigt die Kommentare des Assembler-Quelldatei. Diese werden mit einem Semikolon eingeleitet, wie sp¨ater noch ausfuhrlicher¨ erkl¨art wird. Wie man nun die oben dargestellte prinzipielle Vorgehensweise hinsichtlich eines eige- nen Assembler-Projekts in die Tat umsetzt, h¨angt von der Komplexit¨at der Aufgaben- stellung bzw. des Programms ab. Bei einem einfachen Assembler-Projekt, schematisch dargestellt in Abbildung 4.23, ist es ublich¨ den gesamten Quellcode in eine *.ASM-Datei zu schreiben. Einzelne Programmbl¨ocke k¨onnen in Include-Dateien (*.INC) ausgelagert werden. Diese Dateien k¨onnen neben Programmzeilen, d.h. Assemblertext, beispiels- weise als Textbaustein fur¨ verschiedene Projekte, auch prozessorspezifische Definitio- nen bestimmter sympolischer Namen (z.B. von Registern) enthalten. Beim Zusam-

Beuth Hochschule fur¨ Technik Berlin 65 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

1 0000 ORG 0H ;beginne bei 0 2 0000 7D25 MOV R5,#25H ;lade 25H in R5 3 0002 7F34 MOV R7,#34H ;lade 34H in R7 4 0004 7400 MOV A,#0 ;lade 0 in A 5 0006 2D ADD A,R5 ;addiere den Inhalt von R5 zu A ;nun ist A = A + R5 6 0007 2F ADD A,R7 ;addiere den Inhalt von R7 zu A ;nun ist A = A + R7 7 0008 2412 ADD A,#12H ;addiere zu A den Wert 12H ;nun ist A = A + 12H 8 000A 80EF HERE: SJMP HERE ;bleibe in der Schleife 9 0000 END ;Ende der asm Quelldatei Adresse

Abbildung 4.22: Inhalt einer LST-Datei (List) menfuhren¨ der Assembler-Datei mit der Include-Datei verh¨alt sich der Assembler so w¨are der Inhalt der Include-Datei an einer bestimmten Stelle im Quellcode eingefugt.¨ Assembler und Linker k¨onnen als eine Einheit betrachtet werden. Ist das Assembler-Projekt umfangreicher, so w¨ahlt man fur¨ gew¨ohnlich einen anderen Ansatz. In dem soeben beschriebenen einfachen Fall wurden Assembler und Linker als eine Einheit betrachtet. Sie erfullen¨ aber unterschiedliche Aufgaben, die man bei kom- plexeren Projekten durchaus voneinander trennen muss. Wie bereits in Abbildung 4.20 angedeutet, wandelt der Assembler den menschenlesbaren Text des Assembler-Codes in einen Objektcode um, der anschließend vom Linker in das eigentliche lauff¨ahige Pro- gramm ubersetzt¨ wird. Der Linker ersetzt dazu die relativen Adressen des Objectcodes durch absolute Adressen des Prozessors. Dafur¨ werden naturlich¨ Informationen uber¨ den Speicheraufbau des jeweiligen Mikrocontroller-Typs ben¨otigt. Diese entnimmt der Linker dem sog. Linker-Skript.

Quellcode Output

programm.ASM programm.HEX Assembler + & Linker include.INC programm.LST

Abbildung 4.23: Einfaches Assembler-Projekt

Die Besonderheit ist nun, dass der Linker das Programm aus mehreren Objektcode- Dateien wie aus Bausteinen zusammenbauen kann, die auch nicht zwangsweise vom Assembler erzeugt sein mussen.¨ Dies ist genau der Vorteil fur¨ umfangreichere Pro- jekte, da man einerseits selektiv die ASM-Dateien austauschen kann. Man ubersetzt¨ beispielsweise nur die ASM-Dateien neu, in denen man Anderungen¨ vorgenommen hat, von allen anderen Programmteilen verwendet man die schon vorhandenen Objektcode- Dateien weiter. Andererseits ist es m¨oglich, Teile eines umfangreichen Projektes in un- terschiedlichen Programmiersprachen zu implementieren. Beispielsweise erzeugen auch C-Compiler Objektcode-Dateien, die vom Linker verarbeitet werden k¨onnen. Die Rea- lisierung zu einer gegebenen Aufgabenstellung l¨asst sich also partiell jeweils in C und

Beuth Hochschule fur¨ Technik Berlin 66 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG in Assembler umsetzen. Die aus den unterschiedlichen Programmiersprachen entstan- denen Objektcode-Dateien werden vom Linker zusammen in eine HEX-Datei verarbei- tet. Einen weiteren Vorteil bietet das Arbeiten mit Bibliotheken. Einige typische Proble- me tauchen in vielen Programmen immer wieder auf, z.B. mathematische Berechnun- gen. Fur¨ solche Probleme lassen sich Funktionsmodule in der Form kleiner Assember- oder C-Routinen entwickeln, die zu Object-Dateien assembliert und in Funktionsbi- bliotheken (Programmbibliotheken) zusammengefasst werden k¨onnen. Solche Biblio- theken sind Dateien mit der Endung *.LIB’. Aus mehreren Objektcode-Dateien und Programmbibliotheken kann der Linker schließlich das endgultige¨ Programm zusam- menbauen. Abbildung 4.24 veranschaulicht den soeben dargelegten Ansatz fur¨ umfang- reiche Assembler-Projekte.

Bibliothek Quellcode Output irgendeine.LIB programm.ASM programm.HEX

+ Assembler programm.O Linker

include.INC programm.LST anderes.O

Objectcode device.LKR

Linker-Skript

Abbildung 4.24: Umfangreiches Assembler-Projekt

4.3.5 Vom Assemblerprogramm zum Maschinenprogramm Ein Maschinenprogramm besteht aus Hexadezimalcode. Dieser hexadezimale Maschi- nencode kann direkt von der CPU als Programm ausgefuhrt¨ werden, so dass ein Maschi- nenprogramm als die unterste Ebene der Programmierung“ angesehen werden kann. ” Der Hexadezimalcode fur¨ einen bestimmten Prozessortyen ist vom Hersteller festgelegt und kann den zugeh¨origen Datenbuchern¨ entnommen werden. Der Maschinencode wird in den Speicher der verwendeten Rechnerarchitektur trans- portiert (geladen), der Prozessor liest nacheinander jede Anweisung (Befehl) und fuhrt¨ sie aus. Die Daten werden ebenfalls im Speicher aufbewahrt. Der Prozessor kann die Daten lesen, speichern und uber¨ die Ein-/Ausgabesteuerung einlesen und ausgeben. Hier sind exemplarisch zwei Maschinencodes des 8051 Mikrocontroller und deren Be- deutung aufgelistet. Code Bedeutung 74h kopiere den nachfolgenden Wert (Konstante, hexadezimal) direkt in das A-Register des Rechenwerks E5h kopiere den Inhalt der Speicherzelle in das A-Register, deren Adresse in der nachfolgenden RAM-Speicherzelle genannt wird 8051 spezifische Maschinenbefehle bestehen aus dem Befehlsbyte und bis zu zwei Pa- rameterbytes. Der gesamte Maschinenbefehl kann insgesamt 3 Bytes umfassen. Da es

Beuth Hochschule fur¨ Technik Berlin 67 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG sich bei dem 8051 um einen 8-Bit Mikrocontroller handelt, gibt es insgesamt 256 un- terschiedliche Befehlscodes, also genau die Anzahl an Befehlen, die durch ein Byte darstellbar ist. Bis auf den Code A5 sind alle belegt (vom Hersteller als unbelegt do- kumentiert). Abbildung 4.25 zeigt einen Ausschnitt aus der Befehlsliste des 8051. 8051 Mikrocontroller werden mit externem Takt betrieben, ublicherweise¨ wird dazu eine Frequenz von 12 MHz bis 24 MHz verwendet, bei dem Ur-Typen des 8051 waren es 1,2 MHz, sp¨ater dann bis zu 16 MHz. Beim Standard-8051 besteht 1 Maschinenzyklus aus 12 Takten. Der externe Takt, also der von außen als Referenz angelegte Takt, ist demnach 12-fach h¨oher als der interne“ Takt. Die Anzahl der ben¨otigten Zyklen je ” Maschinenbefehl ist unterschiedlich und variiert zwischen 1 bis 4 Maschinenzyklen pro Befehl. Diese Angaben beziehen sich naturlich¨ auf den internen Takt.

Abbildung 4.25: Auszug aus Befehlsliste fur¨ den 8051

Gegenuber¨ dem Maschinenprogramm ist das Assemblerprogramm durch die Verwen- dung von Mnenonics statt Zahlencodes gekennzeichnet. Diese Mnemonics sind so gestaltet, dass sie meist auf das Ziel hinweisende Befehlsworte gebrauchen. In Ab- schnitt 4.2 wurde bereits ein Befehl vorgestellt, und zwar der Befehl MOV. Der Assem- bler ubersetzt¨ die Befehlsworte Eins-zu-Eins in die entsprechenden Zahlen des Maschi- nencodes. Das ist m¨oglich, da die Assemblersprache so aufgebaut ist, dass Programme fast unver¨andert in Maschinensprache transformiert werden k¨onnen. In Erg¨anzung zur Bereitstellung symbolischer Befehle umfassen die Mnemonics auch spezielle Notatio- nen fur¨ unterschiedliche Adressierungsarten und k¨onnen symbolische Speicheradressen (engl.: labels) verwalten.

Beuth Hochschule fur¨ Technik Berlin 68 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

Fur¨ die oben bereits gezeigten zwei Maschinencodes des 8051 Mikrocontroller ist hier nun die Entsprechung in Assembler-Mnemonics. Code Assemblermnemonik Bedeutung 74 22 mov A, #22h kopiere die Konstante 22h direkt in das Akkumulator-Register des Rechenwerks E5 22 mov A, 22h kopiere den Inhalt der Speicherzelle 22h direkt in das Akkumulator-Register des Rechenwerks Es f¨allt auf, dass die Maschinenbefehle 74h und E5h offensichtlich bereits das Ziel (Akkumulator) des Kopiervorgangs und eine Anweisung zum Umgang mit dem Pa- rameter beinhalten. Am hier gezeigten Beispiel - einmal in Maschinencode, einmal in Assebmler-Code - wird deutlich, dass der Code mit Mnenomics sehr viel leichter lesbar und weniger fehleranf¨allig ist. Abbildung 4.26 zeigt beispielhaft die Codierung des Assemblerbefehls JB (Jump If Bit Is Set). Besonderes Augenmerk sei auf die Repr¨asentation in Maschinencode, die Paramter des Befehls (Bit-Adresse plus relative Sprungadresse), die Zusammensetzung zu 3 Bytes, sowie die allgemeine Wirkung des Befehls gerichtet.

Abbildung 4.26: Beispiel Assemblerbefehl JB (Jump If Bit Is Set)

Die Assemblersprache gestattet uber¨ die symbolische Repr¨asentation des Maschi- nenprogramms hinaus auch eine definierte Form der Steuerung des Verhaltens des Ubersetzerprogramms¨ (Assembler und Linker). Dies geschieht mit sog. Assemblerdirek- tiven, also Befehlen an das Ubersetzerprogramm.¨ Diese Befehle sind nicht Bestandteil des Befehlssatzes. Das ist logisch, da diese Befehle sich ja auch nicht an die CPU richten,

Beuth Hochschule fur¨ Technik Berlin 69 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG sondern an das Programm. Direktiven erm¨oglichen die Definition von Symbolen, die Reservierung von Speicherplatz, die Festlegung von Speicheradressen fur¨ Programme und Daten, sowie die Platzierung von Programmcode in festdefinierte Speicherzellen. Sie sind nur w¨ahrend der Ubersetzung¨ der Assembler-Mnemonics in Maschinensprache von Bedeutung. Die Befehle tauchen im fertigen Maschinenprogramm nicht mehr auf. Wie der Befehlssatz abh¨angig vom verwendeten Prozessortyp ist, so ist der Satz an an- wendbaren Assemblerdirektiven abh¨angig vom verwendeten Assemblerprogramm. Die im Folgenden erl¨auterten Direktiven sind Direktiven des a51-Assemblers von Intel, der auch im Labor verwendet wird.

#22 (dezimal) = 0x16h

!

Abbildung 4.27: Assemblerdirektiven im EdSim

In Abbildung 4.27 ist ein Beispiel fur¨ die Verwendung zweier Assemblerdirektiven (ORG und END) im Kontext mit regul¨aren Assemblerbefehlen gegeben. Die Assemblerbefeh- le sind blau dargestellt und richten sich an die CPU. Im vorliegenden Beispiel soll die CPU ihren Akkumulator A mit der Zahl 22 laden (Zeilen 3A und 3C). Die Zahl soll anschließend in die Speicherzelle DPH ubertragen¨ werden. Die gezeigten Zeilennum- mern geh¨oren nicht zum Quelltext. Die Assemblerdirektiven sind violett dargestellt und steuern die Ubersetzung¨ der Assemblerbefehle durch den Assembler. Der ORG ” 03Ah“-Befehl stellt den Assembler so ein, dass dieser das Programm ab Speicherzelle 03Ah ablegt. Der END-Befehl teilt dem Assembler mit, dass er nicht weiter ubersetzen¨ soll. Weitere Zeilen dahinter werden nicht mehr ubersetzt.¨ Gew¨ohnlicherweise steht diese Direktive am Ende jedes Assemblerprogramms. Die genaue Definition dieser und weiterer Direktiven folgt zu einem sp¨ateren Zeitpunkt.

Beuth Hochschule fur¨ Technik Berlin 70 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

4.3.6 Platzierung von Programmen im Speicher Die Rolle der LST-Datei wurde bereits erl¨autert, ebenso die M¨oglichkeit mit Assem- blerdirektiven Speicherorte zur Ablage von Programmen zu definieren. Um dies zu verdeutlichen, sei hier eine LST-Datei fur¨ ein gegebenes Assemblerprogramm gezeigt, sowie die zugeh¨orige Platzierung des Codes im ROM.

1 0000ORG 00h;beginne bei0 2 0000 7 D25MOV R5,#25h;lade 25h in R5 3 0002 7 F34MOV R7,#34h;lade 34h in R7 4 0004 7400MOV A,#0;lade0 inA 5 0006 2DADD A,R5;addiere Inhalt von R5 zuA ;nun istA=A+ R5 6 0007 2FADD A,R7;addiere Inhalt von R7 zuA ;nun istA=A+ R7 7 0008 2412ADD A,#12h;addiere zuA wert 12h ;nun istA=A+ 12h 8 000A 80EF HERE:SJMPHERE;bleibe in der Schleife 9 000 CEND;Ende der asm Quelldatei

In der LST-Datei ist bereits die Information enthalten, welchem Maschinencode die ein- zelnen Assemblerbefehle (Opcode plus Operanden) entsprechen und an welcher ROM- Adresse diese platziert sind Abschnitt 4.3.6 greift dies noch einmal auf und stellt es separat dar.

ROM Adresse Maschinensprache Assemblersprache 0000 7D25 MOV R5, #25h 0002 7F34 MOV R7, #34h 0004 7400 MOV A,#0 0006 2D ADD A, R5 0007 2F ADD A,R7 0008 2412 ADD A, #12h 000A 80EF HERE:SJMP HERE

Tabelle 4.3: Programmplatzierung im ROM (Beispiel)

Nachdem das Programm in den Codespeicher (ROM) gebrannt wurde, werden der Opcode und die Operanden im ROM platziert, beginnend ab Stelle 0000h. Die Adressen der einzelnen Befehlsbytes im ROM richtet sich nach L¨ange und zus¨atzlich angegebenen Parametern (Operanden). Der Inhalt des ROMs ist in Abschnitt 4.3.6 noch einmal nach aufsteigenden Adressen und pro Byte sortiert. Unter Zuhilfenahme der Befehlsliste des 8051 l¨aßt sich genau ermitteln welches der Bytes Opcode und welches zwangsweise Operand sein muss. Beispielsweise entspricht das erste Byte im ROM 7D laut Befehlsliste dem Befehl MOV ” R5, #data“. Das Register R5 soll also mit der gewunschten¨ Konstante geladen werden (im Beispiel der Wert 25h). Dies setzt voraus, dass diese Konstante zus¨atzlich zum Opcode des Befehls als Operand mit angegeben wird. Laut Befehlsliste umfasst dieser Befehl 2 Bytes, eben genau den Opcode plus den Operanden. Das folgende Byte im ROM (Adresse 0001) muss demnach der zu dem Opcode zugeh¨orige Operand sein.

Beuth Hochschule fur¨ Technik Berlin 71 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

Damit ist auch klar, dass der n¨achste Opcode erst ab Speicherstelle 0002 zu finden sein kann. In gleicher Weise l¨aßt sich der gesamte ROM-Inhalt entschlusseln.¨

ROM Adresse Code 0000 7D 0001 25 0002 7F 0003 34 0004 74 0005 00 0006 2D 0007 2F 0008 24 0009 12 000A 80 000B FE

Tabelle 4.4: Inhalt des ROMs (Beispiel)

Nachdem der Code in den Speicher des 8051 Mikrocontroller geladen wurde, kann er ausgefuhrt¨ werden. Sobald der 8051 eingeschaltet wird, werden bezogen auf das konkrete Beispiel hier folgende Schritte durchlaufen. 1. Der Program Counter hat den Wert 0000 und beginnt damit den ersten Opcode an der Stelle 0000 vom Programmspeicher zu holen 2.W ¨ahrend der Abarbeitung von Opcode 7D holt die CPU den Wert 25h und platziert ihn im Register R5 3. Nun ist ein Befehl beendet, danach wird der Program Counter auf die Adresse 0002 erh¨oht, die Opcode 7F enth¨alt 4.W ¨ahrend der Ausfuhrung¨ von Opcode 7F wird der Wert 34h nach Register R7 geladen 5. Anschließend wird der Program Counter auf 0004 erh¨ohht 6. Der Befehl an Speicherstelle 0004 wird ausgefuhrt¨ und anschließend der Program Counter auf 0006 erh¨oht 7. Nach Abarbeitung des 1-Byte Befehls an Stelle 0006 wird der Program Counter auf 0007 erh¨oht 8. Nach Abarbeitung des 1-Byte Befehls an Stelle 0007 wird der Program Counter auf 0008 erh¨oht 9. Der Prozess h¨alt an, wenn alle Befehle geholt und ausgefuhrt¨ wurden Die Bedeutung und Funktionsweise von Ubersetzungen¨ von Assembleranweisungen in Maschinenanweisungen unter Verwendung der numerischen Aquivalente¨ von Operati- onscodes, Registernamen und Marken sollte nun verstanden sein. Abschließend wird noch auf die Methodik bei der Programmentwicklung eingegangen.

Beuth Hochschule fur¨ Technik Berlin 72 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

4.3.7 Programmentwicklung Die Programmentwicklung fur¨ einen Mikrocontroller unterscheidet sich von der Metho- dik nicht sonderlich von der ublichen¨ Vorgehensweise bei der Software-Entwicklung. Sie l¨auft in den in Abbildung 4.28 dargestellten Schritten ab

Problembeschreibung Spezifikation

Entwurf Algorithmus

Programmierung Programmtext

Übersetzung Maschinenbefehle

Ausführender: Mensch Ausführung Ausführender: Maschine

Abbildung 4.28: Ablauf der Programmentwicklung

• Am Anfang steht immer die Spezifikation, d.h. die Modellierung des Problems bzw. der Aufgabenstellung. Dies umfasst eine Abstraktion der realen Situation und die Ubersetzung¨ in einfache Strukturen. • Es folgt der Entwurf eines Algorithmus zur L¨osung des spezifizierten Problems. Unter einem Algorithmus versteht man im Allgemeinen die Organisierung des Wissens wie eine Aufgabe in kleinen, einfachen und eindeutigen, abgeschlossenen Schritten gel¨ost werden kann. Ein Hilfsmittel beim Entwurf von Algorithmen sind Flussdiagramme. • Nach Festlegung des Algorithmus kann der Programmtext geschrieben werden. Der Programmtext ist die Beschreibung des Algorithmus und der Datenstruktu- ren, auf denen er operiert, in einer maschinenlesbaren Form (hier: Assemblersyn- tax). • Abschließend muss der Programmtext in Maschinencode ubersetzt¨ und schließ- lich zur Ausfuhrung¨ auf den Prozessor gebracht werden. Diese Schritte werden nicht mehr vom Menschen ausgefuhrt,¨ sondern von der Maschine (Assembler, Debugger, Bootloader). Um den Entwurf von Algorithmen zu erleichtern und in eine einheitliche graphische Form zu bringen, haben sich Flussdiagramme bew¨ahrt. Flussdiagramme sind graphi- sche Notationen fur¨ Algorithmen. Sie helfen bei der Strukturierung der Problemstel-

Beuth Hochschule fur¨ Technik Berlin 73 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

Start, Stop eines Algorithmus / Programms

Ein- / Ausgabe

Anweisung, auszuführende elementare Aktion

Verzweigung / Bedingung

Pfeile führen zur nächsten auszuführenden Aktion

Abbildung 4.29: Elementare Konstrukte eines Flussdiagrams lung. Durch Flussdiagramme sind nur Sprunge¨ und Bedingungen als Kontrollstruktu- ren darstellbar. Flussdiagramme sind sehr maschinennah und f¨ordern die strukturierte Programmierung. Sie sind zudem leicht verst¨andlich, bei umfangreichen Algorithmen aber bald unubersichtlich.¨ Die elementaren Konstrukte eines Flussdiagrams sind in Abbildung 4.29 dargestellt. Um die Anwendung von Flussdiagrammen zu demonstrieren, seien diese noch an einem Beispiel (Abbildung 4.30) gezeigt. Aus einem Flussdiagramm kann leicht abgelesen werden, was berechnet wird und wie. Jetzt wo fur¨ die Erstellung eines Programms in Assembler auch eine einheitliche Me- thodik angewendet werden kann, steht der praktischen Umsetzung nichts mehr im Weg. Um aber praktisch mit Assembler zu arbeiten, muss die prozessorspezifische Assem- blersyntax beherrscht werden. Um diese zu verstehen, muss das Hardwaremodell der verwendeten Plattform bekannt sein. Im n¨achsten Kapitel wird nun auf die konkrete Zielplattform, den 8051 Mikrocontroller eingegangen.

Beuth Hochschule fur¨ Technik Berlin 74 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 4. ADRESSIERUNGSARTEN UND MASCHINENPROGRAMMIERUNG

Taster als Eingang konfigurieren

LED einschalten

nein Taster ja Entprellen gedrückt?

LED invertieren

Abbildung 4.30: Praxisbeispiel eines Flussdiagrams

Beuth Hochschule fur¨ Technik Berlin 75 Prof. Dr.-Ing. Sven-Hendrik Voß 5 8051 Mikrocontroller-System

5.1 Prozessorarten

Zur kategorischen Einordnung der hier im Fokus stehenden Zielplattform, dem 8051 Mikrocontroller, seien zun¨achst die existierenden, unterschiedlichen Prozessorarten vor- gestellt. Die Art des Prozessors bedingt letztlich die konkrete Problemstellung beim Entwurf, da sowohl die Anwendbarkeit, als auch die Programmiermethodik bei den Prozessorarten unterschiedlich ist. Man unterscheidet folgende Kategorien:

Typ Eigenschaften Universalprozessoren PCs, Workstations, etc. Mikrocontroller (MCUs) spezialisiert auf kontrolldominierte Anwendungen Digitale Signalprozessoren spezialisiert auf Anwendungen der digitalen Signal- (DSPs) verarbeitung Anwendungsspezifische propriet¨are, anwendungs- und herstellerspezifische Prozessoren (ASIPs) Prozessoren

Tabelle 5.1: Prozessorarten

Auf die sehr limitierten Ressourcen von Mikrocontrollern in Abgrenzung zu Univer- salprozessoren wurde bereits hingewiesen. Ihr Einsatz ist in der Regel nicht auf hohe Verarbeitungsleistung zugeschnitten, sondern auf hohe funktionelle Integration, meist im Kontext von eingebetteten Systemen. Fur¨ die klassischen Aufgaben der Mikro- controller im Einsatz in der Steuerung in Ger¨aten und Anlagen sind Wortbreiten von 8 und 16 Bit v¨ollig ausreichend. Bei Universalprozessoren sind aktuell 32 und 64 Bit ublich.¨ Mikrocontroller sind im Prinzip Spezialprozessoren fur¨ kontrolldominierte An- wendungen, die durchaus ein großes Performance-Spektrum abdecken k¨onnen; vom einfachen Controller bis hin zum komplizierten Prozessor (dann auch mit Wortbreiten gr¨oßer 16 Bit). Sie zeichnen sich durch einige spezifische Charakteristika aus, die im Folgenden aufgelistet sind. • meist nur geringer Speicherplatz auf dem Chip • Befehle fur¨ Einzelbit-Adressierung und -verarbeitung • Zeitgeber fur¨ interne Zeitbasis, Z¨ahler fur¨ externe Ereignisse, Watch-Dog-Timer • flexible Unterbrechungsbehandlung (Interrupts) • serielle/parallele Ports auf dem Chip • A/D bzw. D/A-Wandler auf dem Chip Was unterscheidet nun eigentlich uberhaupt¨ einen Mikrocontroller von einem Mikro- prozessor? Um dies zu erl¨autern, sei zun¨achst eine schematische Darstellung eines Mi- kroprozessors gezeigt (Abbildung 5.1).

76 KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

Prozessor Operations- werk

Steuerwerk

Abbildung 5.1: Schematische Darstellung eines Mikroprozessors

Ein Mikroprozessor besteht grob gesehen aus Rechenwerk, Steuerwerk und Registern (nicht gezeigt, da intern). Er ist die zentrale Recheneinheit eines Rechners (fur¨ beliebige Aufgaben). Viele Komponenten, wie RAM, ROM, Takterzeugung, usw. mussen¨ seperat, also extern, hinzugefugt¨ werden, um ihn lauff¨ahig zu machen. Ein Mikrocontroller ist dagegen ein vollst¨andiges Mikrocomputersystem auf einem Sili- ziumchip. Mikroprozessor, Takterzeugung, Interruptsystem, Ein/Ausgabeinheiten, Ar- beitsspeicher (RAM) und Programmspeicher (ROM) sind gemeinsam auf einem Chip integriert und uber¨ einen bzw. mehrere Busse miteinander verbunden. Schematisch ist dies in Abbildung 5.2 dargestellt.

Mikrocontroller Prozessor Operations- Ein- / werk Speicher Ausgabe Steuerwerk

Abbildung 5.2: Schematische Darstellung eines Mikrocontrollers

Bei den auf dem Chip integrierten Komponenten spricht man von On-Chip- ” Komponenten“. Diese stellen die Gesamtheit der integrierten Funktion eines Mikro- controllers dar. Ein Mikrocontroller kann mit sehr wenigen externen Zusatzbausteinen betrieben werden. Dies hat Vorteile fur¨ die Herstellung vollst¨andiger Systeme: • der Schaltungsentwurf wird einfacher • das vollst¨andige System wird kompakter • die Verlustleistung ist geringer • durch die geringere Anzahl von Leitungen, Sockeln und Steckern verringert sich auch das Risiko von mechanischen Verbindungsst¨orungen • die Fertigung und das Testen der Schaltungen kostet weniger

Beuth Hochschule fur¨ Technik Berlin 77 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

5.2 Controller- und Prozessorfamilien

Mikrocontroller werden in Familien“ mit kompatiblen Befehlss¨atzen, aber unterschied- ” lichem Aufbau gefertigt. Die Mitglieder dieser Familien unterscheiden sich dann in Eigenschaften wie: • On-chip Speichertyp (ROM, RAM, PROM, EPROM) • On-chip Speichergr¨oße • zus¨atzlichen digital-analoge Wandlern (D/A und A/D) • zus¨atzlichen analogen Komponenten (z. B. Verst¨arker) • zus¨atzlichen Timern (teilweise mehrere voneinander unabh¨angige Zeitgeber) Der im Unterricht verwendete Baustein geh¨ort zur 8051-Familie von Intel, einer sehr bekannten Controllerfamilie (vgl. Abschnitt 1.1). So gibt es den 8051, den Ur-Typen mit ROM als Speicher, den 87C31 mit EPROM, den 8052 mit zus¨atzlichem, 256 Byte umfassenden internen RAM und noch viele mehr. Zu dieser Familie geh¨oren auch viele Controller anderer Hersteller (z.B. Siemens, Maxim, Dallas Semi, etc.), die Kompo- nenten mit 8051-kompatiblen Befehlss¨atzen produzieren. Diese nennt man Derivate. Abschnitt 5.2 zeigt exemplarisch die Vielzahl an Derivaten, die nicht einmal vollst¨andig ist.

Hersteller Typ und Eigenschaften AMD 8051 mit optimierten On-Chip Komponenten (werden nicht mehr produziert) Atmel Flash und Semi-Custom Komponenten Cygnal schnellster 8051 mit Flash-Speicher und 12-Bit 1 LSB A/D; 20 MHz interner Takt Dallas schnelle Variante; auch batteriegepuffert Intel 8051 bis 80C51GB / 80C51Sl; Erfinder des 8051! ISSI IS80C51/31 l¨auft bis zu 40 MHz schnell Matra 80C154, Low-Voltage Varianten (statisch) Maxim DS89C4xx, Ultra-High-Speed Flash Microcontroller (wird im Labor verwendet) OKI 80C154, Maskenteile (Chipherstellung) Philips 87C748 bis 89c588, meist alte geerbte Komponenten von Signetics Infineon 80C501 bis 80C517A, und eine Vielzahl an CAN Komponenten SMC COM20051 mit ARCNET Token Bus Netzwerk-Engine SSI 80x52, 2 x HDLC (High-Level Data Link Control) Variante fur¨ den Modemeinsatz

Tabelle 5.2: 8051 Derivate (Auswahl)

Der Grund, warum trotz der hardwarem¨aßig unterschiedlichen Ausstattung (insbeson- dere bezuglich¨ des integrierten Speichers und der peripheren Funktionskomponenten) die Controller einer Famile hinsichtlich der Maschinenbefehle kompatibel sind, liegt darin begrundet,¨ dass die jeweils neu hinzugekommenen Hardware-Komponenten nicht durch neue zus¨atzliche Befehle, sondern uber¨ Register, sog. Spezial-Funktions-Register

Beuth Hochschule fur¨ Technik Berlin 78 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

(SFR) angesprochen und gesteuert werden. Die SFR werden im Folgenden noch detail- lierter betrachtet.

5.3 Eigenschaften der 8051 Architektur

Der 8051 ist ein 8-Bit Mikrocontroller, d.h. s¨amtliche am Rechenprozess beteiligten Einheiten (Akkumulator, Register, Bus) sind auf 8-Bit ausgelegt. Diese Breite wird be- stimmt durch den Mikrocontrollerkern (CPU). Die Kerne der Mikrocontroller entspre- chen dem Mikroprozessor eines Rechners. Durch die Breite der CPU ist auch die Da- tenverarbeitungsbreite, der Befehlssatz, der Registersatz, die Adressierungsarten und die Gr¨oße des adressierbaren Speichers definiert. Mit 8 Bit sind 28 = 256 Befehlscodes m¨oglich, was sich im Umfang des Befehlssatzes ¨außert. Somit ist dies auch diejenige Bitbreite, die in einem Zyklus berechnet werden kann. Zusammengefasst l¨asst sich ein 8051 Mikrocontroller durch folgende Eigenschaften cha- rakterisieren: • logische Harvard-Architektur: max. 64 KByte Programm- und 64 KByte Daten- adressraum (getrennter Speicher- und Datenbereich) • 128 bzw. 256 Byte interner RAM • 4 Registers¨atze mit 8 Registern der Breite 8 Bit • 4 Ports mit je 8 Bit (32 bidirektionale I/O-Leitungen) • externer Bus fur¨ externe Daten- bzw- Programmspeichererweiterung • zwei 16-Bit Timer/Counter • serielle Schnittstelle (UART) • Interruptsystem mit 5 Quellen, je 2 Priorit¨aten • On-Chip Taktgenerator Da es sich, wie bereits in Abschnitt 3.4 erw¨ahnt, bei dem 8051 um eine erweiter- te Akkumulator-Maschine handelt, ist dessen Befehlssatz stark auf die Verwendung des Akkumulators ausgerichtet. Instruktionen, die den Akkumulator nicht als Ope- randen nutzen, ben¨otigen meist die doppelte Anzahl an Maschinenzyklen als solche mit Akkumulator. Dies l¨aßt sich einfach durch einen Blick in die Befehlsliste des 8051 Mikrocontrollers nachvollziehen. Um eine gute Speicherausnutzung zu gew¨ahrleisten, verfugen¨ viele Controller uber¨ Bit- befehle, d.h. Befehle, mit denen einzelne Bits direkt gespeichert und manipuliert werden k¨onnen. So bietet auch der 8051 Mikrocontroller M¨oglichkeiten zur Einzelbitverarbei- tung und -speicherung. Zur Steuerung der Peripherie dienen sogenannte Special Func- tion Register (SFR), die insgesamt 128 Byte einnehmen und meist byteweise, teilweise aber auch bitweise adressiert werden k¨onnen. Die Taktversorgung geschieht beim 8051 ublicherweise¨ mit 12, 16, 20 oder 24 MHz, je nachdem welches Controllerderivat benutzt wird. Genaueres ist dem jeweiligen Da- tenblatt des spezifischen Controllers zu entnehmen. So ist eine Befehlsausfuhrungszeit¨ von einer halben bis zu einer Mikrosekunde m¨oglich, was die Ausfuhrung¨ von ca. 1-2 Millionen Instruktionen pro Sekunde mit 8 Bit Verarbeitungsbreite zul¨asst. In Abschnitt 3.2 wurde der Zusammenhang von Taktzyklen, Maschinenzyklen und Befehlszyklen erl¨autert (vgl. Abbildung 3.11). Ein Befehlszyklus beinhaltet mehrere

Beuth Hochschule fur¨ Technik Berlin 79 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

Maschinenzyklen. Beim Standard-8051 besteht 1 Maschinenzyklus aus 12 Takten. Wo- her resultieren nun aber die 12 Takte? Dies l¨aßt sich leicht erkl¨aren. Es ist auf die interne Ablaufsteuerung des 8051 zuruckzuf¨ uhren.¨ Ein Maschinenzyklus besteht aus einer Sequenz von 6 Zust¨anden. Jeder Zustand dauert 2 Takte. Demzufolge dauert ein Maschinenzyklus 12 Takte. Bei einem angenommenen Referenztakt von 12 MHz dauert ein Maschinenzyklus beispielsweise 1µs (Kehrwert von 1 MHz). Jeder der 6 Zust¨ande teilt sich in 2 Phasen (P1, P2). Diese sind jeweils gleich lang und dauern je 1 Takt (in Summe 2 Takte pro Zustand). Im Normalfall werden in jedem Maschinenzyklus 2 aufeinander folgende Befehlsbytes aus dem internen oder externen Programmspeicher eingelesen, d.h. 2 Abfragen im Programmspeicher generiert (engl.: program fetch), auch wenn der gerade ausgefuhrte¨ Befehl es nicht erfordert. Falls der aktuelle Befehl keine weiteren Bytes ben¨otigt, da es sich um einen 1 Byte- Befehl handelt, wird das zweite eingelesene Byte ignoriert (blinder Speicherzugriff) und beim n¨achsten Maschinenzyklus als Opcode erneut eingelesen. Dies setzt voraus, dass der der Programmz¨ahler zwischenzeitlich nicht erh¨oht wird, da sonst dieses Byte ubersprungen¨ werden wurde.¨ Bei einem 1-Byte Befehl mit einer Ausfuhrungszeit¨ von 4 Maschinenzyklen k¨onnen somit theoretisch maximal 7 blinde Speicherzugriffe auf das n¨achste Byte auftreten. Abschließend sei das 8051-spezifische Verh¨altnis von Maschinen- zu Taktzyklen noch graphisch verdeutlicht (Abbildung 5.3).

Maschinenzyklus Maschinenzyklus Maschinenzyklus

Zustände S1 S2 S3 S4 S5 S6 (S: states)

(P1,P2) Takt Takt

Abbildung 5.3: Verh¨altnis von Maschinen- zu Taktzyklen

Theoretisch lassen sich bei neuen Derivaten die Maschinenzyklen (12 Takte) beschleu- nigen, allerdings wird h¨aufig aus Kompatibilit¨atsgrunden¨ auf das etablierte 12-Takte- Konzept zuruckgegriffen.¨ Obwohl moderne 8051-Derivate wesentlich leistungsf¨ahiger sind als der Ur-Typ des 8051, werden hier nur die Grundfunktionen des klassichen 8051 erl¨autert. Im Rahmen dieser Veranstaltung ist es aus Grunden¨ der Ubersichtlichkeit¨ und Nachvollziehbarkeit sinnvoll, sich auf die grunds¨atzlichen Zusammenh¨ange zu beschr¨anken.

5.4 Aufbau des 8051 Mikrocontrollers

Abbildung 5.4 zeigt den Aufbau des 8051 Mikrocontrollers. Charakteristisch fur¨ einen Mikrocontroller sind alle gezeigten Komponenten (Programm- / Datenspeicher (ROM und RAM), Peripheriefunktionen und internes Bussystem, auf einem Chip monolithisch integriert.

Beuth Hochschule fur¨ Technik Berlin 80 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

externe Interrupts

Interrupt- ROM RAM Timer 1 Zähler- Steuerung 4k x 8 128 x 8 Timer 0 eingänge Programm- Daten- *) 2x 16-Bit speicher speicher

) on-chip Prozessor * mind.128, 8-Bit CPU meist 256

4 I/O Ports

Bus- Serielle Oszillator Steuerung E/A

P0 P1 P2 P3 jeweils 8 Bit TXD RXD

Abbildung 5.4: Aufbau des 8051

Der Prozessor, eine 8-Bit CPU, umfasst die ALU, welche auch uber¨ die Funktiona- lit¨at eines Einzelbit-Rechners (sog. Boolscher Prozessor) verfugt,¨ den Befehlsz¨ahler, das Befehlsregister, den Befehlsdecoder und die Steuereinheit fur¨ den Programmab- lauf. Die ALU fuhrt¨ sowohl logische, arithmetische, als auch Schiebe-Operationen aus. Die Steuerlogik enth¨alt die zentrale Ablaufsteuerung des Rechners. Zur Taktversorgung dient ein integrierter Oszillator, der uber¨ einen ¨außeren Quarz- Baustein stabilisiert wird. Der Oszillator besteht aus einer ruckgekoppelten¨ Inverter- kette, wobei der ¨außere Quarz die Ruckkopplungsschleife¨ schließt. Der Quarz arbeitet als Serien-Resonanzkreis, d.h. er ist nur bei der Resonanzfrequenz niederohmig. Der Speicher besteht beim klassischen 8051 aus Festwertspeicher (ROM) und fluchtigem¨ Schreib / Lese-Speicher (RAM) und enth¨alt die Programmbefehle, respektive die zu verarbeitenden Daten. Wie bereits aus Abschnitt 5.2 ersichtlich, bedienen sich neue Derivate auch modernen Speichertechnologien, so sind Implementierungen mit Flash- Speicher mittlerweile durchaus g¨angig. Damit lassen sich Programm- und Datenspei- cher in Sekundenbruchteilen l¨oschen und neu programmieren. Fur¨ den Boot Loader stellt der Mikrocontroller einen eigenen Speicherbereich innerhalb des Flash bereit, der selbstverts¨andlich nicht uberschrieben¨ werden kann. Der Boot Loader dient der Programmierung im Feld. Der Controller enth¨alt 2 Timer-Komponenten von je 16 Bit Tiefe, die unabh¨angig voneinander betrieben werden und wahlweise als Z¨ahler oder als Zeitgeber eingesetzt werden k¨onnen. Vier I/O Ports mit je 8 digitalen Anschlussen¨ dienen dem bidirektio- nalen Datenaustausch. Dabei kann jeder Anschluß(pin) separat auf Ein- oder Ausgang geschaltet werden. Uber¨ die serielle Ein- / Ausgabe lassen sich Daten seriell senden und empfangen. Es wird ein Voll-Duplexbetrieb unterstutzt,¨ also gleichzeitiges Senden und Empfangen.

Beuth Hochschule fur¨ Technik Berlin 81 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

Um auf Unterbrechungsanforderungen zu reagieren, ist eine Interrupt-Steuerung vor- gesehen. Beim klassischen 8051 werden zwei externe und drei interne Interrupts un- terstutzt.¨ Moderne Derivate mit mehr On-Chip Peripherie unterstutzen¨ freilich mehr Interruptquellen. Die externen Hardware-Interrupts werden durch Interrupt-Signale an externen Anschlussen¨ ausgel¨ost (in der Graphik angedeutet durch die von außen gerich- ten Pfeile), die internen Interrupts werden von internen Komponenten (siehe Pfeile), n¨amlich vom bereits erw¨ahnten Timer oder der seriellen Schnittstelle ausgel¨ost. Die Bussteuerung dient der bidirektionalen Ubertragung¨ von Informationen zwischen Prozessor und externem Speicher bzw. Prozessor und peripheren Bausteinen. Im folgenden Abschnitt wird deutlich, dass die skizzierte Vielseitigkeit des 8051 nur durch eine aufwendige Registerstruktur mit Special-Function-Registern (SFR) und durch die Mehrfachbelegung diverser Anschlusse¨ erm¨oglicht werden kann.

5.5 Programmiermodell des 8051 Mikrocontrollers

Das Programmiermodell eines Mikrocontrollers beschreibt die Hardware innerhalb der CPU, die von einem Programmierer direkt erreichbar ist. Dies umfasst in erster Linie die die Struktur und die Funktionen der Register, uber¨ die die Programmierung erfolgt. Der 8051 besitzt aus Sicht der Programmierung vier Registerb¨anke zu je 8 Datenregis- tern (R0 - R7), einen Akkumulator A fur¨ alle arithmetischen und logischen Operatio- nen, sowie einen Hilfsakkumulator B fur¨ 8-Bit-Multiplikation und Division, der aber auch als allgemein nutzbares Register auftritt. Dazu kommt das Program Status Word (PSW), das vier von der ALU beeinflußte Flags, sowie Auswahlbits zur Festlegung der aktiven Registerbank enth¨alt.

Akkumulatorregister (je 8 Bit) 8-Bit Register Akkumulator A R0 Hilfs-Akkum. B RRR000 R1 RRR111 Status: Program Status Word (8 Bit) R2 RRR222 PSW R3 Program Counter (16 Bit) RRR333 RR44 PC Stack Pointer (8-Bit) RR44 RRR555 SP R5 R6 Zeiger auf Stack RR66 Zeiger auf R6 (int. RAM) R7 Programm- Data Pointer (16-Bit) RRR777 speicher Zeiger auf ext. DPTR Datenspeicher 4 Registerbänke

Abbildung 5.5: Programmiermodell des 8051

Der Stack wird vom Stack Pointer Register (SP) verwaltet und kann im gesamten internen RAM plaziert werden. Der Stack Pointer zeigt jeweils auf den letzten vom Prozessor bei Stackoperationen beschriebenen Speicherplatz.

Beuth Hochschule fur¨ Technik Berlin 82 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

Der Data Pointer (DPTR) dient - wie der Name schon sagt - als Zeiger auf Daten. Es wird von einer Reihe von Befehlen benutzt, die dem 8051 erlauben auf externen Speicher zuzugreifen. Der Program Counter (PC) h¨alt die aktuelle Adresse des n¨achsten Befehls. Die Datenbreite ist einheitlich mit 8 Bit vorgesehen, wobei bei zwei speziellen Registern, dem Program Counter und dem Data Pointer, Abweichungen hiervon auftreten. Das hat den Hintergrund, dass mit 16 Bit Breite sowohl fur¨ den Daten-, als auch den Programmspeicher ein gr¨oßerer Adressraum, n¨amlich volle 64 kByte, angesprochen werden kann. Abbildung 5.5 stellt das Programmiermodell grafisch dar. Das Programmiermodell reflektiert den im vorigen Kapitel bereits umrissenen Funk- tionsumfang des Mikrocontrollers. Es ist trotz der einfachen 8-Bit-Rechnerarchitektur relativ komplex. Bis auf Program Counter und Data Pointer sind also alle 8051 Register 8-Bit Regis- ter. Es existiert also nur ein Datentyp, und zwar unsigned“ 8-Bit Integer. Um eine ” einheitliche Darstellung zu gew¨ahrleisten, werden die 8 Registerbits im vorliegenden Skript stets vom h¨ochstwertigsten Bit (MSB) D7 zum niederwertigsten Bit (LSB) D0 in der in Abbildung 5.6 gezeigten Art dargestellt.

höchst- nieder- wertiges Bit wertigstes Bit 7 0 D7 D6 D5 D4 D3 D2 D1 D0 P0

8 Bit Register

Abbildung 5.6: Einheitliche Darstellung von Registern

Mit einem 8-Bit Datentyp muss jede Datenmenge gr¨oßer als 8 Bit in 8-Bit breite Stucke¨ geteilt werden, bevor sie weiterverarbeitet werden kann. Dies ist z.B. relevant, wenn man eine Subtraktion von zwei 16-Bit Zahlen ausfuhren¨ m¨ochte. Ebenso muss klar definiert sein, nach welchem Schema der Byte-Reihenfolge ( little endian“ oder big ” ” endian“, vgl. Abschnitt 4.1) die Daten im Speicher abgelegt werden.

5.5.1 Abbildung der Register im internen RAM Die gezeigte Registerstruktur des Programmiermodells findet ihre Abbildung im inter- nen RAM des 8051 Mikrocontrollers. Sowohl die allgemeinen 8-Bit-Register (vierfach ausgelegt und jeweils in einem Registersatz zu je 8 Register zusammengefasst), als auch alle Systemregister, d.h. die Register mit direkten Bezug zu Hardwarefunktionen, die sog. Special Function Register (SFR), sind dort untergebracht. Eine Ausnahme bildet der Befehlsz¨ahler (Program Counter). Abbildung 5.7 zeigt die verfugbaren¨ 256 Byte des internen RAM, untergliedert in un- ” tere“ 128 Byte von Adresse 00h bis 7Fh (direkt und indirekt adressierbar) und obere“ ” 128 Byte von Adresse 80h bis FFh. Dieser obere Bereich weist eine Doppelbelegung auf. Der gleiche Adressraum wird von Datenspeicher und Special Function Registern belegt. Als Datenspeicher ist dieser Bereich nur indirekt, in der Funktion der Special

Beuth Hochschule fur¨ Technik Berlin 83 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

100h Special Function Register

80h Byte-adressierbarer RAM-Bereich

Bit-adressierbarer Nur direkt 30h RAM-Bereich adressierbar 20h Direkt und indirekt Register 4x R0...R7 00h adressierbar

Abbildung 5.7: Aufteilung des internen RAM

Function Register nur direkt adressierbar. Eine Eindeutigkeit in der Auswahl des je- weiligen Blocks wird also durch unterschiedliche Adressierungsarten, mit denen diese Bereiche angesprochen werden, erreicht. Der untere Bereich (Adresse 00h bis 1Fh) des internen RAM kann sowohl mit direkter als auch indirekter Adressierung angesprochen werden. Dort liegen zun¨achst die vier Registerb¨anke 0, 1, 2 und 3. Die 32 Bytes, die die Register der vier Registerb¨anke umfassen, k¨onnen mit ihren symbolischen Namen (R0 bis R7 fur¨ die jeweils aktuelle Registerbank) adressiert werden, aber auch mit ihrer Adresse. So kann beispielsweise statt R0 auch 0 geschrieben werden. Jede Registerbank besteht aus 8 Bytes (R0 bis R7). Abbildung 5.8 zeigt die Anordnung der Registerb¨anke im Detail.

100h 20h R7 Registerbank 3 … R0 18h R7 Registerbank 2 … R0 80h 10h R7 Registerbank 1 … R0 30h 08h R7 jeweils 20h Registerbank 0 … 8 Byte 00h 00h R0

Abbildung 5.8: Detailansicht Registerb¨anke im internen RAM

Die Register sind vom Befehlssatz her sehr flexibel einsetzbar und dienen vor allem als tempor¨are Speicherorte fur¨ Daten, auf die h¨aufig zugegriffen wird. Die Organisation uber¨ Registerb¨anke l¨asst eine schnelle Adressierung und somit einen effizienten Zugriff zu. Die Auswahl der Registerb¨anke erfolgt durch 2 Bits im sog. PSW (Program Status Word), einem Special Function Register, welches sp¨ater noch gesondert ausfuhrlich¨ vorgestellt wird. Abschnitt 5.5.1 zeigt die Auswahl der Registerb¨anke anhand der RS1- und RS0-Bits im PSW. Es ist zu jeder Zeit immer nur eine Registerbank aktiv. Nach dem Einschalten des Mikrocontrollers ist Registerbank 0 die Standardeinstellung.

Beuth Hochschule fur¨ Technik Berlin 84 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

RS1 RS0 Registerbank Adresse 0 0 0 00h - 07h 0 1 1 08h - 0Fh 1 0 2 10h - 17h 1 1 3 18h - 1Fh

Tabelle 5.3: Auswahl der Registerb¨anke

Die M¨oglichkeit des Umschaltens der aktiven Registerbank hat einen hohen praktischen Nutzen. Bei der Bearbeitung mehrerer Aufgaben oder Aufrufen von Unterprogrammen mussen¨ so die Registerinhalte nicht immer gerettet werden. Stattdessen schaltet man in eine andere Bank um. Ist die neue Aufgabe oder das aufgerufene Unterprogramm beendet und soll die zuvor unterbrochene Aufgabe fortgesetzt werden, wird einfach auf die alte Registerbank zuruckgeschaltet.¨ Die in dieser Registerbank befindlichen Regis- ter sind nicht ver¨andert worden, obwohl im eingeschobenen Programmteil ebenfalls mit den Registern R0 bis R7 gearbeitet wurde. Diese sind jedoch - da sie zu einer anderen Registerbank geh¨oren - an anderen Adressen angesiedelt. Alle Register der vier Re- gisterb¨anke 0, 1, 2 und 3 sind linear hintereinander angeordnet, d.h. Register R2 der Registerbank 1 hat beispielsweise die interne Byteadresse 0Ah bzw 10d. Abbildung 5.9 zeigt die einzelnen Register aller Registerb¨anke und ihre zugeh¨origen RAM-Adressen.

Bank 0 Bank 1 Bank 2 Bank 3

7 R7 F R7 17 R7 1F R7

6 R6 E R6 16 R6 1E R6

5 R5 D R5 15 R5 1D R5

4 R4 C R4 14 R4 1C R4

3 R3 B R3 13 R3 1B R3

2 R2 A R2 12 R2 1A R2

1 R1 9 R1 11 R1 19 R1

0 R0 8 R0 10 R0 18 R0

Abbildung 5.9: Adressen der Registerbank-Register

Uber¨ den Registerb¨anken ist ein 16 Byte (20h bis 2Fh) umfassender, bitweise adressier- barer Bereich angeordnet. Dieser stellt eine obligatorische Erg¨anzung der Eigenschaft des 8051 dar, Operationen auf einzelnen Bits durchzufuhren.¨ Der bitadressierbare Be- reich umfasst 128 Bitadressen, n¨amlich von 00h bis 7Fh. Uber¨ den Registerb¨anken und den 128 direkt adressierbaren Bits befindet sich ein allgemein nutzbarer Speicherbe- reich mit (mind.) 80 byte-adressierbaren RAM-Speicherpl¨atzen zur freien Verfugung.¨ Da der RAM-Bereich oberhalb von 1Fh nicht von den CPU-Registern belegt ist, kann dieser z.B. als Stack genutzt werden (wenn keine Bitoperationen n¨otig sind). Der obere, 128 Bytes umfassende Bereich (Adresse 80h bis FFh) des internen RAM ist mit den Special Function Registern (SFR) belegt. Diese k¨onnen nur direkt adres-

Beuth Hochschule fur¨ Technik Berlin 85 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM siert werden. Der gleiche Adressbereich steht in Erg¨anzung des unteren Bereichs auch als Datenspeicher zur Verfugung,¨ dann allerdings nur indirekt adressierbar. Die By- tes des Datenspeichers sind mit Hilfe der Register R0 oder R1 indirekt adressierbar. Abbildung 5.10 zeigt die Anordnung der SFR im Detail.

FFh Rechenregister: Akku, B, PSW 100h Pointer: Stackpointer (SP), Data Pointer (DPH, DPL)

I / O -Ports: Port 0, Port 1, Port2, Port3 80h Interrupt-Register: Interrupt-Enable, Interrupt-Priority 30h 20h Timer: Timer-Mode, Timer Control, Timer0: TLO, THO; Timer1: TL1, TH1 00h Serial I / O -Port: Serial Control, Serial Data Buffer 80h

Abbildung 5.10: Detailansicht Special-Function-Register

Bei den Special Function Registern unterscheidet man in • Software-bezogene Register • Hardware-bezogene Register (Peripherie) Wie nachfolgend im Detail gezeigt wird, dienen die meisten SFR zur Steuerung der pe- ripheren Funktionen (Hardware-bezogene Register). Mittels Schreiben und Lesen von Speicherstellen, die den SFRs zugeordnet sind, werden in Wirklichkeit Peripheriebau- steine angesprochen. Durch die Einfuhrung¨ von Special Function Registern im internen RAM, also die Steuerungsm¨oglichkeit von Hardwarefunktionen durch spezielle Regis- ter, wurde eine Rechnerstruktur erm¨oglicht, die flexibel erweiterbar ist. Unter Beibehal- tung der Grundstruktur des 8051 und seines Befehlssatzes lassen sich zus¨atzliche Funk- tionen (z.B. Analog-Digital-Wandler, engl. Analog Digital Converter, kurz ADC) auf dem Chip, d.h. also in die vorhandene Prozessorfamilie integrieren, indem die n¨otigen Steuerregister dieser neuen Einheit (im Beispiel der ADC) einfach an freie Stellen im SFR-Bereich gelegt werden. Beim 8051 sind von den 128 m¨oglichen Adressen 21 mit Special Function Registern be- legt. Dies demonstriert ebenso die bereits bei der Entwicklung des Ur-Typen des 8051 angedachte Erweiterbarkeit. Die meisten dieser 21 SFR sind fur¨ die gesamte 8051- Familie und alle Derivate gleich, um eine weitreichende Abw¨artskompatibilit¨at bei der Programmerstellung zu gew¨ahrleisten. Wie bereits im Abschnitt uber¨ g¨angige 8051 De- rivate angedeutet, werden hier zugunsten der Ubersicht¨ und Nachvollziehbarkeit nur die Grundfunktionen des 8051 erl¨autert. Auf Funktionserweiterungen, die sich schließlich auch auf die ben¨otigten SFR auswirken, wird nicht eingegangen. Special Function Register, deren Adressen durch 8 ohne Rest teilbar sind (die also mit 0 oder 8 enden), sind sowohl byte- als auch bitadressierbar. Insgesamt sind dies 11 Byte-Adressen. So lassen sie sich byteweise, aber auch mit Hilfe der speziellen Bitver-

Beuth Hochschule fur¨ Technik Berlin 86 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM arbeitungsbefehle setzen, l¨oschen oder modifizieren. Die Bitadresse ergibt sich jeweils aus Byte-Adresse plus Nummer des Bits in dem Byte, wobei die Weiternummerierung naturlich¨ mit 80h beginnt. Abbildung 5.11 gibt Aufschluß uber¨ die genauen Adressen der SFR bzw. SFR-Bits. Die Bitnummern z¨ahlen in den Registern wie gewohnt von rechts nach links entsprechend dem Stellenwert. Interessant festzustellen ist, dass alle I/O-Ports bitadressierbar sind.

SFR RAM Adresse Bitadressen 80-F7h gehören zu (Byte und Bit) SFR von P0, TCON, P1, SCON...

Byte Byte adresse adresse Bitad re sse Bitadre sse FF 98 9F 9E 9D 9C 9B 9A 99 98 SCON F0 F7 F6 F5 F4 F3 F2 F1 F0 B 90 97 96 95 94 93 92 91 90 P1 E0 E7 E6 E5 E4 E3 E2 E1 E0 ACC 8D nicht bitadressierbar TH1 D0 D7 D6 D5 D4 D3 D2 D1 D0 PSW 8C nicht bitadressierbar TH0 8B nicht bitadressierbar TL1 8A nicht bitadressierbar TL0 B8 ------BC BB BA B9 B8 IP 89 nicht bitadressierbar TMOD 88 8F 8E 8D 8C 8B 8A 89 88 TCON B0 B7 B6 B5 B4 B3 B2 B1 B0 P3 87 nicht bitadressierbar PCON

A8 AF AE AD AC AB AA A9 A8 IE 83 nicht bitadressierbar DPH A0 A7 A6 A5 A4 A3 A2 A1 A0 P2 82 nicht bitadressierbar DPL 81 nicht bitadressierbar SP 99 nicht Bitadressierbar SBUF 80 87 86 85 84 83 82 81 80 P0 Special Function Register

Abbildung 5.11: Adressen der Special-Function-Register

In Assemblerprogrammen k¨onnen die einzelnen Special Function Register, sowie deren einzelne Bits sowohl durch die Adresse, als auch durch die symbolischen Kurzbezeich- nungen referenziert werden. Beispielsweise l¨asst sich der Akkumulator als ACC, sowie durch seine Adresse (E0h) ansprechen, genauso das Carrybit im PSW als CY oder PSW.7, sowie durch Adresse D7h. Um allerdings ein gewisses Mindestmaß an Les- barkeit der Programme zu gew¨ahrleisten, sollten wenn m¨oglich nur die symbolischen Kurzbezeichner verwendet werden.

5.5.2 Software-bezogene Register des Programmiermodells Zu den Software-bezogenen Special Function Registern geh¨oren die im Folgenden vor- gestellten Register. Der Stackpointer (SP) befindet sich an der Adresse 81h und verwaltet den Stack. Er zeigt jeweils auf den letzten vom Prozessor bei Stackoperationen beschriebenen Spei- cherplatz, enth¨alt also immer die aktuelle Adresse des Stacks. Beim Schreiben auf den Stack wird der Pointer um 1 Byte inkremetiert, beim Lesen um 1 Byte dekrementiert. Der Stackpointer zeigt immer in das interne RAM und kann auch im gesamten internen Daten-RAM plaziert werden. Eine Plazierung des Stacks im externen Daten-RAM ist allerdings nicht m¨oglich. Der Data Pointer Register (DPTR) setzt sich zusammen aus Data Pointer Low an Adresse 82h und Data Pointer High an Adresse 83h. Mit seiner Gr¨oße von 16 Bit dient er

Beuth Hochschule fur¨ Technik Berlin 87 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM indirekten (externen) Datenzugriffen auf maximal 64 KByte (216 = 65536 = 64 · 1024). Kombiniert mit dem Befehl MOVX ( X“ fur¨ extern“) dient er als Zeiger auf einen ” ” externen Datenspeicher (falls vorhanden). Verwendet man ihn zusammen mit dem Befehl MOVC ( C“ fur¨ code“), so stellt er einen Zeiger auf einen externen oder den ” ” internen Programmspeicher dar. Da es sich beim 8051 um eine Akkumulatormaschine handelt, nimmt das Akkumulator- register A (ACC) hier eine zentrale Rolle ein. S¨amtliche Berechnungen und Datentrans- fers greifen auf den Akkumulator zu. Fur¨ arithmetische oder logische Operationen ist es erforderlich, dass einer der Operanden im Akkumulator bereitgestellt wird. Das Ergeb- nis wird wiederum im Akkumulator abgelegt. Der Akkumulator befindet sich an Adres- se 0E0h. Im Programmquelltext wird der Akkumulator mit A bezeichnet, da es einige Befehle gibt, die bereits implizit auf den Akkumulator als Ziel bzw. Quelle referenzieren und so besonders effizient umgesetzt werden. A wird also als symbolischer Name fur¨ die implizite Verwendung des Akkus gebraucht (Befehlsl¨ange und Ausfuhrungszeit¨ kurzer).¨ Das Akkumulatorregister kann aber auch im internen Speicher angesprochen werden, dann verwendet man das Kurzel¨ ACC. Dies ist der symbolische Name fur¨ die Adresse 0E0h (direkter Zugriff). Die Bits des Akkumulatorregistes sind einzeln adressierbar. Speziell fur¨ die Multiplikation und die Division existiert der Hilfsakkumulator B. Dieser ist nur mittels direktem Datenzugriff auf 0F0h erreichbar. Fur¨ die Multiplikation ist es erforderlich, dass einer der Faktoren in B abgelegt wird. Das Ergebnis wird immer im Akkumulator gespeichert. Falls das Produkt allerdings gr¨oßer als 255 - also das, was mit 8 Bit darstellbar ist - ausf¨allt, wird das h¨oherwertige Byte des Ergebnisses in B abgelegt. Bei einer Division enth¨alt B nach Ausfuhrung¨ der Operation den ganzzahligen Divisionsrest. Das Program Status Word (PSW) befindet sich an der Adresse 0D0h und enth¨alt Flags fur¨ den jeweiligen Programmstatus (sog. conditional flags). Diese Flags sind einzelne Kennzeichnungsbits, die Auskunft uber¨ den Zustand der CPU oder das Ergebnis einer Operation geben. Die von der ALU beeinflußten Flags werden nach jeder arithmetischen und logischen Operation je nach Ergebnis gesetzt bzw. ruckgesetzt.¨ Abbildung 5.12 zeigt den Aufbau des Statusregisters.

Program Status Word

PSW

CY AC F0 RS1 RS0 OV -- P

Abbildung 5.12: Flags des Program Status Word

Das PSW ist bitadressierbar. Die Flags des PSW haben die in Abschnitt 5.5.2 gezeigte Bedeutung.

Beuth Hochschule fur¨ Technik Berlin 88 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

Flag Bedeutung CY Carrybit des Akkumulators → Ubertrag¨ vom D7 Bit AC Auxiliary-Carry, Halb-Byte Carrybit des Akkumulators (Hilfs-Carry fur¨ BCD-codierte Addition) → Ubertrag¨ von Bit D3 zu D4 F0 User-definiertes Flag, das bei Interrupt Requests auf dem Stack gerettet wird RS0, RS1 Register Select fur¨ Registerbank (0 bis 3) OV Overflow-Flag (fur¨ vorzeichenbehaftete Arithmetik), Uberlaufbit¨ des Akkumulators – reserviert P Akkumulator-Parit¨at (0 = gerade Anzahl von 1“) des Akkumulators ” Tabelle 5.4: Flags des PSW

Das CY-Flag ist das Carrybit des Akkumulators und wird z.B. nach jeder Additi- on oder Subtraktion ausgewertet. Es wird gesetzt, wenn das Ergebnis nicht im 8- Bit-Akkumulator darstellbar ist (Ubertrag),¨ und ruckgesetzt,¨ wenn das Ergebnis in 8 Bit darstellbar ist. Der Ubertrag¨ entsteht beim Bit 7 (MSB). Das CY-Flag dient zus¨atzlich als Boolescher 1-Bit Akkumulator, d.h. Ergebnisse logischer Bitoperationen stehen grunds¨atzlich im Carry-Bit. Im AC-Flag (Auxiliary Carry) wird ein Ubertrag¨ vom niederwertigen in das h¨oherwertige Halbbyte des Akkus angezeigt. Dies kann zur Korrektur beim Rechnen mit BCD-Zahlen von Bedeutung sein. F0 ist ein freies Flag fur¨ den Anwender. Die Register Select Bits RS0 und RS1 wurden bereits kurz erw¨ahnt. Der Inhalt dieser beiden Bits bestimmt die aktuelle Registerbank und dient der Umschaltung von einer zu einer anderen aktiven Bank. Das OV-Flag ist das Uberlaufbit¨ des Akkumulators und dient zum Rechnen mit vorzeichenbehafteten Zahlen. OV wird gesetzt, wenn der Zahlenbereich von -128 bis 127 uber-¨ oder unterschritten wird. Dies setzt voraus, dass als Datentyp nicht - wie standardm¨aßig beim 8051 - unsigned“ 8-Bit Integer-Werte ” benutzt werden, sondern der mit 8 Bit darstellbare Wertebereich als signed“ defi- ” niert wird. Da es in Assembler keine fest zu definierenden Datentypen gibt, bel¨auft sich dies lediglich auf eine Interpretation der Registerinhalte als Zweierkomplement- darstellungen. Einen Uberlauf¨ erkennt man dann daran, dass beim Bit 7 (MSB) ein Ubertrag¨ entstanden ist, beim Bit 6 jedoch nicht (oder andersrum). Diese Art der Uberlauferkennung¨ ist aus der Veranstaltung Grundlagen digitaler Systeme“ bekannt ” (vgl. XOR-Verknupfung¨ der Carry-Bits der beiden obersten Stellen). Das P-Flag (Parity) gibt Auskunft uber¨ die Parit¨at des Akkumulatorinhalts. Es ist gesetzt, wenn im Akku eine ungerade Zahl Einsen steht und nicht gesetzt, wenn im Akku bereits eine gerade Anzahl an Einsen vorhanden ist (Even Parity). All diese Flags bleiben bis zur nachfolgenden Operation erhalten und k¨onnen bei- spielsweise von bedingten Sprungbefehlen gepruft¨ werden, um abh¨angig vom Ergebnis der Operation eine Verzweigung des Programmablaufs vorzunehmen. Im Vergleich zu anderen g¨angigen Mikrocontrollern f¨allt hier auf, dass es kein allgemeines Interrupt Enable oder Disable Flag gibt. Interrupts werden beim 8051 uber¨ ein separates SFR gesteuert.

Beuth Hochschule fur¨ Technik Berlin 89 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

5.5.3 Hardware-bezogene Register des Programmiermodells Hardware-bezogene Register dienen der Steuerung der peripheren Funktionen und ha- ben so in den meisten F¨allen eine direkte Entsprechung in Hardware. Dies wird im Folgenden deutlich. Wie bereits im Uberblick¨ erw¨ahnt, verfugt¨ der 8051 uber¨ zwei unabh¨angige Timer. Dies sind typische und sehr wichtige Peripheriegruppen, die fast jeder Mikrocontroller besitzt. Beide Timer (Timer 0 und Timer 1) bestehen jeweils aus zwei kaskadierbaren 8-Bit-Z¨ahlerregistern TL0 bzw. TL1 (untere 8 Bit) und TH0 bzw. TH1 (obere 8 Bit). Meist werden beide Z¨ahlregister zusammen als ein 16-Bit breites Z¨ahlregister verwen- det. Die unteren 8 Bit von Timer 0, also das TL0-Register befindet sich an Adresse 8Ah. Das zugeh¨orige High-Byte, TH0, liegt auf Adresse 8Ch. Fur¨ Timer 1 befinden sich die unteren 8 Bit an Adresse 8Bh, Adresse 8Dh beherbergt die oberen 8 Bit. Die Timer k¨onnen in verschiedenen Modi und Betriebsarten betrieben werden. Festge- legt wird dies mittels Timer Modus Register (TMOD). Dieses ist an Adresse 89h zu finden. Die Steuerung der Timer und die Anzeige des entsprechenden Status erfolgt uber¨ Bits im Timer Control Steuer- und Statusregister (TCON), welches an Adresse 88h zu finden ist. Das obere Halbbyte umfasst Werte fur¨ die Timer 0 und 1, das untere Halbbyte Werte fur¨ die Interrupt-Logik. Das Interrupt-System ist ebenfalls eine sehr typische Komponente. Ein Mikrocontroller muss in der Regel eine Vielzahl von Schnittstellen und Subsystemen ansteuern und kontrollieren. Eine Interrupt-Verarbeitung erlaubt es, auf das Peripherieereignis sofort zu reagieren, ohne die entsprechende Komponente st¨andig abzufragen. Konfiguriert wird das Interrupt-System beim 8051 neben den schon erw¨ahnten Bits im TCON- Register uber¨ das Interrupt Enable Register (IE) und das Interrupt Priority Register IP. Das Interrupt Enable Register (IE) befindet sich an Adresse 0A8h und gibt die diversen Interruptquellen (in- und externe) frei oder sperrt sie. Das Interrupt Priority Register IP ist an Adresse 0B8h zu finden und bestimmt die Priorit¨at der Interruptquellen in zweistufiger Hierarchie. Die serielle Schnittstelle wird uber¨ das Serial Control Steuer- und Statusregister (SCON) verwaltet. SCON befindet sich an der Adresse 98h und dient u.a. zur Ein- stellung der Betriebsart und zur Anzeige des Status. Wie die Timer-Komponenten ben¨otigt die serielle Schnittstelle zus¨atzlich zu den Steuerregistern Datenregister, hier beispielsweise um die zu sendenden oder empfangenen Daten bereitzustellen. Dies er- folgt uber¨ das Serial Buffer Register (SBUF). SBUF stellt eigentlich zwei separate Re- gister dar, wobei aus dem Empfangsteil nur gelesen, in den Sendeteil nur geschrieben werden kann. Aus Programmiersicht ist dies nicht erkennbar. Es gibt nur ein Register, auf das zugegriffen werden kann, und zwar SBUF an Adresse 99h. I/O-Ports sind fur¨ Mikrocontroller besonders wichtig, sie erlauben den Austausch di- gitaler Signale mit dem umgebenden System. Uber¨ I/O-Ports werden also bin¨are Si- gnale verarbeitet, die - um Kompatibilit¨at mit dem verwendeten Mikrocontroller zu gew¨ahrleisten - mit TTL-Pegeln (TTL: Transistor-Transistor-Logik, von 0 − 0, 8 V fur¨ Low und 2 − 5 V fur¨ High) dargestellt werden. Der 8051 verfugt¨ uber¨ vier separate I/O-Ports (Port 0-3), diese sind in Gruppen zu 8 Bit aufgeteilt. Aufgrund des internen Aufbaus unterscheiden die Ports sich geringfugig.¨

Beuth Hochschule fur¨ Technik Berlin 90 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

Beim 8051 existieren keine speziellen I/O-Befehle, stattdessen werden die Ports nach der in der Praxis h¨aufig verwendeten Methode des so genannten Memory Mapped ” I/O“ angesprochen 5. Dies ist der Grund warum die Ports ohne zus¨atzliche Program- mierung uber¨ eigene SFR gesteuert werden k¨onnen und sowohl als Eingabe- als auch als Ausgabeports nutzbar sind. Die Ein- und Ausgabe uber¨ die Ports beschr¨ankt sich damit auf das direkte Lesen und Schreiben der entsprechenden SFR. Jeder Port hat eine eigene Adresse im SFR-Bereich und ist byte- und bitadressierbar. Das Port 0 Register (P0) steuert Port 0 mit 8 externen Anschlussen¨ (Pin 32-39). Es befindet sich an der Adresse 80h. Abbildung 5.13 zeigt die gultigen¨ Adressen fur¨ den byte- bzw. bitweisen Zugriff am Beispiel des Port 0. Fur¨ viele bitadressierbaren SFRs sind symbolische Name vordefiniert, beispielsweise P0.4 fur¨ 84h.

7 0 P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 P0.0 P0

87h 86h 85h 84h 83h 82h 81h 80h

Abbildung 5.13: Port-Bit-Zuordnung am Beispiel des Port 0

Das Port 1 Register (P1) stellt Port 1 mit 8 externen Anschlussen¨ (Pin 1-8) dar. Es ist an der Adresse 90h zu finden. Die 8 externen Anschlussen¨ (Pins 21-28) des Port 2 werden durch das Port 2 Register (P2) an Adresse A0h bereitgestellt. Das Port 3 Register (P3) an Adresse B0h gew¨ahrleistet Zugriff auf Port 3, der die Pins 10-17 umfasst. Port 0 ist als einziger I/O-Port tats¨achlich bidirektional mit Tristate-M¨oglichkeit aus- gelegt. Ein Tristate-Ausgang kann außer den beiden niederohmigen Zust¨anden High (logisch 1) und Low (logisch 0) noch einen dritten hochohmigen Zustand annehmen. Intern wird der Port somit entweder auf Ausgang aktiv“ oder Tristate“, d.h. hoch- ” ” ohmig, konfiguriert. Bei Konfiguration als Tristate“ k¨onnen externe Daten eingelesen ” werden, der Port ist dann also als Eingang konfiguriert. Bei den Ports 1, 2 und 3 sind die Anschlusse¨ dagegen pseudobidirektional ausgelegt. Die Portleitungen sind (nach dem Reset) st¨andig auf Ausgang geschaltet. Trotz der nicht zur Verfugung¨ stehenden M¨oglichkeit, die Ports in einen Tristate-Zustand zu versetzen, k¨onnen Eingangswerte eingelesen werden. Dazu mussen¨ die als Ausgang konfigurierten Anschlusse¨ auf einen High-Pegel (logisch 1) gesetzt werden. Aufgrund des internen Hardware-Aufbaus kann dieser Pegel durch externe TTL-Pegel auf Low (logisch 0) gezogen werden, so dass Werte von außerhalb auch eingelesen werden k¨onnen. Um diesen Sachverhalt zu veranschaulichen, zeigt Abbildung 5.14 die interne Schaltung der Ports. Wenn Daten uber¨ den internen Bus auf den Port geschrieben werden, gelangen diese zuerst auf den Latch-Eingang (D) und dann uber¨ den invertierenden Ausgang (Q) an den Gate-Anschluss des Feldeffekttransistors (FET). Wenn eine logische 0 auf den Port geschrieben wird, wird diese uber¨ den invertierenden Latch-Ausgang zu einer logischen 1, die den FET durchsteuern l¨asst. Der Source-Anschluss des FET ist uber¨ ein inter- nes Pullup-Arrangement mit der Betriebsspannung verbunden, der Drain-Anschluss 5Dies stellt einen weiteren wesentlichen Unterschied zu den 80x86-Systemen dar.

Beuth Hochschule fur¨ Technik Berlin 91 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

Abbildung 5.14: Interne Schaltung der Ports befindet sich auf Masse. Beim Durchsteuern wird Source nach Drain geschaltet. Da der physische Portpin ebenfalls auf Source-Potential liegt, wird dieser somit auf Masse gezogen und liegt auf logisch 0. Auf den Port wurde eine logische 0 geschrieben und die logische 0 liegt wie gewunscht¨ auch auf dem Pin. Wenn dieser Port nun als Eingang verwendet werden sollte und am Latch immer noch eine logische 0 anliegen wurde,¨ k¨onnte der Pin niemals aus dem logischen Nullzustand kommen, da er ja uber¨ den durchgesteuerten FET direkt mit Masse verbunden ist. Um den Port also als Eingang zu verwenden, muss intern eine logische 1 an das Latch angelegt werden. Durch den invertierenden Ausgang des Latch wird der FET somit ausgeschaltet. Es gibt nun keine Verbindung mehr zwischen dem Portpin und der Mas- se. Die Spannung am Pin, also das anliegende Eingangssignal, kann nun durch den Read-Pin Buffer ausgelesen werden. Einige Befehle lesen den Signalpegel am Portpin, andere lesen den Latch-Inhalt, um St¨orungen oder Verf¨alschungen auf der Portleitung zu unterdrucken.¨ Die Befehle MOV, ADD oder JNB k¨onnen beispielsweise als Einlesebefehle angesehen werden und lesen den Portpin. Befehle, die Werte des Ports modifizieren bzw. ¨andern, lesen das Register (Read Modify Write). Dazu z¨ahlen beispielsweise ORL, ANL, INC, DEC, INC oder DJNZ. Bei Anderungsbefehlen¨ werden alle Latches des Ports in interne Zwischenre- gister ubertragen,¨ die gewunschten¨ Bitstelle wird durch Maskierung modifiziert und das Ergebnis wird in die Ausgabe-Latches zuruckgeschrieben.¨ Wenn zu einem sp¨ateren Zeitpunkt die einzelnen Befehle detailliert behandelt werden, wird dieser Sachverhalt sicher klarer. Es sei darauf hingewiesen, dass das Konfigurieren eines Ports als Eingang mittels Schrei- ben einer logischen 1 und das Setzen von logischen Einsen an Ausgangs-Pins vom ge- schriebenen Code her keinen Unterschied aufweist. Der Code ist genau der gleiche. Eine

Beuth Hochschule fur¨ Technik Berlin 92 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

Unterscheidung ist einzig und allein durch Inspektion des geschriebenen Codes aus dem Kontext m¨oglich. Daher ist im Falle der Initialisierung von Pins eine aussagekr¨aftige Kommentierung des Codes unumg¨anglich.

Praxisbeispiel

Port 0 soll zun¨achst als ein Eingangsport konfiguriert werden, indem Einsen auf ihn geschrieben werden. Dann sollen Daten von diesem Port nach Port 1 umgeleitet werden.

L¨osung: MOV A,#0FFH;A= 11111111b MOV P0,A;mache P0 zu einem Eingang ;indem 11111111 auf alle Pins geschrieben wird BACK:MOV A,P0;erhalte Daten von Port0 MOV P1,A;sende sie zu Port1 SJMPBACK;und wiederhole...

5.6 Speichermodell des 8051 Mikrocontrollers

Es wurde bereits kurz erw¨ahnt, dass es beim 8051 mehrere Speicherbereiche gibt. Wie dies im Detail aussieht, soll hier nun beschrieben werden.

0FFFFh

Programm- Externe code 0100h Daten Special (RAM) intern / Function extern Internes 0080h Register RAM

0000h /RD = 0 oder /PSEN = 0 /WR = 0

Abbildung 5.15: Uberlappende¨ Adressr¨aume des 8051

Der 8051 hat getrennte Programm- und Datenspeicheradressr¨aume (logische Harvard- Architektur). Da es sich um einen 8-Bit Mikrocontroller handelt, existieren jeweils maximal 28 = 256 m¨ogliche Adressen fur¨ den internen Programm- und Datenbereich. Daruber¨ hinaus gibt es noch einen 128 Byte umfassenden SFR-Bereich und auch ex- terner Speicher, der an ein externes Bussystem angeschlossen wird, muss erreichbar sein. Da damit schon nicht mehr genugend¨ Adressen zur Verfugung¨ stehen, muss eine Unterscheidung mittels unterschiedlicher Befehle, Adressr¨aume und Adressierungsar-

Beuth Hochschule fur¨ Technik Berlin 93 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM ten erfolgen. Abbildung 5.15 zeigt eine modellhafte Vorstellung der Erreichbarkeit des Speichers, das sog. Speichermodell (in Analogie zum Programmiermodell).

8 8 0FFFFh

Programm- 8 8 Externe code Daten 0100h Special Internes (RAM) intern / Function RAM extern 0080h Register 128 Byte, intern 64 kByte, indirekt über DPTR bitadressierbar adressierbar 0000h 4 Registerbänke 256 Byte, intern /RD = 0 oder /PSEN = 0 /WR = 0

Abbildung 5.16: Adressr¨aume detailliert

Das Speichermodell umfasst: • den 256 Bytes großen internen Datenspeicher 6 • den Bereich der Special-Function-Register (max. 128 Byte) • den internen Programmspeicher (meist 8 kByte) • den externen Programmspeicher (bis 64 kByte) • den externer Datenspeicher (ebenfalls bis zu 64 kByte) Alle sind durch uberlappende¨ Addressr¨aume gekennzeichnet. Bedingt durch die beson- dere Struktur des 8051 existieren getrennte Steuersignale fur¨ externe Daten (RD (Read Data), WR (Write Data)) und Code (PSEN (Program Store Enable)). Die Adressie- rung des externen Daten- und Programmcode-Speichers erfolgt nur indirekt und relativ uber¨ den Data Pointer (DPTR). Abbildung 5.16 zeigt die Struktur des Speichers im Detail. Wie wichtig eine eindeutige Adressierung ist, sei anhand des bitadressierbaren Bereichs des Speichers gezeigt. Im Bereich 20h bis 2Fh des internen RAM stehen 16 · 8 = 128 Bit zur Verfugung,¨ beispielsweise zum Zwischenspeichern von einzelnen Bits. Diese sind direkt uber¨ die Adressen 00h bis 7Fh adressierbar und einzeln bitweise erreichbar. Die gleichen Adressen existieren auch fur¨ den byteweise adressierbaren Bereich wie in Abbildung 5.17 (links) dargestellt. Allein durch die Adresse ist also keine eindeutige Zuordnung m¨oglich. Der 8051 besitzt eine Anzahl bitorientierter Befehle. Ausschließlich diese k¨onnen fur¨ den bitadressier- baren Bereich verwendet werden. Außerdem findet in diesem Bereich nur der direkte Adressierungsmodus Anwendung. Eine eindeutige Zuordnung geschieht also anhand des Befehlstypen und der Adressierungsart.

6Beim Ur-Typen des 8051 umfasste dieser Bereich lediglich 128 Bytes RAM, sp¨ater ab Typ 8052 und bei allen Derivaten dann 256 Bytes.

Beuth Hochschule fur¨ Technik Berlin 94 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

Verwechslungen zwischen den Adressen 00-7Fh? Byteadressen Byteadressen

bitadressierbare Positionen bitadressierbare Positionen mind. 80 Byte Byteadressen 00-7Fh für 128 Byte RAM 8 à Zugriff nur in Byte-Größen à verschiedene Adressierungsmodi Internes (direkt oder indirekt) RAM Bitadressen 00-7Fh für 16 Byte der RAM- 16 Byte Positionen 20-2Fh bitadressierbar à Zugriff nur über Einzelbitbefehle 4 Registerbänke 32 Byte à nur direkter Adressierungsmodus

Abbildung 5.17: Adresszuordnung fur¨ bit- und byteweisen Zugriff

5.6.1 Programmspeicher des 8051 Code und Daten liegen beim 8051 in getrennten Speicherbereichen (logische Harvard- Architektur). Wie aus Abbildung 5.15 und Abbildung 5.16 bereits ersichtlich, reichen beide uber¨ den gesamten Adressbereich von 0000h bis FFFFh. Diese Bereiche unterscheiden sich dadurch, dass sie durch unterschiedliche Maschinen- befehle angesprochen werden. Zus¨atzlich werden die Bereiche logisch durch die soeben erw¨ahnten Steuersignale RD (Read Data), WR (Write Data) und PSEN (Program Sto- re Enable) voneinander getrennt. PSEN aktiviert den nur lesbaren Programmspeicher, RD stellt den lesenden und WR den schreibenden Zugriff auf den Datenspeicher her. PSEN und RD/WR werden wiederum durch die fur¨ die unterschiedlichen Speicherbe- reiche gultigen¨ Maschinenbefehle, n¨amlich die Varianten des MOV-Maschinenbefehls MOVC und MOVX, gesteuert. Datentransfers mittels MOVC erfolgen nur in Rich- tung aus dem Codespeicher heraus. Der Prozessor selbst kann aus dem Codespeicher nur lesen, der Codespeicher wird daher oft als ROM bezeichnet, unabh¨angig davon in welcher Technologie er tats¨achlich physisch implementiert ist. Der maximal m¨ogliche Programmspeicher von 64 kByte (Abbildung 5.18) ist in einen externen und einen internen Bereich aufgeteilt. Der interne Bereich belegt die unteren 4 kByte (Adresse 0000h - 0FFFh). Der externe (Adresse 1000h - FFFFh) schließt sich daran an. Der Adressbereich 0 bis 23h des internen Speichers wird fur¨ die Interrupt- Einsprungvektoren benutzt, wie sp¨ater noch detailliert erl¨autert wird. Zugriffe auf den externen Programmspeicher erfolgen immer indirekt uber¨ eine 16-Bit Adresse. Adres- siert wird mittels Program Counter (PC), fur¨ Zwecke des Datentransfers aus dem Codespeicher auch mit dem Data Pointer (DPTR). Alle 8051 beginnen beim Start bei Speicheradresse 0000h. Der Program Counter hat dann also den Wert 0000h. Der erste Befehl muss an Adresse 0000h des Programm- speichers abgelegt sein, da der 8051 dort nach dem ersten Befehl sucht, wenn er aus

Beuth Hochschule fur¨ Technik Berlin 95 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

8

Programm- code

intern / extern

Abbildung 5.18: Programmspeicher dem Reset kommt (vgl. ORG-Anweisung im Quellprogramm). Der Program Counter zeigt stets auf die Adresse des n¨achsten auszufuhrenden¨ Befehls. Sobald die CPU den Befehl aus dem Programmspeicher geholt hat, wird der Program Counter erh¨oht, um auf den n¨achsten Befehl zu zeigen.

5.6.2 Datenspeicher des 8051 Der Aufbau des internen RAMs wurde anfangs bereits erl¨autert. Er ist direkt und im mit SFRs uberlappenden¨ Bereich indirekt adressierbar. Ahnlich¨ dem Programmspei- cher kann der Datenspeicher ebenfalls extern ausgebaut werden. Er gliedert sich in dann in einen externen (maximal 64 kByte) und den internen (128 Byte) Teil.

8

Externe Daten (RAM)

64 kByte, indirekt über DPTR adressierbar

Abbildung 5.19: Externer Datenspeicher

Auf den externen Datenspeicher (Abbildung 5.19) kann entweder mit einer 16-Bit- Adresse im DPTR-Zeigerregister oder mit einer 8-Bit Adresse im Zeigerregister R0 oder R1 indirekt zugegriffen werden. Dies wird begleitet durch die bereits erw¨ahnten Signale RD und WR. Hier ein Beispiel dazu, bei dem der Data Pointer mit der 16-Bit- Adresse 2A6Bh geladen wird.

Beuth Hochschule fur¨ Technik Berlin 96 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

MOV DPH, #2A; Laden vonDPH undDPL mit MOV DPL, #6B; einer 16-Bit Adresse, dann... MOVXA,@DPTR; Laden des Akkumulators MOVX@DPTR,A; oder Speichern des Akkumulators

W¨ahrend man den Programmspeicher typischerweise als ROM auslegt, nutzt man fur¨ den Datenspeicher RAM, also einen Flash- oder anderen beschreibbaren Speichertyp. Fur¨ die externen Speicherzugriffe (Daten oder Code) sind in jedem Fall die beiden Ports 0 und 2 als Adress-/Daten-Leitungen zu reservieren. Im Zusammenhang mit der Beschreibung des Sekund¨armodus werden weitere Details erl¨autert. Zusammengefaßt l¨aßt sich feststellen, dass Mikrocontroller der 8051-Familie uber¨ meh- rere Adressr¨aume mit gleichen Adressen verfugen.¨ Durch uberlappende¨ Addressr¨aume kann eine bestimmte Adresse in 5 verschiedenen Speicherbereichen liegen. Eine Unterscheidung von Speicherzellen mit gleichen Adressen erfolgt durch • den Ablauf des Programms (Befehle k¨onnen nur dem Programmspeicher entnom- men werden) • spezielle Befehle fur¨ unterschiedliche Speichertypen (z.B. MOVX fur¨ externen Datenspeicher und MOVC fur¨ Programmspeicher) • unterschiedliche Adressierungsarten (SFRs k¨onnen nur mit direkter, interner Da- tenspeicher mit gleichen Adressen nur mit indirekter Adressierung angesprochen werden) Begleitet werden externe Zugriffe durch entsprechende Steuersignale fur¨ die Chip- to-Chip Kommunikation. Auf den internen Datenspeicher des Mikrocontrollers kann grunds¨atzlich viel einfacher und schneller zugegriffen werden als auf den externen. Daher ist es anzuraten, h¨aufig verwendete Variablen im internen Datenspeicher des Bausteins zu platzieren.

5.6.3 Stack-Konzept des 8051 In Abschnitt 4.1 wurde die Bedeutung des Stack bereits allgemein dargestellt. Die Um- setzung des Stack-Konzepts in verschiedenen CPUs kann allerdings sehr unterschiedlich sein. So w¨achst bei der 8086 CPU beispielsweise der Stack bei Schreibzugriffen zu nied- rigeren Adressen. Beim 8051 dagegen w¨achst der Stack bei Schreibzugriffen zu h¨oheren Adressen. Dies ist insofern wichtig, als dass u.a. berucksichtigt¨ werden muss wo der Stack anf¨angt, wieviel Speicherplatz reserviert werden muss und wie sich das Register fur¨ den Stack-Zugriff verh¨alt. Wie bei den meisten Mikrocontrollern ublich,¨ ist auch beim 8051 der Stack-Bereich nicht eigenst¨andig physikalisch implementiert, sondern Teil des internen RAM- Speichers. Somit stellt der Stack-Abschnitt einen Bereich des RAMs zur tempor¨aren Speicherung von Informationen dar, der dynamisch schrumpfen und wachsen kann. Das Register fur¨ den Stack-Zugang, der Stackpointer (SP), wurde im Rahmen des Programmiermodells bereits vorgestellt. Dieses Register ist 8 Bit breit, kann also nur Werte von 00h bis FFh annehmen. Da der Stackpointer SP nur auf das interne RAM zeigen kann, muss zudem der Stack im internen RAM liegen und ist somit abzuglich¨ der Doppelbelegung im oberen Teil auf 128 Byte limitiert, was den effektiven Zugriffs-

Beuth Hochschule fur¨ Technik Berlin 97 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

100h

80h

30h 20h 00h Internes RAM

Abbildung 5.20: Internes RAM bereich einschr¨ankt. Von diesen 128 Bytes stehen die unteren 32 Bytes (00h - 1Fh) fur¨ die Registerb¨anke, die folgenden 16 Bytes (20h - 2Fh) fur¨ den bitadressierbaren Be- reich zur Verfugung¨ (). Werden diese Bereiche nicht ben¨otigt, k¨onnen sie vom Stack in Anspruch genommen werden. Dennoch ist bei einer Doppelbelegung Vorsicht geboten, denn dies kann zu schwer identifizierbaren Fehlern fuhren.¨ Die Funktionsweise des Stacks beim 8051 gestaltet sich folgendermaßen: • bei einem Schreibzugriff wird der SP-Inhalt um 1 inkrementiert • dann wird der Inhalt auf die SP-adressierte Zelle im internen Speicher geschrieben (Einbringen von Daten auf den Stack → PUSH“-Operation) ” • bei Lesezugriff wird zuerst gelesen (Herausholen von Daten von dem Stack → POP“-Operation) ” • dann wird SP um 1 dekrementiert Nach dem Reset zeigt der SP auf die Adresse 07h des internen RAM. Dies hat his- torische Grunde.¨ Der erster Schreibzugriff wurde¨ dann also auf Speicheradresse 08h erfolgen. Dort liegt jedoch zugleich Register R0 der zweiten Registerbank (Register- bank 1). Der Stack wurde¨ also die Registerbank 1 uberschreiben,¨ was einen Konflikt darstellt, falls diese verwendet wird. Daher empfiehlt es sich, den SP am Beginn eines Programms auf eine h¨ohere Adresse, also auf ungef¨ahrlichere“ Bereiche, zu setzen. ” Abbildung 5.21 zeigt dies an einem Beispiel. Da der SP vor dem Schreiben in den Stack mittels PUSH inkrementiert wird, sollte man den SP auf die um 1 verminderte Adresse des Stackbereichs setzen. Es ist zu beachten, dass ein Zugriff auf den Stack nur in dem direkten Adressiermodus gestattet ist. Dies wird unter anderem deutlich, wenn beispielsweise Werte des Akku- mulators auf den Stack gespeichert werden sollen. Der Akkumulator kann sowohl durch die Kurzel¨ ACC, als auch A referenziert werden. Der Unterschied zwischen ACC und A ist allerdings erheblich. A wird verwendet, wenn der Maschinenbefehl bereits den Akkumulator benutzt, ist somit also keine explizite Adressierung des Akkus sondern symbolisiert einen inh¨arent im Befehl codierten Quell- oder Zielort. In diesem Fall den Akkumulator. Wenn der Maschinenbefehl also die Angabe einer direkten Adresse (eines Registers) erfordert, muss ACC verwendet werden. Zum Ablegen des Akkuinhalts auf den Stack ist der Befehl PUSH A

Beuth Hochschule fur¨ Technik Berlin 98 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 5. 8051 MIKROCONTROLLER-SYSTEM

Internes RAM Akkumulator Internes RAM Akkumulator

55h 55h

36h SP 36h SP 0BBh 055h 34h 35h 0AAh 0AAh

32h 32h

vorher nach: PUSH ACC 30h 30h Abbildung 5.21: Beispiel einer Stackoperation mittel Stackpointer (SP) also ungultig.¨ Um den Akku auf den Stack zu legen, muss also PUSH 0E0h geschrieben werden. Dies ist die Adresse des Akkumulators. PUSH ACC funktioniert auch, denn ACC ist der symbolische Name fur¨ das Akkumulator-Register und wird als direkte Adresse verwendet. Der Assembler ersetzt ACC einfach durch die Adresse 0E0h.

Praxisbeispiel

Der Inhalt von R5 und A soll auf den Stack gelegt werden und dann vom Stack in R2 und B zuruckgeschrieben¨ werden, so dass am Ende B=A und R2=R5 ist.

L¨osung: PUSH 05;push R5 auf den Stack PUSH 0E0H;push registerA auf den Stack POP 0F0H;pop oberste Daten vom Stack nachB ;nun RegisterB= registerA POP 02;pop oberste Daten vom Stack nach R2 ;nun R2=R6

Beuth Hochschule fur¨ Technik Berlin 99 Prof. Dr.-Ing. Sven-Hendrik Voß 6 Programmierung und Einsatz

6.1 Adressierungsmodi der 8051 CPU

Bevor eingehend der Befehlssatz und die -syntax des 8051 behandelt wird, macht es Sinn, zuvor den spezifischen Adressierungsmodi der 8051 CPU noch etwas genauer Beachtung zu schenken - nicht zuletzt, da die meisten Befehle verschiedene Varian- ten erlauben, um ihre Operanden zu erhalten. Die grunds¨atzlichen Adressierungsmodi wurden bereits in Abschnitt 4.2 vermittelt. Erg¨anzend seien hier die Besonderheiten in Bezug auf die 8051 Architektur dargelegt, die sich schlußendlich aus den im vori- gen Kapitel erl¨auterten Speichereigenarten ergeben. Fur¨ bestimmte Speicherabschnitte sind nur bestimmte Adressierungsarten zul¨assig. In Abschnitt 4.2 konnte darauf noch nicht eingegangen werden, da der 8051 Mikrocontroller als Zielplattform noch nicht vorgestellt wurde. Die Adressierungsarten werden nun durch ihre Charakteristika und anhand eines Beispiels kurz beschrieben.

Direkte Adressierung zul¨assig fur¨ . erste 128 RAM-Zellen im internen Speicherbereich an den Adressen 00h-7Fh . Special Function Register im Bereich 80h-0FFh • Adresse der Speicherzelle des internen RAMs wird als Zahlenwert oder symbolisch direkt im Befehl angegeben • Adressbereich ist mittels eines Bytes adressierbar (8-Bitadresse im Operanden) • Sprungbefehle adressieren den vom Datenspeicher getrennten Codespeicher (max. 64 kByte) • daher: direkte Adressierung bei Sprungbefehlen (Sprungzieladresse) 2 Bytes lang (Beispiel: LJMP-Befehl) Beispiel: MOV 7Fh, A Inhalt des Akkumulators wird in das interne RAM mit der 8-Bit-Adresse 7Fh direkt kopiert Diese Art der Adressierung ist schnell und einfach. Daher ist man bestrebt, h¨aufig benutzte Variable im direkt adressierbaren RAM und weniger h¨aufig benutzte Variablen beispielsweise im indirekt adressierbaren RAM abzuspeichern.

100 KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

Indirekte Adressierung zul¨assig fur¨ . Register R0, R1 . Data Pointer Register (DPTR) • das in der Anweisung mit @“ gekennzeichnete Register tr¨agt das eigentliche ” Zugriffsziel (Adresse) • R0 und R1 tragen jeweils eine 8-Bit Adresse, sind also geeignet fur¨ die Adres- sierung des internen RAMs (128 bzw. 256 Bytes, je nach Controller-Stufe) oder eines externen RAMs (bis 256 Bytes) • DPTR tr¨agt eine 16-Bit Adresse, ist also geeignet fur¨ eine Adressierung auf den gesamten externen Datenspeicher (64 KByte) Beispiel: MOV @R0, A Inhalt des Akkus wird nach Adresse in Register R0 geschrieben (internes RAM) MOVX @DPTR, A Akkuinhalt wird in externes RAM an Adresse in Datenpointer-Register geschrieben Es ist zu beachten, dass die oberen 128 Byte Datenspeicher ausschließlich uber¨ die indirekte Adressierung mittels Registern R0 und R1 ansprechbar sind. Die Special Function Register k¨onnen nicht uber¨ diese Adressierung angesprochen werden. Um einen Speicherplatz ansprechen zu k¨onnen, muss immer zuerst seine Adresse in die entsprechenden Zeiger-Register (R0 oder R1 der aktuellen Registerbank, bzw. DPTR) geladen werden. Nur diese Register sind fur¨ die indirekte Adressierung zugelassen. Erst dann kann ein indirekter Zugriff erfolgen. Diese Art der Adressierung ist etwas umst¨andlicher und langsamer als die direkte Adressierung.

Indizierte Adressierung geeignet fur¨ . ausschließlich Programmspeicher • Adressierungsart unterstutzt¨ die Benutzung einer Tabelle (Look-Up Table) aus dem Programmspeicher • Adresse wird dabei gebildet aus Summe der Inhalte des Basisregisters und des Indexregisters • Basisregister: Datenpointer-Register (DPTR) oder Programmz¨ahler (PC) • Als Indexregister dient immer der Akkumulator Beispiel: MOVC A, @A + DPTR Summe aus Akkuinhalt und DPTR-Inhalt bildet Speicheradresse, Inhalt wird in Akku geladen Nur uber¨ diese Adressierungsart kann auf den Programmspeicher zugegriffen weden. Es ist zu beachten, dass nur die oben genannten Register als Index- und Basisregister herangezogen werden durfen.¨

Registeradressierung zul¨assig fur¨ . Register Register R0...R7 . Akkumulator (A) . Hilfsakkumulator (B) . Data Pointer (DPTR) • Befehle dieser Adressierungsart enthalten keine Operanden • Adresse des Registers ist im Befehl inh¨arent enthalten • Erinnerung: jeweilige Registerbank wird uber¨ zwei Select-Bits im PSW aktiviert

Beuth Hochschule fur¨ Technik Berlin 101 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

Beispiel: INC R0 inkrementiert Inhalt des Registers R0 DEC A dekrementiert Inhalt des Akkus Kennzeichnend fur¨ die Registeradressierung ist der Sachverhalt, dass die Operanden in den oben genannten Registern enthalten sind. Die Information, auf welches Register zugegriffen werden soll, ist im Opcode enthalten.

Direktwertadressierung (unmittelbare Adressierung) zul¨assig fur¨ . 8-Bit- oder 16-Bitkonstante . 8-Bit- oder 16-Bit Zahlenwert • Operand ist ein Direktwert (Konstante) • es erfolgt keine Adressierung (Wert steht nicht in einer Datenzelle, die adressiert werden muss) • Wert (Direktwert) stet unmittelbar als Operand im Befehlscode Beispiel: MOV A, #100 8-Bitwert #100 wird in Akku geladen MOV DPTR, #data16 Datenpointer-Register wird mit 16- Bitkonstante #data16 geladen Mit der Direktwertadressierung k¨onnen Werte als Teile von Befehlen direkt angegeben werden. Da der Befehlscode in einem dynamisch nicht ver¨anderbaren Speicher (ROM) steht, handelt es sich bei diesen Werten um Konstanten. Kennzeichnend ist die Angabe mit #.

Relative Adressierung geeignet fur¨ . Sprungbefehle, insbesondere in Schleifen, weil platz- und zeitspa- render als absolute, auf 16-Bit ausgelegte Adressierung • Program Counter-relative Adressierung fur¨ Sprung um ± 128 Bytes Beispiel: SJMP rel Short-Jump Befehl enth¨alt eine 8-Bit-Adresse, damit ist ein relativer Sprung von -128 bis +127 im Bezug auf die aktuelle Adresse m¨oglich Die relative Adressierung ist also durch die Anwendung in Sprungen¨ in Bezug auf den Program Counter gekennzeichnet. In der Befehlsliste wird dies mit dem Kurzel¨ rel“ ” gekennzeichnet. Dieses Kurzel¨ bezeichnet eine vorzeichenbehaftete 8 Bit-Zahl, die dem Program Counter hinzuaddiert wird. Die neue Adresse im Program Counter kann somit um max. 128 Bytes kleiner bzw. um max. 127 Bytes gr¨oßer sein.

6.2 Assemblernotation fur¨ die 8051 CPU

Dieser Abschnitt bringt eine detaillierte Einfuhrung¨ in den Befehlssatz der 8051- Prozessoren. Der 8051 Mikrocontroller hat einen 111 Befehle umfassenden Befehlssatz. Davon sind... • 49 1-Byte Befehle • 45 2-Byte Befehle • 17 3-Byte-Befehle In Abschnitt 5.3 wurde im Rahmen der Zusammenh¨ange zwischen Maschinen- und Taktzyklen bereits erw¨ahnt, dass in jedem Maschinenzyklus immer zwei aufeinander folgende Befehlsbytes aus dem Programmspeicher eingelesen werden, auch wenn dies

Beuth Hochschule fur¨ Technik Berlin 102 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ nicht erforderlich ist (blinder Speicherzugriff). Hier wird deutlich, warum eine Optimie- rung auf das Einlesen von zwei Bytes sinnvoll ist und dieses Konzept hier angewendet wird. Die Vielzahl der 8051-Assemblerbefehle sind eben Ein- bzw. Zwei-Byte-Befehle. Alle Befehle haben eine einheitliche Syntaxgrundstruktur:

Befehl Befehls-Mnenomic Ziel Quelle

Beispiel Mov A , #22

Abbildung 6.1: Syntaxstruktur der 8051 Befehle

Fur¨ die Schreibweise von Befehlen mit zwei Operanden gilt in der 8051- Assemblersyntax, dass der erste Operand das Ziel und der zweite Operand die Quelle fur¨ die auszufuhrende¨ Operation darstellt. Beide Operanden werden durch ein Komma getrennt. So bedeutet der Befehl MOV A,#22 zum Beispiel, dass die Konstante 22 in den Akkumulator gebracht werden soll. Un¨are Befehle, also Befehle mit nur einem Operanden, geben naturlich¨ nur das Ziel an. Daher ist das Feld, das der Angabe der Quelle entspricht, in Abbildung 6.1 blau markiert. In Abschnitt 3.2 wurde anhand des Beispiels einer einfache Additionsoperation bereits das Befehlsformat und die Bedeutung der Felder im Maschinenbefehl gezeigt (vgl. auch Abbildung 3.6). Dieses Beispiel soll noch einmal aufgegriffen werden, um etwas genau- er auf die interne Repr¨asentation eines Befehls im 8051 einzugehen. Im Instruction Register (IR), dem Befehlsregister, werden nacheinander die Adressen der Befehle im Programmspeicher abgelegt und uber¨ den internen Datenbus werden die Befehlsby- tes ins Befehlsregister transferiert. Zum betrachteten Zeitpunkt steht der aktuell aus- zufuhrende¨ Befehl im Befehlsregister. Dieser setzt sich zusammen, wie in Abbildung 6.2 illustriert, aus Opcode und Adresse.

Op-Code Adresse pc ir 7 24 7 24 or ac Befehlscode Adresse 24 Addiere- Befehl à 7 Prozessor

Abbildung 6.2: Interne Repr¨asentation eines Befehls

Auf Hardware-Ebene bestehen Opcode und Adresse aus verschiedenen Bit-Feldern. Der Opcode-Teil wird an das Mikrosteuerwerk, die Adresse an das Adresswerk weiterlei- tet. W¨ahrend das Adress-Feld als Ganzes, also als Byte-Adresse, decodiert wird, tr¨agt jedes Feld des Opcodes einen Teil der notwendigen Informationen bei, um den vollen

Beuth Hochschule fur¨ Technik Berlin 103 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

Befehl auszufuhren.¨ Mittels eines Dekodierungsschaltnetz (Befehlsdecoder) werden die Informationen des Instruction Register (IR) decodiert. Diese Dekodierschaltung liefert 1 Signal pro Maschinenbefehl. Durch das Signal wird der entsprechende Mikrobefehl (Zeile im Mikroprogrammspeicher) aktiviert. Wie in Abbildung 6.3 angedeutet, kann man sich vorstellen, dass jeder Ausgang des Schaltnetzes einer Zeile im Mikropro- grammspeicher entspricht, die durch den entsprechenden Ausgang aktiviert wird.

Op-Code Adresse

IR (Op-Code) IR (Addr)

MOV A,R0 MOV A,direkt adr ADD A,R0 ADD A,direkt adr ......

Abbildung 6.3: Dekodierungsschaltnetz fur¨ den Opcode

Fur¨ die Intel 8051 Familie gibt es mehrere Assembler mit wenigen Unterschieden. Allen gleich sind die Schreibweise der Befehle und die Verwendung der Register. Die syntak- tische Schreibweise ist zeilenorientiert. Der prinzipielle Aufbau einer Zeile hat folgende Gestalt: [hLabeli]hOpcodei[hOperandeni][hKommentari] Die Felder haben folgende Bedeutung: • Label: symbolische Marke, die (meist) mit der aktuellen Speicheradresse verbun- den ist • Opcode: symbolischer Maschinenbefehl oder Assemblerdirektive (Steueranwei- sung fur¨ den Assembler) • Operanden: z.B. Angaben zur Adressierungsart, Adressen • Kommentar: meist bis Ende der Zeile (eingeleitet mit einem speziellem Zeichen, einem Semikolon) Abbildung 6.4 zeigt den prinzipiellen Aufbau eines in 8051-Assemblersyntax geschrie- benen Programms. Fur¨ die Zahlendarstellung gelten Konventionen: • Dezimalzahlen: Verwendung wie gewohnt, z.B. 55 • Hexadezimalzahlen: Kennzeichnung durch nachgestelltes h“, z.B. 37h ” • Bin¨arzahlen: Kennzeichnung durch nachgestelltes b“, z.B. 00110111b ” Es existieren 7 Gruppen von Assemblerbefehlen: • Transferbefehle • Bitverarbeitungsbefehle • Logische Verknupfungen¨ • Arithmetische Befehle

Beuth Hochschule fur¨ Technik Berlin 104 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

ORG OH ;(origin, Herkunft) beginne an ;Stelle (Adresse) 0 MOV R5, #25H ;lade 25H in R5 Direktiven generieren keinen MOV R7, #43H ;lade 34H in Rz Maschinencode und MOV A, #0 ;lade o in A werden nur vom MOV A, R5 ;addiere Inhalt von R5A szseum bAler benutzt ;nun ist A = A + R5 Mnemonics ADD A, R7 ;addiere Inhalt von R7 zu A; erzeugen ;nun ist A = A + R7 Befehlscode ADD A, #12H ;addiere zu A den Wert 12H ;nun ist A = A + 12H HERE: SJUMP HERE ;bleibe in dieser Schleife END ;Ende des Programms Beschriftung ermöglicht dem Kommentare sollten am Ende einer Zeile Programm, eine Codezeile durch oder auf einer eigenen Zeile stehen. Der den Namen zu identifizieren Assembler ignoriert Kommentare

Abbildung 6.4: Prinzipieller Aufbau von 8051 Assemblercode

• Sprungbefehle • Unterprogrammbefehle • sonstige Befehle Transferbefehle dienen dem Datenverkehr zwischen Registern, Speicherstellen und I/O Ports. Bitverarbeitungs- und logische Befehle erlauben die logische Verknupfung¨ von Bitgruppen, das Setzen, L¨oschen, Invertieren und Testen einzelner Bits, sowie die Ver- schiebung und Rotation von Bitstellen. Arithmetische Befehle dienen der numerischen Verarbeitung und umfassen die Addition, Subtraktion und den Vergleich zweier Ope- randen. Sprung- und Unterprogrammbefehle bewirken eine Anderung¨ des Programm- flusses. Mit ihrer Hilfe kann die normalerweise linear aufeinanderfolgende Befehlsbear- beitung durchbrochen werden. Im Folgenden werden die einzelnen Befehlsgruppen und deren einzelne Befehle vorge- stellt. Eine ausfuhrliche¨ Beschreibung jedes einzelnen Befehls findet man in den ent- sprechenden Datenbuchern,¨ sowie in der bereits im Vorwort erw¨ahnten Befehlsliste des 8051 Mikrocontroller, die als Zusatzmaterial zum Labor angeboten wird. Zus¨atzlich zu der Beschreibung findet man in der Liste eine Angabe uber¨ die ben¨otigten Taktsyklen. Jeder Befehl besitzt ein in der Regel festgelegtes, reproduzierbares Zeitverhalten. Dieses wird durch die intern abzuarbeitenden Teilschritte bestimmt (vgl. Abbildung 5.3).

6.2.1 Transferbefehle Zun¨achst wird die Befehlsgruppe der Transferbefehle betrachtet. Diese Befehle kopieren Daten zwischen Registern, zwischen Register und Speicher und ggf. sogar zwischen verschiedenen Speicherstellen. Folgende Transferbefehle stehen zur Verfugung:¨

Beuth Hochschule fur¨ Technik Berlin 105 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

MOV Kopie, bezogen auf Register und internen Datenbereich MOVX Kopie, bezogen auf externen Datenbereich MOVC Kopie, bezogen auf Codebereich XCH Austausch Register-Register, Register-direktes RAM, Register- indirektes RAM XCHD Austausch der niederwertigen Halbbytes (low digit) von Akkumulator und indirektem RAM CLR Kopieren einer Null in Akkumulator SWAP Austausch der Halbbytes im Akkumulator PUSH Kopie einer direkten RAM-Zelle auf Stack POP Kopie des Stack-Inhalt in direkte RAM-Zelle Der MOV Befehl l¨adt einen bestimmten Wert in ein Register oder eine Speicherzelle. Er teilt der CPU mit, den Quelloperanden in den Zieloperanden zu kopieren. Der Ausdruck MOV ist eigentlich keine gute Bezeichnung, da keine Verschiebung sondern ein Kopieren stattfindet. Dabei wird die Quelle nicht ver¨andert. Die Syntax sieht folgendermaßen aus: MOV Ziel, Quelle ;kopiert die Quelle in das Ziel Abbildung 6.5 zeigt Beispiele fur¨ die Anwendung von MOV Befehlen.

„#“ zeigt an, dass es ein Zahlenwert ist

MOV A,#55H ;lade Wert 55H in das Register A MOV R0,A ;kopiere Inhalt von A in R0 ; (nun ist A=R0=55H) MOV R1,A ;kopiert Inhalt von A in R1 ;(nun ist A=R0=R1=55H) MOV R2,A ;kopiert Inhalt von A in R2 ;(nun ist A=R0=R1=R2=55H) MOV R3,#95H ;lädt den Wert 95H in R3 ;(nun ist R3=95H) MOV A,R3 ;kopiert Inhalt von R3 in A ;nun ist A=R3=95H

Abbildung 6.5: Beispiele fur¨ die Anwendung von MOV Befehlen

Noch einige Hinweise zum praktischen Umgang: Werte(mit vorangestelltem “# “) k¨onnen direkt nach A, B oder R0 - R7 geladen werden. Abbildung 6.6 verdeutlicht dies. Wenn Werte von 0 - F in ein 8-Bit Register kopiert werden, wird angenommen, dass der Rest der Registerbits Nullen sind. MOV A, # 5 ;Ergebnis A=05 bzw. A = 00000101 Wenn ein zu großer Wert in ein Register geladen werden soll, wird ein Fehler verur- sacht. MOV A, # 7F2h ;nicht erlaubt: 7F2h > 8 bits (FFh) Fur¨ die Befehle MOV, MOVX und MOVC gibt es spezifische Anwendungsf¨alle . Dies wurde in Abschnitt 5.6 im Rahmen der Erl¨auterungen zum Speichermodell bereits

Beuth Hochschule fur¨ Technik Berlin 106 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

Ohne vorangestelltes „#“bedeutet es das Laden von einer Registeradresse · MOV A, #23H · MOV R5, #0F9H

Füge eine 0 hinzu, um anzugeben, dass F eine Hex-Zahl ist und kein Buchstabe

Abbildung 6.6: Anwendung von MOV Befehlen erw¨ahnt. Abbildung 6.7 fasst den Sachverhalt abschließend zusammen.

nur indirekt über DPTR 0FFFFh

Programm- Externe code nur indirekt nur direkt Daten 0100h Special Internes (RAM) intern / Function RAM extern 0080h Register direkt und indirekt 0000h

MOV MOVX MOVC

Abbildung 6.7: Varianten der MOV-Befehle

Die Gultigkeit¨ der Adressierungsformen ist in 6.8 dargelegt. Die M¨oglichkeit, die Re- gister auch mit ihren Adressen anzusprechen, etwa R0 der Registerbank 1 auch mit Adresse 08, ist insofern vorteilhaft, als es Transferbefehle zwischen Registern nicht gibt, dieser Mangel aber durch die Schreibweise als Register-Speicher-Transfer umgan- gen werden kann (z.B. MOV R0, R1 ist nicht erlaubt, MOV R0, 1 jedoch schon).

Beuth Hochschule fur¨ Technik Berlin 107 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

Code- Datenspeicher speicher

R r d T R in . C t i i a R T P P s

r t R R T P + n D A k R P o + A D e von @ @ r D K A i @ @ d @ A

r Rr e h c i DPTR e p s

n direkt adr e t a

D @Ri @DPTR @Ri r - e Konst. e h c d i o

e @A+DPTR C p

s @A+PC

Abbildung 6.8:G ultigkeit¨ der Adressierungsformen

6.2.2 Bitverarbeitungsbefehle Der 8051 bietet die M¨oglichkeit, Einzelbits zu adressieren und zu manipulieren. Dies ist ein erheblicher Unterschied zu nahezu allen anderen Prozessoren. Von besonde- rer Bedeutung ist dies insbesondere, da es die M¨oglichkeit des effizienten Schreibens von Programmen zur Hardwaremanipulation bietet. Dass Einzelbit-Operationen durch- gefuhrt¨ werden, ist auf das Vorhandensein des integrierten Bit-Prozessors (Boolescher 1-Bit Akkumulator) zuruckzuf¨ uhren.¨ Das Arbeitsregister fur¨ solche Operationen ist das Carry-Bit, weshalb dieses hier h¨aufig als Ziel angegeben ist, d.h. Ergebnisse logischer Bitoperationen stehen grunds¨atzlich im Carry-Bit. Der Boolsche Akkumulator macht das sonst bei vielen Prozessoren notwen- dige Ausmaskieren von Bits vor deren Weiterverarbeitung uberfl¨ ussig¨ und beschleunigt damit den Programmablauf. Folgende Bitmanipulationsbefehle stehen zur Verfugung:¨ Un¨are Befehle CLR fur¨ L¨oschen eines Bits SETB fur¨ Setzen eines Bits CPL fur¨ Komplementbildung eines Bits Diese Befehle wirken entweder auf das Carry-Bit, adressiert mit C (z.B. CLR C), oder auf direkt zu adressierende Bits. Befehle fur¨ 2 Operanden (Carry-Bit plus direkt adressierbare Bitstelle) ANL fur¨ das logische UND ORL fur¨ das logische ODER MOV fur¨ Kopieren eines Bits Die Befehle ANL und ORL haben als Ziel immer das Carry-Bit. Der Inhalt der Bitstelle kann bei ANL und ORL auch invertiert angegeben werden (z.B. ANL C, /35h). Der

Beuth Hochschule fur¨ Technik Berlin 108 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

MOV Befehl hat als Ziel entweder das Carry-Bit oder ein RAM-Bit. MOV beherrscht die Invertierung nicht. Der Befehl ORL C, P1.1 beispielsweise fuhrt¨ eine OR-Verknupfung¨ des Carry-Bit mit dem Bit P1.1 (Port 1, Bit 1) durch und schreibt das Ergebnis der Operation in das Carry-Bit zuruck.¨

6.2.3 Befehle zur logischen Verknupfung¨ In der Befehlsgruppe der logischen Befehle sind Shift- und Rotations-Operationen, sowie byteweise logische AND-, OR- und XOR-Verknupfungen¨ integriert. Un¨are Befehle CPL das Einer-Komplement RL der Rotationsbefehl links RLC der Rotationsbefehl links mit Carry RR der Rotationsbefehl rechts RRC der Rotationsbefehl rechts mit Carry Diese Befehle wirken ausschließlich auf den Akkumulator. Befehle fur¨ 2 Operanden ANL das logische UND ORL das logische ODER XRL das logische EXKLUSIV-ODER Fur¨ die Adressierung gilt Folgendes: Wenn bei diesen Befehlen als Ziel der Akkumula- tor angegeben wird, dann kann die Quelle nur eines der Register R0...R7, eine direkt oder indirekt adressierbare RAM-Zelle (nicht extern!) oder eine direkt angegebene Kon- stante sein. Wird als Ziel eine direkt adressierbare RAM-Zelle angegeben, dann haben als Quelle nur der Akku oder eine direkt angegebene Konstante Gultigkeit.¨ Andere Kombinationen gibt es fur¨ diese Befehle nicht. Der RR Befehl rotiert die 8 Bits des Akkumulators um jeweils 1 Bit nach rechts. RR A ;rotiere Akkumulator nach rechts Wenn das unterste Bit, also das LSB (Bit D0), nach rechts aus dem Register her- ausgeschoben wurde, wird es links wieder angeh¨angt. Abbildung 6.9 veranschaulicht dies.

MSB LSB

MOV A,#36h ;A = 0011 0110 RR A ;A = 0001 1011 RR A ;A = 1000 1101 RR A ;A = 1100 0110 RR A ;A = 0110 0011

Abbildung 6.9: Prinzip des Rotate Right (RR) Befehls

Analog zum RR Befehl rotiert der RL Befehl die 8 Bits des Akkumulators um jeweils

Beuth Hochschule fur¨ Technik Berlin 109 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

1 Bit nach links. RL A ;rotiere Akkumulator nach links Wenn das oberste Bit, also das MSB (Bit D7), nach links aus dem Register heraus- geschoben wurde, wird es rechts wieder angeh¨angt, wie in Abbildung 6.10 zu sehen ist.

MSB LSB

MOV A,#72h ;A = 0111 0010 RL A ;A = 1110 0100 RL A ;A = 1100 1001

Abbildung 6.10: Prinzip des Rotate Left (RL) Befehls

Sowohl den Rechts-, als auch den Links-Rotationsbefehl gibt es auch noch in der Vari- ante einer zus¨atzlichen Bit-Stelle, n¨amlich dem Carry-Bit. RRC A ;rotiere nach rechts mit Carry Wie in Abbildung 6.11 zu sehen ist, rotiert der RRC Befehl den Akkumulatorinhalt von links nach rechts uber¨ das Carry-Bit. Nachdem das oberste Bit, also das LSB (Bit D0), nach links aus dem Register herausgeschoben wurde, landet es zun¨achst im Carry-Bit und wird erst im n¨achsten Schritt an die Stelle des MSB (Bit D7) geschrieben.

MSB LSB CY

CLR C ;mach CY = 0 MOV A,#26h ;A = 0010 0110 RRC A ;A = 0001 0011 CY = 0 RRC A ;A = 0000 1001 CY = 1 RRC A ;A = 1000 0100 CY = 1

Abbildung 6.11: Prinzip des Rotate Right Carry (RRC) Befehls

Andersherum funktioniert das mit dem Befehl RLC. RLC A ;rotiere nach links mit Carry Der RLC Befehl rotiert den Akkumulatorinhalt von rechts nach links uber¨ das Carry- Bit. Das MSB (Bit D7) wird zum Carry-Bit geschoben und der Inhalt vom Carry-Bit wird anschließend zum LSB (Bit D0). Schematisch ist dies in Abbildung 6.12 darge- stellt. Der CPL Befehl invertiert alle Bits eines Registers (Einerkomplement). CPL A ;(CPL = Komplement) invertiert Akkumulator Um das Zweierkomplement zu erhalten, muss eine 1 zum Einerkomplement hinzuad- diert werden. Der ANL Befehl fuhrt¨ ein logisches UND auf beide Operanden aus und platziert das Ergebnis im als Ziel angegebenen Ort. Dieses Ziel ist normalerweise der Akkumulator,

Beuth Hochschule fur¨ Technik Berlin 110 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

CY MSB LSB

Programm, das die Anzahl an 1en in einem Byte findet

MOV R1,#0 MOV R7,#8 ;Zähler=08 MOV A,#97h AGAIN: RLC A JNC NEXT ;prüfe auf CY INC R1 ;wenn CY=1 addiere zum Zähler NEXT: DJNZ R7,AGAIN

Abbildung 6.12: Prinzip des Rotate Left Carry (RLC) Befehls kann aber auch eine direkt adressierbare RAM-Zelle sein. Fur¨ die gultigen¨ Quellen gelten obengenannte Einschr¨ankungen. ANL Ziel, Quelle ;Ziel = Ziel UND Quelle

Zeige das Ergebnis des Folgenden.

MOV A,#35h ;A = 35h ANL A,#0Fh ;A = A UND OFh X Y X U ND Y ANL wird oft benutzt, um 35h 0 0 1 1 0 1 0 1 0 0 0 bestimmte Bits eines 0Fh 0 0 0 0 1 1 1 1 0 1 0 0Fh 0 0 0 0 0 1 0 1 Operanden zu maskieren 1 0 0 (0 zu setzen) 1 1 1

Abbildung 6.13: Beispiel fur¨ die Anwendung des ANL Befehls

Der ORL Befehl fuhrt¨ ein logisches ODER auf beide Operanden aus und platziert das Ergebnis im als Ziel angegebenen Ort. Auch hier gelten die oben genannten Kombina- tionsm¨oglichkeiten aus gultigen¨ Zielen und Quellen. ORL Ziel, Quelle ;Ziel = Ziel ODER Quelle

Zeige das Ergebnis des Folgenden.

MOV A,#04h ;A = 04 ORL A,#68h ;A = A ODER 68h = 6C X Y X ODER Y Der ORL Befehl kann 04h 0 0 0 0 0 1 0 0 0 0 0 benutzt werden, um 68h 0 1 1 0 1 0 0 0 0 1 1 bestimmte Bits eines 6Ch 0 1 1 0 1 1 0 0 1 0 1 Operanden 1 zu setzten 1 1 1

Abbildung 6.14: Beispiel fur¨ die Anwendung des ORL Befehls

Der XRL Befehl fuhrt¨ ein logisches XODER auf beide Operanden aus und platziert das Ergebnis im Ziel. XRL Ziel, Quelle ;Ziel = Ziel XODER Quelle

Beuth Hochschule fur¨ Technik Berlin 111 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

Zeige das Ergebnis des Folgenden.

MOV A,#54h XRL A,#78h X Y X XOR Y Der XRL Befehl kann 54h 0 1 0 1 0 1 0 0 0 0 0 benutzt werden, um 78h 0 1 1 1 1 0 0 0 0 1 1 2Ch 0 0 1 0 1 1 0 0 bestimmte Bits des 1 0 1 Operanden zu toggeln. 1 1 0

Abbildung 6.15: Beispiel fur¨ die Anwendung des XRL Befehls

6.2.4 Arithmetische Verarbeitungsbefehle Folgende arithmetische Verarbeitungsbefehle stehen zur Verfugung:¨ ADD Addition ohne Berucksichtigung¨ des Carrys ADDC Addition mit Berucksichtigung¨ des Carrys SUBB Subtraktion mit Berucksichtigung¨ des Carrys (Borrow) MUL Multiplikation DIV Division INC Inkrement eines Registers oder Speicherzelle DEC Dekrement eines Registers oder Speicherzelle DA Dezimale Justitierung (Decimal Adjust) Die Addition ist sowohl mit, als auch ohne Carry-Bit implementiert. Die Subtrakti- on allerdings ist ohne Borrow des Carry-Bits nicht vorgesehen. Fur¨ den praktischen Umgang bedeutet dies, dass vor jeder ersten Subtraktion das Carry-Bit durch CLR C gel¨oscht werden muss. Das Ziel der hier genannten Befehle ist immer der Akkumulator. Als Quelle kommen wiederum die Register R0...R7, RAM-Speicherzellen (direkt oder via R0, R1 indirekt adressierbar), sowie direkt angegebene Konstanten in Frage. Der ADD Befehl veranlasst die CPU, das Quellbyte zum Akkumulator hinzuzuaddieren und das Ergebnis wiederum im Akkumulator zu speichern. ADD A, Quelle ;Addiere den Quelloperanden Abbildung 6.16 zeigt Beispiele fur¨ die Anwendung des ADD Befehls. ADD R4, A und ADD R2, #12h w¨aren ungultige¨ Befehle, da in beiden F¨allen Register A nicht das Zielregister w¨are.

MOV A, #25H ;lade 25H in Register A Es gibt immer MOV R2, #34H ;lade 34H in Register R2 mehrere Wege ADD A, R2 ;addiere R2 zum Akku Programme zu ;(A = A + R2) schreiben, abhängig davon MOV A, #25H ;lade einen Operanden welche Register ;in Register A ( A = 25H) genutzt werden ADD A, #34H ;addiere den 2. Operanden ;34H zu Register A

Abbildung 6.16: Beispiel fur¨ die Anwendung des ADD Befehls

Der SUBB Befehl veranlasst die CPU, das Quellbyte, sowie das Carry-Bit vom Akku-

Beuth Hochschule fur¨ Technik Berlin 112 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ mulator zu subtrahieren und das Ergebnis letztlich auch dort zu speichern. SUBB A, Quelle ;A = A - Quelle - CY Um aus SUBB eine einfache Subtraktion zu machen, also gewissermaßen den nichtexis- tenten Befehl SUB abzuleiten, muss das Carry-Bit gel¨oscht werden, bevor der Befehl ausgefuhrt¨ wird. Dabei ist allerdings besondere Vorsicht geboten, da das Carry-Bit stets fur¨ den Ubertrag¨ gebraucht wird. Multiplikation und Division werden beide vorzeichenlos ausgefuhrt.¨ Sie beziehen sich immer auf den Akkumulator A, sowie den Hilfsakkumulator B und werden daher immer als MUL AB bzw. DIV AB angegeben. Sowohl Multiplikation, als auch Division sind nur Byte-fur-Byte¨ m¨oglich. MUL AB ;AxB, 16-Bit Ergebnis in B, A Bei einer 8 · 8-Bit Multiplikation steht das 16-Bit Ergebnis in A (Low Byte) und B (High Byte), das Carry-Bit wird gel¨oscht. Eine Zusammenfassung der vorzeichenlosen Multiplikation (MUL AB) ist in Ab- schnitt 6.2.4 gegeben.

Multiplikation Operand1 Operand2 Ergebnis Byte x Byte A B B = high Byte A = low Byte

Tabelle 6.1: Eigenschaften der Multiplikation beim 8051

Eine Division legt das 8-Bit-Ergebnis in A und den Rest (MOD(A/B)) in B ab. Das Carry-Bit ist bei dieser Operation eigentlich immer Null. Bei einem auftretenden Uberlauf¨ (Division durch 0) wird allerdings das Carry- und das Overflow-Bit gesetzt. Fur¨ diesen Fall (Division durch 0) ist der Inhalt von A und B undefiniert. DIV AB ;Teile A durch B, A/B Abschnitt 6.2.4 gibt eine Zusammenfassung der vorzeichenlosen Division (DIV AB).

Division Z¨ahler Nenner Quotient Rest Byte / Byte A B A B

Tabelle 6.2: Eigenschaften der Division beim 8051

Die Befehle INC und DEC werden auch als Z¨ahlbefehle bezeichnet. Sie k¨onnen Register- oder Speicherinhalte erh¨ohen bzw. verringern, allerdings haben sie keinerlei Einfluss auf die im PSW befindlichen CY-, AC- oder OV-Flags, d.h. es kann kein Uber-¨ bzw. Unterlauf angezeigt werden. Gultige¨ Operanden sind der Akkumulator, die Register R0...R7, sowie eine direkt oder indirekt adressierte RAM-Speicherzelle. Der Befehl INC (und nur INC!) kann auch den Data Pointer DPTR inkrementieren. Mit dem Befehl DA (Decimal Adjust) l¨asst sich das Ergebnis einer vorangegangenen Addition zweier BCD-Zahlen korrigieren. Wenn beispielsweise das untere Halbbyte gr¨oßer als 9 ist oder ein Ubertrag¨ in das h¨ohere Halbbyte stattgefunden hat (was auch durch das AC-Flag im PSW angezeigt wird), addiert dieser Befehl den Wert 6 auf den Akku (vgl. BCD-Darstellung in Abschnitt 1.2). Somit kann das Ergebnis fehlerfrei in BCD-Darstellung angezeigt oder weiterverarbeitet werden.

Beuth Hochschule fur¨ Technik Berlin 113 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

6.2.5 Sprungbefehle In der Gruppe der Sprungbefehle sind alle bedingten und unbedingten Sprungbefehle zusammengefasst, deren Aktion die Beeinflussung des Program Counters beinhaltet. So l¨adt die CPU den n¨achsten Befehl nicht mehr von den konsekutiven Stelle im Pro- grammcode, sondern von einer beliebigen anderen Stelle und fuhrt¨ diesen dann aus. Man unterscheidet zwei Kategorien • unbedingte Sprungbefehle ( Jumps“) ” • bedingte Sprungbefehle ( Branch“) ” Als unbedingte Sprungbefehle ist die Benutzung folgender Befehle gestattet: AJMP Absolute gesprungen werden kann innerhalb des aktuellen 2 KByte Jump Blocks, 2-Byte-Befehl, Befehl enth¨alt 11-Bit-Adresse, bei Bildung der vollst. Adr. werden 5 Adressbits A11 bis A15 aus Program Counter ubernommen¨ und restliche Bits oh- ne Ubertrag¨ durch Sprungziel ersetzt, direkte Adressie- rungsform, Befehl wird in 2 Buszyklen abgearbeitet, Be- fehl vorwiegend fur¨ Zugriff auf internen Progammspeicher LJMP Long Jump gesprungen werden kann im kompletten 64 KByte Code- segment, Adresse ist dabei 2 Bytes lang, Befehl wird in 2 Buszyklen abgearbeitet SJMP Short Jump relative Adressierung unabh¨angig von Blockgrenzen, in- dem um -128 oder +127 Bytes gesprungen werden kann JMP Jump indirect besonders fur¨ Mehrfachweisungen geeignet, Sprungadres- relative se steht im Akkumulator und im Data Pointer Register (korrekte Form: JMP @A+DPTR), im DPTR kann z.B. Grundadresse einer Sprungtabelle gehalten werden, in A dann der Offset innerhalb der Tabelle Bedingte Sprungbefehle beziehen sich in der 8051-Architektur relativ zur Adresse im Befehlsz¨ahler, sind also mit relativer Adressierung (d.h. mit Sprungzielen im Bereich -128 bis +127 von der Adresse des Folgebefehls) ausgefuhrt¨ (SJMP). Befehle, die abh¨angig vom angegebenen Bitwert sind, sind die Folgenden: JB testet das angegebene Bit und springt bei 1 JNB testet das angegebene Bit und springt bei 0 JBC testet und springt bei 1 und l¨oscht (clear) das Bit Befehle, die abh¨angig vom Inhalt des Akkumulators sind, sind diese: JZ testet den Akkumulatorinhalt und springt bei 0 JNZ testet den Akkumulatorinhalt und springt bei ungleich 0 Befehle, die abh¨angig vom Carry Flag sind, sind letztlich: JC testet das Carry Flag und springt bei 1 JNC testet das Carry Flag und springt bei 0 Die JNB- und JB-Befehle sind h¨aufig verwendete Single-Bit Operationen. Sie erlauben die Uberpr¨ ufung¨ eines beliebigen Bits und treffen Entscheidungen abh¨angig davon, ob es 0 oder 1 ist. Beispielsweise k¨onnen diese Befehle fur¨ jedes Bit der I/O Ports 0, 1, 2 und 3 benutzt werden.

Beuth Hochschule fur¨ Technik Berlin 114 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

Praxisbeispiel

Ein Programm soll Folgendes tun: Es soll das P1.2 Bit uberwachen¨ bis es auf einen High-Pegel gesetzt wird. Dann soll der Wert 45h auf Port 0 geschrieben werden und ein High-to-Low Impuls an P2.3 ausgel¨ost werden.

L¨osung: SETB P1.2;mache P1.2 zu einem input MOV A,#45H;A=45H AGAIN:JNB P1.2,AGAIN;geh raus wenn P1.2=1 MOV P0,A;gebeA an Port0 aus SETB P2.3;setze P2.3 high CLR P2.3;setze P2.3 low fuerH-to-L

Der JZ Befehl bezieht sich implitit auf den Akkumulator und fuhrt¨ zu einem Sprung, wenn der Inhalt des Akkumulators gleich Null ist. JZ Sprungmarke ;Springe, wenn A = 0

MOV A, R0 ;A = R0 JZ OVER ;Springe wenn A = 0 MOV A,R1 ;A = R1 JZ OVER ;Springe wenn A = 0 ... Kann nur für Register A benutzt OVER: werden, sonst für kein andere Register

; Bestimmte ob R5 den Wert 0 enthält. Wenn ja, Lade R5 mit 55H

MOV A, R5 ;kopiere R5 in den Akku JNZ Next ;springe, wenn der Akku nicht 0 ist MOV R5, #55H NEXT: ...

Abbildung 6.17: Beispiel fur¨ die Anwendung des JZ Befehls

Der JNC Befehl pruft¨ das Carry-Bit und fuhrt¨ daraufhin einen Sprung durch. • wenn CY = 0 erfullt¨ ist, wird Befehl von der Adresse der Sprungmarke geholt und ausgefuhrt¨ • wenn CY = 1, wird kein Sprung ausgefuhrt,¨ sondern der Befehl nach JNC abge- arbeitet JNC Label ;Springe wenn kein Ubertrag,¨ CY=0 Die bedingten Sprungbefehle werden erg¨anzt durch solche, die einen Registerinhalt dekrementieren und dann abh¨angig vom Inhalt des Registers verzweigen. DJNZ Rn, rel dekrementiert ein Register R0..7 und verzweigt, wenn Er- gebnis nicht 0 ist DJNZ direkt adr, rel dekrementiert eine direkt zug¨anglich Speicherstelle und verzweigt, wenn Ergebnis nicht 0 ist Diese Befehle eignen sich gut zur Realisierung von Schleifen. Darunter versteht man

Beuth Hochschule fur¨ Technik Berlin 115 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

Finde die Summer der Werte 79H, F5H, E2H. Lege die Summe in Register R0 (low Byte) und R1 (high Byte) ab. Auch möglich: MOV R5, #0 MOV A,#0 ;A=0 MOV R5,A ;lösche R5 ADD A,#79H ;A=0+79H=79H JNC N_1 ;wenn CY=0, addiere nächste Zahl INC R5 ;wenn CY=1, inkrementiere R5 N_1: ADD A,#0F5H ;A=79+F5=6E und CY=1 JNC N_2 ;Springe wenn CY=0 INC R5 ;Wenn CY=1,inkremeniere R5 (R5=1) N_2: ADD A,#0E2H ;A=6E+E2=50 und CY=1 JNC OVER ;Springe wenn CY=0 INC R5 ;Wenn CY=1, inkrementiere 5 OVER: MOV R0,A ;nun ist R0=50H, und R5=02

Abbildung 6.18: Beispiel fur¨ die Anwendung des JNC Befehls eine bestimmte Anzahl von Wiederholungen von Befehlssequenzen. Eine Schleifenaktion wird ausgefuhrt¨ durch DJNZ Register, Sprungmarke und arbeitet wie folgt: Der Registerinhalt wird dekrementiert und anschließend auf Null gepruft.¨ Wenn der Registerinhalt nicht Null ist, springt das Programm zur Zieladresse, die durch die Sprungmarke angezeigt wird. Vor dem Schleifenstart muss das verwendete Register mit der Anzahl an Wiederholungen geladen werden. Dazu verwendet man Register R0...R7 oder einen Speicherort im RAM.

Eine Schleife kann nur 255 mal wiederholt werden, wenn (hier) R2 = FF hex ist ; Diese Programm addiert 10 mal den Wert 3 zum Akku MOV A, #0 ;A=0 -->löscht den Akku MOV R2, #10 ;Lädt Anzahl R2=10 WIEDER: MOV A, #03 ;addiere 03 zum Akku DJNZ R2, WIEDER ;wiederholt bis R2 = 0 ;--> wiederholt 10 mal MOV R5,A ;speichert Ergebnis in R5

Abbildung 6.19: Schleifen mit Sprungbefehlen

Wenn eine Aktion mehr als 256 mal wiederholt werden soll, mussen¨ Schleifen innerhalb einer Schleife angeordnet werden. Man spricht dann von sog. verschachtelten Schleifen, engl.: Nested Loop. Realisiert wird dies durch Nutzung mehrerer Register zur Speiche- rung der Durchl¨aufe. Merke: Eine verschachtelte Schleife l¨asst sich noch weiter vereinfachen, wenn man be- denkt, dass nach Anwendung des DJNZ-Befehls auf ein Register, welches bereits den Wert 0 hat, wieder der Wert 255 (dezimal) steht. So muss man also den Maximalwert eines 8-Bit Registers nicht explizit noch einmal neu hineinschreiben.

Beuth Hochschule fur¨ Technik Berlin 116 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

Praxisbeispiel

Ein Programm soll den Akkumulator mit dem Wert 55h laden und diesen dann 700 mal invertieren.

L¨osung:

MOV A, #55H;A= 55H MOV R3, #10;R3=10, Anzahl der aeusseren Schleife NEXT:MOV R2, #70;R2=70, Anzahl der inneren Schleife WIEDER:CPLA;invertiere RegisterA DJNZ R2, WIEDER;wiederhole 70 mal DJNZ R3, NEXT;wiederhole 10 mal

Zus¨atzlich existieren kombinierte Vergleichs- und Sprungbefehle. CJNE A, direkt adr, rel vergleicht Akkumulator-Inhalt mit direktem RAM- Inhalt und springt bei Ungleichheit CJNE A, #data, rel vergleicht Akkumulator-Inhalt mit Konstante und springt bei Ungleichheit CJNE Rn, #data, rel vergleicht Register-Inhalt mit Konstante und springt bei Ungleichheit CJNE @Rn, #data, rel vergleicht indirekten RAM-Inhalt mit Konstante und springt bei Ungleichheit Wie eingangs erw¨ahnt, werden bedingte Sprunge¨ alle mit relativer Adressierung aus- gefuhrt.¨ Die anzuspringenden Ziele fur¨ die Sprunge¨ mussen¨ im Befehl codiert sein und werden in der Praxis mit Sprungmarken referenziert, um die Programmierung zu er- leichtern. Dahinter verbergen sich Adressen, fur¨ die bei der Assemblierung die jeweilige Sprungmarke gegen die effektive Adresse ausgetauscht wird. Die effektive Adresse er- gibt sich relativ zum Program Counter und ist somit als Offset zu verstehe, der zum Program Counter hinzuaddiert wird. Die Angabe des Sprungziels relativ zum Program Counter hat u.a. den Vorteil, dass das Programm ablauff¨ahig ist egal wohin es geladen wird. Im Befehl ist das erstes Byte der Opcode, das zweites Byte eine relative Zieladresse. Um nun die Zieladresse eines relativen Sprunges (SJMP, JNC, DJNZ, etc.) zu berech- nen, wird das zweite Byte zum Program Counter hinzuaddiert, sofort nachdem der Sprungbefehl ausgefuhrt¨ wurde. Wenn die Zieladresse außerhalb des Bereiches -128 bis +127 fur¨ einen kurzen Sprung liegt, generiert der Assembler einen Fehler mit der Mel- dung, das der Sprung außerhalb der Reichweite liegt (engl.: out of range error). Die Umsetzung in das reale Sprungziel ist in Abbildung 6.20 gezeigt.

6.2.6 Unterprogrammbefehle Unterprogramme (oder Subroutinen) werden oft benutzt um h¨aufig anfallende Aufga- ben auszufuhren.¨ Sie verhelfen dem Programm zu einem strukturierteren Aufbau und sparen Speicherplatz, indem Programmteile, die mehrfach ausgefuhrt¨ werden mussen,¨

Beuth Hochschule fur¨ Technik Berlin 117 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

Ze ile PC Opcode Mnemonischer Operand 1 0000 ORG 0 2 0000 7800 MOV R0, #0 3 0002 7455 MOV A, #55H 4 0004 6003 JZ NEXT 5 0006 8 INC R0 6 0007 4 AGAIN: INC A + 7 0008 4 INC A 8 0009 2477 NEXT: ADD A, #77H 9 000B 5005 JNC OVER 10 000D E4 CLR A 11 000E F8 MOV R0, A + 12 000F F9 MOV R1, A 13 0010 FA MOV R2, A 14 0011 FB MOV R3, A 15 0012 2B OVER: ADD A,R3 16 0013 50F2 JNC AGAIN 17 0015 80FE + HERE: SJMP HERE 18 0017 END

Abbildung 6.20: Adressberechnung kurzer Sprunge¨ einmal als geschrieben werden und daraufhin vom Hauptprogramm aus beliebig oft aufgerufen werden k¨onnen. Wenn die Subroutine aufgerufen wird, wird die Kontrolle der Subroutine ubertragen.¨ Abbildung 6.21 illustriert die Partitionierung eines Programms in Haupt- und Unterprogramme. Subroutinen nutzen den Stack fur¨ die Speicherung der Ruckkehradresse.¨ Dabei wird folgendermaßen vorgegangen: • der Stackpointer (SP) wird zun¨achst inkrementiert • der Program Counter Inhalt (2 Bytes) wird an die Stelle im RAM kopiert, auf die der SP zeigt • der Program Counter wird dann durch den Unterprogrammaufruf uberschrieben¨ • der RET-Befehl kopiert die Rucksprungsadresse¨ vom Stack in den Program Coun- ter zuruck¨

Beuth Hochschule fur¨ Technik Berlin 118 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

;Hauptprogramm, welches Subroutinen aufruft ORG 0 MAIN: LCALL SUBR_1 Es ist gebräuchlich, ein LCALL SUBR_2 Hauptprogramm zu LCALL SUBR_3 haben und viele HERE: SJMP HERE Subroutinen, die vom ;------Ende von MAIN Hauptprogramm aus SUBR_1: ... aufgerufen werden ... RET ;------Ende von Subroutine1 Das ermöglicht es einem aus SUBR_2: ... jeder Subroutine ein ... separates Modul zu machen RET - jedes Modul kann einzeln ;------Ende von Subroutine2 getestet und dann mit dem SUBR_3: ...... Hauptprogramm RET zusammengeführt werden ;------Ende von Subroutine3 - in großen Programmen END ;Ende der ASM Datei könne die einzelnen Module auf verschiedene Programmierer aufgeteilt werden

Abbildung 6.21: Partitionierung eines Programms in Haupt- und Unterprogramme

ORG 0 BACK: MOV A,#55H ;lade A with 55H MOV P1,A ;sende 55H zu Port 1 LCALL DELAY ;time delay MOV A,#0AAH ;lade A mit AA (in hex) MOV P1,A ;sende AAH zu Port 1 LCALL DELAY Nach Abarbeitung „LCALL DELAY“ wird die SJMP BACK ;maAcdhre sdsaes diemsm Beerf ewhilse ddearrunter, „MOV A, #0AAh“ auf den Stack gelegt, und der 8051 springt zu Zähler R5 wird auf Programmadresse 300h. FFh gesetzt, also wird die Schleife 255 mal wiederholt.

;------Das ist die DELAY Subroutine ------ORG 300H ;legt DELAY auf Adresse 300H DELAY:MOV R5,#0FFH ;R5=255 (FF in hex), Zähler AGAIN:DJNZ R5,AGAIN ;bleib hier bis R5 = 0 RET ;Rückkehr zum Hauptprogramm wenn R5=0 END Sobald R5=0 wird, wird RET ausgeführt à Adresse vom Stack wird in den PC geschoben und das Hauptprogramm wird unter dem CALL Befehl weiter abgearbeitet

Abbildung 6.22: Ablauf eines Unterprogrammaufrufs

Aus diesem Prinzip wird ersichtlich, dass bei Unterprogrammaufrufen (Calls) - wie auch bei Sprungen¨ per Long Jumps - der Befehlsz¨ahler vollst¨andig (16 Bit) uberschrieben¨ wird. Damit ist jede Adresse innerhalb der maximal zur Verfugung¨ stehenden 64 kByte erreichbar. Diese Vorgehensweise birgt allerdings auch Gefahren. Da die gesamte Infor-

Beuth Hochschule fur¨ Technik Berlin 119 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ mation uber¨ die beim Rucksprung¨ relevanten Adressen auf dem Stack gehalten wird, durfen¨ weder der Stackpointer, noch der Stackinhalt beim Rucksprung¨ ver¨andert sein. Von Manipulationen des Stacks ist daher unbedingt abzuraten. Der Ablauf eines Un- terprogrammaufrufs ist in ?? dargestellt. Unterprogramme oder Subroutinen werden... • durch CALL-Befehle angesprungen • durch Return-Befehle wieder verlassen (folgende Programmstelle der aufrufenden Stelle)

001 0000 ORG 0 002 0000 7455 BACK: MOV A,#55H ;lade A mit 55H 003 0002 F590 MOV P1,A ;sende 55H zu p1 004 0004 120300 LCALL DELAY ;Zeitverzögerung 005 0007 74AA MOV A,#0AAH ;lade A mit AAH 006 0009 F590 MOV P1,A ;sende AAH zu p1 007 000B 120300 LCALL DELAY 008 000E 80F0 SJMP BACK ;tu das immer wieder 009 0010 010 0010 ;------Das ist die Delay-Subroutine------011 0300 ORG 300H 012 0300 DELAY: 013 0300 7DFF MOV R5,#0FFH ;R5=255 014 0302 DDFE AGAIN: DJNZ R5,AGAIN ;bleib hier 015 0304 22 RET ;Rückkehr zum caller 016 0305 END ;Ende der ASM Datei

Stack Frame nach dem ersten LCALL

0A Lowbyte geht zuerst und das 09 00 Highbyte zuletzt rein, d.h. das 08 07 Highbyte liegt zuerst auf SP = 09 Abbildung 6.23: Speicherung der Rucksprungadresse¨ bei einem Unterprogrammaufruf

Beuth Hochschule fur¨ Technik Berlin 120 Prof. Dr.-Ing. Sven-Hendrik Voß 01 0000 ORG 0 02 0000 7455 BACK: MOV A,#55H ;lade A mit 55H 03 0002 F590 MOV P1,A ;sende 55H zu p1 04 0004 7C99 MOV R4,#99H KAPITEL05 6. 0 PROGRAMMIERUNG006 7D67 UND EINSATZ MOV R5,#67H 06 0008 120300 LCALL DELAY ;Zeitverzögerung 07 000B 74AA MOV A,#0AAH ;lade A mit AAH 08 000D F590 MOV P1,A ;sende AAH zu p1 09 000F 120300 LCALL DELAY 10 0012 80EC SJMP BACK ;tu es immer wieder

11 0014 ;------Das ist die Delay-Subroutine------12 0300 ORG 300H 13 0300 C004 DELAY: PUSH 4 ;push R4 14 0302 C005 PUSH 5 ;push R5 15 0304 7CFF MOV R4,#0FFH ;R4=FFH 16 0306 7DFF NEXT: MOV R5,#0FFH ;R5=FFH 17 0308 DDFE AGAIN: DJNZ R5,AGAIN 18 030A DCFA DJNZ R4,NEXT 19N o0rm30aCle rDw0e0i5s e muss die POP 5 ;POP in R5 A20n z0a3h0l dE eDr 0P0U4S H und POP POP 4 ;POP in R4 B21e fe0h3l1e0 i n2 e2i ner Subroutine RET ;Rückkehr zum caller 22 03ü1b1e reinstimmen END ;Ende der ASM Datei

Nach erstem LCALL Nach PUSH 4 Nach PUSH 5 0B 0B 0B 67 R5 0A 0A 99 R4 0A 99 R4 09 00 PCH 09 00 PCH 09 00 PCH 08 0B PCL 08 0B PCL 08 0B PCL

Abbildung 6.24: Rolle des Stack bei einem Unterprogrammaufruf

Folgende Unterprogrammbefehle stehen zur Verfugung:¨ LCALL adr16 fur¨ Unterprogrammaufrufe innerhalb des gesamten 64 KByte großen Adressraums ACALL adr11 fur¨ Unterprogrammaufrufe innerhalb des aktuellen 2 KByte Blocks RET fur¨ die Ruckkehr¨ aus dem Unterprogramm RETI fur¨ die Ruckkehr¨ von Interrupt-Service-Routinen Abbildung 6.23 und Abbildung 6.24 verdeutlichen die Rolle des Stacks bei einem Un- terprogrammaufruf.

6.2.7 Sonstige Befehle In dieser Kategorie gibt es nur einen einzigen Befehl. NOP (No Operation) NOP ist ein 1 Byte langer und einen Taktzyklus einnehmender Befehl, der nichts be- wirkt. Allerdings wird nach Aufruf des Befehls der Befehlsz¨ahler um 1 erh¨oht, da daraufhin ja auf den nachfolgenden Befehl gezeigt werden muss. Der wird mit dem n¨achsten Taktzyklus ausgefuhrt.¨ Der Befehl kann beispielsweise zur Beeinflussung der Ablaufdauer eines Programms, also zum Abgleich von Programm-Zeitschleifen mit ei- ner bestimmten Laufzeit, verwendet werden, da er genau einen Taktzyklus ben¨otigt.

6.2.8 Assemblerdirektiven In Abschnitt 4.3 wurden Direktiven als Steueranweisungen fur¨ den Assembler bereits kurz erw¨ahnt. Dies soll hier nun noch etwas vertieft werden, um einen besseren Einblick

Beuth Hochschule fur¨ Technik Berlin 121 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ zu bekommen was die Anweisungen zu Beginn und am Ende von Assemblerprogrammen bedeuten. Assemblerdirektiven sind immer abh¨angig vom verwendeten Assembler. Aufgrund der hier zugrunde gelegten Hardware-Zielplattform, wird der ASEM-51 Assembler verwen- det. Dies ist ein Makro-Assembler fur¨ die Intel 8051 Mikrocontroller-Familie. Es basiert auf der Standard-Intel-Syntax und beherrscht u.a. bedingte Assemblierung, die Verwen- dung von Makros und von Include-Dateien. Der Assembler kann Objekt-Code in Intel HEX- oder Intel OMF-51-Format ausgeben und detaillierte LST-Dateien generieren. Vom ASEM-51 werden mehr als 70 Derivate des 8051unterstutzt.¨ Der Assembler l¨auft unter MS-DOS, Windows und Linux. Zur Erinnerung: Assemblerdirektiven sind nicht Bestandteil des Befehlssatzes des Pro- zessors. Sie richten sich an das Assemblerprogramm und legen fest, auf welche Weise etwas assembliert wird (nicht das Programm selbst!). So kann beispielsweise festge- legt werden, ab welcher Adresse das Programm im Speicher stehen soll, unter welcher symbolischen Adresse Strings und Daten abgelegt werden. Auch k¨onnen symbolische Namen fur¨ Variablen, Register und Programmadressen bestimmt werden. Sie k¨onnen damit wesentlich dazu beitragen, den Quellcode zu strukturieren und einfacher zu ge- stalten. Folgende Direktiven stehen beim ASEM-51 zur Verfugung:¨ END markiert das Ende des Quelltextes, muss in jedem Assemblerpro- gramm genau einmal vorkommen (sonst: Fehlermeldungen vom Assembler) Syntax: END ORG definiert die genaue Position der auf diese Anweisung folgenden Instruktionen im Programmspeicher des Controllers, die Adresse wird ublicherweise¨ als Hexzahl angegeben Syntax: ORG Adresse Jedes Programm sollte zu Beginn die ORG Anweisung enthalten, um beispielsweise die Programmstartadresse im Speicher zu definieren und so auch bei einem Reset wieder neu beginnen zu k¨onnen. Des weiteren ist sie erforderlich, um Einsprungadressen der Interrupts mit dem Programmcode zu verknupfen.¨ $INCLUDE bindet Textdateien an der Stelle der Include-Anweisung ein, un- abh¨angig vom Inhalt der Dateien und fur¨ Assembliervorgang v¨ollig transparent (Achtung bei Symbolen und Sprungmarken mit gleichen Namen) Syntax: $INCLUDE (Dateiname) DB / DW belegen Speicherstellen im Programmspeicher des Controllers mit angegebenen Werten (DB belegt 1 Byte, DW belegt 2 Byte = ein Datenwort); so werden Datenfelder im Programmspeicher angelegt, auf die mit dem MOVC-Befehl zugegriffen werden kann (Sprungmarke notwendig, deren Adresse man mit MOV DP- TR,#Sprungmarke in das DPTR-Register bekommt) Syntax: db /dw Wert1,Wert2, ... ,Wertn

Beuth Hochschule fur¨ Technik Berlin 122 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

DATA und BIT bezeichnen Bytes oder Bits im Programmspeicher des Control- lers, die sich ebenso verwenden lassen wie Variablen; sie belegen den Speicher direkt an der Position, an der sie sich im Program- mablauf des Programmspeichers befinden Syntax: Bezeichner DATA / BIT Adresse EQU oder SET ordnen einem Bezeichner einen Wert (fur¨ Adressen oder Da- ten) zu, der sich im Programmcode wie eine Konstante einset- zen l¨aßt; bei EQU ist die Zuweisung konstant und nicht mehr ¨anderbar, bei SET ist die Zuweisung variabel und durch neues SET ¨anderbar Syntax: Bezeichner EQU / SET Wert IF, IFDEF oder fuhrt¨ zu bedingter Assemblierung: Assemblercode zwischen IFNDEF IF(N)DEF und ENDIF wird nur dann assembliert, wenn IF- Bedingung wahr ist: jeder IF-Block muss mit ENDIF abgeschlos- sen sein; Bedingung bei IF muss logischer Ausdruck sein, Bedin- gung bei IFDEF oder IFNDEF pruft¨ ob der dahinter angegebene Bezeichner definiert oder nicht definiert ist Syntax: IF Ausdruck ... IFDEF Bezeichner ... IFNDEF Bezeich- ner ... ELSE ... ENDIF

Beuth Hochschule fur¨ Technik Berlin 123 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

6.3 Modi und Pinout des 8051

Mikrocontroller sind i.a. optimiert auf den Single-Chip-Betrieb, d.h. sie enthalten alle notwendigen Teile wie ROM und RAM. Dies ist zuruckzuf¨ uhren¨ auf ihren zugeschnitte- nen Einsatz in eingebetteten Systemen. Sie sind meist ohne weitere externe Bausteine betriebsbereit, sollen nur einen sehr geringen Platz auf der Platine einnehmen, weisen unterschiedlichen Kombinationen von On-Chip-Komponenten auf und haben einen ge- ringen Stromverbrauch. In der Regel entf¨allt also die Notwendigkeit fur¨ externe Daten- und Adressbusse. In einigen F¨allen sind externe Busse aber dennoch notwendig, sei es fur¨ Erweiterungen im Programm- oder Datenbereich oder bei bestimmten Controllertypen, die uber¨ keine internen Speicherbereiche verfugen.¨ So unterscheidet man zwischen zwei Modi: • Prim¨armodus • Sekund¨armodus Prim¨ar- und Sekund¨armodus basieren auf dem Konzept der Doppel- und Mehrfachbele- gung von digitalen I/O-Portpins. Ein Portpin erfullt¨ je nach Programmierung verschie- dene Aufgaben. Dementsprechend weisen beide Modi unterschiedliche Pinbelegungen betreffend Ports 0, 2 und 3 und deren Verwendung auf. Die Differenzierung zwischen beiden Modi geschieht bei Port 0 und 2 automatisch bei Bereichsuberschreitungen¨ im Programm- oder Datenspeicher oder bei Belegung des EA-Pins mit einem Low-Pegel. Fur¨ Adressierungen unterhalb von 1000h werden keine zus¨atzlichen I/O-M¨oglichkeiten ben¨otigt. Aufgrund der limitierten Speicherressourcen im Mikrocontroller muss aber ab Adresse 1000h automatisch ein externer Speicher angesprochen werden. Mittels des EA-Pins l¨asst sich im unteren Speicherbereich manuell zwischen internem Speicher und externem Speicher ausw¨ahlen. In jedem Fall erfolgt die Adressierung beim Programm- zugriff uber¨ den 16 Bit breiten Program Counter, unabh¨angig davon, ob mit internem oder externem Speicher gearbeitet wird.

6.3.1 8051 im Prim¨armodus Abbildung 6.25 zeigt das Pinout des 8051 im Prim¨armodus. In Abschnitt 5.5 wurden die Port-Charakteristiken detailliert besprochen. Ports 1 bis 3 sind pseudobidirektional ausgelegt und stellen jeweils 8 pseudobidirektionale Portleitungen zur Verfugung.¨ Diese sind st¨andig auf Ausgang geschaltet. Das Einlesen von Eingangswerten ist allerdings trotz Fehlen von Tristate-Treibern m¨oglich. Dazu mussen¨ die Ports auf einen High- Pegel gesetzt werden. Die Ports k¨onnen byteweise gesetzt werden, einzelne Portpins auch bitweise. Aufgrund des in Abschnitt 5.5 beschriebenen internen Aufbaus kann dieser Pegel durch externe TTL-Signale auf Low-Pegel gezogen und Daten so eingelesen werden. Port 0 ist tats¨achlich bidirektional (Tristate) ausgelegt. Im Prim¨armodus wird nur mit internen On-Chip-Komponenten gearbeitet und exter- ne Bussysteme nicht ben¨otigt. Dem Anwender stehen (fast) alle digitalen I/O-Ports uneingeschr¨ankt zur Verfugung.¨ Erg¨anzend zu den Portpins sind in Abbildung 6.25 noch weitere Anschlusse¨ zu sehen. Der RST bzw. VPD Eingang dient dem Ausl¨osen eines Resets bei Anlegen eines High

Beuth Hochschule fur¨ Technik Berlin 124 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

Abbildung 6.25: Pinbelegung im Prim¨armodus

Pegels an diesen Pin. Der ausl¨osende Pegel muss wenigstens zwei Maschinenzyklen lang anliegen, ansonsten wird der Mikrocontroller unter Umst¨anden nicht zuruckgesetzt.¨ Der Eingang hat noch eine alternative Funktion. Wenn die Versorgungsspannung VCC unter 4,5 V absinkt oder sogar ausgeschaltet wird, ist die sichere Funktion des internen RAM nicht mehr gew¨ahrleistet. In diesem Fall wird intern umgeschaltet und die an Pin (VP owerDown) anliegende Spannung wird zur RAM-Versorgung verwendet. Die XTAL1 und XTAL2 Eing¨ange stellen den Anschluss fur¨ den Oszillator zur Lieferung der Referenzfrequenz bereit. Der Oszillator wird zwischen beide Eing¨ange angeschlossen und mit zwei kleinen Kondensatoren stabil gehalten. RST bzw. VPD, sowie XTAL1 und XTAL2 sind unabh¨angig des Betriebsmodus immer vorhanden.

6.3.2 8051 im Sekund¨armodus Im Sekund¨armodus stellen die Ports wichtige alternative Funktionen zur Verfugung.¨ Sowohl Port 0, als auch Port 2 und 3 haben im Sekund¨armodus eine spezifische Pe- ripheriebedeutung. Port 1 bleibt dagegen unver¨andert. Port 3 umfasst Anschlusse¨ fur¨ die serielle Schnittstelle, Timer, externe Interrupts, usw. Uber¨ die Ports P0 und P2 kann u.a. die Schnittstelle zu einem externen Speicher realisiert werden. Dazu wird ein gemeinsamer Adress- und Datenbus verwendet. Wenn mit externen Speicher- bzw. ex- ternen Peripherie-Bausteinen gearbeitet wird, die diese Busanbindung ben¨otigen, fallen zu deren Realisierung eine bestimmte Anzahl I/O-Portpins weg, d.h. dem Anwender stehen weniger allgemein verwendbare Portpins zur Verfugung.¨ Abbildung 6.26 zeigt das Pinout des 8051 im Sekund¨armodus. Signale, die mit einem /“ vor dem Namen ” gekennzeichnet sind (z.B. /PSEN) werden active low“ angesteuert, d.h. werden mit ”

Beuth Hochschule fur¨ Technik Berlin 125 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ einer logischen 0 aktiv geschaltet.

Abbildung 6.26: Pinbelegung im Sekund¨armodus

Am ursprunglichen¨ Port 3 sind nun spezifische Peripherie-I/Os zu finden. Die An- schlusse¨ RxD und TxD entsprechen den ublichen¨ Kommunikationsein- und -ausg¨angen bei serieller Kommunikation. INT0 und INT1 sind Eing¨ange fur¨ externe Interruptquel- len. Die Eing¨ange mit den Bezeichnungen T0 und T1 dienen den internen Timern, z.B. fur¨ Z¨ahlereignisse, Pulsweiten etc. WR und RD werden fur¨ Busoperationen als Schreib- oder Lesesignale fur¨ Datenzugriffe auf den externen Speicherbereich ben¨otigt. Die Anschlusse¨ A8 bis A15 stellen den h¨oherwertigen 8-Bit-Teil des Adressbus dar. Fur¨ externe Zugriffe werden diese Leitungen mit den entsprechenden Adressbits belegt. Die Anschlusse¨ AD0 bis AD7 stellen einen gemultiplexten Adress-/Datenbus dar, an dem der niederwertige Teil des Adressbus A0 bis A7 zusammen mit dem 8-Bit brei- ten Datenbus anliegt. Uber¨ die gleichen Portpins werden 8-Bit-Datenworte und die zugeh¨origen unteren 8 Bit der Adresse zeitlich abwechselnd (nacheinander) im so ge- nannten (Zeit-) Multiplex-Betrieb ausgesendet. Durch dieses Konzept werden weniger Anschlusspins im Pinout ben¨otigt, dafur¨ ist aber ein erh¨ohter externer Schaltungsauf- wand zur exakten Trennung der beiden Signalgruppen erforderlich. PSEN (Program Store Enable) signalisiert den Lesemodus fur¨ den externen Programm- speicherzugriff. Es wird aktiviert (Low-Pegel), falls der Mikrocontroller auf externen Programmcode zugreifen will und bleibt inaktiv (High-Pegel), wenn ein interner Pro- grammspeicherzugriff erfolgt oder ein Zugriff auf den Datenspeicher (vgl. Harvard- Modell). Das Multiplexing von Daten- und Adressbusteil macht eine externe Beschaltung zum Zwischenspeichern der Adressbits n¨otig. Zur Zwischenspeicherung wird in der Praxis

Beuth Hochschule fur¨ Technik Berlin 126 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ ein Latch verwendet. Ein Latch ist als Auffangregister zu verstehen und besteht aus zustandsgesteuerten Flipflops. Das Latch speichert je nach aktivierendem Zustand an- liegende Daten, die dann an seinem Ausgang pr¨asent bleiben. Das Signal ALE (Adress Latch Enable) gibt den momentanen Zustand des Adress- / Datenbusses an und kann somit auch als aktivierender Zustand fur¨ das Latch, also zum externen Zwischenspei- chern, verwendet werden. Im Augenblick, wo Port 0 als Datenbus arbeitet, ist das ALE-Signal auf Low-Pegel. Arbeitet dieser als Adressbus, so ist das ALE-Signal auf High-Pegel. Externe Speicherbausteine ben¨otigen die gesamte Adresse w¨ahrend der Dauer des Zu- griffs. Um also gleichzeitig 8 Bit an Daten und 16 Bit an Adressen an einen extern angeschlossenen Speicher zu ubertragen,¨ werden die unteren Adressbits A0 bis A7 fur¨ die nachfolgende Datenbusdauer in einem Latch 7 zwischengespeichert. Ist ALE auf High-Pegel (bei dem am Port Adressen anliegen), bedeutet dies Transparenz der Lat- ches. Bei Low-Pegel (bei dem am Port Daten anliegen) sollen die Latches den Wert halten, da der Bus nunmehr mit dem Datenteil belegt ist. ALE wird w¨ahrend jedes Maschinenzyklus zweimal aktiv. ALE entf¨allt nur dann einmal, wenn ein MOVX-Befehl ausgefuhrt¨ wird. Ohne externen Datenzugriff liegt am ALE-Signal ein um Fakor 6 reduzierter Refe- renztakt an (fosz/6), beispielsweise 2 MHz bei einem Referenztakt von 12 MHz. Das ALE-Signal ist in diesem Fall als Takt fur¨ externe Schaltungen verwendbar. Das Potential am EA-Eingang (External Access) legt fest, ob im unteren Adreßraum (kleiner als 1000h) der interne oder der externe Programmspeicher angesprochen wird. Dabei selektiert EA mit einem High-Pegel den internen Programmspeicher, der Low- Pegel steht fur¨ den externer Programmspeicher. Bei Adressen ab 1000h wird immer auf einen externen Programmspeicher zugegriffen, EA ist dann bedeutungslos. Wie eingangs erl¨autert, l¨asst sich durch das EA-Signal so ein Wechsel zwischen Prim¨ar- und Sekund¨armodus forcieren. Bei Datenzugriff auf externen Speicher muss logischerweise der Sekund¨armodus aktiv sein.

6.3.3 Prozessorbus im Sekund¨armodus Der Betrieb des 8051 Mikrocontroller im Sekund¨armodus soll nun noch etwas genauer betrachtet werden. In dieser Betriebsart werden die Ports 0 und 2 als Prozessorbus zur Ankopplung externen Speichers verwendet. An diesen Prozessorbus k¨onnen maxi- mal 64 kByte Programm- und maximal 64 kByte Datenspeicher angeschlossen werden. Insgesamt k¨onnen extern somit 128 kByte Speicher angeschlossen werden. Fur¨ den Betrieb eines externen Speichers, sei es Daten- oder Programmspeicher, muss ein Datenverkehr mit 16 Bit Adressbreite und 8 Bit Datenbreite organisiert werden. Die oberen Bits A8 bis A15 der anzulegenden Speicheradressen werden dabei uber¨ Port 2 ausgegeben. Sie bleiben dort w¨ahrend der gesamten Dauer eines Lese- bzw. Schreibzy- klus stehen. Naturlich¨ kann auf einen Programmspeicher nur lesend zugegriffen werden, da das Beschreiben eines Programmspeichers nicht m¨oglich ist. Fur¨ den Datenspeicher gilt das zuvor Genannte aber auch. Nach dem Zugriff erscheint der ursprungliche¨ Inhalt

7Ein Latch fur¨ 8-Bit umfasst acht Flipflops in einem einzigen Geh¨ause. In der Praxis kann ein 74’LS373 bzw. 74’LS573 Baustein aus der TTL 74er-Reihe verwendet werden.

Beuth Hochschule fur¨ Technik Berlin 127 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ des Port 2 wieder an den Anschlussen.¨ Die unteren Bits A0 bis A7 der anzulegenden Speicheradressen werden in einem Zeitmultiplex-Verfahren mit dem zu verarbeitenden Datenbyte uber¨ die Anschlusse¨ des Ports 0 ubertragen.¨ Mit dem Signal ALE lassen sich die unteren Adressbits der Adresse extern in einem Latch zwischenspeichern. Dabei sind die Adressen bei der ne- gativen ALE-Flanke, also wenn das Signal von High (inaktiv) zu Low (aktiv) ubergeht,¨ gultig.¨ Beim Anschluß eines externen Programmspeichers, gezeigt in Abbildung 6.27, l¨asst sich das ALE Signal direkt mit dem LE (Latch Enable) Eingang des Latches verbinden 8. Dies ist der Steuereingang des Latches, der bei einer fallenden Flanke die Informationen an den Eing¨angen des Latches gleichzeitig ubernimmt¨ und einspeichert und an den Ausg¨angen des Latches zur Verfugung¨ stellt. Fur¨ die Speicherung im vorliegenden Fall muss ein 8-Bit Latch mit 8 Ein- und Ausg¨angen verwendet werden. Solange am LE Eingang ein High-Pegel anliegt, ist das Latch transparent. Bei Ubergang¨ zum Low-Pegel findet die Speicherung statt. Gem¨aß des beschriebenen Verhaltens des ALE Signals kann es in Abstimmung mit den anliegenden Daten (Adressen, Daten) genau diese logische Funktion bereitstellen und wird daher direkt mit LE verbunden. Ein ROM als Programmspeicher verfugt,¨ ebenso wie ein Latch, notwendigerweise uber¨ Steuereing¨ange. Damit der Inhalt einer durch die anliegende Adresse ausgew¨ahlten Speicherzelle an den Datenausg¨angen erscheint, mussen¨ die Eing¨ange CE (Chip Ena- ble) und OE (Output Enable) aktiviert werden. Bei dem in der Abbildung gezeigten Baustein sind diese, wie auch die hier betroffenen Signale am 8051, active low“, wes- ” halb sie direkt verbunden werden k¨onnen. Damit ein ROM-Baustein uberhaupt¨ verwendet werden kann, muss er uber¨ seinen CE-Eingang eingeschaltet sein. Mittels CE werden die Steuerleitungen des Bausteins aktiviert. Wenn CE inaktiv ist (High-Pegel), werden s¨amliche Signale an Steuerlei- tungen ignoriert. Wenn auf den Speicher zugegriffen werden soll, muss CE also mit einem Low-Pegel aktiv geschaltet werden. Da dies genau der Fall ist, wenn das Latch den gespeicherten Adressteil zur Verfugung¨ stellt, kann CE direkt durch den Wert am ALE-Ausgang des 8051 gespeist werden. Mit dem OE-Eingang am ROM-Baustein kann unabh¨angig von CE bestimmt werden, ob die herausgesuchten Daten auch an den Datenausg¨angen erscheinen oder nicht. Ist OE inaktiv (High-Pegel), werden die Daten zwar herausgesucht, gelangen aber nicht zu den Ausg¨angen, da die Ausgangstreiber der Datenleitungen nicht freigeschaltet sind. Fur¨ den Fall, dass Daten aus dem Speicher ausgelesen werden sollen, ist OE also mit einem Low-Pegel aktiv zu schalten. Analog zum CE-Eingang und der Verknupfung¨ mit dem ALE-Signal kann hier der OE-Eingang direkt mit dem PSEN-Signal des 8051 verbunden werden. Der Mikrocontroller signalisiert mit dem PSEN-Signal, dass Daten aus einem externen Programmspeichers gelesen werden sollen. Er zeigt mit einem Low- Pegel nach außen einen Lesezugriff auf den Programmspeicher an. Diese fallende Flanke von PSEN kann als Signal fur¨ den Programmspeicher verwendet werden, das diesem anzeigt, dass etwas aus ihm ausgelesen werden soll.

8Zu Orientierungszwecken sind sowohl in Abbildung 6.27, als auch in Abbildung 6.28 die Portbe- zeichnungen aus dem Prim¨armodus fur¨ die Ports 0 und 2 zus¨atzlich eingezeichnet, obwohl diese im hier betrachteten Sekund¨armodus keine Relevanz haben.

Beuth Hochschule fur¨ Technik Berlin 128 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

ROM

Daten

Adress- Low-Byte- Latch Low-Byte- Adresse/Datum Adresse Adresse Low-Byte

8051 LE

High-Byte-Adresse Adresse High-Byte

/CE /OE

Abbildung 6.27: Anschluß eines externen Programmspeichers beim 8051

Bei der Verwendung eines externen Speichers, sowohl Daten- als auch Programmspei- cher, ist Port 2 fur¨ sonstige Ein- oder Ausgabefunktionen nicht verwendbar. Das gilt auch dann, wenn von den oberen Adressbits A8 bis A15 beispielsweise nur ein Anschluss fur¨ die Speicheradresse ben¨otigt wird. Der Mikrocontroller k¨onnte n¨amlich nicht diffe- renzieren, welche Bits zur Adresse geh¨oren und welche nicht. Daher wurde¨ die Adress- information verf¨alscht und falsche Daten verarbeitet werden. Beim Anschluß eines externen Datenspeichers, dargestellt in Abbildung 6.28, werden zus¨atzlich zu dem aus Port 0 und 2 bestehenden Adress- bzw. Datenbus zwei Steuer- signale ben¨otigt, da ja sowohl schreibend, als auch lesend auf ihn zugegriffen werden kann und die Art des Zugriffs eindeutig gekennzeichnet werden muss. Dazu dienen die Steuersignale RD (Read Data) und WR (Write Data), die von Port 3 herangezogen werden. RD steuert den Speicherzugriff beim Lesen, das Signal WR beim Schreiben. Wie aus der Abbildung ersichtlich, sind diese Signale ebenfalls active low“. Die Buss- ” teuerung des 8051 gibt beim Lesen einen Low-Pegel an RD und beim Schreiben einen Low-Pegel an WR aus. Analog zum ROM verfugt¨ ein RAM-Baustein ebenfalls uber¨ dedizierte Steuereing¨ange. Das OE (Output Enable) wurde bereits beim ROM-Baustein behandelt. Zus¨atzlich wird hier ein weiteres Signal zur wahlweisen Aktivierung von Schreib- oder Lesebetrieb ben¨otigt. Dies wird durch den Anschluss WE (Write Enable) bedient. Damit der Baustein elektrisch gel¨oscht und beschrieben werden kann, muss das Schreib- signal WE ( active low“) aktiviert sein. Da das WR-Signal des 8051 ja eben dies si- ” gnalisiert, n¨amlich einen Schreibzugriff, kann es direkt zum WE-Eingang des RAM- Bausteins gefuhrt¨ werden. Das RD-Signal des 8051 aktiviert den Lesezugriff. Dafur¨ reicht es beim RAM-Baustein aus, die Ausg¨ange zu aktivieren, was mit dem schon

Beuth Hochschule fur¨ Technik Berlin 129 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

RAM

Daten

Adress- Low-Byte- Latch Low-Byte- Adresse/Datum Adresse Adresse Low-Byte

8051 LE

High-Byte-Adresse Adresse High-Byte

/WE /OE

Abbildung 6.28: Anschluß eines externen Datenspeichers beim 8051 bekannten OE-Anschluss realisiert wird. Da vom Controller aus WR und RD niemals gleichzeitig aktiv sein k¨onnen, ist seitens des RAM-Bausteins keine gesonderte Beschal- tung erforderlich. Nachdem nun die logischen Verbindungen zu einem externen Speicher erl¨autert wurden, seien nun abschließend noch Ablauf und Timing dieser Busverbindung dargelegt. Der 8051 nutzt ein synchrones Busprotokoll fur¨ die Zugriffe zur Peripherie, zum Code- und zum externen Datenspeicher. Ein Maschinenzyklus entspricht beim 8051 genau 12 Takt- zyklen. Da die Kommunikation uber¨ die Ports (Ports 0 und 2 als Prozessorbus, Port 3 fur¨ Peripherie-Steuersignale) von innen gesteuert wird und auf Befehle zuruckzuf¨ uhren¨ ist, die von diesem internen Referenztakt abh¨angen, entspricht der Buszyklus ebenfalls 12 Taktzyklen. Da der 8051 (und alle Derivate) eine logische Harvard-Architektur mit getrennten Datenspeicher- und Programmspeicherbereichen besitzt, unterscheiden sich auch die Zugriffe und werden daher hier gesondert behandelt. Der schnellstm¨ogliche Zugriff ist der Zugriff auf Programmspeicher. Nun mag man sich fragen warum das so ist? Die Antwort sollte in ihrem Kern schon bekannt sein. Es resultiert aus der optimierten Fetch Phase (Laden des n¨achsten Befehls), die bei der Kommunikation mit dem Codespeicher Anwendung findet. LautAbschnitt 5.3 sind Lesezugriffe beim 8051 so optimiert, dass w¨ahrend eines Buszyklus beim Programmspeicher immer 2 Bytes eingelesen werden k¨onnen. Die Optimierung auf 2-Byte-Befehle hat auch Auswirkungen auf auftretende 1-Byte- und 3-Byte-Befehler (vgl. Abschnitt 6.2). 1-Byte-Befehle werden ebenfalls wie 2-Byte- Befehle geladen, nur wird das nicht relevante Byte ignoriert. Damit bringt die Optmi- mierung hier beim Einlesen keinen Geschwindigkeitsvorteil. 3-Byte-Befehle, die l¨angste

Beuth Hochschule fur¨ Technik Berlin 130 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

Befehlsart, werden in 4 Bytes mit Wiederholung des letzten Bytes und damit in der doppelten Zeit als 2-Byte-Befehle eingelesen.

Abbildung 6.29: Zugriff auf Codespeicher (fur¨ 2-Byte-Befehle) am 8051

Abbildung 6.29 zeigt den Zugriff auf Codespeicher (fur¨ 2-Byte-Befehle) am 8051. Darge- stellt ist etwas mehr als ein Buszyklus. Ein Buszyklus, ebenso wie ein Maschinenzyklus, besteht ja aus einer Sequenz von 6 Zust¨anden zu je 2 Takten. Dargestellt sind 7, be- ginnend und endend bei Zustand (engl.: state) 4. Eingeleitet wird der Zugriff seitens des 8051 durch Setzten von ALE und PSEN auf High. Adressiert wird der Programm- speicher mittels Program Counter (PC), zu sehen in der Abbildung in der Unterteilung PC high“ fur¨ das obere Byte und PC low“ fur¨ das untere Byte des 16 Bit Registers. ” ” Das obere Byte (A8 - A15) wird auf Port P2, das untere Byte (A0 - A7) auf Port P0 ubertragen.¨ Damit tragen A0 - A15 zusammen den Inhalt des Program Counter und bilden die Adresse der auszulesenden Speicherstelle im Codespeicher. Nun wechselt ALE von High auf Low. Das ist das Signal fur¨ den Latch-Baustein, die Adressbits A0 - A7 zwischenzuspeichern. Der Mikrocontroller nimmt danach die Bits A0 - A7 vom Port P0 zuruck¨ und wartet einen Moment. Port P0 (AD0..7) ist nun bereit, den Inhalt der adressierten Programmspeicherstelle aufnehmen zu k¨onnen. Nun setzt der 8051 das Lese-Steuersignal PSEN auf Low-Pegel. Diese fallende Flanke von PSEN ist das Signal fur¨ den Programmspeicher, das aus ihm etwas ausgelesen werden soll. Die Adresse der gewunschten¨ Speicherstelle liegt nun am Programmspeicher an. Die Adressbits A0 - A7 werden vom Ausgang des Adress-Latches gespeist, die Bits A8 - A15 direkt vom Port P2. Nach Ablauf der Zugriffszeit erscheinen die gewunschten¨ Daten auf dem Datenbus (in der Abbildung als Data Sample“ gekennzeichnet). Der ” Mikrocontroller setzt nun PSEN wieder auf High-Pegel und liest gleichzeitig den Zu- stand von Port P0 (AD0..7) in sein internes Befehlsregister, wo der Befehl decodiert und ausgefuhrt¨ wird. Damit ist das Einlesen des ersten Bytes beendet und der n¨achste Einlesevorgang beginnt wieder mit den oben genannten Signalen. Durch das zweimalige Aktivwerden des ALE- und PSEN-Signals im gew¨ahlten Ausschnitt ist zu erkennen, dass hier w¨ahrend eines Buszyklus offensichtlich zwei Befehlsbytes geladen werden. M¨ochte man nun ein reales Controller-basierter Hardwaresystems bauen, sind nicht nur die Signalabfolgen an der Schnittstelle, sondern die tats¨achlichen Zeiten (engl.: timing als Begriff fur¨ Zeitablauf, Zeiteinteilung), die fur¨ den angeschlossenen Speicher

Beuth Hochschule fur¨ Technik Berlin 131 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ inklusive der notwendigen Dekodierung verbleiben, wichtig. Das Timing spielt eine große Rolle und ist in den Datenbl¨attern der zu verwendenden Komponenten (z.B. RAM-Baustein) verbindlich vorgegeben. Die Timings definieren sehr detailliert das Zusammenspiel der einzelnen Steuer- und Bussignale. Diese Vor- gaben mussen¨ unbedingt eingehalten werden. Sind die Abweichungen beim Timing zu groß, ist die Funktionsf¨ahigkeit des gesamten Designs nicht mehr garantiert.

Abbildung 6.30: Tats¨achliche Zugriffszeiten beim 8051 (vereinfacht)

Abbildung 6.30 zeigt ein beispielhaftes Timing-Diagramm fur¨ den Zugriff auf den Co- despeicher mit allen relevanten Zeitabschnitten fur¨ reale Zugriffszeiten. Man erkennt dort, wie und in welcher zeitlichen Reihenfolge, die einzelnen externen Steuer- und Bussignale erscheinen und welcher zeitlicher Zusammenhang zwischen ihnen besteht bzw. einzuhalten ist. Abschnitt 6.3.3 untersetzt die eingezeichneten Timing-Segmente mit realen Werten. Der Aufbau bzw. der Ablauf der Timing-Diagramme ist bei bei allen 8051 Mikrocon- trollern gleich, denn alle Derivate mussen¨ ja nach außen hin das gleiche Verhalten zeigen. Der einzige Unterschied besteht darin, dass bei den moderneren Bausteinen die Abl¨aufe schneller stattfinden, nicht jedoch anders.

Bezeichnung Wert allgemein Wert fur¨ fMAX = 12 MHz [ns] tCY (Minimum Time) 12 tRef 1000 tLHLL (ALE Pulse Width) 2 tRef − 40ns 127 tAV LL (Adress Setup to ALE) tRef − 30ns 53 tLLIV ( ALE to Valid Instruction) 4 tRef − 100ns 233 tLLP L (ALE to /PSEN) tRef − 25ns 58 tAV IV (Address to Valid Instruction In) 5tRef − 115ns 302

Tabelle 6.3: Berechnung der Zugriffszeiten

Alle in Abschnitt 6.3.3 gezeigten Angaben beziehen sich auf den externen Referenztakt fRef , der hier mit 12 MHz angenommen wird. Damit ist fRef = 83, 33 ns. So ergeben sich Zugriffszeiten von 233 ns fur¨ die Dekodierung und den gesamten Zugriff. Diese Zeit reicht bei heutiger Technologie bei weitem aus, ein stabiles System aufzubauen.

Beuth Hochschule fur¨ Technik Berlin 132 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

Wenn z.B. ein Mikrocontroller-System bis an die Grenzen seiner Leistungsf¨ahigkeit ausgelegt werden soll, wenn es also z.B. auf maximale Geschwindigkeit getrimmt wer- den soll, so ist immer ein Blick in die Timing-Diagramme notwendig, um festzustellen, welche Anforderungen an die anderen externen Bausteine zu stellen sind, damit diese noch mit der maximal m¨oglichen Arbeitsgeschwindigkeit des Mikrocontrollers mithal- ten k¨onnen (Impulsbreite, Zeitabst¨ande, Flankensteilheiten, etc.). In der praktischen Umsetzung begegnet man meist noch weiteren Herausforderungen. Da die Leitungen eines Hardwaresystems neben einem Widerstand auch Kapazit¨aten und Induktivit¨aten aufweisen, findet die Ausbreitung der elektrischen Signale real im- mer etwas verz¨ogert (engl.: delay) und mit reduzierter Flankensteilheit statt. Dies ist zu berucksichtigen¨ und entsprechende Gegenmaßnahmen auf Platinenebene zu treffen. Geeignete Methoden hier aufzulisten, wurde¨ allerdings den Rahmen sprengen. Daher wird darauf verzichtet. Nachdem nun ausfuhrlich¨ der Zugriff auf den Programmspeicher beleuchtet wurde, folgt die Betrachtung des Datenspeichers. Beim Datenspeicher kann w¨ahrend eines Buszyklus immer nur 1 Byte eingelesen werden, da eine Optimierung auf mehr als ein Byte hier keinen Sinn hat. Zudem kann auf den externen Datenspeicher nur indirekt uber¨ den Umweg eines Zeigerregisters zugegriffen werden. Daher zeigt der Lesevorgang aus dem externen RAM ein vom Code Fetch abweichendes zeitliches Verhalten. Dieses ist in Abbildung 6.31 dargestellt und wird im Folgenden genau beschrieben.

Abbildung 6.31: Zugriff auf Datenbyte aus externem RAM (Lesezugriff)

Fur¨ die indirekte Adressierung wird ein 8-Bit Zeigerregister, das dazu in der Lage ist, eine 8-Bit-Adresse aufzunehmen, verwendet. In der Abbildung ist das Zeigerregis- ter mit Ri (R0 oder R1) bezeichnet. Zun¨achst wird der Befehl, in diesem Fall nur 1 Byte umfassend, aus dem Programmspeicher geladen. Dies ben¨otigt einen Buszyklus. W¨ahrend dieses Buszyklus wird das Befehlsbyte geladen und interpretiert. In einem zweiten Buszyklus wird das Datenbyte, welches durch den Inhalt der Adresse (00h .. 0FFh), die in Ri steht, eindeutig referenziert ist, geladen und aus dem externen RAM in den Akkumulator geschrieben. Dieser zweite Buszyklus soll anhand der Abbildung nun genau erl¨autert werden.

Beuth Hochschule fur¨ Technik Berlin 133 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ

Am Anfang des Lesezugriffs auf den Datenspeicher setzt der 8051 die Steuersignale ALE und PSEN auf High-Pegel und h¨alt das Lese-Steuersignal RD zun¨achst ebenfalls auf High. Dann gibt er uber¨ den Port P0 die durch das Zeigerregister Ri dargestellte Adresse aus. Da es sich um eine 8-Bit Adresse handelt, sind die oberen Adressbits A8 - A15 auf Null gesetzt und ¨andern sich w¨ahrend des gesamten Lese-Zyklusses nicht. Das Signal ALE wird vom 8051 nach einiger Zeit von High nach Low gezogen, zeitlich gesehen genau in der Mitte des Anliegens der Adresse aus Ri. Damit werden nun die Adressbits A0 - A7 in das Adress-Latch zwischengespeichert und liegen nun am Datenspeicher an. Anschließend wechselt das Lese-Steuersignal RD seinen Zustand von High- nach Low-Pegel, womit dem Speicher signalisiert wird, die angeforderten Daten auf den Datenbus P0 (AD0..7) zu geben. Aufgrund der Zugriffszeit des Speichers vergeht nun eine kurze Zeitspanne, bis diese anliegen (in der Abbildung als Data Sample“ gekennzeichnet). Gleichzeitig nimmt ” der 8051 jetzt die Adressbits vom Datenbus P0 (AD0..7) weg, damit der Speicher die angeforderten Daten auf P0 legen kann, ohne das es dort u.U. zu Kollisionen mit noch anliegenden Adressdaten kommt. Nun setzt der Mikrocontroller sein RD-Signal wieder auf High und liest im gleichen Augenblick (beim Wechsel von Low auf High) die Daten vom Datenbus P0 in seine internen Verarbeitungseinheiten. Damit ist der zweite Buszyklus komplett beendet. Diese Kommunikation uber¨ den Prozessorbus ben¨otigt damit insgesamt 24 Taktzyklen. Dargestellt sind in der Abbildung wiederum 7 States. Hier ist zu erkennen, dass die Signale ALE und PSEN im gew¨ahlten Ausschnitt jeweils nur einmal aktiv sind, da hier ein externer Datenspeicherzugriff ausgefuhrt¨ wird. Der Ablauf eines Schreibvorgangs in das externe RAM erfolgt analog zum Lesezugriff. Die externe Datenzelle wird mit einem Datenbyte, das aus dem Akkumulator stammt, und dessen Bestimmungsort durch R0 oder R1 gegeben ist, beschrieben. Zuerst wird der Befehl geladen und interpretiert, in einem zweiten Buszyklus, dem eigentlichen Schreibzyklus, wird das Datenbyte in das externe RAM ubertragen.¨

Abbildung 6.32: Zugriff auf Datenbyte aus externem RAM (Schreibzugriff)

Der Schreibzyklus beginnt wieder mit dem Setzen der Steuersignale ALE und PSEN auf High-Pegel. Das Schreib-Steuersignal WR wird vom Mikrocontroller zun¨achst ebenfalls

Beuth Hochschule fur¨ Technik Berlin 134 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 6. PROGRAMMIERUNG UND EINSATZ fest auf High gesetzt. Analog zum zuvor beschriebenen Lesevorgang gibt der Control- ler seine Adresse, repr¨asentiert durch den Inhalt von Ri, auf Port 0 aus. Das Signal ALE wird vom Mikrocontroller nach einiger Zeit von High nach Low gewechselt, zeit- lich wiederum genau in der Mitte der anliegenden Adressinformation auf Port 0. Etwas sp¨ater gibt der Controller die in die Speicherstelle zu schreibenden Daten (in der Abbil- dung als Data Out“ gekennzeichnet) auf dem gleichen Port aus. Unmittelbar danach ” wechselt das Schreib-Steuersignal WR seinen Zustand von High- nach Low-Pegel. Die Daten werden so in den Speicherbaustein geschrieben. Dieser komplette Ablauf ist in Abbildung 6.32 dargestellt. Die bisher beschrieben Abl¨aufe, insbesondere das Setzen der Steuersignale ALE, WR, PSEN, sowie die Ausgabe der Adressen und Daten auf P0 bzw. P2 im richtigen Timing werden vom 8051 selbst¨andig und automatisch durchgefuhrt.¨ Anhand des Befehls, z.B. MOVX fur¨ externen Datenspeicher, MOVC fur¨ Codespeicher, erkennt die interne Ab- laufsteuerung des Mikrocontrollers auf welche Art des Speichers zugegriffen wird und generiert die n¨otigen Steuersignale. Als Programmierer muss man sich darum also nicht kummern.¨

Beuth Hochschule fur¨ Technik Berlin 135 Prof. Dr.-Ing. Sven-Hendrik Voß 7 Funktionsgruppen der Peripherie und Steuerung

7.1 Interrupt-Programmierung

In den letzten zwei Kapiteln wurden die vielseitigen Peripheriekomponenten des 8051 Mikrocontrollers vorgestellt und erl¨autert. Der 8051 kann damit als stellvertretend fur¨ eine ganze Reihe von Mikrocontroller betrachtet werden, die durchaus auch noch mehr Komponenten aufweisen k¨onnen. Daruber¨ hinaus wurde die M¨oglichkeit beleuchtet, uber¨ die I/O-Ports weitere externe Komponenten anzuschliessen. Der Mikrocontrollerkern muss also eine Vielzahl von Subsystemen ansteuern und bedie- nen. In vielen Applikationen mussen¨ Mikrocontrollersysteme zudem auf zeitlich nicht vorhersehbare Ereignisse schnell reagieren (Echtzeitanwendungen). Zu diesen Ereignis- sen z¨ahlen beispielsweise: • jemand druckt¨ eine Taste • uber¨ eine Schnittstelle wurden Daten empfangen • ein Z¨ahler ist ubergelaufen¨ und hat damit die konfigurierte Zeitspanne erreicht Der Mikrocontroller hat nun zwei M¨oglichkeiten auf solche Ereignisse zu reagieren. Ent- weder er wartet aktiv auf das Ereignis oder er verh¨alt sich passiv und wird von dem Ereignis benachrichtigt. Die erste Variante nennt man Polling (eng.: to poll, abfragen), die zweite wird durch den Begriff Interrupt-Behandlung (engl.: to interrupt, unter- brechen) beschrieben. Diese zwei Varianten werden im Folgenden genauer betrachtet, anschließend steht die Interrupt-Programmierung des 8051 im Fokus.

7.1.1 Polling und Interrupt Fur¨ die Erkennung von Anforderungen der Peripherie wurden soeben zwei unterschied- liche Prinzipien vorgestellt. Das Polling ist charakterisiert durch eine zyklische Abfrage von passiven Steuereing¨angen oder Statusregistern der Interface-Komponenten. Diese Abfrage muss direkt im Programm beschrieben sein, d.h. man muss als Programmierer selbst dafur¨ Sorge tragen. Die zyklische Abfrage kann auf verschiedene Arten realisiert werden. Man unterscheidet zwei Varianten: • Variante 1: blockierende Abfrage • Variante 2: nicht-blockierende Abfrage Die einfachste M¨oglichkeit ist, eine Schleife zu programmieren. Diese Grundidee liegt beiden Varianten zugrunde. Bei der blockierenden Abfrage wartet das Programm in einer Schleife, bis sich etwas ¨andert. Prinzipiell kann man diese Warteschleife allein durch einen JNB-Befehl realisieren. In dieser Zeit kann die CPU nicht anderes tun,

136 KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG da die gesamte Rechenleistung auf das Polling verwendet wird, worauf diese Variante ihren Namen verdankt. Bei der nicht-blockierenden Abfrage ist die zyklische Abfrage so in das Programm inte- griert, daß dieses fur¨ sich ebenfalls in einer Schleife abl¨auft (man spricht von einer sog. Hauptprogrammschleife) und bei jedem Durchgang uberpr¨ uft,¨ ob sich etwas an den zu uberwachenden¨ Schnittstellen ge¨andert hat. Dazu kann die erw¨ahnte JNB-Schleife er- weitert werden, indem man zus¨atzlich zur eigentlichen Abfrage des Signals noch andere T¨atigkeiten ausprogrammiert. Dies geht dann jedoch auf Kosten des Echtzeitverhal- tens: je l¨anger die Poll-Schleife wird, umso seltener wird das Ereignis abgefragt und um- so langsamer ist die Reaktion darauf. Die Ubersichtlichkeit¨ des resultierenden Codes ist ebenfalls betroffen, da die Uberpr¨ ufung¨ bei jeder Iteration der Hauptprogrammschleife durchgefuhrt¨ werden muss. In beiden F¨allen wird bei Erkennung eines Ereignisses zu dem entsprechenden Pro- grammteil verzweigt, der dieses behandelt. Bei mehreren Peripherieeinheiten wird das Roundrobin-Verfahren9 angewendet. Ein Beispiel fur¨ ein nicht-blockierendes Polling zeigt folgender Codeauszug am Beispiel des sp¨ater noch vorgestellten Timer 0.

JNB TF0, Skip;hier wird Polling durchgefuehrt(zyklische Abfrage von TF0) CPL P3.0;toggle P3.0 jedes Mal wenn Timer0 ueberlaeuft CLR TF0;dann kann auch das Timer Flag wieder zurueckgesetzt werden

Skip :

;***** Hier steht Hauptprogramm(schleife)

Bei der Erkennung von Anforderungen der Peripherie per Interrupt reagiert das Steuer- werk direkt auf das abzufragende Ereignis. Dieses wird repr¨asentiert durch ein eigenes Signal (Flag oder Anzeigebit) bzw. einen aktiven Steuereingang. Das laufendes Pro- gramm wird unterbrochen und ein dem Ereignis zugeordnetes Unterprogramm wird gestartet. In diesem Unterprogramm (Interrupt Service Routine) ist dann die Reak- tion auf das Ereignis ausprogrammiert. Anschließend wird die Bearbeitung des ur- sprunglichen¨ Programms an der gleichen Stelle wieder aufgenommen. Wenn das abzu- fragende Ereignis nicht auftritt, verursacht es somit keinerlei Programmlaufzeit. Die Erkennung von Anforderungen der Peripherie durch Interrupts wird im folgenden Codeauszug wiederum am Beispiel des sp¨ater noch diskutierten Timer 0 verdeutlicht. Die Reaktion auf den Timeruberlauf¨ ist die gleiche wie im gezeigten Polling-Beispiel. Im weiteren Verlauf des Kapitels werden die Mechanismen und Vorg¨ange deutlich, die dazu fuhren,¨ dass und warum hier die Marke ISR angesprungen wird.

;***** Hier steht Hauptprogramm(schleife)

ISR: CPL P3.0;toggle P3.0 jedes Mal wenn Timer0 ueberlaeuft RETI;Timer Flag wird hier aber automatisch zurueckgesetzt!

9Beim Roundrobin-Verfahren werden die Behandlungen nach einem festdefinierten zeitlichen Sche- ma nacheinander abgearbeitet, weshalb es auch unter dem Begriff Zeitscheibenverfahren bekannt ist.

Beuth Hochschule fur¨ Technik Berlin 137 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Abbildung 7.1 skizziert die unterschiedlichen Prinzipien fur¨ die Erkennung von Anfor- derungen der Peripherie. Insbesondere auf die Vorg¨ange w¨ahrend des Auftretens einer Interrupt-Anforderung wird im Folgenden noch genauer eingegangem.

Haupt- programm

Anfangs- bedingungen Interrupt Service Routine einstellen ISR externes Signal- Register retten Hauptaufgabe ereignis

Befehl i Reaktion bei Interrupt Befehl i+1

Register zurück

RETI Eingabe Rückkehr aus Interrupt Überwachung Signal- bei Polling ereignis ja vorhanden? Reaktion nein

Abbildung 7.1: Polling vs. Interrupt-Behandlung

Polling ist sehr simpel in der Umsetzung und kann deterministisch ausgelegt werden. Das heißt, dass die Reaktionszeiten fur¨ den best case“ und den worst case“ bere- ” ” chenbar sind. In jedem Fall sind die Verz¨ogerungen groß genug, dass man von keiner unmittelbaren Reaktion ausgehen kann, was in vielen F¨allen schon ein Problem dar- stellt. Der Befehl JNB alleine ben¨otigt ja schon 2 Befehlszyklen. Bei der Realisierung als nicht-blockierende Abfrage wird die Reaktionszeit auf ein Ereignis bestimmt von der Summe der Programmlaufzeiten, die zwischen zwei Abfragen dieses Ereignisses auf- treten k¨onnen. Die Reaktion wird besonders langsam, wenn - um Rechenzeit zu sparen - selten gepollt wird. Da in der Regel auch nicht bei jeder Abfrage eine Reaktion vonn¨oten ist, wird durchschnittlich viel Rechenzeit fur¨ unn¨otige Abfragen vergeudet. Interrupts gehen schonender mit den zur Verfugung¨ stehenden Ressourcen um, wes- wegen der Interrupt-Betrieb die Effizienz enorm steigert. Ereignisse, die nicht auf- treten, verursachen keine Laufzeit. Da direkt auf die Ereignisse reagiert wird, ist die Reaktionszeit gegenuber¨ Polling minimal. Dies ist vor allem fur¨ eine in man- chen Systemen geforderte Echtzeitf¨ahigkeit entscheidend. Dort spielt eine garantierte

Beuth Hochschule fur¨ Technik Berlin 138 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG und sichere Reaktion des Mikrocontrollers auf ein Ereignis innerhalb einer definier- ten maximalen Reaktionszeit eine große Rolle. Fur¨ die Interrupt-Behandlung ist aller- dings fur¨ jedes Ereignis ein eigenes Kontrollsignal n¨otig. Interrupts erfordern zudem zus¨atzlichen Hardware-Aufwand und bei Vorhandensein mehrerer Interruptquellen eine Priorit¨atsbehandlung.

Polling Interrupts . große Reaktionsverz¨ogerung . schnellstm¨ogliche Reaktion . Rechenzeitverlust fur¨ Hauptaufgabe . kein Rechenzeitverlust . schwankender Abfrageabstand . zus¨atzlicher Hardwareaufwand . die meisten Abfragen umsonst . Software kann sehr komplex werden . keine Zusatzhardware . Flag meist autom. zuruckgesetzt¨ . einfache Realisierung . ausl¨osende Flags manuell zurucksetzen¨

Tabelle 7.1: Gegenuberstellung¨ Polling - Interrupts

Die Interrupt-Verarbeitung ist - entgegen der Polling-Methode - nicht vollkommen deterministisch. Je mehr Interrupts verwendet werden, umso unkalkulierbarer wird das Zeitverhalten des Systems (z.B. bei gleichzeitigem Auftreten aller Interrupts). Dennoch ist diese Methode fur¨ Echtzeitanforderungen die bessere Wahl, da die Latenzzeiten auf jeden Fall sehr viel geringer sind. Zudem bleibt der resulierende Code ubersichtlicher.¨ Wegen der genannten Grunde¨ verfugen¨ fast alle Mikrocontroller uber¨ die M¨oglichkeit der Interrupt-Verarbeitung. Abschnitt 7.1.1 fasst die Eigenschaften beider Varianten abschließend zusammen.

7.1.2 Prinzip der Interrupt-Behandlung Ein durch ein internes oder externes Ereignis ausgel¨oster Interrupt unterbricht das gerade laufende Programm. Dazu setzt die zu uberwachende¨ Peripherie ein Interrupt Request Flag, uber¨ das der Controller Anderungen¨ an eben dieser Peripherie erkennt. Jede CPU-Architektur hat eine fest definierte Anzahl von Interrupts. Die Behandlung des Ereignisses erfolgt in einem Codeabschnitt namens Interrupt Service Routine (kurz: ISR). Jeder Interrupt muss mit seiner individuellen ISR in Verbindung gebracht werden, d.h. wenn Interrupt x“ von der CPU empfangen wird, soll die ISR x“ ausgefuhrt¨ ” ” werden. Die CPU-Architektur definiert jeweils eine bestimmte Code-Adresse fur¨ jede ISR. Gespeichert ist diese individuelle Adresse in der sog. Interruptvektortabelle, einer Gruppe von Speicherorten fur¨ alle ISRs. Interrupts mussen¨ vor Gebrauch freigegeben werden (mittels sog. Enable-Flags). Wenn nun ein Interrupt auftritt, holt die CPU ihre ISR-Codeadresse aus der Interruptvek- tortabelle, verzweigt auf die dem aktuellen Interrupt zugeordnete Adresse und fuhrt¨ die ISR aus. Dies entspricht einem internen LCALL“ zu einer bestimmten Adresse ” im Programmspeicher. ISRs sind im Grunde Unterprogramme, die allerdings einige spezifische Eigenschaften haben, wie sp¨ater noch n¨aher erl¨autert wird. Ist die Service Routine abgearbeitet, wird das Programm an der zuvor unterbrochenen Stelle fortgesetzt. Dies wird erm¨oglicht, indem ¨ahnlich wie bei einem Call der Stand

Beuth Hochschule fur¨ Technik Berlin 139 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG des Befehlsz¨ahlers vor der Interruptverzweigung auf dem Stack gespeichert und von diesem anschließend wieder zuruckgeholt¨ wird. Dadurch wird das Programm an der ursprunglich¨ unterbrochenen Adresse fortgesetzt. Die Nutzung von Interrupts kann somit dazu beitragen, den Code ubersichtlicher¨ zu gestalten, da die Behandlungen von verschiedenen Ereignissen in verschiedene Funktionen ausgelagert wird. Beim Ausl¨osen eines Interrupts durchl¨auft der 8051 folgende Schritte: 1. die Ausfuhrung¨ des aktuellen Befehls wird noch beendet (zur Erinnerung: ein Befehl besteht aus mehreren Maschinenzyklen) 2. der aktuelle Inhalt des Befehlsz¨ahlers wird auf den Stack gerettet (um ein Wie- deraufnehmen des bisherigen Programms nach der Abarbeitung der Interrupt Servieve Routine zu gew¨ahrleisten) - Low Byte First! 3. der aktuelle Interrupt-Status wird intern gespeichert 4. Interrupts gleicher oder niedrigerer Priorit¨at werden blockiert (auch der gerade angenommene Interrupt wird gesperrt, damit er nicht mehrfach aufgerufen wird) 5. der Befehlsz¨ahler wird mit der Vektoradresse der ISR geladen → Sprung in die ISR 6. die ISR wird ausgefuhrt¨ Interrupt Service Routinen ben¨otigen ublicherweise¨ das PSW, den Akkumulator und einen Registersatz. Daher empfiehlt sich in der Interrupt Service Routine das Umschal- ten auf einen anderen Registersatz als den aktuell verwendeten. Abschließend mussen¨ dann die Inhalte des PSW und des Akkumulators auf den Orginalstand zuruckgesetzt¨ werden und die zuvor benutzte Registerbank selektiert werden. Letzteres l¨asst sich einfach durch Ruckladen¨ des PSW vom Stack realisieren. Bei Ausfuhrung¨ der RETI-Anweisung durchl¨auft der 8051 folgende Schritte: 1. der Befehlsz¨ahler wird vom Stack geholt 2. je nach Interrupt-Quelle wird das Interrupt Request Flag automatisch gel¨oscht 3. der alte Interrupt-Status wird wiederhergestellt: die vorher gesperrte Prio- rit¨atsebene fur¨ Interrupts derselben Priorit¨at wird wieder freigegeben → damit k¨onnen Interrupts wieder aktiviert werden 4. die Ausfuhrung¨ des Hauptprogramms f¨ahrt dort fort, wo es unterbrochen wurde Der Rucksprung¨ aus der ISR muss mittels RETI-Befehl erfolgen. Dieser Befehl wirkt wie der RET-Befehl mit der zus¨atzlichen Eigenschaft, dass dem Interrupt-System ge- meldet wird, dass eine Interrupt-Bearbeitung beendet ist. Der normale RET-Befehl darf nicht verwendet werden, da die Interrupts deaktiviert bleiben wurden.¨ RETI re- ” aktiviert“ die Interrupts auf dieser Ebene und kehrt zum unterbrochenen Programm zuruck.¨ Es sei an dieser Stelle darauf hingewiesen, dass Interrupt Service Routinen keine Re- gister, Flags oder ¨ahnliches ver¨andern sollten, die im Hauptprogramm verwendet wer- den. Dies kann zu schweren und schwer identifizierbaren Fehlern fuhren.¨ Ublicherweise¨ ben¨otigt die Interrupt Service Routine den Akkumulator, ver¨andert damit damit das Program Status Word und greift auf Register zu. Im Zweifelsfalls empfiehlt es sich den Akku, das PSW und zus¨atzlich Registerinhalte auf den Stack zu retten und am En- de der Service Routine zuruckzuholen.¨ Alternativ kann man auch auf einen separaten Registersatz umschalten.

Beuth Hochschule fur¨ Technik Berlin 140 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

7.1.3 Zeitlicher Ablauf eines Interrupt Die Unterbrechung eines Programms durch Aktivwerden von Interrupts ist in Abbil- dung 7.2 schematisch dargestellt. Interrupts k¨onnen unterschiedliche Priorit¨aten zuge- ordnet werden. Bei mehreren Interrupts hat ein Interrupt h¨oherer Priorit¨at Vorrang vor solchen niederer Priorit¨at. Eine gerade laufende Interrupt Service Routine (in der Abbildung hellrot dargestellt) k¨onnte durch einen Interrupt aus einer weiteren Stelle unterbrochen werden, wenn der neue Interrupt uber¨ eine h¨ohere Priorit¨at verfugte.¨ Bei gleicher oder niedrigerer Priorit¨at muss der neue Interrupt so lange warten, bis die aktuelle Interrupt Service Routine abgearbeitet ist. Erst dann wird er wirksam.

Zeit

Hauptprogramm

ISR ISR

Hauptprog. Hauptprog. Hauptprogramm

Abbildung 7.2: Unterbrechung eines Programms durch Interrupts

Ein Programm kann ausschließlich zwischen zwei Befehlen unterbrochen werden, ein Befehl selbst wird nie unterbrochen, sondern immer erst zuende ausgefuhrt.¨ Wird ein Interrupt aktiv, wird das in dem entsprechenden Anzeigebit signalisiert. Das sog. In- terrupt Request Flag wird gesetzt.

laufender Befehl Zyklus (=12 Takte)

zwei Zyklen Unterbrechung für den ab hier annehmen Sprung zum Beginn der (parallel zum zwischen Beginn der Interrupt- laufenden Unterbrechungen der Interrupt- Routine Befehl) gleichen Priorität Routine entscheiden (parallel zum laufenden Befehl)

Abbildung 7.3: Zeitlicher Ablauf eines Interrupt (1)

Die Interrupt Request Flags werden w¨ahrend jedes Maschinenzyklus abgefragt (State 5, Phase 1). Wurde ein Interrupt Request Flag gesetzt, so wird im darauffolgende Maschinenzyklus das gesetzte Flag erkannt und es folgt der Aufruf der Interrupt Service

Beuth Hochschule fur¨ Technik Berlin 141 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

laufender Befehl Zyklus (=12 Takte)

Unterbrechung hier ist der Program Counter ab hier annehmen durch die Hardware auf eine der Beginn der (parallel zum folgenden Adressen eingestellt: Interrupt- laufenden externer Interrupt 0: 0003h Routine Befehl) Timer 0: 000Bh Externer Interrupt 1: 0013h Timer 1: 001Bh serielle Schnittstelle: 0023h

Abbildung 7.4: Zeitlicher Ablauf eines Interrupt (2)

Routine. Dieser Aufruf selbst dauert zwei Maschinenzyklen (LCALL). Es vergehen also mindestens drei Maschinenzyklen zwischen Aktivierung eines Interrupt und der Ausfuhrung¨ des ersten Befehls der zugeh¨origen ISR. Skizziert ist dieser Vorgang in Abbildung 7.3 und Abbildung 7.4. Die Antwortzeit bis zur Ausfuhrung¨ der Service Routine kann sich zus¨atzlich verl¨angern, wenn eine der folgenden Blockierungen vorliegt: • der momentan laufende Befehl ist noch nicht abgearbeitet (d.h. der momentane Maschinenzyklus ist nicht der letzte Zyklus eines Befehls) • ein Interrupt gleicher oder h¨oherer Priorit¨at ist aktiv • der gerade aktive Befehl ist ein RETI, oder es findet gerade ein Zugriff auf eines der Interrupt SFRs statt Ist der momentan aktive Befehl noch nicht zu Ende, betr¨agt die zus¨atzliche Warte- zeit h¨ochstens 3 Zyklen, da die l¨angsten Befehle (MUL bzw. DIV) 4 Maschinenzyklen ben¨otigen. Ist ein Interrupt gleicher oder h¨oherer Priorit¨at aktiv, wird die Wartezeit von der Laufzeit der aktuell ausgefuhrten¨ Interrupt Service Routine bestimmt. L¨auft gerade ein RETI ab oder fndet ein Zugriff auf die Special Function Register, die der Interrupt-Konfiguration zugeordnet sind, statt, wird immer noch der n¨achste Befehl ausgefuhrt.¨ Deshalb kann dann die zus¨atzliche Wartezeit h¨ochstens 5 Zyklen betragen. Diese 5 Zyklen setzen sich zusammen aus 1 Zyklus fur¨ den momentan laufenden Befehl und 4 Zyklen fur¨ einen der l¨angstm¨oglichen Befehle (MUL bzw. DIV). Die Antwortzeit betr¨agt dann also immer mehr als 3 und weniger als 9 Zyklen, wenn kein Interrupt gleicher oder h¨oherer Priorit¨at aktiv ist.

7.1.4 Interrupt-Vektortabelle Das Interrupt-System des Original 8051 umfaßt funf¨ Quellen und zwei Priorit¨atsebenen. Diese funf¨ setzen sich zusammen aus zwei externen und drei internen Interrupt-Quellen. Moderne 8051-Derivate verfugen¨ indes uber¨ umfangreichere Features und Komponen-

Beuth Hochschule fur¨ Technik Berlin 142 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG ten als der Ur-Typ. Dies setzt folglich die Unterstutzung¨ einer gr¨oßeren Anzahl an Interrupts voraus, Interrupt-Funktionen fur¨ bis zu 32 Interrupts (0-31) sind durchaus ublich.¨ Entsprechend gr¨oßer f¨allt die Interrupt-Vektortabelle aus. Abschnitt 7.1.4 zeigt die Interrupt-Vektortabelle des 8051. Sie enth¨alt die Interrupt- Quellen mit den entsprechenden Einsprungadressen (Vektoradressen) im Programm- speicher, sowie die assoziierten Interrupt Request Flags, die je nach Quelle gesetzt werden (z.B. IE0 beim externen Interrupt 0, TF1 beim Timer 1, usw.). Da beim Start (Anlegen der Versorgungsspannung) bzw. nach einem Reset immer auf Speicheradresse 0000h zuruckgesprungen¨ und dort nach ausfuhrbarem¨ Code gesucht wird, kann der Re- set selbst als eine entsprechende Interrupt-Quelle mit Vektoradresse 0000h verstanden werden. Der Hardware-Reset kann durch Programmierung nicht unterdruckt¨ werden. An der fur¨ den Reset zugeordneten Adresse 0000h ist ein Bereich von 3 Byte reserviert (0000h - 0002h). Die Einsprungadressen aller weiteren Interrupt-Quellen beginnen ab Code-Adresse 0003h. Jeder folgende Eintrag in der Interrupt-Vektortabelle ist 8 Byte groß. Ein Interrupt mit Nummer k fuhrt¨ also zu einem Sprung an Adresse 0003h+8·k.

Interrupt Flag Vektoradressse System Reset RST 0000h External Interrupt 0 IE0 0003h Timer 0 TF0 000Bh External Interrupt 1 IE1 0013h Timer 1 TF1 001Bh Serial Port RI oder 0023h TI

Tabelle 7.2: Interrupt-Vektortabelle des 8051

Da die Ausl¨osung des jeweiligen Interrupts bzw. die Ausfuhrung¨ der zugeh¨origen ISR von den Flags ausgeht, kann die Unterbrechung prinzipiell auch manuell durch das Setzen des entsprechenden Flags (oder der entsprechenden Bitadresse des Flags) per Software erfolgen. Somit k¨onnen Interrupts, beispielsweise fur¨ die Testphase, durch die Software gesetzt oder schwebende Interrupt-Anforderungen gestrichen werden. Beson- dere Vorsicht ist geboten, wenn Interrupt Request Flags sowohl softwarem¨aßig mani- puliert, als auch nativ von den individuellen Quellen gesetzt werden, da es zu einem unuberschaubaren¨ Wechselspiel kommen kann. Werden die Interrupt Request Flags durch ein aktiviertes Interrupt-System verarbeitet, so l¨oscht der Controller in der Regel beim Rucksprung¨ (RETI) aus der Routine das Flag, das den Interrupt ausgel¨ost hat. Eine Ausnahme bilden die Flags RI und TI der seriellen Schnittstelle. Der 8051 hat nur einen Interrupt fur¨ die serielle Kommunikation, sowohl fur¨ den Empfang als auch fur¨ das Senden. Die ISR muss schließlich die RI- und TI-Flags kontrollieren, um zu ermitteln, welches der Flags den Interrupt ausgel¨ost hat, um entsprechend zu reagieren. Daher k¨onnen diese Flags nicht automatisch gel¨oscht, sondern mussen¨ in jedem Fall manuell in Software zuruckgesetzt¨ werden. Naturlich¨ k¨onnen die in Abschnitt 7.1.4 aufgefuhrten¨ Flags auch per Polling abgefragt werden. Dann muss in jedem Fall ein manuelles L¨oschen der Flags erfolgen.

Beuth Hochschule fur¨ Technik Berlin 143 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

100h ISR RI/TI 0023h TF1 001Bh 30h IE1 0013h TF0 00h 000Bh IE0 Internes ROM 0003h RST 0000h springt nach IE1 = 1

Abbildung 7.5: Sprung in Vektortabelle bei aktivem externen Interrupt

Interrupt Routinen ext. Interrupt 0

Haupt- programm 100h Start e

l RI/TI l e b

a TF1 t r

30h o t IE1 k e v

t TF0 Interrupt-

p vektoren 00h u r

r IE0 } 8 Bytes

e Startvektor Internes ROM t n I RST SJMP Start

Abbildung 7.6: Partitionierung des Speichers und Auslagerung der Interrupt Routinen

Abbildung 7.5 zeigt beispielhaft den Aufruf einer ISR fur¨ einen aktiven externen In- terrupt. Wie bereits aus Abschnitt 7.1.4 ersichtlich, nimmt die Interrupt-Vektortabelle einen Speicherbereich von 0003h bis 0023h (bzw. 002Bh) ein. Da dieser Speicherbe- reich fur¨ die Einsprungadressen reserviert ist, darf dort kein normaler Programmcode stehen. Da die CPU beim Start an Adresse 0000h stets ihren ersten Befehl erwartet, muss hier ein Sprungbefehl platziert werden, der die nachfolgenden Interruptvektoren (ab Adresse 0003h) uberspringt.¨ Nur wenn keine Interrupts verwendet werden, steht der genannte Speicherplatz frei zur Verfugung.¨ Wie bereits kurz dargelegt, stehen zwischen den Interrupt-Einsprungadressen maxi- mal 8 Byte zur Verfugung.¨ Fur¨ den Fall, dass die auszufuhrenden¨ Interrupt Service Routinen vom Programmcode her kompakt genug sind, k¨onnen sie direkt in dem zur Verfugung¨ stehenden Intervall zwischen zwei Vektoren platziert werden. Sind die Rou- tinen l¨anger - und das ist bei komplexeren Aufgabenstellungen meist der Fall - mussen¨ sie in einem separaten Speicherbereich hinter den Interruptvektoren platziert und aus

Beuth Hochschule fur¨ Technik Berlin 144 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG dem Vektorraum mit geeigneten Sprungbefehlen angesprungen werden. Abbildung 7.6 zeigt eine beispielhafte Partitionierung des Speichers mit der Interrupt-Vektortabelle und ausgelagertem Speicherplatz fur¨ die Interrupt Routinen.

7.1.5 Interrupt SFR Eine Ubersicht¨ uber¨ das Interrupt-System des 8051 Mikrocontroller ist in Abbil- dung 7.7 gegeben. Als individuelle Quellen sind die bereits erl¨auterten Interrupt Request Flags aufgelistet. Unter dem Flag Namen steht die Einsprungadresse der Interrupt-Vektortabelle, also die Adresse, auf die der Befehlsz¨ahler bei Aktivwerden des Interrupts gesetzt wird. Das Triggersignal fur¨ die externen Interrupts kann auf Pegel- oder Flankenausl¨osung gesetzt werden. Nach einem Reset sind alle Interrupts zun¨achst gesperrt. Sie mussen¨ vor Verwendung separat freigegeben (engl. enable) oder wieder gesperrt (engl. disable) bzw. maskiert werden. Diesem Zweck dient das Interrupt Enable Register (IE). Es enth¨alt entsprechende Bits fur¨ jede individuelle Interrupt-Quelle, sowie eine globale Freigabe.

Quelle Pegel Maske Priorisierung Interrupt Interrupt- IE Register IP Register mit hoher Request-Flags pegel- Priorität getriggert Int0 IE0

0003h flanken- getriggert Timer0 TF0

000Bh Interrupt- Int1 IE1 Polling- Sequenz 0013h

Timer1 TF1

001Bh

Serial I/O RI / TI EA 0023h individuelle Interrupt Program Counter Freigaben generelle Interruptfreigabe mit („Enables“) (oder: globale „Disables“) niedriger Priorität

Abbildung 7.7: Ubersicht¨ Interrupt-System des 8051

Fur¨ die Interrupt-Behandlung verfugt¨ der 8051 uber¨ zwei Priorit¨atsebenen. Stehen mehrere Interrupts gleichzeitig an, entscheidet die eingestellte Priorit¨at uber¨ die Rei- henfolge, in der sie abgearbeitet werden. Auf die Bevorzugung von Interrupts h¨oherer Priorit¨at und die M¨oglichkeit der Unterbrechung niedriger priorisierter Interrupts wur- de im Ansatz schon eingegangen. Interrupts gleicher Priorit¨atsebene fuhren¨ nicht zu einer Unterbrechung untereinander, stattdessen werden sie nach einer fest vorgegebenen Reihenfolge abgearbeitet.

Beuth Hochschule fur¨ Technik Berlin 145 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Diese Reihenfolge ist bereits in Abbildung 7.7 angedeutet. Die Abbildung veranschau- licht die Behandlung der Priorit¨atsebenen uber¨ das Register IP. Stehen mehrere Inter- rupts gleichzeitig an, haben die Interrupts in der dargestellten Reihenfolge der Interrupt Request Flags von oben nach unten Vorrang. Das heißt, die an h¨oherer Stelle aufge- listete Interrupt-Quelle hat die h¨ohere Priorit¨at. Die Reihenfolge entspricht direkt den Interrupt-Einsprungadressen in der Vektortabelle. Das Interrupt Enable Register (IE) befindet sich an Adresse 0A8h und hat den Reset- Wert 00h. Wie bereits erw¨ahnt, umfasst das Register Bits zur individuellen oder ge- nerellen Freigabe bzw. Sperrung von Interrupt-Quellen. So k¨onnen uber¨ das Steuerbit EA (Enable All) die Interrupts global gesperrt werden, um beispielsweise kritische Pro- grammteile zu schutzen¨ und Programmoperationen bedingungslos ausfuhren¨ zu lassen. Etwaige Programmunterbrechungen jedweder Quelle werden durch Setzen des EA-Bits auf 0 verhindert. Nach der Abarbeitung der kritischen Routine kann das EA-Bit wie- der gesetzt und fortgefahren werden. Uber¨ die individuellen Freigabebits k¨onnen die Interrupts einzeln aktiviert und deaktiviert werden. Werden Interrupts maskiert, wirkt der entsprechende Interrupt nicht.

Interrupt Enable Register 0

IE Alternativname: IEN0

MSB EA WDT ET2 ES ET1 EX1 ET0 EX0 LSB nicht für Interrupt- kein Timer 2 beim Steuerung klassischen 8051

Abbildung 7.8: Flags des Interrupt Enable Register

Das IE ist bitadressierbar. Die Flags des IE haben die in Abschnitt 7.1.5 gezeigte Bedeutung.

Flag Bedeutung EA generelle Interruptfreigabe: Wert 1 fur¨ alle Interrupts freigegeben, 0 fur¨ sperren WD Watchdog Timer Reset ET2 Freigabe Timer 2 Interrupt: Wert 1 fur¨ Freigabe, Wert 0 fur¨ Sperren ES Freigabe serieller Interrupt (1 oder 0, siehe oben) ET1 Freigabe Timer 1 Interrupt (1 oder 0, siehe oben) EX1 Freigabe externer Interrupt 1 (1 oder 0, siehe oben) ET0 Freigabe Timer 0 Interrupt (1 oder 0, siehe oben) EX0 Freigabe externer Interrupt 0 (1 oder 0, siehe oben)

Tabelle 7.3: Flags des IE

Bei Derivaten mit mehr Interrupt-Quellen (80535, 80C517 und sp¨ateren Derivaten) entspricht das IE Register dem dort befindlichen IEN0 Register. Bei diesen Derivaten

Beuth Hochschule fur¨ Technik Berlin 146 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG erstrecken sich die Steuerbits fur¨ die Freigabe und Sperrung aufgrund der gr¨oßeren An- zahl kontrollierbarar Quellen uber¨ zwei Register, IEN0 und IEN1. Abbildung 7.8 zeigt den Aufbau des Interrupt Enable Registers. Das gezeigte Register enth¨alt zus¨atzlich ein Flag fur¨ Timer 2 und Watchdog. Diese Einheiten sind ebenfalls nur bei sp¨ateren De- rivaten vorhanden. Im usprunglichen¨ Interrupt Enable Register sind diese Flags (IE.5 und IE.6) ungenutzt.

Timer 0 und 1 Interrupts Aus der Architekturubersicht¨ des 8051 ist bereits bekannt, dass der Controller zwei Timer-Komponenten enth¨alt, die unabh¨angig voneinander betrieben werden und wahl- weise als Z¨ahler oder als Zeitgeber eingesetzt werden k¨onnen. Laufen die Timer (bzw. Counter) uber,¨ setzen sie die Interrupt Request Flags TF0 (Timer Flag 0) bzw. TF1 (Timer Flag 1) und l¨osen dadurch den Timer 0 bzw. 1 Interrupt aus. Die Interrupt Request Flags TF0 und TF1 sind dem Timer Control Register (TCON) zugeordnet. Die Timer werden in einem sp¨ateren Abschnitt separat ausfuhrlich¨ behandelt. Voraus- setzung fur¨ die Ausl¨osung des jeweiligen Timer Interrupts ist die Freigabe durch die Bits EA (IE.7) und ET0 (IE.1) bzw. ET1 (IE.3) im Interrupt Enable Register. TF0 und TF1 werden nach der Verzweigung auf die Interrupt Service Routine durch die Hardware automatisch gel¨oscht.

Interrupt der seriellen Schnittstelle Der Betrieb der seriellen Schnittstelle l¨asst sich ebenfalls durch eine Interrupt- Steuerung unterstutzen.¨ Vorausgesetzt die Freigabebits EA (IE.7) und ES (IE.4) sind aktiv (auf 1 gesetzt), wird dieser Interrupt entweder durch das RI- oder das TI-Bit ausgel¨ost. Beide Interrupt Request Flags (RI und TI) sind dem Serial Control Register (SCON) zugeordnet, welches im Rahmen der seriellen Schnittstelle in einem separaten Abschnitt behandelt wird. Es ist zu beachten, dass die Flags RI und TI nicht durch die Hardware automatisch zuruckgesetzt¨ werden. Stattdessen muss durch Abfragen die Interrupt-Quelle (RI oder TI) ermittelt und das entsprechende Flag anschließend per Software gel¨oscht werden.

Externe Interrupts 0 und 1 Der 8051 hat zwei externe Hardware-Interrupts. Diese sind den Portpins P3.2 (Pin 12) P3.3 (Pin 13) zugeordnet (vgl. Abbildung 7.9) und tragen die Bezeichnung INT0 (P3.2) und INT1 (P3.3). Solange die externen Interrupts (EX0, EX1) im IE Register nicht aktiviert sind, werden die genannten Pins als normale I/Os genutzt. Sofern die externen Interrupts im IE Register aktiviert sind, wird dauerhaft einmal pro Maschinenzyklus der INT0 bzw. INT1-Eingang nach einem Low-Signal abgetastet. Es gibt 2 Aktivierungsf¨alle fur¨ die externen Hardware-Interrupts: • pegelgesteuert • flankengesteuert Nach einem Reset ist die Pegelsteuerung voreingestellt. Im pegelgesteuerten Modus sind INT0 (P3.2) und INT1 (P3.3) normalerweise auf High-Pegel gesetzt. Wird ein Low-Pegel Signal angelegt, so wird der Interrupt ausgel¨ost (und zwar so lange wie der Low-Pegel anliegt). Das Speichern der Interruptanforderung und das Abfragen

Beuth Hochschule fur¨ Technik Berlin 147 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

8051 Pins für externe Interrupts

Abbildung 7.9: Eing¨ange fur¨ externe Interrupts der Request Bits erfolgt in jedem Maschinenzyklus neu. Der pegelgesteuerte Interrupt wird also nicht gefangen. Deshalb muss der Pin bis zum Beginn der ISR in einem Low- Zustand gehalten werden. Um die Aktivierung des Interrupt sicherzustellen, muss das Low-Pegel Signal also lang genug anliegen, d.h. bis zum Start der ISR. Dies umfasst ca. 4 Maschinenzyklen, wie in Abbildung 7.10 dargestellt. Ebenso gilt, dass das Low-Pegel Signal am INT0 bzw. INT1 Pin vor der Ausfuhrung¨ des letzten Befehls (RETI) der ISR entfernt werden muss, ansonsten wird ein weiterer Interrupt erzeugt. Um INT0 und INT1 zu flankengesteuerten Interrupts zu machen, mussen¨ entsprechende Konfigurations-Bits gesetzt werden. Diese sind wiederum im Timer Control Register (TCON), das sp¨ater noch ausfuhrlich¨ behandelt wird, lokalisiert. Abbildung 7.11 zeigt die Konfiguration von Pegel- bzw. Flankentriggerung durch das IT0-Bit (fur¨ Timer 0) bzw. IT1-Bit (fur¨ Timer 1) im TCON Register. Sind die Bits IT0 bzw. IT1 auf 1 gesetzt, ist die fallende Flanke das den Interrupt ausl¨osende Moment, andernfalls der Low-Pegel. Die Einsprungadressen fur¨ INT0 und INT1 stehen in der Vektortabelle an 0003h, respektive 0013h, was in der Abbildung fur¨ die jeweilige Aktivierung angedeutet ist.

1 MZ 4 Maschinenzyklen zu INT0 oder 1,085µs INT1 Pins 4 x 1,085µs

Abbildung 7.10: Zeitliche Rahmenbedingungen fur¨ pegelgetriggerte Interrupts

Je nach Triggerung ergeben sich unterschiedliche Triggerpunkte. Der Triggerpunkt legt fest, wann genau zeitlich das ausl¨osende Moment eintritt. In beiden F¨allen muss ein Ubergang¨ von logisch 1 zu logisch 0, also ein High-Low-Wechsel erfolgen, wobei einmal der Low-Pegel selbst ausgewertet wird (Pegeltriggerung), im anderen Fall der Ubergang¨

Beuth Hochschule fur¨ Technik Berlin 148 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

(Flankentriggerung). Nur im Idealfall kann man von einem rechteckigen Signalverlauf ausgehen. Real ist dies nicht m¨oglich. Praktisch hat der High-Low-Wechsel eine end- liche Flankensteilheit. Dazu kommt, dass die High- und Low-Pegel selbst meist nicht stabil sind, sondern durch induktive und kapazitive Eigenschaften der Signalleitungen verrauscht anliegen.

Aktivierung von INT0

Pegelgesteuert INT0 0 IT0 (Pin 3.2) 0003 1 IE0 Flankengesteuert (TCON.1)

Aktivierung von INT1

Pegelgesteuert INT1 0 IT1 (Pin 3.3) 0013 1 IE1 Flankengesteuert (TCON.3)

Abbildung 7.11: Triggeroptionen fur¨ die externen Interrupts

Daher wird bei der Pegelsteuerung der Trigger ausgel¨ost, wenn der Eingangspegel einen definierten Schwellwert uber-¨ bzw. unterschreitet. Abbildung 7.12 illustriert die unter- schiedlichen Triggerpunkte in Abh¨angigkeit der Auswahl des Triggermodus im Speci- al Function Register TCON. Im gezeigten Beispiel fur¨ die Pegeltriggerung liegt der Schwellwert in der Mitte des High-Low-Pegelabstands. Bei der Flankensteuerung muss das Eingangssignal naturlich¨ ebenfalls einen Schwellwert uberschreiten,¨ zum anderen muß es sich um eine fallende Flanke handeln. Die Flankensteilheit des Signals sollte eine Mikrosekunde nicht uberschreiten.¨ Zur Flankenerkennung wird der Pin jeweils einmal pro Maschinenzyklus abgetastet. Wenn die Abtastung in einem Maschinenzyklus zuerst einen High-Pegel und im dar- auffolgenden Maschninenzyklus einen Low-Pegel liefert, trat eine Flanke auf. Der Trig- gerpunkt f¨allt in dem Fall mit dem erkannten Low-Pegel zusammen, der zur Flankener- kennung erforderlich ist. Daraus ergeben sich wie auch schon fur¨ die Pegeltriggerung definierte zeitliche Rahmenbedingungen. Gem¨aß Abbildung 7.13 muss die externe Quel- le fur¨ mindestens 1 Maschinenzyklus high gehalten werden und danach fur¨ mindestens 1 Maschinenzyklus low sein. Werden uber¨ die genannten Eing¨ange fur¨ die externen Interrupts solche ausgel¨ost, setzen sie die Interrupt Request Flags IE0 (Interrupt Extern 0) bzw. IE1 (Interrupt Extern 1). Die Interrupt Request Flags IE0 und IE1 sind wiederum dem Timer Control Register (TCON) zugeordnet. Voraussetzung fur¨ die Ausl¨osung ist die globale Freigabe durch das EA-Bit, sowie die Freigabe uber¨ die Interrupt Enable Bits EX0 (IE.0) bzw. EX1 (IE.2). Wie bereits erw¨ahnt, werden pegelaktive Interrupts grunds¨atzlich nicht gefangen. Fur¨

Beuth Hochschule fur¨ Technik Berlin 149 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Pegeltriggerung IT1 IT0 = 0: Null-Pegel getriggerter Input

Schwelle (Threshold) in INT0 oder INT1 Pins t Triggerpunkt

Flankentriggerung IT1 IT0 = 1: 1 Maschinenzyklus fallende-Flanke getriggerter Input

1,085µs 1,085µs 1 Maschinenzyklus in INT0 oder INT1 Pins t Triggerpunkt

Abbildung 7.12: Triggermodi fur¨ externe Interrupts

1 MZ 1 MZ Minimum Impulsdauer, um flankengesteuerte Interrupts zu erkennen für XTAL = 11.0592 MHz 1,085µs 1,085µs

Abbildung 7.13: Zeitliche Rahmenbedingungen fur¨ flankengetriggerte Interrupts

flankengetriggerte Interrupts gilt, dass die fallenden Flanken der Pins INT0 und INT1 vom 8051 gefangen und im IE0 und IE1 Flag gehalten werden. Diese Flags signalisieren, dass der Interrupt gerade behandelt wird und auf keinen neuen Interrupt an diesem Pin geantwortet wird, solange die Behandlung nicht abgeschlossen ist. Die Bits IE0 und IE1 werden nach der Verzweigung auf die Interrupt Service Routine durch die Hardware gel¨oscht, falls es sich um flankengesteuerte Interrupts gehandelt hat. Bei pegelgesteuerten Interrupts enthalten diese Bits den negierten Pegel des jeweiligen Eingangspins.

Beuth Hochschule fur¨ Technik Berlin 150 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Praxisbeispiel

An einem 8051 Mikrocontroller ist an Port P1 eine 8-Bit-LED-Ausgabeeinheit angeschlossen. Am externen Interrupt-Eingang INT0 befindet sich eine Schalter- einheit. Mit jeder fallenden Flanke am INT0 Eingang soll der auf den LEDs aus- zugebene Wert um 1 erh¨oht werden.

L¨osung: ORG 00h SJMP start

ORG 03h SJMP isr

ORG 30h start : MOV P1,#00h;alle LEDs an Port P1 aus SETB P3.2;externen Interrupt Eingang0 als Input konfigurieren SETB IT0;Interrupt-Ausloesung mit der fallenden Flanke an INT0 SETBEXO;externen Interrupt0 zulassen SETBEA;allgemeine Interruptfreigabe Hier :SJMP Hier;Endlosschleife

ORG 40h isr :;Interruptroutine fuer den externen Interrupt0 PUSHACC;Inhalt des Akkus retten PUSHPSW;PSW sichern INC P1;Inhalt des Ports P1(LED Ausgabe) um1 erhoehen POPPSW;PSW wiederherstellen POPACC;Originalinhalt des Akkus wiederherstellen RETI;zurueck zum Hauptprogramm

Der Vollst¨andigkeit halber sei hier noch das erweiterte Interrupt Enable Register IEN1 des 80535, 80C517 und sp¨aterer Derivate gezeigt (Abbildung 7.14). Fur¨ den in die- ser Veranstaltung im Fokus stehenden 8051 hat dieses Register keine Bedeutung. Das Register IEN1 ist an Adresse B8h zu finden, der gleichen Adresse wie das in Kurze¨ vor- gestelle Interrupt Priority Register des klassischen 8051. Per Reset hat dieses Register den Wert 00h.

Interrupt Enable Register 1

IEN1 nicht im klassischen 8051

MSB EXEN2 SWDT EX6 EX5 EX4 EX3 EX2 EADC LSB nicht für Interrupt- Steuerung

Abbildung 7.14: Flags des erweiterten Interrupt Enable Register

Die Flags des erweiterten Interrupt Enable Registers (IEN1) haben die in Ab- schnitt 7.1.5 gezeigte Bedeutung.

Beuth Hochschule fur¨ Technik Berlin 151 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Flag Bedeutung EXEN2 Interrupt des externen Reload fur¨ Timer 2: Wert 1 fur¨ freigeben, Wert 0 fur¨ sperren SWDT Watchdog Timer Start Flag (gleiche Funktion wie WD) EX6 Freigabe externer Interrupt 6: Wert 1 fur¨ Freigabe, Wert 0 fur¨ Sperren EX5 Freigabe externer Interrupt 5 (1 oder 0, siehe oben) EX4 Freigabe externer Interrupt 4 (1 oder 0, siehe oben) EX3 Freigabe externer Interrupt 3 (1 oder 0, siehe oben) EX2 Freigabe externer Interrupt 2 (1 oder 0, siehe oben) EADC Freigabe A/D-Wandler Interrupt (1 oder 0, siehe oben)

Tabelle 7.4: Flags des IEN1

7.1.6 Interrupt Priorit¨aten Interrupts unterschiedlicher Quellen k¨onnen unterschiedliche Priorit¨aten haben. Die Priorisierung ist indes nur sinnvoll, wenn mehr als eine Interrrupt-Quelle gleichzei- tig eine Programmunterbrechung anfordern kann. Bei mehreren Interrupts hat also ein Interrupt h¨oherer Priorit¨at Vorrang vor solchen niederer Priorit¨at und kann diese unter- brechen. Gleich priorisierte Interrupts oder Interrupts einer niedrigeren Priorit¨atsebene k¨onnen sich dagegen nicht beeinflussen. Soll nun generell verhindert werden, dass mehr als ein Interrupt gleichzeitig bearbeitet wird, so sind die Priorit¨aten der Interrupt- Quellen alle auf gleiche Ebene zu setzen. Wird mit mehreren Interrupt-Quellen gearbeitet, so mussen¨ die Priorit¨aten der In- terrupts vorab festgelegt werden. Dies geschieht durch die 8051-eigene Interrupt- Priorit¨atsstruktur, auf die ansatzweise bereits in Abbildung 7.7 Bezug genommen wur- de. Anhand des bitadressierbaren Special Function Registers IP (Interrupt Priority) sind die Priorit¨aten aller vorhandenen Interrupt-Quellen (bedingt) einstellbar. Abbil- dung 7.15 zeigt den Aufbau des Interrupt Priority Registers. Es befindet sich an Adresse 0B8h und hat den Reset-Wert 00h.

Interrupt Priority Register

IP

MSB -- -- PT2 PS PT1 PX1 PT0 PX0 LSB

Abbildung 7.15: Flags des Interrupt Priority Register

Die Priorit¨at wird durch die den Interrupt-Quellen zugeordneten Bits in dem Register festgelegt. Abschnitt 7.1.6 gibt eine komplette Ubersicht¨ die zur Verfugung¨ stehen- den Priorit¨ats-Steuerbits im IP Register. Jede Interrupt-Quelle kann einer von zwei Priorit¨atsebenen (0 oder 1) zugeordnet werden. Diese Ebene entspricht direkt den Priorit¨ats-Steuerbits des IP Registers. Eine 1, also ein gesetztes Bit, veranlasst den Prozessor diesen Interrupt mit hoher Priorit¨at zu behandeln. Bei gel¨oschtem Bit wird

Beuth Hochschule fur¨ Technik Berlin 152 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG der zugeh¨orige Interrupt jeweils mit niedrigerer Priorit¨at behandelt. Nach einem Reset sind zun¨achst alle Interrupt-Quellen der Priorit¨atsebene 0 zugeordnet.

Flag Bedeutung – reserviert PT2 Timer 2 (1: hohe Priorit¨at, 0: niedrige Priorit¨at) PS serielle Schnittstelle (1: hohe Priorit¨at, 0: niedrige Priorit¨at) PT1 Timer 1 (1: hohe Priorit¨at, 0: niedrige Priorit¨at) PX1 extern INT1 (1: hohe Priorit¨at, 0: niedrige Priorit¨at) PT0 Timer 0 (1: hohe Priorit¨at, 0: niedrige Priorit¨at) PX0 extern INT0 (1: hohe Priorit¨at, 0: niedrige Priorit¨at)

Tabelle 7.5: Flags des IP

Innerhalb einer Priorit¨atsebene gilt fur¨ den Fall des gleichzeitigen Auftretens das fol- gende vorgegebene, nicht ver¨anderbare Priorit¨atsschema: IE0 > TF0 > IE1 > TF1 > RI oder TI Diese Reihenfolge entspricht direkt der Abfolge der Interrupt-Quellen in der Inter- ruptvektortabelle und bestimmt die Reihenfolge der Abarbeitung. Bei gleichzeitig an- stehenden Interrupts unterschiedlicher Priorit¨at werden zuerst Interrupts mit hoher Priorit¨at abgearbeitet und anschließend die der niedrigeren. Voraussetzung dafur¨ ist allerdings, dass bei Aufhebung der Sperrbedingung die zuruckgewiesenen¨ Flags noch gesetzt sind. Wie bekannt, fragt die Interruptschaltung in jedem Maschinenzyklus ein- mal alle Interrupt-Quellen ab, ob eine Anforderung ansteht. Sind diese nicht mehr aktiv, wird der zuruckgewiesene¨ Interrupt nicht mehr ausgefuhrt.¨

Praxisbeispiel

In einer Applikation mit mehreren Interrupts soll der externe Interrupt 1 (IE1) die h¨ochte Priorit¨at haben. Das IP Register ist entsprechend zu konfigurieren. Was passiert, wenn IE0, IE1 und TF0 gleichzeitig aktiv werden?

L¨osung: MOV IP, #00000100b Bei gleichzeitiger Ausl¨osung ergibt sich die Reihenfolge: IE1 > IE0 > TF0

Beuth Hochschule fur¨ Technik Berlin 153 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

7.2 Timer-Programmierung

Auf dem 8051 Mikrocontroller sind zwei unabh¨angige 16-Bit-Z¨ahler/Zeitgeber- Schaltungen (T0 und Tl) integriert. Diese Schaltungen k¨onnen entweder als Ereig- nisz¨ahler (Counter) oder als Zeitgeber (Timer) konfiguriert werden. Sie erfullen¨ also eine Doppelfunktion. Bevor die architektonischen Besonderheiten beleuchtet werden, sei zun¨achst der Fokus auf eine eindeutige Begrifflichkeit gelenkt. Worin unterscheidet sich denn ein Counter von einem Timer? Der Counter - wie der Name schon andeutet (engl. to count) - z¨ahlt. Wie es beim Z¨ahlen so ublich¨ ist, erh¨alt man einen Zahlenwert als Ergebnis. Der Counter kann also als Einheit verstanden werden, die Bin¨arzahlen generiert. Diese Bin¨arzahlen folgen einer bestimmten Z¨ahlreihenfolge. Der Timer - im Namen (engl. time: Zeit) schon eindeutig - dient dagegen als Zeitgeber. Letztlich tut der Timer auch nichts anderes als Impulse zu z¨ahlen. Dadurch, dass diese Impulse beim Timer aber Oszillatorimpulse sind, z¨ahlt der Timer hier also eine Zeit. Als Resultat des Timereinsatzes folgt also die Generierung einer definierten Zeitspanne. Wozu ben¨otigt man Counter und Timer in der Praxis? Die Einsatzfelder sind viel- schichtig. Stellvertretend seien hier einige Beispielanwendungen gegeben: • Generierung von Zeitverz¨ogerungen (vgl. Programmlaufzeiten) • Messung von Pulsdauer oder Zeitintervallen • Z¨ahlen von Impulsen oder Ereignissen • Generierung und Auswertung von PWM-Signalen (Puls-Weiten-Modulation) • Generierung eines Baudraten-Taktes fur¨ den internen seriellen I/O Port • Erzeugung von Interrupts Zeitverz¨ogerungen k¨onnen prinzipiell auch uber¨ Warteschleifen erzeugt werden. Viele Anwendungen erfordern allerdings exakte Zeitverz¨ogerungen bzw. Zeitspannen, die mit Warteschleifen praktisch unm¨oglich umzusetzen sind. Zudem kann der Mikrocontroller bei der Abarbeitung einer Schleife keine anderen Aufgaben erfullen.¨ Zur Entlastung des Mikrocontrollers und zur Erfullung¨ exakter Zeitbedingungen werden also integrierte Z¨ahler/Zeitgeber-Schaltungen verwendet. Das Kernstuck¨ der Z¨ahler/Zeitgeber-Schaltungen des 8051 ist ein zyklischer Vorw¨artsz¨ahler, der durch eingehende Impulse inkrementiert wird. Wie bereits an- gedeutet, unterscheidet bei entsprechender Konfiguration letztlich die Herkunft der Impulse zwischen den Funktionen als interner“ Zeitgeber (Timer) oder externer“ ” ” Ereignisz¨ahler (Counter). Im Counter-Betrieb kommen die Impulse uber¨ einen Pin von außen in den Mikro- controller und werden gez¨ahlt. Arbeitet die Z¨ahler/Zeitgeber-Schaltung also als Coun- ter, wird sie immer extern getaktet. Im Timer-Betrieb werden die Impulse durch das Herunterteilen des internen Oszillatortaktes gewonnen. Da der Oszillatortakt bekannt ist, sind damit exakte Zeitmessungen m¨oglich. Arbeitet die Z¨ahler/Zeitgeber-Schaltung also als Timer, wird sie immer intern getaktet. Der Einfachheit halber wird im Folgenden der Oberbegriff Z¨ahler/Zeitgeber- Schaltungen durch den 8051-spezifischen Ausdruck Timer/Counter 0 und 1 (oder nur Timer) fur¨ die beiden unabh¨angigen Schaltungseinheiten abgekurzt.¨ Timer/Counter 0 und 1 sind (fast) identisch. Der einige Unterschied besteht darin, dass nur Timer/Coun-

Beuth Hochschule fur¨ Technik Berlin 154 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG ter 1 den Sendetakt fur¨ die integrierte serielle Schnittstelle generieren kann. Die beiden Timer 0 und 1 sind bei jedem 8051-Kompatiblen vorhanden. Ab dem 8052 und sp¨ateren Derivaten ist ein zus¨atzlicher Timer 2 enthalten und kann abweichende Register und Funktionen haben.

7.2.1 Betriebsarten von Timer und Counter Jeder der beiden Timer/Counter 0 und 1 besteht aus zwei kaskadierbaren 8-Bit- Z¨ahlregistern TH0 bzw. TL0 und TH1 bzw. TL1 (High und Low Byte) mit den zugeh¨origen Eingangpins. Die Konfiguration und Programmierung der Timer erfolgt uber¨ zwei weitere SFRs, dem Timer Modus Register (TMOD) und dem Timer Control Steuer- und Statusregister (TCON). Dies wird in einem sp¨ateren Abschnitt ausfuhrlich¨ behandelt. Die Timer k¨onnen in 4 verschiedenen Betriebsmodi arbeiten: • Modus 0: 5 Bit Teiler (Low-Byte) und nachgeschalteter 8-Bit-Z¨ahler (13 Bit) • Modus 1: 16-Bit-Counter/Timer (Low- und High-Byte) • Modus 2: 8-Bit-Counter/Timer mit automatischem 8-Bit-Reload • Modus 3: Timer bildet 2 unabh¨angige 8-Bit-Timer (nur Timer 0)10 Modus 1 und Modus 2 sind die zwei wichtigsten Betriebsarten. Die Modi 0 und 3 werden aufgrund von Kompatibilit¨at zu ¨alteren Mikrocontrollern nach wie vor imple- mentiert, haben jedoch nahezu keine praktische Relevanz. Daher beschr¨anken sich die Ausfuhrungen¨ im Folgenden auf die Modi 1 und 2. In Modus 1 nutzen die Timer die Z¨ahlregister TL0 und TH0, bzw. TL1 und TH1 voll aus, da diese zu einem einzigen 16-Bit-Z¨ahlregister zusammengeschaltet werden. Damit steht jeweils ein 16-Bit Timer zur Verfugung.¨ In Modus 2 werden die Register TH0 und TL0 bzw. TL1 und TH1 nicht als ein Z¨ahlregister zusammengeschaltet. Stattdessen wird nur das Timer-Low-Z¨ahlregister (TL0 bzw. TL1) als 8-Bit Z¨ahlregister verwendet. Das Timer-High-Z¨ahlregister (TH0 bzw. TH1) dient als Speicher fur¨ einen 8-Bit Reloadwert. Beim Uberlauf¨ von TL0 wird beispielsweise der in TH0 gespeicherte Wert wieder nach TL0 geschrieben und der Z¨ahlwert somit nachgeladen. Damit l¨aßt sich der Zeitraum zwischen den Uberl¨ ¨aufen entsprechend verkurzen.¨ Dieses Auto-Reload-Verfahren erm¨oglicht ein zyklisches Fort- setzen des Z¨ahlvorgangs ohne Programmeingriff. Es ist damit eine geeignete Methode zur Erzeugung eines unabh¨angigen, periodischen Signals mit einstellbarer Periode. Mit einem 8-Bit Z¨ahlregister ist die programmierbare Zeit allerdings erheblich kleiner als mit einem 16-Bit Register.

7.2.2 Funktionsweise Die Timer z¨ahlen stets aufw¨arts von Null oder einem programmierten Anfangswert. Beim Ubergang¨ des Maximalwertes (alle Bits auf 1 gesetzt) auf 00h im Z¨ahlregister (Uberlauf)¨ wird ein Bit (Uberlauf-Flag¨ TF0 fur¨ Timer 0, bzw. TF1 fur¨ Timer 1) gesetzt.

10Modus 3 ist ein Split-Timer Modus: Z¨ahlregister TL0 (8-Bit Timer/Counter) wird von den Timer 0 Kontrollbits gesteuert, TH0 (8-Bit Timer/Counter) wird von den Timer 1 Kontrollbits gesteuert. Daher ist nur der Betrieb eines einzelnen Timer, n¨amlich Timer 0, m¨oglich.

Beuth Hochschule fur¨ Technik Berlin 155 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Dieses Bit ist Bestandteil des TCON Registers, das sp¨ater genauer erl¨autert wird, und kann einen Interrupt ausl¨osen oder in einer Schleife zyklisch abgefragt werden (vgl. Polling). Es ist das Interrupt Request Flag der Timer-Einheit (vgl. Abschnitt 7.1).

Internes Taktsignal

Timer Interrupt z.B. 256 z.B. 256

Abbildung 7.16: Funktion: Zeitgeber (Timer) - Interne Takt z¨ahlen

Die beiden Timer/Counter 0 und 1 k¨onnen grunds¨atzlich in allen Betriebsarten ent- weder als Timer oder als Counter benutzt werden. Konfiguriert in der Timer-Funktion wird das Z¨ahlregister vom entsprechend geteilten Oszillatortakt regelm¨aßig inkremen- tiert. Die Inkrementierung erfolgt dabei um 1 bei jedem internen Taktzyklus. Zur Er- innerung sei darauf hingewiesen, dass 1 Maschinenzyklus aus 12 Oszillatorimpulsen besteht.11 Damit erfolgt praktisch eine Z¨ahlung der Maschinenzyklen, da die Z¨ahlrate 1/12 des Oszillatortaktes ist. Bei einer Oszillatorfrequenz von f = 12MHz entspricht das einem Schritt pro 1µs. Ein Sonderfall ist die Gated Timer“-Funktion. Hier arbeitet die Schaltung wie ein ” Timer, allerdings nur, wenn durch die Aktivierung eines externen Pins (Eingang INT0, fur¨ Timer 0; bzw. INT1, fur¨ Timer 1) ein Tor (engl. gate) freigeschaltet wird, das sonst das Z¨ahlen unterdrucken¨ kann. Abbildung 7.16 zeigt das Funktionsprinzip abh¨angig vom internen Taktsignal.

Impuls- eingang T0 / T1 Gate Signal INT0 / INT1

Abbildung 7.17: Funktion: Z¨ahler (Counter) - Externe Pulse z¨ahlen

Ist die Counter-Funktion aktiviert, so wird das Z¨ahlregister immer dann inkremen- tiert, wenn eine fallende Flanke, also ein 1-0-Pegelwechsel, an den entsprechenden Z¨ahleing¨angen (T0, P3.4 fur¨ Timer 0 bzw. T1, P3.5 fur¨ Timer 1) erkannt wurde. Zur Flankenerkennung wird der Pin jeweils einmal pro Maschinenzyklus abgetastet. Wenn die Abtastung zuerst einen High-Pegel und im darauffolgenden Zyklus einen Low-Pegel ergibt, wird der Z¨ahlerstand inkrementiert. Der neue Z¨ahlwert erscheint im darauffolgenden Maschinenzyklus im Z¨ahlregister. Das beschriebene Prinzip setzt also voraus, dass jeder Pegel des Eingangssignals mindestens einen Maschinenzyklus lang anliegt, d.h. vor und nach der Flanke des intern geteilten Oszillatortakts. So erfordert es

11Um den 8051 schneller zu machen, haben neuere Versionen des 8051 die Anzahl an Taktzyklen pro Maschinenzyklus von 12 auf 4 oder sogar 1 reduziert. Die Frequenz fur¨ den Timer ist immer 1/12 der Quarzfrequenz, die an den 8051 angeschlossen ist, unabh¨angig von der Version.

Beuth Hochschule fur¨ Technik Berlin 156 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG mindestens zwei Maschinenzyklen (24 Oszillatorperioden) um einen 1-0-Wechsel zu er- kennen. Daher ist die h¨ochstm¨ogliche Eingangsfrequenz fur¨ die Counter-Funktion 1/24 der Oszillatorfrequenz. Bei einer exemplarischen Oszillatorfrequenz von f = 12MHz entspricht das 2µs. Damit ist also eine externe Takterkennung von maximal 500kHz m¨oglich. Schnellere Signale k¨onnen nicht mehr sicher erkannt werden.

8051

· Eingänge für externe Interruptquellen oder

· Gate Signal für Timer

· Eingänge für Counter

alternativ auch normale Ein-/ Timer 0 Ausgabe-Ports für Primärmodus Timer 1

Abbildung 7.18: Steuereing¨ange fur¨ Timer/Counter

Ein Sonderfall - ¨ahnlich der Gated Timer“-Funktion - ist die Gated Counter“- ” ” Funktion. Ist die Gate-Funktion aktiviert, so wird durch das Anlegen eines Signals mit High-Pegel am Eingang INT0 / INT1 wiederum ein Gate freigeschaltet, das sonst das Z¨ahlen unterdrucken¨ wurde.¨ Der Z¨ahlvorgang kann also von außen gesteuert wer- den. Das Funktionsprinzip wird in Abbildung 7.17 veranschaulicht. Auch die Gate- Steuerung ist dargestellt. In diesem Kontext sei zu beachten, dass sich beim Z¨ahlen externer Ereignisse die INT0- und T0-Anschlusse,¨ bzw. INT1- und T1-Anschlusse¨ ge- genseitig verriegeln. Fur¨ das Z¨ahlregister ist somit nicht zu erkennen, ob beispielsweise INT0 T0 steuert oder umgekehrt. Die relevanten Steuereing¨ange fur¨ die beiden Timer/Counter 0 und 1 sind in Abbil- dung 7.18 zusammengefasst. Insbesondere die fur¨ den Gate-Betrieb relevanten An- schlusse¨ sind hier interessant. Uber¨ die INT0- und INT1-Eing¨ange kommen norma- lerweise externe Interrupt-Anforderungen (vgl. Abschnitt 7.1.5). Daneben k¨onnen sie auch als normale I/Os verwendet werden. Die INT0- und INT1-Anschlusse¨ haben also drei verschiedene Funktionen • normale Ein-/Ausgabeleitungen • Eingange fur¨ externen Interrupt-Anforderungen • Steuerung von Start und Stop der internen Timer/Counter uber¨ externe Signale

Beuth Hochschule fur¨ Technik Berlin 157 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

7.2.3 Timer SFR Die Funktionsweise der Timer/Counter 0 und 1 wird durch die SFRs TCON und TMOD gesteuert. Beim Beschreiben der Timer SFR ist darauf zu achten, dass TCON bitadressierbar, TMOD aber nur byteadressierbar ist (vgl. dazu auch Abbildung 5.11). Demnach muss eine Modifikation des TMOD Inhalts unter Verwendung logischer Mas- kierung erfolgen. Das Timer Control Steuer- und Statusregister (TCON) befindet sich an Adresse 88h und hat den Reset-Wert 00h. Entgegen seines durch den Namen zu vermutenden Zweckes zur Steuerung der Timer/Counter-Funktionalit¨at enth¨alt das Register auch Flags zur generellen Steuerung und Kennzeichnung aufgetretener Interrupts. Dabei be- einflusst das obere Halbbyte des Registers (Bits 4 - 7) die Funktion von Timer/Counter 0 und 1. Abbildung 7.19 veranschaulicht dies durch Hervorhebung der entsprechenden Bits.

Timer 0/1 Control Register

TCON

MSB TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 LSB

beeinflussen die Funktion steuern die Interrupts von Timer/Counter 0 und 1 INT0 und INT1

Abbildung 7.19: Flags des Timer Control Register (oberes Halbbyte hervorgehoben)

Die Timer/Counter k¨onnen durch die vorhandenen Bits gestartet und gestoppt werden, zus¨atzlich beinhaltet das Register deren Uberlaufbits.¨ Das untere Halbbyte steuert die Interrupts INT0 und INT1. Durch Abbildung 7.20 wird dies wiederum durch Hervor- hebung der betroffenen Bits verdeutlicht.

Flag Bedeutung TF1 Timer 1 Overflow Flag: wird bei Uberlauf¨ des Timer/Counter gesetzt und beim Sprung zur Interrupt Routine gel¨oscht TR1 Timer 1 Start-/Stopbit (Run): schaltet Timer 1 ein (1) oder h¨alt ihn an (0) TF0 Timer 0 Overflow Flag: wird bei Uberlauf¨ des Timer/Counter gesetzt und beim Sprung zur Interrupt Routine gel¨oscht TR0 Timer 0 Start-/Stopbit (Run): schaltet Timer 0 ein (1) oder h¨alt ihn an (0)

Tabelle 7.6: Flags des TCON zur Steuerung von Timer/Counter 0 und 1

Die Flags des TCON zur Funktionssteuerung von Timer/Counter 0 und 1 haben die in Abschnitt 7.2.3 gezeigte Bedeutung. Die Run-Bits TR0 und TR1 ubernehmen¨ die Freigabe der beiden Timer/Counter. Wird in dieses Bit eine 1 geschrieben, beginnt

Beuth Hochschule fur¨ Technik Berlin 158 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG der Timer bzw. Counter zu z¨ahlen, anderenfalls stoppt er. Somit kann der Timer bzw. Counter jederzeit angehalten und wieder gestartet werden. Die Uberlauf-Flags¨ TF0 und 1 kennzeichnen einen Uberlauf¨ der Timer/Counter 0 bzw. 1. Diese Flags wer- den jedes Mal automatisch gesetzt, wenn der Timer oder Counter seinen H¨ochstwert uberschritten¨ hat und von vorne (0) zu z¨ahlen beginnt.

Timer 0/1 Control Register

TCON

MSB TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 LSB

beeinflussen die Funktion steuern die Interrupts von Timer/Counter 0 und 1 INT0 und INT1

Abbildung 7.20: Flags des Timer Control Register (unteres Halbbyte hervorgehoben)

Die Flags des TCON zur Beeinflussung der externen Interrupts 0 und 1 haben die in Abschnitt 7.2.3 gezeigte Bedeutung. IE0 und IE1 sind die Kennzeichnungsbits fur¨ die externen Interrupts INT0 bzw. INT1. Diese werden gesetzt, wenn ein externer Interrupt auf dem entsprechenden Eingang ausgel¨ost wird. IT0 und IT1 sind die bereits bekannten Steuerbits fur¨ Flanken- oder Pegel-Triggerung der externen Interrupts.

Flag Bedeutung IE1 Interrupt 1 Request Flag: wird bei externem Interrupt /INT1 gesetzt und bei Ausfuhrung¨ des Interrupts gel¨oscht IT1 Interrupt 1 Typ: Wert 1 fur¨ Flankentriggerung → Interrupt wird aus- gel¨ost bei einer Negativ-Flanke an /INT1, Wert 0 fur¨ Pegeltriggerung → Interrupt wird ausgel¨ost solange LOW-Pegel an /INT1 anliegt IE0 Interrupt 0 Request Flag: wird bei externem Interrupt /INT0 gesetzt und bei Ausfuhrung¨ des Interrupts gel¨oscht IT0 Interrupt 0 Typ: Wert 1 fur¨ Flankentriggerung → Interrupt wird aus- gel¨ost bei einer Negativ-Flanke an /INT0, Wert 0 fur¨ Pegeltriggerung → Interrupt wird ausgel¨ost solange LOW-Pegel an /INT0 anliegt

Tabelle 7.7: Flags des TCON zur Steuerung der externen Interrupts 0 und 1

Das Timer Modus Register (TMOD) definiert die grundlegenden Einstellungen und den Modus der beiden Timer/Counter. Es residiert an Adresse 89h und hat - wie auch das TCON Register - den Reset-Wert 00h. Es enth¨alt Flags zur Festlegung der Betriebs- arten der Timer/Counter 0 und 1. Wie in Abbildung 7.21 dargestellt, beeinflussen die oberen 4 Bits Timer/Counter 1, die unteren Timer/Counter 0. Die Flags des TMOD zur Moduseinstellung von Timer/Counter 0 und 1 haben die in Abschnitt 7.2.3 gezeigte Bedeutung. Das Gate-Bit entscheidet uber¨ Hardware- oder Software-Kontrolle des Counters, indem es die Steuerung der Z¨ahler/Zeitgeber- Komponente durch die bereits erw¨ahnte Torschaltung erm¨oglicht. Ist das Gate-Bit

Beuth Hochschule fur¨ Technik Berlin 159 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Timer 0/1 Mode Register

TMOD

MSB Gate C/T M1 M0 Gate C/T M1 M0 LSB

steuern Arbeitsweise steuern Arbeitsweise von Timer 1 von Timer 0

Abbildung 7.21: Flags des Timer Modus Register gleich 1, so l¨auft der Timer/Counter nur, wenn am externen Gate-Anschluß (INT0 oder INT1) ein High-Pegel anliegt und das Bit TR0 bzw. TR1 gesetzt ist. Das Si- gnal am INT0- bzw. INT1-Anschluß gibt also die am externen Eingang anliegenden Z¨ahlimpulse frei oder sperrt diese. Dies entspricht einer Hardware-Kontrolle, da sich der Timer/Counter uber¨ ein physisch an einen Pin angelegtes externes Signal steuern l¨asst. Ist das Gate-Bit gleich 0, so l¨auft der Timer/Counter nur, wenn das entsprechen- de TR0- bzw. TR1-Bit im TCON-Register 1 ist. Dies ist eine interne Kontrolle und entspricht somit einer Software-Kontrolle.

Flag Bedeutung Gate aktiviert = 1, dann Timer-/Counter-Freigabe bei High-Signal an Ein- gang P3.2 fur¨ Timer 0 (/INT0) bzw. P3.3 fur¨ Timer 1 (/INT1); deak- tiviert = 0, dann keine Abh¨angigkeit von externer Freigabe C/T Counter oder Timer Auswahlbit, Wert 1 fur¨ Counter-Betrieb (ext. Takt an P3.4 fur¨ Timer 0 bzw. P3.5 fur¨ Timer1); Wert 0 fur¨ Timer-Betrieb (int. Takt mit Osz.-Frequenz : 12) M1, M0 Auswahl der 4 Timer Modi 0, 1, 2, 3

Tabelle 7.8: Flags des TMOD zur Steuerung von Timer/Counter 0 und 1

Das entscheidende Flag, um zwischen Counter- und Timer-Betriebsart zu wechseln, ist das Bit C/T. Damit entscheidet es auch uber¨ die Taktquelle. Wenn das C/T-Bit gleich 1 ist, wird die Z¨ahler/Zeitgeber-Schaltung als Z¨ahler (Counter) benutzt und erh¨alt ihre Impulse von außerhalb. Der Z¨ahler z¨ahlt hoch, solange an Pin 14 (T0, Timer 0 Input) und Pin 15 (T1, Timer 1 Input) Impulse anliegen. Abschnitt 7.2.3 unterstreicht dies durch Auflistung der relevanten Portpins. C/T-Bit auf 0 bedeutet dagegen Timer-Betrieb. Dort wird mittels der bekannten internen Frequenz eine Zeit- spanne generiert.

Pin-Nr. Portpin Funktion Beschreibung 14 P3.4 T0 Timer/Z¨ahler 0 externer input 15 P3.5 T1 Timer/Z¨ahler 1 externer input

Tabelle 7.9: Pins des Port 3 zur Nutzung fur¨ Timer 0 und 1

Beuth Hochschule fur¨ Technik Berlin 160 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

OSC C/T=0 :12 TL1 TH1 C/T=1 P3.5 0=open 8 Bit 8 Bit T1 0 1 1=close Gate C/T M1 M0 Gate C/T M1 M0

P3.3 /INT1

TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0

Abbildung 7.22: Konfiguration als 16-Bit Counter/Timer mit relevanten SFRs

Nachfolgend sind fur¨ Modus 1 (16-Bit-Counter/Timer), sowie fur¨ Modus 2 (8-Bit- Counter/Timer mit automatischem 8-Bit-Reload) die internen Zusammenh¨ange gra- fisch illustriert. In Abbildung 7.22 ist die Konfiguration des Timer 1 im 16-Bit Modus mit allen beteiltigen SFRs und deren logischen Zusammenh¨angen dargestellt. Intern er- folgt die Umschaltung zwischen Counter- und Timer-Betrieb durch einen Multiplexer. Wie aus der Abbildung ersichtlich, ist mit C/T = 0 die Funktion als Timer aktivert. Durch die Kombination aus invertiertem Gate-Bit und Status des Portpins P3.3 erfolgt die Freigabe des Timers, jeweils abh¨angig vom Timer Run Bit TR1. Dies resultiert aus der in der Abbildung dargestellten AND-Verknupfung,¨ deren Ausgang damit den sym- bolischen Schalter bestimmt.

OSC 8 Bit C/T=0 :12 TL1 C/T=1 P3.5 0=open T1 1 0 1=close Gate C/T M1 M0 Gate C/T M1 M0 Reload

TH1 P3.3 8 Bit /INT1

TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0

Abbildung 7.23: Konfiguration als Auto-Reload Counter/Timer mit relevanten SFRs

Die 8-Bit-Z¨ahlregister TL1 (Timer Low 1) und TH1 (Timer High 1) sind hintereinander geschaltet. So ergibt sich ein 16-Bit-Z¨ahler mit 216 = 65536 Z¨ahlschritten. Die beiden Z¨ahlregister TL1 und TH1 lassen sich auf bestimmte Anfangswerte (0000h bis F F F F h) setzen. Ab diesen Werten z¨ahlen sie nach dem Starten des Z¨ahlers aufw¨arts bis zum Maximalwert. Beim Uberlauf¨ wird das Uberlauf-Flag¨ TF1 gesetzt. In der Abbildung ist dies durch die Verbindung von den Z¨ahlregistern zum TF1-Flag gekennzeichnet. Wie bereits angedeutet, kann das Uberlauf-Flag¨ vom Programm abgefragt werden oder einen Interrupt ausl¨osen. Nach dem Uberlauf¨ kann der Z¨ahler wieder auf einen Anfangs- wert gesetzt werden. Wird kein Anfangswert gesetzt, beginnt der Z¨ahler bei 0000h. Der

Beuth Hochschule fur¨ Technik Berlin 161 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Timer l¨auft nach einem Uberlauf¨ einfach weiter. Praktisch muss er jedoch angehalten werden, der Anfangswert neu geladen und anschließend neu gestartet werden.

OSC C/T=0 :12 TL1 TH1 C/T=1 P3.5 T1 externer TMOD TL0 TH0 P3.4 Zähltakt Gate C/T M1 M0 Gate C/T M1 M0 T0 Timer 0 Timer 1

P3.3 NOT /INT1 externe NOR AND P3.2 Steuerung TCON /INT0 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 Hardwareeingänge

Abbildung 7.24: Registerzugeh¨origkeiten fur¨ die Programmierung von Timer/Counter

Abbildung 7.23 zeigt die Konfiguration des Timer 1 als 8-Bit-Counter/Timer mit au- tomatischem 8-Bit-Reload. In diesem Modus wird nur das 8-Bit-Z¨ahlregister TL1 als Z¨ahler verwendet und entsprechend inkrementiert. Das Register TH1 enth¨alt einen 8-Bit Nachladewert. Mit diesem wird bei einem Uberlauf¨ das Z¨ahlregisters TL1 auto- matisch nachgeladen und der Z¨ahlvorgang beginnt neu. Der Nachladevorgang ver¨andert TH1 nicht. Der Nachladeautomatismus endet, wenn der Modus des Z¨ahlers ge¨andert wird. Eine Zusammenfassung der Registerzugeh¨origkeiten fur¨ die Programmierung von Ti- mer/Counter 0 und 1 ist in Abbildung 7.24 gegeben. Farblich abgesetzt sind die Timer 0 betreffenden Register bzw. Registerflags gelb, die fur¨ Timer 1 relevanten Register- flags orange gekennzeichnet. Entsprechend sind auch die Eing¨ange fur¨ den externen Z¨ahltakt und die externen Steuereing¨ange hervorgehoben.

7.2.4 Programmierung des Timers Die Programmierung der auf dem 8051 integrierten Z¨ahler/Zeitgeber-Schaltungen ge- staltet sich recht einfach, wenn man nach einem festen Schema vorgeht. Mit zu- nehmender Routine kann man sich von diesem Schema auch entfernen und eigene Ideen, Abwandlungen und Optimierungen mit einbringen. Dies ist inbesondere dann von N¨oten, wenn die individuelle Applikation einen spezifischen Gebrauch der Timer- Funktionalit¨at erfordert. Zun¨achst sei hier eine Schritt-fur-Schritt¨ Anleitung fur¨ das Programmieren einer Zeitverz¨ogerung (Modus 0 oder 1) mit einem Timer gegeben. 1. Lade den Wert in das TMOD Register, der angibt, welcher Timer (Timer 0 oder Timer 1) benutzt werden soll und in welchem Modus (0 oder 1) (TMOD z.B. mit Wert 00000001b (Timer 0, Modus 1 (16-Bit Modus)) setzen) 2. Lade Register TL und TH mit einem Anfangswert 3. Starte den Timer (TR0 bzw. TR1 auf 1 setzen) 4. Timer-Flag TF0 bzw. TF1 beobachten (Polling, Interrupt), um den aktuellen Timerstatus zu ermitteln

Beuth Hochschule fur¨ Technik Berlin 162 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

(Polling beispielsweise mit JNB TFx, Ziel“) ” 5. Stoppe den Timer (TR0 bzw. TR1 auf 0 setzen) 6.L ¨osche das TF0- bzw. TF1-Flag fur¨ die n¨achste Runde (nur beim Polling) 7. Geh zuruck¨ zu Schritt 2 und lade TH- und TL-Register wieder Fur¨ die Behandlung mit Interrupts sind zus¨atzliche Schritte erforderlich, so z.B. die globale Freigabe, dann die Freigabe des Timer Interrupts im IE-Register, etc. Die Einzelheiten dazu wurden bereits in Abschnitt 7.1 erl¨autert. Zur Erzeugung eines zyklischen Signals mit einstellbarer Periode wird der 8-Bit Auto- Reload Modus benutzt. Nachfolgend ist analog zur soeben dargelegten Vorgehensweise eine Schritt-fur-Schritt¨ Anleitung fur¨ das Programmieren einer Zeitverz¨ogerung in die- ser Betriebsart (Modus 2) gegeben. 1. Lade den Wert fur¨ Modus 2 in das TMOD Register und definiere welcher Timer (Timer 0 oder Timer 1) benutzt werden soll (TMOD z.B. mit Wert 00100000b (Timer 1, Modus 2 (Auto-Reload)) setzen) 2. Lade Register TH mit einem Anfangswert 3. Starte den Timer (TR0 bzw. TR1 auf 1 setzen) 4. Timer-Flag TF0 bzw. TF1 beobachten (Polling, Interrupt), um den aktuellen Timerstatus zu ermitteln (Polling beispielsweise mit JNB TFx, Ziel“) ” 5.L ¨osche das TF0- bzw. TF1-Flag (nur beim Polling) 6. Geh zuruck¨ zu Schritt 4, da Modus 2 automatisch nachl¨adt und zwischendurch nicht gestoppt werden muss Zur Programmierung des Timers ist das Setzen eines sinnvollen Anfangswertes in den Z¨ahlregistern TL0 und TH0, bzw. TL1 und TH1 (in der obigen Liste in Punkt 2 jeweils als TH fur¨ Timer High und TL fur¨ Timer Low dargestellt) erforderlich. Von diesem Startwert wird jeweils bis zum Uberlauf¨ hochgez¨ahlt. Allgemein ergibt sich der Startwert des Z¨ahlers zu:

Breite Z¨ahlregister S = 2 − t · (fosz/12) (7.1) Relevant fur¨ diese Berechnung sind: • Breite des Z¨ahlregisters: 16 (Modus 1, 16-Bit-Z¨ahler) oder 8 (Modus 2, selbst- nachladender 8-Bit-Z¨ahler) • t : gewunschte¨ Zeit • fosz: Oszillatorfrequenz als Referenz-Taktversorgung (zum Beispiel 11,0592 MHz) Fur¨ 20 ms mit Timer 0 (Modus 1) ergibt sich beispielsweise:

 1  S = 216 − 20 · 10−3s · (11, 0592 · 106 )/12 = 47104 = B800h (7.2) s Das Lowbyte dieser vierstelligen Hexadezimalzahl wird folglich in das Timer Low Regis- ter, das Highbyte in das Timer High Register ubertragen.¨ Fur¨ die Timer 0 zugeh¨origen Register ergibt sich damit: • TH0 = B8h • TL0 = 00h

Beuth Hochschule fur¨ Technik Berlin 163 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Der Z¨ahlerstand kann jederzeit (auch im laufenden Betrieb) gelesen und auch ge¨andert werden. Dies gilt fur¨ alle Modi. Es ist allerdings je nach Timermodus besondere Vorsicht geboten. Fur¨ den Timer im 8-Bit-Modus, 8-Bit Auto-Reload Modus (Modus 2) oder Split-Timer Modus (Modus 3), ist ein einfaches Auslesen des 1-Byte-Wertes des Timers ohne Weiteres m¨oglich. Fur¨ die Ermittlung des aktuellen Z¨ahlerwertes beim Timer im 16-Bit-Modus gibt es zwei g¨angige Methoden: • Auslesen des aktuellen Wertes des Timers als 16-Bit Zahl • Detektion des Uberlaufs¨ des Timers Das potentielle Problem beim Auslesen eines 13-Bit- oder 16-Bit-Timers liegt dar- in, dass nur mit einer 8-Bit-Schreib- oder Leseoperationen auf das 16 Bit breite Z¨ahlerregister zugegriffen werden kann. Der Timer kann jedoch zwischen Lesevorg¨angen fur¨ High- und Low-Byte einen Ubertrag¨ vom Low- ins High-Register gehabt haben. Dieses Problem bezeichnet man als Phasenfehler“. Der Phasenfehler tritt auf, wenn ” zwischen den beiden fur¨ 16 Bit erforderlichen Lese-Operationen das Low-Byte in das High-Byte uberl¨ ¨auft. Ein Beispiel verdeutlicht den Vorgang: Es soll der 16-Bit-Wert aus dem laufenden Timer 1 gelesen werden. Es wird angenommen, dass der Z¨ahlerwert TH1=14 und TL1=255 war. Ausgelesen wurde allerdings TH1=15 und TL1=255. Warum? Offensichtlich hatte der Timer zwischen den beiden Lesevorg¨angen einen Ubertrag¨ vom Low- ins High-Register. Damit geh¨ort der gelesene High-Wert nicht mehr zum gelesenen Low-Wert. Also m¨ogliche L¨osung dieses Phasenfehlers bietet sich folgende Vorgehensweise an: 1. High-Byte des Timers auslesen 2. Low-Byte auslesen 3. wieder High-Byte auslesen 4. wenn das High-Byte beim zweiten Auslesen nicht dasselbe ist wie beim ersten Auslesen, beide noch einmal auslesen Um diese Vorgehensweise praktisch zu verdeutlichen, sei hier ein Programmausschnitt gezeigt, in dem ein On the fly“-Auslesen eines Timer-Wertes stattfindet. Nach Durch- ” laufen des Codes steht in R0 das Low-Byte des Timers, in R7 das High-Byte des Timers.

Wiederhole:MOV A,TH0 MOV R0,TL0 CJNE A, TH0, Wiederhole MOV R7,A

Ahnliche¨ Probleme treten auch beim Schreiben in den laufenden Timer auf, so dass diese Schwierigkeiten am besten dadurch beseitigt werden, dass der Z¨ahler vorher mit- tels Deaktivierung des entsprechenden Timer Run Bit (z.B. CLR TR0) gestoppt wird (wenn es m¨oglich ist).

Beuth Hochschule fur¨ Technik Berlin 164 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Praxisbeispiel

Hier ist ein Beispiel fur¨ eine Timer-Programmierung gegeben. MOV TMOD, #01 Sprung :MOV TL0, #11110010b MOV TH0, #11111111b CPL P1.5 ACALL Delay SJMP Sprung Delay : SETB TR0 Nochmal :JNB TF0, Nochmal CLR TR0 CLR TF0 RET 1. Welche Werte nimmt das Z¨ahlregister nach Initialisierung wie oben an? 2. Wievielen Z¨ahlzyklen entspricht das? 3. Was fur¨ eine Frequenz wird schließlich hier umgesetzt? (Annahme: 12 MHz Referenztakt)

L¨osung: zu 1. FFF 2,FFF 3,FFF 4, ..., F F F E, F F F F, 0000 2. Es wird 14 mal gez¨ahlt. 3. 12MHz → 1µs, halber Puls nach 14µs, volle Periode nach 28µs. Die Frequenz betr¨agt also 1/28µs = 35, 714kHz.

7.2.5 Beeinflussung der Zeitintervalle beim Timer Timer arbeiten parallel zum laufenden Programm. Beim Erreichen einer durch den ge- setzten Startwert im Timer-Z¨ahlerregister definierten Zeitspanne wird das zugeh¨orige Request Flag (TF0 bzw. TF1) gesetzt, auf welcher per Polling oder Interrupt rea- giert werden kann. Durch die L¨ange der Timer-Z¨ahlregister (8, 13, 16 Bit) und die Z¨ahlfrequenz ist die Dauer der erzeugbaren Zeitintervalle begrenzt. Bei einer Referenz- frequenz von fosz = 11, 0592 MHz ergibt sich damit folgende Maximaldauer:

16 ttimer = 2 · 12/fosz = 65536 · 1, 0851µs = 71, 1ms (7.3) Abbildung 7.25 illustriert die mit einem Timer l¨angste einstellbare Zeitspanne durch Verwendung des nach maximal 216 Schritten auftretenden Request Flags. Durch Aufw¨artsz¨ahlen und Abfragen eines Registers bei jedem aufgetretenen Uberlauf¨ des Timers kann die Dauer der behandelbaren Zeitintervalle erh¨oht werden. Dazu emp- fiehlt sich die Verwendung von Interrupts. Beim Erreichen des Maximalwerts wird jeweils das Timer Request Flag gesetzt, welches die entsprechende ISR triggert. Dar- in muss der Timer dann angehalten werden, ein separates Register zum Z¨ahlen des Aufrufes inkrementiert werden und der Z¨ahlwert neu gesetzt und der Timer wieder gestartet werden. Zum Erzeugen eines periodischen Signals muss diese Prozedur dann entsprechend der zu realisierenden Zeitspanne wiederholt werden. Der Ansatz wird

Beuth Hochschule fur¨ Technik Berlin 165 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

max. 216 Schritte

Starten des Timers Interrupt-Signal

Abbildung 7.25: Maximale Zeitintervalle mit einem 16-Bit Timer

max. 216 Schritte max. 216 Schritte

Starten des Timers Interrupt-Signale, Inkrementieren eines Registers, ...

Abbildung 7.26: Erh¨ohung der Zeitintervalle durch Mehrfachaufruf eines 16-Bit Timers durch Abbildung 7.26 anschaulich dargestellt. Setzt man den soeben erl¨auterten Ansatz praktisch um, so resultiert dies in folgendem Assemblercode. Hier wurde die Zeitspanne des einfachen 16-Bit Timers um das 100- fache erh¨oht, d.h. erst nach hundertmaligem Durchlaufen der ISR wird der entsprechend gekennzeichnete Codeabschnitt ausgefuhrt.¨

CJNE R0, #63h, Label;Sprung nach Label fuer R0 ungleich 99 MOV R0, #00h;R0 zuruecksetzen

;***** Aktionen, die nach 100 maligem Durchlaufen ausgefuehrt werden

RETI;Ruecksprung

Label : INC R0;R0 inkrementieren RETI;Ruecksprung

Die Nutzregister zum Z¨ahlen (im gezeigten Beispiel R0) sind beim 8051 alle 8 Bit breit. Damit sind maximal 28 = 256 Wiederholungen verwaltbar. Also Maximalzeitspanne ergibt sich somit:

tmax = 256 · 71, 1ms = 18, 2044s (7.4) Diese Methode ist prinzipiell auch zum Generieren von asymmetrischen Rechtecksigna- len geeignet. In Abbildung 7.27 ist ein Beispiel fur¨ ein asymmetrisches Rechtecksignal gegeben, das an Port P2.1 generiert wird. Das Rechtecksignal hat eine High-Pegeldauer von 1085µs und eine Low-Pegeldauer von 15µs und soll unter Verwendung von Timer

Beuth Hochschule fur¨ Technik Berlin 166 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

1 (Modus 1) generiert werden. Als Referenzfrequenz wird wieder fosz = 11, 0592MHz angenommen.

15µs 1085µs 15µs

Port P2.1 t

Abbildung 7.27: Generierung von asymmetrischen Rechtecksignalen

Als Vorbetrachtung wird zun¨achst wieder die Dauer der internen Referenz, also auf Maschinenzyklusebene betrachtet. Die Dauer eines Maschinenzyklus betr¨agt 1, 0851µs. Bezogen auf diese Referenz l¨asst sich also die High-Pegeldauer von 1085µs als 1085µs = 1, 0851µs · 1000 ausdrucken.¨ Die Low-Pegeldauer von 15µs entspricht dagegen genau 15µs = 1, 0851µs · 14. Hier empfiehlt es sich nicht, fur¨ beide Zeitabschnitte unterschiedliche Timer zu ver- wenden bzw. fur¨ einen gemeinsamen Timer jeweils unterschiedliche Timer-Startwerte zu bestimmen. Stattdessen wird der Timer nur fur¨ die Generierung des langen Zeitab- schnittes verwendet, w¨ahrend die Dauer fur¨ den kurzen Abschnitt durch die notwen- digen Maschinenbefehle selbst zuzuglich¨ einem Z¨ahlregister (alternativ: NOP-Befehle) realisiert wird. Der Overhead fur¨ das Anhalten, Neusetzen des Startwertes und erneute Starten des Timers fur¨ die Low-Pegeldauer wurde¨ die zur Verfugung¨ stehende Zeit- spanne bei weitem ubersteigen.¨ Hier kann die fur¨ das Neusetzen des Startwertes fur¨ die High-Pegeldauer erforderliche Zeit gleich genutzt werden. Als Startwert ergibt sich 216−1000 = 64536 = FC18h fur¨ die High-Pegelgenerierung. Das vollst¨andige Programm ist hier gelistet:

ORG 000h SJMP Start

ORG 01Bh SJMPISR

Start : CLR TR1;Timer1 anhalten CLR TF1;TF1 zuruecksetzen MOV TH1, #0FCh;Wert fuer 1085 us(High Byte) MOV TL1, #018h;Wert fuer 1085 us(Low Byte) ANL TMOD, #00001111b;Betriebsart einstellen, diesmal Timer1 ORL TMOD, #00010000b;TMOD muss 0001xxxx sein SETB ET1;Interrupt fuer Timer1 freigeben SETBEA;Interrupts global freigeben SETB TR1;Timer1 starten

ISR:;Interrupt Service Routine CLR TR1;Timer1 anhalten CLR P2.1;Port 2.1 ist nun 0, Start des Low-Pegel-Bereichs MOV R2, #4;Dauer des Low-Pegels durch Verbrauchen und Zaehlen ;von Maschinenzyklen(MZ), fuer diesen Schritt2MZ

Hier : DJNZ R2, Hier;hier4x2MZ

Beuth Hochschule fur¨ Technik Berlin 167 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

MOV TH1, #0FCh;Nachladen von Timer1 High Byte (2MZ) MOV TL1, #018h;Nachladen von Timer1 Low Byte (2MZ) SETB TR1;Timer1 wieder starten SETB P2.1;Port 2.1 ist nun 1, Start des High-Pegel-Bereichs RETI;Ruecksprung zu Hauptprogramm(Start) END

Beuth Hochschule fur¨ Technik Berlin 168 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

7.3 Aufbau und Programmierung der seriellen Kommunikationsschnittstelle

Zur Kommunikation mit der Außenwelt besitzt ein Mikrocontroller in der Regel ver- schiedene Schnittstellenanbindungen. Neben den 4 Ports zu je 8 Bit z¨ahlt bei dem 8051 zu den wesentlichen Schnittstellenanbindungen die serielle Schnittstelle. Bevor diese im Detail erl¨autert wird, werden zun¨achst die notwendigen Grundlagen beschrieben.

7.3.1 Grundbegriffe der Datenkommunikation Den Kern der Datenkommunikation bildet der Transport der Daten, also die Datenubertragung¨ von einem Sender mittels eines Ubertragungskanals¨ zu einem Empf¨anger. In der Praxis existieren unterschiedliche Ubertragungsmethoden,¨ - ausfuhrungen,¨ und -geschwindigkeiten. Abbildung 7.28 fasst dies im Uberblick¨ zusam- men. Ein Analogsignal bildet einen kontinuierlichen Vorgang kontinuierlich ab. Physikalische oder Zahlengr¨oßen werden durch Spannungen oder Str¨ome dargestellt, deren H¨ohe oder St¨arke den dargestellten Gr¨oßen entspricht. Ein Digitalsignal dagegen stellt eine Nachricht dar, die nur aus Zeichen eines Zeichenvorrats besteht. Die Ubertragung¨ kann synchron oder asynchron erfolgen. Bei einer synchronen Ubertragung¨ besteht zwischen Sender und Empf¨anger st¨andiger Gleichlauf. Die Taktinformation wird im allgemeinen von der Datenubertragungseinrichtung¨ geliefert. Bei der asynchronen Ubertragung¨ wird die Synchronisation zwischen Sender und Empf¨anger durch sog. Start-/Stoppbits“ fur¨ ” jedes einzelne Zeichen neu hergestellt wird. Darauf wird in Kurze¨ n¨aher eingegangen.

Datenübertragung

Signal Gleichlauf Zeichenübertragung Betrieb

analog asynchron 1 1 1 0 1 1 0 1 bitseriell simplex

1 0 digital synchron 1 bitparallel halbduplex 1 0

vollduplex

Abbildung 7.28: Varianten der Datenubertragung¨

Nach der auf einer Verbindung m¨oglichen Ubertragungsrichtung¨ unterscheidet man Simplex-Betrieb (unidirektionaler Kanal), Halbduplex-Betrieb (bidirektional abwech- selnd), sowie Vollduplex-Betrieb (bidirektional gleichzeitig). Die Ubertragung¨ der Da- ten kann entweder parallel oder seriell erfolgen. Bei der parallele Datenubertragung¨ werden mehrere Bits zeitgleich uber¨ mehrere Da- tenleitungen ubertragen.¨ Die Anzahl der Datenleitungen ist meist ein Vielfaches von

Beuth Hochschule fur¨ Technik Berlin 169 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

8 (vgl. Byte-Struktur) plus ggf. zus¨atzliche Kan¨ale fur¨ Parit¨at, Taktsignal, etc. Abbil- dung 7.29 zeigt als Beispiel eine 8-Bit breite parallele Datenubertragung.¨

Sender Empfänger MSB 0 0 MSB 0 0 1 1 0 0 1 1 1 1 0 0 LSB 1 1 LSB

Abbildung 7.29: 8-Bit breite parallele Datenubertragung¨

Bei der seriellen Datenubertragung¨ werden einzelne Bits zeitlich nacheinander uber¨ eine Leitung ubertragen.¨ Dies setzt voraus, dass am Sender Bytes in serielle Bits konvertiert werden mussen,¨ beispielsweise uber¨ einen Parallel-Seriell-Wandler oder ein Schiebere- gister. Am Empf¨anger ist dann wiederum eine Seriell-Parallel-Wandlung erforderlich. Werden die Bits nacheinander ubertragen,¨ so ist die zugrundegelegte Bit-Reihenfolge von entscheidender Bedeutung, damit es nicht zu einer Fehlinterpretation der Daten kommt. Es muss also beachtet werden, ob das niederwertige Bit zuerst ubertragen¨ wird (LSB first) oder das h¨oherwertige (MSB first). Abbildung 7.30 reflektiert dies anhand eines Beispiels fur¨ die bitweise Datenubertragung¨ (LSB first).

Sender Empfänger MSB 0 0 MSB 0 0 1 zeitlich nacheinander (seriell) 1 0 0 1 0 0 1 0 1 1 0 1 1 1 MSB LSB 1 0 0 LSB 1 1 LSB

Abbildung 7.30: Bitserielle Datenubertragung¨

Hinsichtlich der Anwendung beim 8051 wird im Folgenden der Fokus auf die serielle Schnittstelle gerichtet. Fur¨ serielle Schnittstellen werden h¨aufig folgende Abkurzungen¨ verwendet: • UART: Universal Asynchronous Receiver Transmitter • USART: Universal Synchronous/Asynchronous Receiver Transmitter Wie aus dem Namen direkt abzuleiten ist, arbeitet eine UART-Schnittstelle nur asynchron, eine USART dagegen sowohl synchron, als auch asynchron. Die UART-Schnittstelle ist dann also erg¨anzt um die F¨ahigkeit einer synchronen Da- tenubertragung.¨ Bei einer synchronen Ubertragung¨ ist eine zus¨atzliche Taktleitung (XCK) erforderlich. Eine USART ist demnach nicht mehr auf einen genau abgegliche- nen Takt beim Sender und Empf¨anger angewiesen .

Beuth Hochschule fur¨ Technik Berlin 170 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

H¨aufig wird eine U(S)ART-Schnittstelle mit einer RS232-Schnittstelle synonym be- zeichnet. Dies ist im engeren Sinne nicht ganz korrekt, da beide Ausdrucke¨ Unter- schiedliches beschreiben. U(S)ART beschreibt die Art der seriellen Datenubertragung¨ auf logischer Ebene, also unabh¨angig von den zur Ubertragung¨ eingesetzten Span- nungen (5V TTL-, 3V CMOS-Pegel, etc.) und somit auch unabh¨angig von konkreten I/O-Standards (RS232, optisch, high oder low aktiv, etc.). RS232 ist dagegen ein Schnittstellenstandard, der die Datenubertragung¨ auf elektri- scher Ebene spezifiziert. RS232 - RS steht fur¨ Recommended Standard, ursprunglich¨ fur¨ die Abteilungsbezeichnung Radio Sector - ist die amerikanische Norm und entspricht in- ternational funktionell der ITU-T V.24 (International Telecommunication Union) und elektrisch der V.28. Der Standard umfasst die Festlegung der an der Ubertragung¨ betei- ligten Ubertragungspegel¨ (+/-12V Pegel, bipolar pro Leitung, low-aktiv), die Definition der vorhandenen Signale (2 Datenleitungen und viele Steuerleitungen), die Festlegung des physikalischen Interface (9-poliger DSUB-Stecker, bei ¨alteren Systemen auch ein 25-poliger Stecker), sowie die Vereinbarung zul¨assiger Reichweiten (ublicherweise¨ 6-8 Meter). Eine UART wird oft zur Daten-Ein- und Ausgabe uber¨ den PC eingesetzt. Hierzu ist auf der PC-Seite in der Regel ein Terminalprogramm n¨otig. Die UART liefert Ein- und Ausgabe-M¨oglichkeiten und kann unterstutzend¨ zum Debugging, beispielsweise durch Ausgabe von Variablen an Problemstellen, herangezogen werden. Eine USART wird oft zur Impementierung eines SPI-Masters (Serial Peripheral Interface) genutzt. Dies ist ein von Motorola entwickeltes Bus-System fur¨ die synchrone serielle Ubertragung.¨ Es wird zur Verbindung digitaler Schaltungen nach dem Master-Slave-Prinzip eingesetzt.

Controller Board

Mikrocontroller RS232 DSUB9 Transceiver Buchse TxD UART RxD Verbindung zum PC o.ä.

Abbildung 7.31: Schnittstellenimplementierung auf Controllerboard

Die bidirektionale UART ben¨otigt zwei Datenleitungen und naturlich¨ eine Massever- bindung (GND). • TxD“ (Transmit Data = Daten Senden) - P3.0 (Port 3) ” • RxD“ (Receive Data = Daten Empfangen) - P3.1 (Port 3) ” Die Signale direkt am Mikrocontroller sind (fast immer) CMOS- oder TTL-Pegel. Ein direkter Anschluss einer RS232-Schnittstelle o.¨a. ist in der Regel also nicht m¨oglich. Fur¨ die verschiedenen Schnittstellen existieren passende Treiber/Receiver-ICs (auch genannt Transceiver) wie z.B. der MAX232-Chip fur¨ RS232 oder der MAX485-Chip

Beuth Hochschule fur¨ Technik Berlin 171 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG fur¨ RS485, und viele andere. Diese Chips setzen die erforderliche Pegelwandung fur¨ die Kompatibilit¨at mit den Schnittstellenstandards um. Abbildung 7.31 zeigt eine schematische Darstellung des 8051 Entwicklungsboards, das im Labor verwendet wird. Die Rolle des RS232-Transceivers wurde soeben kurz erl¨autert. Er fuhrt¨ die Pegelwandlung von 5V TTL-Pegel auf 12V RS232-Pegel um. Dazu verfugen¨ die Transceiver in der Regel uber¨ integrierte DC-DC-Wandler. Um eine korrekte Wandlung eines TTL-Signals auf ein RS232-Signal zu erm¨oglichen, muss eine Pegelumsetzung auf die h¨oheren Pegel erfolgen und zus¨atzlich muss das Signal inver- tiert werden, da eine logische Eins bei TTL 5V und bei RS232 -12V entspricht. Die Wandlung von RS232 auf TTL erfolgt analog dazu, ein Pegel von -12V wird auf 5V umgesetzt. Abbildung 7.32 erg¨anzt die Graphik um die Kennzeichnung der Wandler- stufe.

Controller Board

Mikrocontroller RS232 DSUB9 Pegelwandlung! Transceiver Buchse TxD UART RxD Verbindung zum PC o.ä.

RS232 5V TTL Pegel Pegel (+/-12V)

Abbildung 7.32: Pegelwandlung auf Controllerboard

Fur¨ kurze Strecken, z.B. auf einer Platine, k¨onnen die UART-Signale direkt mit Lo- gikpegel benutzt werden. Dies entspricht allerdings dann keiner standardkonformen RS232-Schnittstelle, sondern stellt lediglich eine serielle Verbindung mit CMOS Pegeln dar. Dieser Sonderfall ist im vorliegenden Fall jedoch nicht relevant. Die physische Ausfuhrung¨ der Schnittstelle erfolgt als 9-polige D-SUB-Buchse. Abbil- dung 7.33 zeigt die Nummerierung und Abschnitt 7.3.1 die entsprechende Signalzu- ordnung. Der Name geht zuruck¨ auf die amerikanische Firma ITT-Cannon, die diesen Verbindungstyp aufgrund der D-¨ahnlichen Form des ¨außeren Steckverbinders und we- gen der fur¨ damalige Verh¨altnisse sehr kleinen Bauform D subminiature“ nannte, kurz ” D-SUB.

Beuth Hochschule fur¨ Technik Berlin 172 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

RS232 Stecker DSUB9

Abbildung 7.33: Physische Ausfuhrung¨ der Schnittstelle

Pin Beschreibung 1 Data carrier detect (DCD) 2 Received data (RxD) 3 Transmitted data (T xD) 4 Data terminal ready (DTR) 5 Signal ground (GND) 6 Data set ready (DSR) 7 Request to send (RTS) 8 Clear to send (CTS) 9 Ring indicator (RI)

Tabelle 7.10: Pinbelegung der DSUB-9 Buchse

Abschließend sei noch einmal ein komplettes Bild der RS232-Ubertragung¨ auf physika- lischer Ebene gezeigt. Abbildung 7.34 zeigt die Beschaltung des 8051 Mikrocontrollers, sowie die des Transceiver-Bausteins MAX232 der Firma Maxim. Ebenso ist die Ver- bindung uber¨ zwei DSUB9-Buchsen inkl. Stiftbelegungen dargestellt.

7.3.2 Ubertragungsmethoden¨ Eine serielle Ubertragung¨ kann auf zwei verschiedene Wege erfolgen, als asynchrone oder synchrone Datenubertragung.¨ Beide Varianten werden kurz n¨aher erl¨autert. Die asynchrone Datenubertragung¨ bezeichnet man auch als zeichenweise Ubertragung.¨ Sie arbeitet mittels Zeichensynchronisation (auch Start-Stop-Verfahren“ genannt) und ” ist nicht nach einem Taktsignal ausgerichtet. Der Empfangstakt synchronisiert sich nach jedem ubertragenen¨ Zeichen erneut mit dem Sendetakt. Dabei darf der Empfang- stakt gegenuber¨ dem Sendetakt w¨ahrend der Ubertragungsdauer¨ eines Zeichens nicht um mehr als eine halbe Taktperiode abweichen. Die asynchrone Datenubertragung¨ ubertr¨ ¨agt in einer Nachricht nicht nur die reinen Nutzdaten, sondern zus¨atzliche Informationen an den Empf¨anger. Diese Informationen dienen der Synchronisation. Eine Nachricht beinhaltet dabei ein Start Bit (0), Daten- bits, optional ein Parit¨atsbit und ein oder mehrere Stop Bits (1). Das Start Bit signa- lisiert den Beginn einer Ubertragung.¨ Die Datenbits beinhalten die zu ubertragende¨ Information. Das Parit¨atsbit l¨asst erkennen, ob eine Ubertragung¨ fehlerhaft war. An- hand vom Stop Bit wird das Ubertragungsende¨ signalisiert. Das zweite Stop Bit ist

Beuth Hochschule fur¨ Technik Berlin 173 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

PC

Serielles Kabel

8051

Oszillator

Abbildung 7.34: Technische Realisierung einer RS232-Verbindung je nach Ausfuhrung¨ der UART n¨otig, um dem Empf¨anger mehr Zeit fur¨ die Synchro- nisation auf den Datenstrom oder mehr Zeit fur¨ die Verarbeitung zwischen einzelnen Zeichen zu geben12. Eine Zeichenfolge besteht also aus einer Folge von Datenbits, die fur¨ jedes Zeichen von Start- und Stop Bit eingerahmt werden. Bei der asynchronen Ubertragung¨ mussen¨ den beiden Kommunikationspartnern im Vorfeld der Ubertragung¨ Folgendes bekannt sein: • Schrittgeschwindigkeit (Baudrate) • Anzahl der Datenbits pro Zeichen • Parit¨at (gerade oder ungerade) • Anzahl der Stop Bits (ublicherweise¨ 1 oder 2) Zwischen zwei aufeinanderfolgenden Zeichen k¨onnen beliebig lange Pausen vorkommen, da der Beginn eines Zeichens am Start Bit eindeutig erkannt wird. Aus diesem Schema

12Man bedenke dabei, dass bei modernen Systemen die Zeitspanne zwischen einzelnen Zeichen deutlich geringer ausgelegt werden kann als zu einer Zeit, wo Taktgeschwindigkeiten und der Prozes- sordurchsatz noch sehr niedrig waren.

Beuth Hochschule fur¨ Technik Berlin 174 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG ist ableitbar, dass bei asynchroner Ubertragung¨ die Ubertragungsrate¨ reduziert ist, da z.B. fur¨ 8 Informationsbits mind. 10 Bits uber¨ die Leitung gesendet werden mussen.¨ Dies entspricht einem Overhead von 25%.

T E S T

0 0 0 1 0 1 0 1 0 1 1 0 1 0 1 0 0 0 1 0 1 1 0 1 1 0 0 1 0 1 0 1 1 0 0 0 1 0 1 0 1 0 1 1

Datenbits Datenbits Datenbits Datenbits Start Bit Start Bit Start Bit Start Bit Stop Bits Stop Bits Stop Bits Stop Bits

Datenstrom asynchron

Abbildung 7.35: Asynchrone Datenubertragung¨ mit einem Start Bit und zwei Stop Bits

Abbildung 7.35 zeigt die asynchrone Datenubertragung¨ mit einem Start Bit und zwei Stop Bits. Der Overhead bezogen auf die Nutzdaten ist hier deutlich erkennbar. Der Ablauf bei asynchroner Datenubertragung¨ folgt folgendem Schema: • Datenleitung liegt im Ruhezustand immer auf logisch 1 • jedem Zeichen ist ein Start Bit vorangestelt (immer Wert 0) Empfangsbaustein erkennt wann ein Zeichen ankommt • Datenbits in LSB-first Reihenfolge • nach Datenbits folgt optional Prufbit¨ (Parity) • letztlich folgen 1 oder 2 Stop Bits (immer Wert 1) somit Trennung zum n¨achsten Start Bit Bei der synchronen Datenubertragung¨ wird die Ubertragung¨ mit einem Taktsignal zeitlich synchronisiert. Es ist kein Start- bzw. Stop Bit erforderlich, auch die Schrittge- schwindigkeit (Baudrate) muss nicht zwangsl¨aufig bekannt sein. Das Taktsignal kann uber¨ eine eigene Leitung mitubertragen¨ werden oder vom Empf¨anger aus dem Daten- signal oder einer vorab ubertragenen¨ Synchronisationssequenz wieder zuruckgewonnen¨ werden. Dies wird in der Literatur als Taktruckgewinnung“¨ [Wiegelmann 05] bezeich- ” net. Durch Verwendung einer sog. Rahmensynchronisation wird der bei der asynchronen Ubertragung¨ verursachte Overhead reduziert. Der Empfangstakt synchronisiert sich nicht mehr nach jedem Zeichen, sondern erst nach Ubertragung¨ eines gr¨oßeren Da- tenblocks erneut mit dem Sendetakt. Damit ist ein h¨oherer Datendurchsatz m¨oglich, da mehrere hundert Bytes ohne Pause zwischen einzelnen Zeichen (ohne Redundanz) ubertragen¨ werden k¨onnen. Es herrschen allerdings h¨ohere Anforderungen an Sende- und Empfangstakt. W¨ahrend der Ubertragung¨ eines kompletten Datenblocks darf die Abweichung beider Taktgeneratoren nicht gr¨oßer als eine halbe Taktperiode sein. Abbildung 7.36 zeigt die synchrone Ubertragung¨ einer Folge von Datenbits, die hintereinander als Ganzes ubertragen¨ wird. Man unterscheidet bei der synchronen

Beuth Hochschule fur¨ Technik Berlin 175 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

T E S T

0 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 1 0 0 1 0 1 0 0 0 1 0 1 0 1 0

Datenstrom synchron

Abbildung 7.36: Synchrone Ubertragung¨ von Datenbl¨ocken ohne Unterbrechung

Ubertragung¨ zwischen zwei Protokollklassen: • zeichenorientierte Ubertragung¨ • bitorientierte Ubertragung¨ Bei der zeichenorientierten Ubertragung¨ werden Daten auf der Basis von einzelnen Zeichen ubermittelt.¨ Ein Datenblock besteht aus einem oder mehreren Zeichen glei- cher Breite (z.B. erweiteter ASCII-Code mit 8 Bit / ANSI-Zeichencode). Die codierten Zeichen werden als Bitstrom ubertragen¨ und mit der gleichen Codetabelle wieder um- gesetzt. Die Anzahl der ubertragenen¨ Bits ist stets ein Vielfaches der Bitzahl eines Zeichens. Ein Beispiel fur¨ die zeichenorientierte Ubertragung¨ ist in Abbildung 7.38 gegeben.

Zeichen Zeichen Zeichen Zeichen Zeichen

SYNC STX Daten Daten ETX

Zeichenorientierte Übertragung, z.B. 8-Bit ASCII Code

Abbildung 7.37: Beispiel fur¨ zeichenorientierte Ubertragung¨

Bei der bitorientierten Ubertragung¨ liegen die Daten dagegen als Bitstrom vor und werden vor der Ubertragung¨ in einen Rahmen (engl. frame) eingepackt. In diesem Rahmen mit festem Format werden die Daten ubertragen.¨ Die Position der Bits zeigt an, ob es sich um Steuerinformationen (z.B. Bit-Muster zur Erkennung von Nutzdaten) oder Daten handelt. Die Daten bestehen aus einer unterschiedlichen Anzahl von Bits, wobei die Anzahl der ubertragenen¨ Bits theoretisch beliebig, in der Praxis allerdings limitiert ist. In Abbildung 7.38 ist dies anhand eines Beispiels anschaulich dargestellt. Die L¨angen der einzelnen Bitfelder sind mit den Buchstaben m − r gekennzeichnet

m Bits n Bits o Bits p Bits q Bits r Bits

Flag Adresse Steuerfeld Daten CRC Flag

Bitorientierte Übertragung, z.B. HDLC (High-Level Data Link)

Abbildung 7.38: Beispiel fur¨ bitorientierte Ubertragung¨

Beuth Hochschule fur¨ Technik Berlin 176 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Der Ablauf bei synchroner Datenubertragung¨ folgt folgendem Schema: • Taktsignal oder Synchronisation zu Beginn der Datenubertragung¨ n¨otig damit Empfangsbaustein Anfang einzelner Zeichen erkennt • Synchronisation geschieht durch Ubertragung¨ einiger Synchronisationszeichen • wenn keine Daten zur Ubertragung¨ anstehen: Idle-Sequenz zur Synchronisation • synchrone Ubertragung¨ erfolgt blockweise (Datenblock durch Blocksicherungszei- chen (Prufsumme,¨ CRC) und Blockende- kennzeichnung markiert) • Datenbits in LSB-first Reihenfolge

7.3.3 Betriebsarten der seriellen Schnittstelle Die serielle Schnittstelle des 8051 ist eine Vollduplex-Schnittstelle, die ein zeitgleiches Versenden und Empfangen von Daten erm¨oglicht. Ferner ist sie empfangsgepuffert, d.h. es kann mit dem Empfang eines weiteren Bytes begonnen werden, w¨ahrend das vohergehende noch auf die Abholung durch die CPU wartet. Wie beim Timer erfolgt die Konfiguration und Programmierung der seriellen Schnittstelle uber¨ ein SFR. Auch der Datentransfer wird durch ein SFR realisiert. Dies wird in einem sp¨ateren Abschnitt ausfuhrlich¨ behandelt. Die serielle Schnittstelle kann in 4 verschiedenen Betriebsmodi arbeiten (1x synchron, 3x asynchron): • Modus 0: Schieberegister-Modus (synchroner Modus) • Modus 1: Asynchrone 8-Bit-Datenubertragung,¨ variable Baudrate • Modus 2: Asynchrone 9-Bit-Datenubertragung,¨ feste Baudrate • Modus 3: Asynchrone 9-Bit-Datenubertragung,¨ variable Baudrate Die Baudrate der seriellen Schnittstelle kann uber¨ verschiedene M¨oglichkeiten erzeugt werden: • Baudrate wird von der Oszillatorfrequenz abgeleitet (Modus 0 und 2) • Baudrate wird mittels Timer 1 erzeugt (Modus 1 und 3) Die verschiedenen Betriebsarten werden im Folgenden kurz erl¨autert. Modus 0 ist der einzige Modus fur¨ eine synchrone Ubertragung.¨ Die synchro- ne Ubertragung¨ setzt das Vorhandensein eines Taktgebers voraus. Eine synchrone Ubertragung¨ ohne Takt oder mit unterschiedlichen Takten funktioniert nicht. Daher stellt die Schnittstelle den Takt fur¨ die Ubertragung¨ an einem gegenuber¨ den Daten getrennten Pin zur Verfugung.¨ Da es zu diesem Zweck aber keinen zus¨atzlichen Pin gibt, wird ein sonst fur¨ die Datenubertragung¨ vorgesehener Pin zweckentfremdet. Als Taktleitung fur¨ die Synchronisation dient die TxD-Leitung (P3.1). Die RxD-Leitung (P3.0) stellt die Datenleitung fur¨ ein- und ausgehende Daten dar, womit in dieser Be- triebsart kein Vollduplexmodus m¨oglich ist. Abbildung 7.39 zeigt den zeitlichen Verlauf der Datenausgabe. Es werden jeweils acht Datenbits ubertragen,¨ wobei das Least Significant Bit (LSB) zuerst ubertragen¨ wird. Dieser Modus eignet sich gut dazu, ein Schieberegister zu fullen¨ bzw. Daten aus einem solchen zu lesen. Daher wird dieser Modus auch als Schieberegister-Modus bezeichnet. Die Baudrate betr¨agt hier immer fest 1/12 von der Oszillatorfrequenz fosc und ist nicht ver¨anderbar. Modus 1 nutzt die asynchrone Datenubertragung.¨ In den asynchronen Betriebsarten

Beuth Hochschule fur¨ Technik Berlin 177 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Abbildung 7.39: Modus 0: Schieberegister-Modus wird der Takt fur¨ die Ubertragung¨ nicht separat zur Verfugung¨ gestellt, stattdessen mussen¨ alle Teilnehmer an der Ubertragung¨ auf dieselbe Baudrate eingestellt sein. Die I/Os der seriellen Schnittstelle haben hier die definitionsgem¨aße Bedeutung: Die RXD- Leitung (P3.0) dient dem Empfang von eingehenden Daten, die TXD-Leitung (P3.1) dient dem Versenden von ausgehenden Daten. Um die Nutzdaten zu erkennen, sind diese bei den asynchronen Modi in Start- und Stop Bits eingebettet. In Modus 1 werden insgesamt zehn Bit ubertragen:¨ ein Start Bit (0), acht Datenbits (LSB first) und schließlich ein Stop Bit (1). In Abbildung 7.40 ist dies anschaulich illustriert. Beim Empfang wird das Stop Bit im SFR SCON im Flag RB8 gespeichert. Die Baudrate in Modus 1 ist variabel einstellbar (z.B. uber¨ Timer 1). Modus 1 ist der in der Praxis (und daher auch im Labor) am h¨aufigsten verwendete Modus.

Sender Empfänger MSB 0 Stop Bit Start Bit 0 MSB 0 8 Daten-Bits (LSB first) 0 1 1 0 0 1 1 0 0 1 0 1 1 0 1 0 1 1 MSB LSB 1 0 0 LSB 1 1 LSB

Abbildung 7.40: Modus 1: Asynchrone 8-Bit-Datenubertragung¨

In Modus 2, der ebenfalls asynchron ist, werden insgesamt elf Bit ubertragen:¨ ein Start Bit (0), 8 Datenbits (LSB first) zzgl. eines programmierbaren 9. Datenbits und ein Stop Bit (1). Das neunte Datenbit kann fur¨ verschiedene Zwecke verwendet werden. Beispielsweise kann darin ein Parity-Bit13 untergebracht werden, um die Ubertragung¨ zu sichern. Eine weitere M¨oglichkeit besteht darin, das neunte Bit immer auf 1 zu set- zen und es als zweites Stop Bit zu verwenden, da es als h¨ochstwertigstes Bit (MSB) als letztes ubertragen¨ wird, direkt vor dem regul¨aren Stop Bit. In diesem Zusam- menhang ist zu erw¨ahnen, dass es beim 8051 keine hardwarem¨aßige Erkennung von Ubertragungsfehlern¨ gibt. Auftretende Fehler bei der Parit¨at, Uberlaufe,¨ sowie Stop-

13Die Parity-Information ist jeweils im PSW zu finden. Das Paritybit P zu einem zu sendenden Byte kann also direkt PSW.0 entnommen werden.

Beuth Hochschule fur¨ Technik Berlin 178 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Bit-Fehler mussen¨ per Software erkannt werden, d.h. durch den Programmierer selbst umgesetzt werden. Beim Versenden wird das neunte Datenbit im SFR SCON im Bit TB8 angegeben. Beim Empfang wird es analog im Flag RB8 gespeichert.

Stop Bit Start Bit 9 Daten-Bits (LSB first)

1 0 0 0 1 0 1 1 0 1 0 xB8 MSB LSB

Abbildung 7.41: Modus 2: Asynchrone 9-Bit-Datenubertragung¨

Abbildung 7.41 zeigt die Ubertragung¨ der neun Datenbits im Modus 2. Abbildung 7.42 unterfuttert¨ dies durch Veranschaulichung des Datenrahmens der Ubertragung.¨ Die Baudrate im Modus 2 wird direkt aus der Oszillatorfrequenz fosz des Bausteins abge- leitet. Sie ist entweder mit 1/64 oder 1/32 der Oszillatorfrequenz konfigurierbar.

Datenrahmen 1 2 3 4 5 6 7 8 9 10 11 Schritt

1 2 3 4 5 6 7 8 Datenbit

Stop Bit 9.Datenbit oder Paritätsbit 1.-8.Datenbit Start Bit

Abbildung 7.42: Datenrahmen der asynchronen 9-Bit-Datenubertragung¨

Im letzten asynchronen Modus der Schnittstelle, Modus 3, werden wiederum ins- gesamt elf Bit ubertragen.¨ Das Format der Datenubertragung¨ und die Anwen- dungsm¨oglichkeiten entsprechen denen im Modus 2. Der Unterschied liegt lediglich in der flexibleren Erzeugung der Baudraten, die dem Modus 1 entspricht. Die Baudra- te ist in einem weiten Bereich variabel einstellbar und kann beispielsweise durch Timer 1 bereitgestellt werden.

7.3.4 SFR fur¨ die serielle Schnittstelle Sowohl die Programmierung (SCON), als auch der Datentransfer (SBUF) der seriellen Schnittstelle erfolgt uber¨ SFRs. Das Serial Control Steuer- und Statusregister (SCON) ubernimmt¨ die generelle Steuerung der seriellen Schnittstelle, dient der Programmie- rung und beinhaltet Statusanzeigen. Es befindet sich an Adresse 98h und wird mit dem Wert 00h resettet. Abbildung 7.43 zeigt den Aufbau des Serial Control Registers.

Beuth Hochschule fur¨ Technik Berlin 179 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Serial Control Register

SCON

MSB SM0 SM1 SM2 REN TB8 RB8 TI RI LSB

Abbildung 7.43: Flags des Serial Control Register

Neben der Betriebsart der seriellen Schnitstelle wird der Inhalt eines optionalen 9. Daten-Ubertragungsbit¨ festgelegt, das beim Senden und Empfangen bestimmte Funk- tionen (Parit¨at, Adresse/Daten) erfullt.¨ Fur¨ den Sendebetrieb in den Modi 2 und 3 muss dieses Bit entsprechend den Anforderungen in TB8 gesetzt werden. Im Emp- fangsbetrieb der gleichen Modi wird das Bit in RB8 hinterlegt und l¨asst sich zur wei- teren Ausweitung von der Steuersoftware auslesen. In der Betriebsart 1 stellt RB8 das empfangene Stop Bit dar, w¨ahrend es in der Betriebsart 0 keine Verwendung findet. Das SCON Register enth¨alt neben der generellen Freigabe (REN) fur¨ den Empfang serieller Daten auch die beiden Interruptbits TI und RI. Das Bit TI (Transmit In- terrupt) wird am Ende eines Sendevorganges von der Prozessor-Hardware gesetzt und l¨asst sich zur weiteren Verwendung auslesen. Beispielsweise l¨asst sich damit das Senden des n¨achsten Datenbytes veranlassen. Das Setzen dieses Bits durch die Hardware er- folgt im Modus 0 am Ende des achten Bits, in den ubrigen¨ Modi zu Beginn des neunten Bits (Stop Bit). Das Bit RI (Receive Interrupt) wird im Modus 0 am Ende des achten Bits und in den ubrigen¨ Modi in der Mitte des Stop Bits gesetzt und zeigt damit den Empfang eines seriellen Datenwortes an. Die Uberwachung¨ der seriellen Schnittstelle kann per Interrupt oder durch Bitabfrage der Flags TI und RI (Polling) erfolgen. Wie bereits in Abschnitt 7.1 erl¨autert, mussen¨ die Flags in jedem Fall manuell in Software gel¨oscht werden. Die genaue Bedeutung aller einzelnen Flags ist in Abschnitt 7.3.4 dargestellt. Das SCON ist bitadressierbar.

Beuth Hochschule fur¨ Technik Berlin 180 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Flag Bedeutung SM0, SM1 Auswahl der 4 Betriebs-Modi 0, 1, 2, 3 SM2 Hilfsbit fur¨ Multicontroller-Kommunikation: bei Modus 0 Wert 0, bei Modus 1 Wert 1, bei Modi 2 und 3 Wert 1: RI wird nicht aktiviert, wenn empfangenes Datenbit 9 Wert 0 hat REN generelle Empfangsfreigabe: Wert 1 fur¨ Empfang zugelassen, Wert 0 fur¨ nicht zugelassen TB8 zu sendendes Datenbit 9 (Modi 2 und 3) RB8 empf. Datenbit 9 (Modi 2 und 3) oder Stop Bit (Modus 1); in Modus 0 nicht verwendet TI Transmit Interrupt: wird in Mode 0 bei Bit 8 automatisch gesetzt, in anderen Modi bei Stop Bits; manuelles L¨oschen notwendig RI Receive Interrupt: wird in Mode 0 bei Bit 8 automatisch gesetzt, in anderen Modi bei Stop Bits; manuelles L¨oschen notwendig

Tabelle 7.11: Flags des SCON

Die Betriebsmodi der seriellen Schnittstelle werden durch die Bits SM0 und SM1 gew¨ahlt. Abschnitt 7.3.4 zeigt die m¨ogliche Auswahl. Das zus¨atzliche Steuerbit SM2 dient zur Aktivierung der Multiprozessor-Kommunikation und wird nicht n¨aher be- trachtet. SM0 SM1 Modus 0 0 Modus 0 - synchroner Betrieb, feste Baudrate 0 1 Modus 1 - 8-Bit UART, variable Baudrate 1 0 Modus 2 - 9-Bit UART, feste Baudrate 1 1 Modus 3 - 9-Bit UART, variable Baudrate

Tabelle 7.12: Auswahl der Schnittstellenmodi

Das Register fur¨ die Sende- und Empfangsdaten ist SBUF (Abbildung 7.44). Dieses SFR bedient in der Hardware physikalisch zwei unterschiedliche Register: das Ein- und das Ausgabepufferregister. Angesprochen wird das Register uber¨ nur eine Adresse, n¨amlich Adresse 99h. Serial Interface Buffer Register

SBUF

MSB LSB

7 6 5 4 3 2 1 0

Abbildung 7.44: Serial Buffer Register

Die Unterscheidung erfolgt durch Lesen oder Schreiben auf SBUF: Lesen adressiert das Empfangsregister, w¨ahrend Schreiben das Senderegister betrifft. Zudem wird durch

Beuth Hochschule fur¨ Technik Berlin 181 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG einen Schreibvorgang auf das Register die Ubertragung¨ des eingeschriebenen Bytes (im vorher gew¨ahlten Modus) uber¨ die serielle Schnittstelle eingeleitet. Das SBUF Register ist ausschließlich byte-adressierbar und hat einen undefinierten Reset-Wert.

7.3.5 Empfangen und Versenden von Daten In allen Modi wird das Versenden von Daten durch das Beschreiben des SBUF Regis- ters initiiert, d.h. durch einen Befehl, der SBUF als Ziel angibt. Die Triggerung zum eigentlichen Senden erfolgt dann durch Uberlauf¨ von Timer 1 oder bei der Ableitung durch die Oszillatorfrequenz nach entsprechender Anzahl von Takten. Die Beendigung des Sendevorgangs wird durch das bereits erl¨auterte TI-Flag angezeigt. Der Empfangsvorgang wird abh¨angig vom Modus unterschiedlich ausgel¨ost. In den asynchronen Modi (Modi 1-3) beginnt der Datenempfang automatisch, sobald eine fal- lende Flanke am RxD-Pin (am Controller, TTL-Pegel) entdeckt wird. Diese negative Flanke entspricht der Erkennung des Start Bit, da die RxD-Leitung (TTL-Pegel) ja im Ruhezustand auf High-Pegel liegt14. Die Erkennung der fallenden Flanke geschieht durch Uberabtastung¨ des RxD-Pins mit 16-facher Baudrate. Durch die fallende Flanke an RxD wird Timer 1 zuruckgesetzt.¨ In Schritt 7, 8 und 9 der 16 Takte wird der an RxD anliegende Wert abgetastet. Der in 2 der 3 F¨alle erkannte Wert wird akzeptiert. Abschließend werden die 8 Bits nach SBUF gespeichert und mit RI eine Interruptan- forderung ausgel¨ost. Voraussetzung dafur¨ ist, dass die globale Empfangsfreigabe, das Receive Enable Bit (REN), im SCON Register gesetzt ist.

Seriell-Control-Register SCON SM0 SM1 SM2 REN TB8 RB8 TI RI

SBUF Senderegister 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 TxD 8 7 0 Steuerlogik 8051 interner Bus der seriellen SBUF Empfangsregister Schnittstelle 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 8 7 0

Timer 1 CPU Überlauf Takt 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 RxD 8 7 Schieberegister 0

Abbildung 7.45: Aufbau und Steuerung des seriellen Ports

Im synchronen Modus (Modus 0) mussen¨ zum Datenempfang grunds¨atzlich die Emp-

14Hier sind die logischen Pegel an der TTL-Schnittstelle des Controllers gemeint. Die RS232- Datenleitung liegt im Ruhezustand elektrisch auf -12V (entspricht genau dem logischen High-Pegel). Das Start Bit wird mit dem logischen Low-Pegel signalisiert. Am Beginn des Start Bits ¨andert sich somit der Pegel der Datenleitung von -12V auf +12V. Das ist fur¨ den Empf¨anger das Zeichen dafur,¨ dass der Datentransfer beginnt. Das Stop Bit bzw. der Ruhezustand auf der Leitung weist den inversen Pegel zum Start Bit auf.

Beuth Hochschule fur¨ Technik Berlin 182 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG fangsfreigabe REN auf 1 und das Flag RI gel¨oscht sein. Damit wird die Hardware des Prozessors veranlasst, mit Hilfe seines synchronen Taktausganges TxD die Daten von dem seriellen Eingangs-Pin RxD zu ubernehmen.¨ Eine komplizierte Abtastung ist in diesem Fall nicht von N¨oten. Zur Verdeutlichung des Aufbaus und der Steuerung des seriellen Ports sind in Abbil- dung 7.45 alle beteiligten Einheiten und Register zusammenh¨angend dargestellt.

Einfacher Sendevorgang

Seriell-Control-Register SCON MOV SBUF, A SM0 SM1 SM2 REN TB8 RB8 TI RI Send: JNB SCON.1, Send CLR SCON.1 SBUF Senderegister 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 TxD 8 7 0 Steuerlogik 8051 interner Bus der seriellen SBUF Empfangsregister Schnittstelle 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 8 7 0

Timer 1 CPU Überlauf Takt 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 RxD 8 7 Schieberegister 0

Abbildung 7.46: Beispiel fur¨ Sendevorgang uber¨ seriellen Port

Die interne Steuerlogik kontrolliert den Ablauf des Datenaustauschs. Mittels Timer 1 wird die Baudrate generiert, die die Geschwindigkeit fur¨ die Datenkommunikation bestimmt. Anlieferung und Abtransport der zu sendenden, respektive empfangenen Daten erfolgt uber¨ einen internen Datenbus, der die Verbindung zu den getrennten SBUF Ein- und Ausgabepufferregistern schafft. Der Empfangszweig verfugt¨ uber¨ ein zus¨atzliches Schieberegister, das zur Seriell-Parallel-Wandlung genutzt wird. Letzlich zeigt die Abbildung auch die Verbindung zur Verwaltung des optionalen 9. Daten- Ubertragungsbits.¨ Anhand eines einfachen Sendevorgangs illustriert Abbildung 7.46 beispielhaft die re- levanten Vorg¨ange. Nicht beteiligte bzw. aktive Register und Komponenten sind dun- kel hinterlegt. Der Beispielcode zeigt die zum Senden notwendigen Anweisungen. Das Senden wird durch das Beschreiben des SBUF Registers ausgel¨ost. Anschließend wird mittels Polling das TI-Flag abgefragt und nach Ausl¨osen wieder gel¨oscht. Abbildung 7.47 zeigt ein analoges Beispiel fur¨ den Empfangsvorgang. Auch hier sind die nicht beteiligten Register und Komponenten farblich abgedunkelt. Der Beispielcode zeigt zun¨achst die Abfrage des RI-Flags, nach Ausl¨osen des Flags dessen L¨oschung und das Kopieren des empfangenen Datenwortes in den Akku. Bedingt durch das Polling wartet die CPU w¨ahrend des Sendens und des Empfangens ausschließlich auf das Aktivwerden des TI- bzw. RI-Flag. W¨ahrend dieses Wartevor- gangs ist also keine andere Verarbeitung m¨oglich. Alternativ zum Polling kann auch per Interrupt auf die serielle Schnittstelle reagiert werden. Dies bietet unter anderem den

Beuth Hochschule fur¨ Technik Berlin 183 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Einfacher Empfangsvorgang

Seriell-Control-Register SCON Empf: JNB SCON.0, Empf SM0 SM1 SM2 REN TB8 RB8 TI RI CLR SCON.0 MOV A, SBUF SBUF Senderegister 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 TxD 8 7 0 Steuerlogik 8051 interner Bus der seriellen SBUF Empfangsregister Schnittstelle 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 8 7 0

Timer 1 CPU Überlauf Takt 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 RxD 8 7 Schieberegister 0

Abbildung 7.47: Beispiel fur¨ Empfangsvorgang uber¨ seriellen Port

Vorteil, dass zwischenzeitlich (w¨ahrend des Sendens und des Empfangens uber¨ die seri- elle Schnittstelle) weitere Verarbeitungen m¨oglich sind. In dieser Hinsicht ist allerdings zu beachten, dass der Empfangs- und der Sende-Interrupt den gleichen Interruptvektor verwenden. Das bedeutet, dass beide Flags denselben Interrupt ausl¨osen. Daher muss die Interrupt Service Routine (ISR) auswerten welches Ereignis aufgetreten ist. Die Art des Interrupt-Ereignisses ist schließlich anhand der Flags feststellbar. Je nachdem muss die ISR ein oder beide Flags (RI, TI) zurucksetzen.¨

7.3.6 Programmierung des seriellen Schnittstelle Ahnlich¨ wie die Programmierung der Z¨ahler/Zeitgeber-Schaltungen gestaltet sich die Programmierung der seriellen Schnittstelle des 8051 einfach, wenn man nach einem festen Schema vorgeht. Zun¨achst sei hier eine Schritt-fur-Schritt¨ Anleitung fur¨ das Senden gegeben (Beispiel: serieller Modus 1, also 8-Bit Daten asynchron plus Start und Stop Bit). Bei der Wahl des Timer Modus fur¨ die Baudratengenerierung empfiehlt sich der 8-Bit Auto-Reload Modus (Modus 2). 1. Setze das TMOD Register fur¨ den Einsatz von Timer 1 in Modus 2 (TMOD mit Wert 00100000b beschreiben) 2. Konfiguriere die Baudrate durch Beschreiben des TH1 Registers 3. Setze das SCON Register fur¨ den seriellen Modus 1 (SCON mit Wert 01010000b beschreiben) 4. Starte den Timer (TR1 auf 1 setzen) 5.L ¨osche das Transmit Interrupt Flag (TI auf 0 setzen mit CLR TI“ Anweisung) ” 6. Beschreibe das SBUF Register mit dem seriell zu ubertragenden¨ Zeichen 7. Beobachte das TI-Flag-Bit (Polling, Interrupt), um den Ubertragungsstatus¨ zu

Beuth Hochschule fur¨ Technik Berlin 184 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

ermitteln (Polling beispielsweise mit JNB TI, xx“) ” 8. Zur Ubertragung¨ des n¨achsten Zeichens gehe zuruck¨ zu Schritt 5 Fur¨ die Behandlung mit Interrupts sind wiederum zus¨atzliche Schritte erforderlich, so z.B. die globale Freigabe, dann die Freigabe des Serial Interrupts im IE-Register, etc. Die Einzelheiten dazu wurden bereits in Abschnitt 7.1 erl¨autert. Nachfolgend ist analog zur soeben dargelegten Vorgehensweise eine Schritt-fur-Schritt¨ Anleitung fur¨ das Empfangen uber¨ die serielle Schnittstelle gegeben (Beispiel: serieller Modus 1). 1. Setze das TMOD Register fur¨ den Einsatz von Timer 1 in Modus 2 (TMOD mit Wert 00100000b beschreiben) 2. Konfiguriere die Baudrate durch Beschreiben des TH1 Registers 3. Setze das SCON Register fur¨ den seriellen Modus 1 und aktiviere das Empfangsbereitschaft-Flag (Receive Enable) (SCON mit Wert 01010000b beschreiben) 4. Starte den Timer (TR1 auf 1 setzen) 5.L ¨osche das Receive Interrupt Flag (RI auf 0 setzen mit CLR RI“ Anweisung) ” 6. Beobachte das RI-Flag-Bit, um den Empfangsstatus zu ermitteln (Polling beispielsweise mit JNB RI, xx“; wenn RI = 1: SBUF hat das Byte und ” es wandert an einen sicheren Ort“) ” 7. Lies das SBUF Register mit dem empfangenem Zeichen aus 8. Zum Empfang des n¨achsten Zeichens gehe zuruck¨ zu Schritt 5 Diese Anleitungen geben eine sichere Vorgehensweise in der Konfiguration der seriellen Schnittstelle vor. Einzig auf die Details zur Baudratenkonfiguration wurde bisher nicht n¨aher eingegangen. Einzelheiten hierzu folgen getrennt im n¨achsten Abschnitt.

7.3.7 Erzeugung der Baudrate Die Baudrate (in der Literatur auch oft als Symbolrate bezeichnet) ist ein Maß fur¨ die Schrittgeschwindigkeit vs bei der Datenubertragung¨ und gibt die Anzahl der ubertragenen¨ Informationen (Symbole) pro Sekunde an. Fur¨ die Schrittgeschwindigkeit gilt als Einheit: Symbol = 1Baud (7.5) s Benannt ist die Baudrate nach Jean Maurice Emile´ Baudot (1845 - 1903), einem franz¨osischen Ingenieur und Erfinder, der 1874 den Baudot-Code und den damit arbei- tenden Baudot-Telegraphen erfand. Die Schrittgeschwindigkeit ist der Kehrwert der Schrittdauer, wobei als Schritt das kleinstes Zeitintervall zwischen zwei aufeinanderfolgenden Zustandswechseln bei zeit- diskreten Signalen zu verstehen ist. Mit einem Schritt k¨onnen ein oder mehrere Bits eines Datenstroms ubertragen¨ werden.

Beuth Hochschule fur¨ Technik Berlin 185 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

1 vs = (7.6) Ts

Die Baudrate wird oft mit der Datenrate (Ubertragungsgeschwindigkeit)¨ vd gleichge- setzt. Die Ubertragungsgeschwindigkeit¨ bezeichnet man auch als Bitrate, gemessen in bit/s bzw. bps. Diese Gleichsetzung ist allerdings nicht korrekt (Baudrate 6= Bitrate). Vielmehr gilt folgender Zusammenhang: Die Datenubertragungsrate¨ vd berechnet sich aus der Schrittgeschwindigkeit vs und der Ubertragungsbreite¨ m (in Bits). Zur Darstellung von n unterschiedlichen Kennzust¨anden ben¨otigt man m = log2(n) Bits (vgl. Abschnitt 7.3.7)15. Die Ubertragungsbreite¨ entspricht also dem Logarithmus der Anzahl der Kennzust¨ande n zur Basis 2. Dies l¨aßt sich durch den Logarithmus Dualis ld ausdrucken,¨ dem Logarithmus zur Basis 2.

vd = vs · log2(n) = vs · ld(n) (7.7) Die Bitrate ergibt sich also aus der Anzahl an Bits pro Zustand (bzw. Logarithmus Dualis der Zust¨ande) multipliziert mit der Baudrate. Somit kann die Baudrate zwar gleich der Bitrate sein, muss aber nicht. Zur Anschauung betrachten wir im Folgenden zwei F¨alle.

Kennzust¨ande Bit 2 1 4 2 8 3 16 4

Tabelle 7.13: Zusammenhang zwischen Kennzust¨anden und verwendeten Bits

Bei dem in Abbildung 7.48 dargestellten Signal wird je Schritt ein Symbol ubertragen,¨ das genau durch ein Bit codiert ist. Mit einem Bit (m = 1) lassen sich n = 21 = 2 Zust¨ande codieren. Wenn ein Symbol genau einem Bit entspricht, sind Baudrate (Schrittgeschwindigkeit) und Bitrate (Ubertragungsgeschwindigkeit)¨ gleich. Dies folgt aus vd = vs ·ld(n) mit n = 2. Es handelt sich hier um ein zweiwertiges (bin¨ares) Signal. Bei bin¨aren Signalen codiert jeder Zustandswechsel ein Bit. Mehrstufige Signale k¨onnen mehr als zwei Werte annehmen. Bei Amplitudenmodulati- on etwa kann die St¨arke des elektrischen Wertes in mehrere Teile geteilt werden. Paare von Bits (Dibits (zwei Bit pro Signalwert), 3 oder 4 Bits, etc.) werden dann durch unterschiedliche Spannungswerte repr¨asentiert. Bei acht unterscheidbaren Teilwerten werden beispielsweise je Schritt drei Bit ubertragen.¨ Fur¨ mehrstufige Signale mit n m¨oglichen Wertestufen ergibt sich nach der Beziehung vd = vs · ld(n) fur¨ die Datenrate (bit/s) ein Wert gr¨oßer als die Baudrate (Baud), da je Schritt - also fur¨ ein Symbol - mehrere Bits ubertragen¨ werden. Bei dem in Abbildung 7.49 dargestellten Signal wird je Schritt ein Symbol ubertragen,¨ das durch zwei Bits codiert ist. Mit zwei Bit (m = 2) lassen sich n = 22 = 4 Zust¨ande

15Andersrum kann man mit m Bits n = 2m Zust¨ande darstellen. Die Logarithmusfunktion zur Basis 2 ist die Umkehrfunktion der Exponentialfunktion zur Basis 2.

Beuth Hochschule fur¨ Technik Berlin 186 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

U

5V 1

0 Bitstrom 0 1 0 1 1 0 1 0 t Baud = BPS

Abbildung 7.48: Baudrate gleich Bitrate darstellen. Verglichen mit Abbildung 7.48 ist die Ubertragung¨ doppelt so vieler Infor- mationsbits mit gleicher Baudrate m¨oglich.

U

15V 11

10V 10

5V 01

00 Bitstrom 0 0 1 0 0 1 1 1 0 1 1 1 1 0 0 0 t Baud <> BPS

Abbildung 7.49: Baudrate ungleich Bitrate

Die serielle Schnittstelle nutzt zweiwertige (bin¨are) Signale. Damit ist die Baudra- te gleich der Bitrate. Es existieren beim 8051 grunds¨atzlich zwei M¨oglichkeiten der Baudraten-Erzeugung fur¨ die serielle Schnittstelle: • mit Hilfe des Timer 1 • mittels Baudratengenerator (falls verfugbar,¨ z.B. beim 80c515c) Die uberwiegende¨ Mehrheit der heutigen 8051 Derivate verfugen¨ uber¨ einen integrier- ten Baudratengenerator. Dieser ist flexibler in der Programmierung als ein Timer und hat uberdies¨ den Vorteil, dass Timer 1 anderweitig verwendet werden kann. Der Bau- dratengenerator ist nicht Bestandteil des Ur-Typen des 8051, weshalb im vorliegenden Skript eine Beschr¨ankung auf die Generierung mittels Timer 1 stattfindet.

Baudrate in Modus 0 Die Baudrate im Modus 0 wird direkt von der Oszillatorfrequenz abgeleitet und ist damit fest. Sie ist definiert durch:

Baudrate Modus 0 = fosz/12 (7.8)

Baudrate in Modus 2

Beuth Hochschule fur¨ Technik Berlin 187 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Die Baudrate im Modus 2 wird ebenfalls direkt von der Oszillatorfrequenz abgeleitet. Zus¨atzlich kann sie uber¨ ein Flag im Special Function Register PCON (Power Control Register) erh¨oht werden (vgl. Abbildung 7.52). Dieses Flag (SMOD) bewirkt eine op- tionale Verdopplung der Baudrate. Die Baudrate ist damit also maßgeblich vom Bit SMOD im SFR PCON abh¨angig. • SMOD=0: Baudrate 1/64 der Oszillatorfrequenz • SMOD=1: Baudrate 1/32 der Oszillatorfrequenz In der Voreinstellung ist SMOD auf 0 gesetzt.

SMOD  Baudrate Modus 2 = 2 /64 · fosz (7.9)

Baudrate in den Modi 1 und 3 In Modus 1 und in Modus 3 kann die Baudrate mit dem Timer 1 variabel erzeugt werden. Die Baudrate leitet sich so von der Uberlaufrate¨ des Timer 1 ab, wobei die Abh¨angigkeit vom Flag SMOD bestehen bleibt. Unter der Uberlaufrate¨ ist die Anzahl der Uberl¨ ¨aufe des Timer pro Sekunde zu verstehen. Durch welche Betriebsart des Timer 1 die Uberlaufrate¨ zustande kommt, ist nicht von Bedeutung.

SMOD  Baudrate Modi 1 und 3 = 2 /32 · Timer 1 Uberlaufrate¨ (7.10) Fur¨ eine gewunschte¨ Baudrate sollte eine Betriebsart gew¨ahlt werden, die den gerings- ten Softwareaufwand fur¨ diese Baudrate erfordert. Fur¨ die g¨angigen Baudraten emp- fiehlt sich der Betrieb von Timer 1 im Modus 2. Dieser nutzt den Timer als 8-Bit-Timer mit Reload bei Uberlauf¨ aus Register TH1. Aufgrund der Auto-Reload-Methode kann hier der Timer-Interrupt gesperrt werden, da beim Uberlauf¨ auf diesen nicht reagiert werden muss. Die folgende Formel zeigt die entstehenden Baudraten in Abh¨angigkeit vom gew¨ahlten Reloadwert (mit Timer 1 in Modus 2):

SMOD  8  Baudrate Mode 1 und 3 = 2 /32 · fosz/(12 · (2 − TH1)) (7.11) An dieser Formel erkennt man einige bekannte Eigenarten des Taktsystems des 8051 Mikrocontroller, andere hier implizierte Faktoren bedurfen¨ allerdings noch einigen Erl¨auterungen. Zur Verdeutlichung sei hier beispielhaft wieder eine Referenzfrequenz von fosz = 11, 0592 MHz angenommen. Bekannt ist, dass ein Maschinenzyklus 12 Tak- te dauert, weshalb hier mit einer durch 12 dividierten Oszillatorfrequenz (fmz = 921, 6 kHz) gerechnet wird. Die 8051 UART teilt die resultierende Maschinenzyklusfrequenz wiederum um den Faktor 32 (fuart = 28800 Hz). Die sich hieraus ergebende Fre- quenz kann nun zus¨atzlich mit einem entsprechenden Timer 1 Z¨ahlregisterwert (TH1) verlangsamt werden. Da der Timer immer aufw¨arts z¨ahlt und beim Uberlauf¨ vom Maxi- malwert zu Null den Timer-Interrupt ausl¨ost, der letztlich die Baudrate fur¨ die serielle Schnittstelle erzeugt, muss hier in der Formel der TH1 Wert vom Maximalwert 256 (fur¨ den 8-Bit Auto-Reload Modus) subtrahiert werden. Erg¨anzend zu der gezeigten Formel l¨asst sich die Abh¨angigkeit der Baudrate von der Oszillatorfrequenz fur¨ die serielle Schnittstelle im Modus 1 und 3 auch durch die in

Beuth Hochschule fur¨ Technik Berlin 188 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Abbildung 7.50 gezeigte Graphik darstellen. Hierbei wird zun¨achst davon ausgegangen, dass eine Verdopplung der Baudrate nicht n¨otig ist, so dass SMOD gleich 0 ist.

/ 12 / 32 Quarz- Masch.- Timer 1 Oszillator UART zyklen

11,0592 MHz 921,6 kHz 28.800 Hz Baud Rate

Abbildung 7.50: Beziehung zwischen Oszillatorfrequenz und Baudrate (Modi 1 und 3)

Aus Abbildung 7.50 wird deutlich, dass fuart = 28800 Hz die relevante Frequenz darstellt, um den Timer 1 fur¨ die Baudraten-Generierung zu programmieren. Dies gestaltet sich nun sehr einfach, da man lediglich das Verh¨altnis der einzustellenden Baudrate zu dieser Frequenz bilden muss und diesen Faktor direkt als negative Zahl in der Zweierkomplementdarstellung angeben kann. Wie und wieso das funktioniert wird im Folgenden etwas genauer beschrieben. In Kompatibilit¨at zu der Kommunikation mit einem PC, was hier der g¨angige Fall ist, existieren eine Reihe von Standard-Baudraten, z.B. 19200 Baud, 9600 Baud, 4800 Baud, 2400 Baud, etc. Die meisten dieser Baudraten sind ganzzahlig teilbar durch 28800. Soll beispielsweise eine Baudrate von 9600 Baud konfiguriert werden, so muss laut obenstehender Formel Timer 1 alle drei Takte uberlaufen.¨ TH1 musste¨ also mit dem Wert 28 − 3 = 253 beschrieben werden und wurde¨ dann dank des Auto-Reload Modus) nach Uberlauf¨ immer wieder neu mit diesem Wert besetzt werden. Eine Programmierung von TH1 ist allerdings auch in verkurzter¨ - und vor allem einfa- cher zu merkender - Form m¨oglich. Statt TH1 den Startwert 253 zu geben, l¨asst sich das gleiche Verhalten allein mit der Angabe −3 realisieren. Abschnitt 7.3.7 fasst die Standard-Baudraten zusammen und gibt den damit verbundenen Wert fur¨ TH1 einmal in der konventionell zu berechnenden Dezimalzahl an, sowie verkurzt¨ als negative Zahl in der signed“ Darstellung. ” Baudrate TH1 (dezimal) TH1 (signed) TH1 (hex) 9600 253 -3 FD 4800 250 -6 FA 2400 244 -12 F4 1200 232 -24 E8

Tabelle 7.14: Programmierung von TH1 in verkurzter¨ Form

Standardm¨aßig werden beim 8051 einfach 8-Bit Integer-Werte benutzt. Hierbei geht der Programmierer davon aus, dass der Inhalt seiner Speicher grunds¨atzlich aus ganz- zahligen positiven Zahlen besteht. Ein Byte Speicher kann somit die Zahlen 0 bis 255 enthalten. Die Speicherzelle nennt kein Vorzeichen. Per se unterstutzt¨ der 8051 keine signed“ Arithmetik. ” Es ist bekannt, dass signed“ und unsigned“ dazu bestimmt sind, einen Datentyp als ” ” vorzeichenbehaftet oder als vorzeichenlos auszuweisen. Da es in Assembler keine fest

Beuth Hochschule fur¨ Technik Berlin 189 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG zu definierenden Datentypen gibt, bel¨auft sich diese Unterscheidung also lediglich auf eine Interpretation der Registerinhalte. Fur¨ die CPU spielt die Interpretation der Bit- werte keine Rolle. Da die Interpretation des Registerinhaltes also frei ist, kann der mit 8 Bit darstellbare Wertebereich nun einfach als signed“ definiert werden, so dass die ” in den Registern enthaltenen Bitkombinationen einfach als Zweierkomplementdarstel- lungen interpretiert werden. Hier geht der Programmierer nun davon aus, dass seine Speicherzellen vorzeichenbehaftete Zahlen enthalten. Sollen arithmetische Operationen durchgefuhrt¨ werden, muss allerdings das Bestehen der Darstellungsgrenzen beachtet werden. In der Zweierkomplementdarstellung hal- biert sich der Darstellungsbereich im Betrag. Das MSB des Bytespeichers stellt das Vorzeichen dar und zeigt an, ob die entsprechende Dezimalzahl positiv (MSB 0) oder negativ (MSB 1) ist. Ein Byte Speicher kann bei der Zweierkomplementdarstellung nun die Zahlen −128 bis +0 bis +127 enthalten, wie nachfolgend veranschaulicht wird.

-128 = 80h (1000 0000) -127 = 81h (1000 0001) ...... -1 = FFh (1111 1111) (7.12) 0 = 00h (0000 0000) +1 = 01h (0000 0001) ...... +127 = 7Fh (0111 1111) Zur Verdeutlichung des Prinzips sind in Abschnitt 7.3.7 zwei Beispiele gegeben. Beide Beispiele zeigen, dass die Bin¨arrepr¨asentation identisch ist, unabh¨angig davon, ob die Zahl als positiv oder negativ interpretiert wird.

Beispiel in Dezimal Beispiel in Hex Darstellung von -5d Darstellung von -34h 5 = 0000 0101 34h = 0011 0100 CPL = 1111 1010 CPL = 1100 1011 +1 = 1111 1011 +1 = 1100 1100 Hex = FBh Hex = CCh oder Dez = -52d also: 1111 1011 = -5d also: 1100 110 = -52d aber auch 251d aber auch 204d

Tabelle 7.15: Beispiele zur Darstellung mit und ohne Komplement

In der in Abbildung 7.50 gezeigten Graphik wurde das SMOD-Flag zun¨achst als 0 ange- nommen. Es existieren aber einige Baudraten, wie z.B. 19200 Baud, die nicht ganzzah- lig durch 28800 teilbar sind und so mit einem einfachen Teilverh¨altnis nicht bestimmt werden k¨onnen. Hier kommt nun das SMOD-Flag (im Power Control Reg. PCON) zur Anwendung, durch das die einstellbaren Baudraten erweitert werden k¨onnen, indem die UART-Frequenz optional verdoppelt werden kann (fuart = 2 · 28800 = 57600 Hz). Abbildung 7.51 zeigt eine um diese Eigenschaft erweiterte Graphik. Hier wurde die praktische Anwendung des SMOD Flag im SFR PCON zur optionalen

Beuth Hochschule fur¨ Technik Berlin 190 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

/ 16 Timer 1 SMOD=1 / 12 Quarz- 57.600 Hz Oszillator Masch.- oder zyklen / 32 11,0592 MHz 921,6 kHz Timer 1 SMOD=0

28.800 Hz Baud Rate

Abbildung 7.51: Beziehung zwischen Oszillatorfrequenz und Baudrate mit SMOD Flag

Verdopplung der Baudrate soeben demonstriert. Der Vollst¨andigkeit halber sind in Abbildung 7.52 alle im Power Control Register enthaltenen Flags dargestellt.

Power Control Register

PCON

MSB SMOD PDS IDLS SD GF1 GF0 PDE IDLE LSB nur serielle Schnittstelle

Abbildung 7.52: Flags des Power Control Register

Das Register beeinhaltet die Flags zur Steuerung des sog. Schlafzustandes (Idle) und des Power-Down-Modus. Die Steuerung der Energiesparoptionen ist sinnvoll bei auto- nomen, akkubetriebenen Applikationen. PCON befindet sich an Adresse 87h und ist nur byte-adressierbar. Es hat den Reset Wert 0xxx0000b. Aufschluss uber¨ die Bedeu- tung der einzelnen Flags gibt Abschnitt 7.3.7.

Flag Bedeutung SMOD serielle Schnittstelle: Wert 1 fur¨ Verdoppelung der Baudrate in den Modi 1, 2 und 3 PDS Power Down Start: Wert 1 fur¨ Power Down Modus aktiv IDLS Idle Start: Wert 1 fur¨ Idle Modus aktiv SD Shut Down: Wert 1 fur¨ Ruhezustand GF0, GF1 generelles Flag 0 und 1 (kann allgemein benutzt werden) PDE, IDLE Power Down und Idle Mode Enable: jeweils Wert 1 fur¨ Freigabe

Tabelle 7.16: Flags des PCON

Sehr niedrige Baudraten lassen sich auf die gezeigte Weise nicht erzeugen. Sind diese erforderlich, ist es zweckm¨aßig den Timer 1 im Modus 1 zu betreiben (16-Bit-Modus).

Beuth Hochschule fur¨ Technik Berlin 191 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 7. FUNKTIONSGRUPPEN DER PERIPHERIE UND STEUERUNG

Der notwendige Reload des Z¨ahlerwertes muss dann allerdings durch Software unter Verwendung des Timer-Interrupts vorgenommen werden. Hier muss der Interrupt also vorab freigegeben werden. Das Vorgehen ist etwas komplizierter und wird nicht durch die gezeigten Vereinfachungen abgedeckt. Um einen fehlerfreien Datentransfer zwischen dem 8051 und einer Gegenstelle - bei- spielsweise einem PC - zu erm¨oglichen, muss sichergestellt werden, dass die Baudrate des 8051 mit der des Kommunikationspartners - im Falle des PC mit der Baudrate des COM Ports vom PC - ubereinstimmt.¨ Fur¨ die ublichen¨ Datenpakete von 10 Bits bei der asynchronen Ubertragung¨ kann eine Abweichung bis etwa 4% in Kauf genom- men werden. Fur¨ eine sichere Ubertragung¨ sollte die Abweichung jedoch geringer sein, damit noch Reserven fur¨ Laufzeitfehler und Bauteilabweichungen bleiben. Die Anforde- rungen sind so ausgelegt, dass mit einer Vielzahl an unterschiedlichen Taktbausteinen gearbeitet werden kann, wenn auch nicht immer zuverl¨assig. Um die RS232-Standard- Baudraten genau zu erreichen, gibt es spezielle Quarze mit krummen Frequenzen wie 3,6864 MHz, 7,3728 MHz und 11,0592 MHz (vgl. Taktversorgung auf dem MDE 8051 Trainer Board).

Beuth Hochschule fur¨ Technik Berlin 192 Prof. Dr.-Ing. Sven-Hendrik Voß 8 Hardwarenahe Programmierung in C

8.1 Die Programmiersprache C

Bisher wurde gezeigt wie ein 8051 Mikrocontroller mit Assembler programmiert werden kann. Diese Art der Programmierung ist dem letztendlich erzeugten Bin¨arcode sehr nahe, wie bereits in Abschnitt 4.3 ausfuhrlich¨ erl¨autert wurde. In diesem Abschnitt wurde auch bereits auf die Programmierung in C hingewiesen. Dies soll hier nun weiter vertieft werden. Die Programmiersprache C wurde 1972 von Ken Thompson und Dennis Ritchie entwi- ckelt. Als Einsatzzweck von C war zun¨achst die Programmierung des Betriebssystems UNIX geplant, welches zu dieser Zeit noch vollst¨andig in Assembler programmiert war. Um UNIX portierbar, also zwischen verschiedenen Rechnerplattformen ubertragbar¨ zu machen, musste die einzusetzende Programmiersprache maschinenunabh¨angig - al- so unabh¨angig von der Maschinensprache eines bestimmten Prozessors - sein. Da ein Betriebssystem unmittelbar auf die Rechnerhardware aufsetzt, musste die Sprache zu- dem maschinennah sein, also einen leichten Zugriff auf die Komponenten der Hard- ware (insbesondere Speicherzellen und Prozessorregister) gestatten und sich effizient in Maschinensprache ubersetzen¨ lassen. Keine der damals zur Verfugung¨ stehenden Programmiersprachen konnte dies leisten. C wurde als Nachfolger der Programmiersprache B (wiederum basierend auf BCPL, Basic Combined Programming Language), einer hardwarenahen Sprache mit Unter- programmen, aber ohne differenzierte Datentypen, implementiert. Als Namen fur¨ die neue Programmiersprache wurde einfach der na¨achste Buchstabe im Alphabet gew¨ahlt. C beseitigte vorherrschende Einschr¨ankungen von B und fuhrte¨ dabei unter anderem verschiedene Datentypen ein, freie Speicherzugriffe, sowie automatische Wandlung von Datentypen und mehr. Weil die Programmiersprache C anfangs nur durch das Dokument The C Program- ” ming Language“ [Kernighan 78] definiert war, wurde dieser de facto Standard von den verschiedenen Compiler-Herstellern h¨aufig verletzt bzw. erweitert. Auf diese Weise ging die ursprungliche¨ Idee, dass C-Programme portierbar sein sollten, durch die vielen Compiler-Varianten im Laufe der Zeit verloren. Deshalb wurde bald darauf vom Techni- cal ANSI Committee X3J11 (American National Standards Institute) ein Standard fur¨ die Programmiersprache C erarbeitet, der 1989 verabschiedet und als ANSI-C-Standard bekannt wurde [ANSI 89]. Ein Jahr sp¨ater wurde der Standard von der ISO (Internatio- nal Organization for Standardization) mit kleinen Anderungen¨ als Standard ISO/IEC 9899:1990 ubernommen¨ und seitdem in unregelm¨aßigen Abst¨anden aktualisiert. Durch die Entstehungshistorie ist die Programmiersprache C nah an der Hardware orientiert, so dass sie gern zur Programmierung von Mikrocontrollern, aber auch Be- triebssystemen und zugeh¨origen Systemprogrammen, wie Datenbanken und Webser-

193 KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C vern, eingesetzt wird. In der Hochschulausbildung dient C h¨aufig als Einstiegssprache“ und wird in einer ” Grundvorlesung zur Einfuhrung¨ in die Programmierung eingesetzt. Die dort vermittel- ten Kenntnisse werden hier - wie bereits im Vorwort dieses Skripts dargelegt - voraus- gesetzt, so dass nicht mehr auf die Grundlagen der Programmierung in C eingegangen wird. Die Programmierung eines Mikrocontrollers in der Sprache C unterliegt allerdings einigen Besonderheiten, die sich durch die N¨ahe zur Hardware erkl¨aren lassen. Diese Besonderheiten stehen in diesem Kapitel im Vordergrund und werden nachfolgend dis- kutiert.

8.1.1 Gegenuberstellung¨ von C und Assembler Aufgrund der Leistungsf¨ahigkeit der Hochsprachenprogrammierung hat diese im prak- tischen Einsatz mittlerweile einen festen Stand. Neben Assembler ist die Sprache C bei Mikrocontrollern die am h¨aufigsten verwendete Programmiersprache. Entgegen der PC-Programmierung sind Architekturkenntnisse hier außerordentlich wichtig fur¨ die Programmierung. Abschnitt 8.1.1 fasst die Vor- und Nachteile von Assembler und C fur¨ die Mikrocontroller-Programmierung zusammen.

Assembler C-Compiler + Laufzeit + Entwicklungszeit + beste Hardware-Kontrolle + Portabilit¨at - zeitaufwendig - Implementierung problematisch - fehleranf¨allig - u.U. kein ANSI-Standard

Tabelle 8.1: Gegenuberstellung¨ von Assembler und C

Zusammenfassend l¨asst sich feststellen, dass C einfacher und weniger zeitaufwendig in der Programmentwicklung ist. Zudem ist der C-Code leichter zu ¨andern und zu aktualisieren. Ohne Gebrauch von compiler-spezifischen Erweiterungen der Sprache oder speziellen Betriebssystemfunktionen lassen sich in C Programme erstellen, die relativ einfach ohne Modifikationen (oder nur mit geringen) auf unterschiedliche Hard- wareplattformen (d.h. auch auf andere Mikrocontroller) portiert werden k¨onnen. Diese offensichtlichen Vorteile sind dem Performance- und Kontrollverlust verglichen mit As- sembler gegenuberzustellen.¨ Nur der Assembler-Programmierer hat die volle Kontrolle uber¨ die Hardware, n¨amlich ohne den Zwischenschritt uber¨ einen Compiler.

8.1.2 Systemn¨ahe von C C ist eine sehr hardwarenahe Programmiersprache, die ursprunglich¨ als eine Art maschi- nenunabh¨angiger Makroassembler gedacht war, wie sich aus der Entstehungsgeschichte zweifelsohne ableiten l¨asst. Die Systemn¨ahe einer Programmiersprache beschreibt, ob und wie eine m¨oglichst direkte“ Verwendung der Hardware m¨oglich ist. In C wird dies ” haupts¨achlich durch Zeiger (engl. Pointer) erm¨oglicht. Ein Pointer ist eine Variable, deren Wert eine Adresse darstellt. So wird der Zugriff auf beliebige Speicherzellen eines Rechnersystems erm¨oglicht (vgl. indirekte Adressierung).

Beuth Hochschule fur¨ Technik Berlin 194 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C

Im Zusammenhang mit der Programmierung eines Mikrocontrollers kann mit Hilfe von Pointern z.B. auf Konfigurationsregister zugegriffen werden. Durch Festlegen der Adresse des Pointers zeigt“ dieser auf das entsprechende Register. Anschließend kann ” auf die Adresse geschrieben oder von ihr gelesen werden. Zudem erm¨oglichen spezielle Schlusselw¨ ¨orter eine gezielte Beeinflussung des Compilers. Das Schlusselwort¨ volatile“ ” weist beispielsweise den Compiler an, von der entsprechenden Adresse grunds¨atzlich zu lesen und nicht zwischengespeicherte Werte zu verwenden. Ein weiteres systemnahes Konzept sind Bit-Operatoren, wie z.B. AND, OR, XOR und SHIFT. Diese Operatoren sind in C verfugbar¨ und erm¨oglichen eine gezielte Manipu- lation einzelner Bits, was h¨aufig zur Programmierung von Mikrocontrollern16 ben¨otigt wird. Beispielsweise k¨onnen mit Bit-Operatoren und Pointern einzelne Bits in Konfigu- rationsregistern gesetzt und auch gel¨oscht werden, womit die volle Zugriffsflexibilit¨at sichergestellt ist. In Abschnitt 4.3 wurde der Design Flow, auch unter Verwendung von Hochsprachen, bereits skizziert. Der C-Compiler produziert HEX-Files, die zur Programmierung des Mikrocontrollers auf dessen ROM geladen werden. Auf der Gr¨oße des HEX-File liegt dabei das Hauptaugenmerk, denn Mikrocontroller haben begrenzten on-chip ROM17. Die C-Programmierung ist in der Regel zwar weniger zeitraubend, produziert aber durch die Compilierung gr¨oßere HEX-Files.

8.1.3 Operatoren in C Grundkenntnisse in C werden vorausgesetzt. Abschnitt 8.1.3 und Abschnitt 8.1.3 zeigen zur Wiederholung die in C vorhandenen Operatoren.

16Architekturen mit Bitoperationen, wie z.B. der 8051 Mikrocontroller 17Der Programmspreicher des 8051 Mikrocontrollers ist limitiert auf 64K Bytes.

Beuth Hochschule fur¨ Technik Berlin 195 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C

Operator Beschreibung Beispiel prim¨are Operatoren () Klammerung von Ausdrucken¨ x = y ∗ (2 + z) unit¨are Operatoren (rechts-assoziativ) − Vorzeichen x = −y; ! logisches NICHT !(a > b) ++ Inkrementoperator i + +, + + i −− Dekrementoperator i − −, − − i bin¨are Operatoren (Operatoren, die zwei Operanden bewerten) + Addition x = y + z; − Subtraktion x = y − z; ∗ Multiplikation x = y ∗ z; / Division x = y/z; % modulo (Rest einer Division) x = y%z; < kleiner als x < y > gr¨oßer als x > y <= kleiner oder gleich x <= y >= gr¨oßer oder gleich x >= y == gleich i == 1 ! = ungleich i! = 1 && logisches UND (i == 1)&&(j == 1) || logisches ODER (i == 1)||(j == 1) Zuweisungsoperatoren = Zuweisung i = 1; + = Zuweisung und Addition i+ = 2; − = Zuweisung und Subtraktion i− = 2; ∗ = Zuweisung und Multiplikation i∗ = 2; / = Zuweisung und Division i/ = 2; % Zuweisung und modulo i% = 2; =? : bedingte Zuweisung y = (x >= 0)?1 : −1;

Tabelle 8.2: Operatoren in C

Beuth Hochschule fur¨ Technik Berlin 196 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C

Operator Beschreibung Beispiel Bitoperationen & logisch UND (bitweise) & = logisch UND (bitweise) | logisch ODER (bitweise) | = logisch ODER (bitweise) ˆ logisch XOR (Exklusiv-ODER) ˆ= logisch XOR (Exklusiv-ODER) ˜ Einerkomplement << Shift Left (Linksschieben) >> Shift Right (Rechtsschieben)

Tabelle 8.3: Operatoren in C (Fortsetzung)

Besonders h¨aufig werden die Logik-Operatoren && (AND), || (OR) und ! (NOT) ver- wendet. Fur¨ die Programmierung von Mikrocontrollern sind zudem die Bit-Operatoren & (AND), | (OR),ˆ(XOR),˜(Inverter), >> (Shift Right) sowie << (Shift Left) inter- essant. Diese Operatoren werden h¨aufig benutzt in Software Engineering fur¨ Embedded Systems und Steuerung. Abschnitt 8.1.3 zeigt die Anwendung der Bit-Operatoren.

AND OR XOR Inverter AB A&B A | B AˆB ˜B 0 0 0 0 0 1 0 1 0 1 1 0 1 0 0 1 1 1 1 1 1 1 0 0

Tabelle 8.4: Anwendung logischer Operatoren in C

8.1.4 Datentypen in C Der C-Standard definiert einige Grund-Datentypen, die vom Compiler unterstutzt¨ wer- den mussen.¨ Mit Hilfe dieser Datentypen k¨onnen andere, komplexe Datentypen erstellt werden. Abschnitt 8.1.4 stellt die Grund-Datentypen und ihre Bitbreiten dar.

Beuth Hochschule fur¨ Technik Berlin 197 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C

Name Gr¨oße char 8 Bit, Wertebereich 0 bis 255 unsigned char wie char signed char 8 Bit, Wertebereich -128 bis +127 short 16 Bit, Wertebereich -32768 bis 32767 long 32 Bit, Wertebereich -214783648 bis +2147483647 unsigned long 32 Bit, Wertebereich 0 bis 4294967295 float 32 Bit, IEEE-Format unsigned char bit 1 Bit int Abh¨angig vom Zielsystem unsigned int wie int, jedoch ohne Vorzeichen sbit 1 Bit, spezifisch fur¨ 8051 und C51-Compiler sfr 0 bis 255, spezifisch fur¨ 8051 und C51-Compiler

Tabelle 8.5: Datentypen in C

Der Datentyp int“ nimmt eine Sonderrolle ein, da dessen Bitbreite vom Compiler ” und Zielsystem abh¨angig und somit nicht fest definiert ist. Weiterhin wird durch den Standard garantiert, dass die Anzahl der Bits in int“ gr¨oßer / gleich der Gr¨oße von ” short“ und kleiner / gleich der Gr¨oße von long“ ist. Dementsprechend kann die Gr¨oße ” ” von int“ zwischen 16 Bit ( short“) und 32 Bit long“ variieren. ” ” ” Moderne Compiler, die fur¨ x86-CPUs Bin¨arcode generieren, legen fur¨ int“ h¨aufig ” 32 Bit fest. Fur¨ Mikrocontroller erzeugter Code weicht hiervon in der Regel ab. Mikrocontroller verarbeiten Ganzzahlen (Integers) eines definierten Datentyps, n¨amlich abh¨angig von ihrer nativen, durch die Architektur definierten Bitbreite. 8051 Mikro- controller sind 8-Bit Mikrocontroller, der Befehlssatz des Mikrocontrollers ist daher fur¨ 8-Bit-Operationen optimiert. Dass fur¨ den Integertypen keine feste Bitbreite definiert ist, kann bei 8-Bit Mikrocon- trollern unter Umst¨anden zu Problemen fuhren.¨ Dies sei anhand des folgenden Beispiels demonstriert. Dieser C-Code beschreibt ein Programm, das auf einem Mikrocontroller laufen soll.

INT x, y, z; VOID f () { z = x + y; }

Die Funktion wird vom C-Compiler in folgende 8051-Befehle ubersetzt.¨ Da wie oben beschrieben in der Umwandlung von 16 Bit ausgegangen wird, muss die Rechnung in Portionen von 8 Bit aufgeteilt werden.

Beuth Hochschule fur¨ Technik Berlin 198 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C

MOV A, x +01h ADD A, y +01h MOV z +01h, A MOV A,x ADDC A,y MOV z,A RET

Hier ist die gleiche Funktion fur¨ einen 16-Bit Mikrocontroller (z.B. 80C166) darge- stellt. Die 16 Bit Operationen k¨onnen direkt abgebildet werden. Die Ausfuhrungszeit¨ ist kurzer¨ bei gleicher Code-Gr¨oße (12 Byte).

MOV R4, x ADD R4, y MOV z, R4 RET

Die spezifischen Eigenarten der Zielhardware gilt es also stets zu beachten, wenn man auf abstrakterem Level Operationen auf Daten beschreibt. Ein gutes Verst¨andnis von C Datentypen fur¨ den 8051 Mikrocontroller kann Programmierern helfen, effizientere Programme und damit kleinere HEX-Files zu erstellen. Konkret bedeutet dies, dass bei der Deklaration von Variablen immer der Typ char“ ” bzw. unsigned char“ (beide 8 Bit, Wertebereich 0-255, bzw. 00-FFh) zu bevorzugen ” ist, wenn der Wertebereich dies denn zul¨asst. Es ist der am weitesten verbreitete Da- tentyp fur¨ den 8051 und findet beispielsweise Verwendung fur¨ Z¨ahlerwerte oder die Darstellung von ASCII-Zeichen. C-Compiler benutzen signed char“ als Grundeinstel- ” lung, wenn nicht explizit das Schlusselwort¨ unsigned“ hinzugefugt¨ wird. Da Register- ” und Speicherzugriffe in 8-Bit Bl¨ocken vorgenommen werden, fuhrt¨ der Missbrauch von Integervariablen (mind. 16 Bit) nahezu immer zu gr¨oßeren HEX-Dateien. Fur¨ Mikrocontroller, insbesondere den weitverbreiteten 8051, steht eine Auswahl an speziellen C-Compilern zur Verfugung.¨ Diese fur¨ Mikrocontroller angepassten Compi- ler verfugen¨ uber¨ Erweiterungen, um einen effizienten und vollst¨andigen Zugriff auf die Architektur des Bausteins zu erm¨oglichen. Unter anderem existieren spezifische Daten- typen fur¨ die 8051 Hardware, die eine Erweiterung des ANSI-C Standards18 darstellen. Zur direkten Unterstutzung¨ der 8051-Architektur verfugt¨ ein C51-Compiler beispiels- weise uber¨ die Datentypen sfr“ und sbit“. Der Datentyp sbit“ erlaubt beispielsweise ” ” ” den Zugriff zu den einzelnen Bits des bitadressierbaren Speicherraums 20-2Fh. Um auf die bytegroßen SFR Register zuzugreifen, wird der Datentyp sfr“ benutzt. Auf die ” Mikrocontroller-Compiler wird sp¨ater noch einmal Bezug genommen.

8.1.5 C Programmaufbau fur¨ Mikrocontroller Ein in C geschriebenes Programm setzt sich im einfachsten Fall aus einer einzelnen Funktion zusammen. Es besteht weiterhin die M¨oglichkeit aus einer Funktion heraus weitere Funktionen aufzurufen. Hierauf wird im Folgenden jedoch nicht weiter einge- gangen.

18In Anlehnung an den 8051 wird dieser erweiterte C-Compiler als C51 bezeichnet.

Beuth Hochschule fur¨ Technik Berlin 199 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C

Damit der Compiler einen korrekten Einsprungspunkt setzen kann, existiert in C die zentrale Funktion main()“. Diese ist fur¨ C-Programmierer Anfang und Ende des Pro- ” gramms. Im allgemeinsten Fall ist sie wie folgt definiert:

INT main(INT argc,CHAR *argv[]) {

// Programmcode

RETURN 0; }

Die Funktion main“ (gewissermaßen das Hauptprogramm) gibt fur¨ diesen Fall einen ” Wert vom Typ int“ zuruck¨ (erstes int“ vor main“), welcher vom Betriebssystem ” ” ” verarbeitet wird. Ebenso werden der Funktion zwei Argumente ubergeben,¨ welche dazu dienen die Argumente der Kommandozeile im Programm zu repr¨asentieren (Teil hinter main“). ” Da bei der Programmierung von Mikrocontrollern kein Betriebssystem verwendet, son- dern die Hardware direkt angesprochen wird, kann man fur¨ diesen Fall main“ auf die ” folgende Darstellung reduzieren:

VOID main(VOID){

// Programmcode

}

Der Datentyp void“ ist hierbei ein Platzhalter und gibt an, dass main“ fur¨ die- ” ” sen Fall weder Parameter ubernimmt¨ (zweites void“ hinter main“), noch einen ” ” Ruckgabewert¨ (erstes void“) besitzt. Damit resultiert ein freistehendes Programm, ” das niemals zuruckkehrt¨ (wohin auch?) und somit keinen Ruckgabewert¨ ben¨otigt. Ferner zeichnen sich Mikrocontroller-Programme dadurch aus, dass sie niemals enden. Das Hauptprogramm main()“ muss also immer eine Endlosschleife enthalten. Ohne ” explizite Anweisung einer solchen wurde¨ es zu einem Soft Reset kommen, d.h. der Con- troller wurde¨ das komplette Programm (Startup-Routine) neu aufrufen. Nachfolgend ist ein Beispiel fur¨ ein Programm gegeben, das zun¨achst beispielhaft eine Iterations- schleife durchl¨auft, um dann in einer Endlosschleife zu enden.

VOID main (VOID) {CHAR i; FOR(i=10; i>0; i--) { // weitere Befehle } WHILE(1);// Endlosschleife }

In der Regel geh¨oren zum Aufbau eines C-Programms noch Anweisungen fur¨ den Pr¨aprozessor (z.B. Einbindung von C-Bibliotheken), die Definition von globalen Varia- blen (Definition von im Programm verwendeten Variablen), sowie optional zus¨atzliche,

Beuth Hochschule fur¨ Technik Berlin 200 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C selbst geschriebene Funktionen (Aufbau ¨ahnlich dem Hauptprogramm). Beim Ubersetzen¨ generiert der Compiler selbst¨andig den Startup-Code, den er vor dem User-Programm einfugt.¨ Der Startup-Code definiert den Stackbereich, setzt den Stack- pointer, initialisiert die Variablen, setzt Interruptvektoren und springt zum Hauptpro- gramm main()“. ” 8.2 Programmierung des 8051 mit C

Die Programmierung eines Mikrocontrollers in der Sprache C unterliegt einigen Be- sonderheiten. Diese sind bedingt durch die N¨ahe zur Hardware. Zum einen gilt es, die limitierten Ressourcen wie Speicher, Rechenleistung und Geschwindigkeit bei der Pro- grammierung zu berucksichtigen.¨ Zum anderen muss - sofern der eingesetzte Mikro- controller dies unterstutzt¨ - ein bitweiser Zugriff auf Speicherstellen und I/O-Ports gew¨ahrt werden. Der 8051 zeichnet sich durch einige Eigenarten aus, die in diesem Zusammenhang es- sentiell sind. Es ist ein 8-Bit Mikrocontroller. Die Bitbreiten von Datentypen wie z.B. int“ sind, wie bereits vorab diskutiert, durch den Compiler festgelegt und mussen¨ ” nicht zwangsl¨aufig den Bitbreiten der konkret eingesetzten Prozessoren bzw. Mikro- controllern entsprechen. Der Befehlssatz des 8051 umfaßt Befehle zur Bearbeitung des Inhalts einzelner Bits (z.B. bestimmte Speicherstellen oder Ein-/ Ausgabeleitungen). Ferner sind I/Os und die verfugbaren¨ On-Chip Komponenten uber¨ spezielle Funktionsregister ansprechbar. Der ANSI-C Standard verbietet in der Regel den direkten Zugriff auf Register außerhalb eines zul¨assigen Bereiches. Um diese Problematik zu umgehen und z.B. auf Funktions- register des 8051 zugreifen zu k¨onnen, wurden die Compiler entsprechend erweitert. Auf diese speziellen C-Compiler wurde bereits verwiesen. Diese sind nicht mehr stan- dardkonform. Hinsichtlich der Limitierung der Ressourcen ist zu beachten, dass der 8051 uber¨ maxi- mal 64 kB externen und maximal 256 Byte internen Speicher verfugt.¨ Ebenso erfolgt eine Unterteilung in zwei separate Segmente, n¨amlich Data und Code.

8.2.1 Auswahl des richtigen Compilers Fur¨ den 8051 Mikrocontroller existiert eine Reihe von C Compilern. Dazu z¨ahlen µVision IDE (Keil), der Small Device C Compiler (SDCC, Open Source Projekt) so- wie der µC51 (Fa. Wickenh¨auser). Bei der Auswahl eines geeigneten Compilers sollte auf dessen Funktionsumfang und ggf. auf den Preis geachtet werden. Weiterhin ist die Qualit¨at des erzeugten Codes entscheidend, diese l¨asst sich jedoch oftmals nur schwer bestimmen. Von den kommerziell erh¨atlichen Compilern gibt es in der Regel Evaluationsversionen, die durch die maximal erzeugbare Codegr¨oße limitiert sind. Bspw. kann die Evaluati- onsversion des Compilers von Keil maximal 2 kB großen Code erzeugen, w¨ahrend der Compiler der Firma Wickenh¨auser in dieser Variante 8 kB großen Code erzeugen kann. Die Gr¨oße des erzeugten Codes kann dabei als Maß fur¨ die Code-Qualit¨at angesehen

Beuth Hochschule fur¨ Technik Berlin 201 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C werden. Einsteigern wird empfohlen, eine vollst¨andige Entwicklungsumgebung (IDE, engl. In- tegrated Design Environment) zu verwenden. Hier eignen sich µVision2 und µC51. Die Verwendung des SDCC erfolgt im Allgemeinen uber¨ die Kommandozeile. Eine Integra- tion in frei verfugbare¨ IDEs wie z.B. Eclipse ist jedoch ebenfalls m¨oglich.

8.2.2 Verwendung von Special Function Registern Verwendet man systemnahe Hochsprachen (wie z.B. die Sprache C) in Verbindung mit einem Mikrocontroller, so werden vom Hersteller Bibliotheken zur Programmie- rung bereitgestellt. Diese sind notwendig, um die Schnittstellen des Mikrocontrollers zu steuern. Die angesprochene Portabilit¨at geht hierbei in Teilen verloren, da unterschiedliche Mikrocontroller eine unterschiedliche Schnittstellenansteuerung aufweisen. Ist das Pro- gramm jedoch modular aufgebaut, so muss bei einer Portierung lediglich der Code angepasst werden, der zur Schnittstellenansteuerung notwendig ist. Zur Steuerung der auf dem Chip integrierten Hardware und I/Os des 8051 dienen die Special Function Register (SFR), die einen 128 Byte großen Bereich im internen RAM des 8051 umfassen. Aus der Anwendung mit Assembler ist bekannt, dass sie SFRs wie normale Speicherzellen angesprochen werden. Zu diesem Zweck hat jedes SFR einen eindeutigen Namen, unter dem es im Programm angesprochen werden kann. Fur¨ eine ubersichtliche¨ Programmierung k¨onnen die SFRs in C durch Inkludieren einer Header-Datei angesprochen werden. In dieser Header-Datei ist die korrekte Zuordnung der Adresse zum symbolischen Namen des Registers vorgenommen. Der Name der Include-Datei entha?lt meist Teile der IC-Bezeichnung. Fur¨ den 8051 Mikrocontroller ist das die Datei reg51.h“. Das entsprechende Code-Fragment sieht wie folgt aus: ”

#INCLUDE

VOID main (VOID)//Beginn des Hauptprogramms { //...... }

Nachfolgend ist ein Auszug aus der Header-Datei fur¨ die Register-Namen-Zuordnung ( reg51.h“) dargestellt. ”

/*------REG51.h ------*/

/*BYTE Register*/ sfr P0 = 0x80; sfr P1 = 0x90; sfr P2 = 0xA0; sfr P3 = 0xB0; sfr PSW = 0xD0; sfr ACC = 0xE0; sfr B = 0 xF0 ; sfr SP = 0x81;

Beuth Hochschule fur¨ Technik Berlin 202 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C

sfr DPL = 0x82; sfr DPH = 0x83; sfr PCON = 0x87; sfr TCON = 0x88; sfr TMOD = 0x89; sfr TL0 = 0x8A; sfr TL1 = 0x8B; sfr TH0 = 0x8C; sfr TH1 = 0x8D; sfr IE = 0xA8; sfr IP = 0xB8; sfr SCON = 0x98; sfr SBUF = 0x99;

Diese Header-Datei ist erweiterbar, so dass auch neue SFRs oder SFRs mit eigenen Namen erstellt werden k¨onnen. Der bitweise Zugriff auf Register ist unter Compiler- Herstellern allerdings nicht einheitlich gel¨ost. So existieren keine Standard-Namen fur¨ einzelne Bits der I/O-Ports (z.B. Port 0, Bit 4). Oft ist dies also nur durch einen Blick in die Header-Dateien selbst zu l¨osen.

8.2.3 Ein- Ausgabeoperationen in C Die soeben vorgestellte Header-Datei enth¨alt Deklarationen der SFRs und somit die Bezeichnungen P0, P1, usw. fur¨ die I/O-Ports. Dies erleichtert den Zugriff auf die Register des 8051. Zun¨achst zeigt Abbildung 8.1 wie die Werte 00-FFh an P1 gesendet werden.

#include void main(void) 1. Achte auf die Größe der Daten { 2. Versuche unsigned char anstatt int zu benutzen unsigned char z; for (z=0;z<=255;z++) P1=z; }

Abbildung 8.1: Programm mit eingebundener Header-Datei zur Ausgabe an P1

Auch die Ausgabe von ASCII Zeichen anhand ihrer Hex-Werte l¨asst sich so ein- fach realisieren, wie der folgende Ausschnitt zeigt. Die Hex-Werte der ASCII Zeichen 0,1,2,3,4,5,A,B,C,D werden an P1 gesendet.

#INCLUDE VOID main(VOID) { UNSIGNEDCHAR mynum[]="012345ABCD"; UNSIGNEDCHAR z; FOR (z=0;z<=10;z++) { P1=mynum[z]; } }

Beuth Hochschule fur¨ Technik Berlin 203 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C

Um andererseits beispielsweise die Bits an Port P1 kontinuierlich zu toggeln, ist fol- gender Code notwendig.

#INCLUDE VOID main(VOID) { FOR(;;)//toggle P1 fuer immer { p1 =0 x55 ;//01010101 p1 =0 xAA ;//10101010 } }

Meist gehen die gewunschten¨ Anwendungen uber¨ das simple Setzen oder Ausgeben von Werten hinaus. Mit dem folgenden Code geschieht die Abfrage von Daten am Port P0 und deren Auswertung. Ist die gelesene Zahl kleiner als 100, wird sie direkt am Port P1 ausgegeben. Ist sie gleich oder gr¨oßer als 100, so findet eine Weiterleitung an Port P2 statt.

#INCLUDE VOID main(VOID) { UNSIGNEDCHAR mybyte; P0 =0 xFF ;//mache P0 zum input Port WHILE (1) { mybyte =P0;//hole ein Byte von P0 IF (mybyte<100) P1= mybyte ;//sende es zu P1 ELSE P2= mybyte ;//sende es zu P2 } }

Zu beachten ist, dass hier bewusst der Datentyp unsigned char“ fur¨ die Variable byte“ ” ” gew¨ahlt worden ist. D.h. es wird implizit davon ausgegangen, dass die Daten an P0 niemals negative Zahlen repr¨asentieren sollen. Fur¨ denn Fall, dass negative Zahlen zu lesen sind, sollte “char“ als Datentyp verwendet werden. Es gibt mehrere M¨oglichkeiten einzelne Bits in C fur¨ den 8051 zu setzen. Als Beispiel soll eine LED, die an Port 0, Bit 0 angeschlossen ist, ein- und ausgeschaltet werden. Dazu dient ein Schalter an Port 3, Bit 2. Die LED ist low-aktiv angeschlossen, d.h. wenn Bit 2 an P3 den Wert 0 (Schalter geschlossen) erh¨alt, leuchtet die LED. Bei Setzen des Wertes 1 leuchtet die LED nicht (Schalter offen). Real ist dies ein g¨angiger Fall, denn bei ge¨offnetem Schalter liegt der Port bedingt durch einen internen Pull-Up- Widerstand auf logisch 1. Die erste M¨oglichkeit den gewunschten¨ Effekt zu erreichen besteht darin, die Datei reg51.h“ zu erweitern. ”

UNSIGNEDCHAR P1 @ 0x90;// Port 1, Byte-Zugriff UNSIGNEDCHAR bit P1_B0 @ 0x90;// Port 1, Bit0 UNSIGNEDCHAR bit P1_B1 @ 0x91;// Port 1, Bit 1, etc.

Beuth Hochschule fur¨ Technik Berlin 204 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C

Der nicht-standardkonforme Operator @ weist hierbei dem entsprechenden Symbol eine Adresse zu. Im Beispiel wird z.B. das Symbol P0 B0“ der Adresse 90h zugewiesen. ” Fortan kann es im Code verwendet werden.

#INCLUDE #DEFINELED P0_B0// Port 0, Bit0 #DEFINE Schalter P3_B2// Port 3, Bit2

VOID main (VOID) { IF (Schalter == 0) { LED = 0; } ELSE { LED = 1;// es geht auch kuerzer:LED= Schalter } }

Zus¨atzlich wurden hier define-Anweisungen eingefuhrt,¨ um die Lesbarkeit des Program- mes zu erh¨ohen. Die zweite M¨oglichkeit einzelne Bits zu manipulieren stellt der Operator ˆ“ dar. Mit ” Hilfe des Datentyps sbit“ und der Notation Pxˆy“ besteht also die M¨oglichkeit ein- ” ” zelne Bits gezielt zu w¨ahlen und zu modifizieren.

//ein einzelnes Bit toggeln #include Ports 0-3 sind bitadressierbar und sbit mybit=P2^4; benutzen den sbit-Datentyp, um auf ein void main(void) einzelnes Bit von P0-P3 zuzugreifen { while (1) { Wir benutzen das Px^y Format, mybit=1; // P2.4 an machen wo x der Port 0,1,2 oder 3 ist mybit=0; // P2.4 aus machen } und y das Bit 0-7 des Ports }

Abbildung 8.2: Programm zum Tooglen eines Bits mittels XOR-Operator

Die Controller-spezifische Datentyperweiterung sbit“ stellt eine Variable mit der Bit- ” breite 1 Bit zur Verfugung.¨ Gleichzeitig erm¨oglicht die XOR-Operation das Toggeln von P2.4, ohne die anderen Bits von P2 zu st¨oren. In Erg¨anzung zu den hier gezeigten Beispielen werden im Unterricht zus¨atzliche Programme behandelt werden.

8.2.4 Timer-Programmierung Fur¨ die Implementierung einer Zeitverz¨ogerung gibt es mehrere M¨oglichkeiten. Zum einen kann einer der Timer des 8051 verwendet werden, zum anderen kann man eine FOR-Schleife benutzen. Die Genauigkeit der implementierten Verz¨ogerung ist jeweils durch die folgenden Parameter beeinflusst: • Design des 8051, d.h. die Anzahl der Maschinenzyklen, um einen Befehl aus- zufuhren¨ sowie die Anzahl der Takte pro Maschinenzyklus

Beuth Hochschule fur¨ Technik Berlin 205 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C

• Taktfrequenz, mit der der 8051 betrieben wird; diese wird in der Regel durch den Quarz an den Pins X1 / X2 bestimmt Bei der Programmierung mit C spielt zudem der Compiler eine entscheidende Rolle, da hierdurch implizit festgelegt wird, wieviele Befehle uberhaupt¨ notwendig sind um z.B. die FOR-Schleife zu konstruieren. Unterschiedliche Compiler produzieren durchaus unterschiedlichen Code. Grunds¨atzlich kann gesagt werden, dass der Einfluss des C- Compilers am wenigsten zu kontrollieren ist.

8.2.4.1 Zeitverz¨ogerung mittels FOR-Schleife Zur Modellierung eines Timers mit Hilfe einer FOR-Schleife kann der folgende Code verwendet werden.

#INCLUDE #DEFINE TIMER_CONST 1275 VOID ms_delay(UNSIGNEDINT);// Funktionsdefinition

VOID main(VOID){ WHILE (1) {//fuer immer wiederholen

P1 = 0 x55 ;// toggle Bits an P1 ms_delay(250);// 250ms delay P1 = 0 xAA ;// toggle Bits an P1 ms_delay(250);// 250ms delay } }

VOID ms_delay(UNSIGNEDINT delay) { UNSIGNEDINT i, j; FOR (i = 0; i < delay; i++) { FOR (j = 0; j < TIMER_CONST; j++) { } } }

Der Programmablauf ist wie folgt: Zun¨achst wird auf P1 der Wert 55h (01010101b) ausgegeben. Anschließend erfolgt eine Verz¨ogerung um 250 ms. Danach wird 0AAh (10101010b) auf P1 gesetzt, gefolgt von einer weiteren Verz¨ogerung von 250 ms. Im Anschluss daran beginnt der Zyklus von vorn, d.h. alle Bits von Port 1 toggeln konti- nuierlich mit einer Verz¨ogerungszeit von 250 ms. Die Realisierung des Delays erfolgt dabei in der separaten Funktion ms delay. Diese ubernimmt¨ die Gr¨oße der Verz¨ogerung in ms als Parameter. Die Funktion selbst besteht aus zwei ineinander verschachtelten FOR-Schleifen. Dabei dient die innere Schleife als Zeitkonstante. Hierzu wurde die Konstante TIMER CONST empirisch ermittelt19. Ein Durchlauf der inneren Schleife erzeugt somit eine Verz¨ogerung von 1 ms. Entsprechend muss die innere Schleife mehrfach durchlaufen werden, um eine gr¨oßere Verz¨ogerung zu erreichen.

19Empirische Ermittlung beispielsweise durch Messung mit einem Oszilloskop

Beuth Hochschule fur¨ Technik Berlin 206 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C

8.2.4.2 Zeitverz¨ogerung mittels Timer Ahnlich¨ wie in Assembler sind auch in C die Hardware-Register zur Timer- Programmierung verwendbar. Die SFRs des 8051 zur Timer-Programmierung sind TMOD, TCON, THx und TLx (Z¨ahlregister). Das nachfolgende Code-Beispiel zeigt erneut das Toggeln an Port 1, jedoch mit einem Hardware-Timer als Delay-Funktion.

#INCLUDE VOID ms_delay(UNSIGNEDINT);// Funktionsdefinition

VOID main(VOID){ WHILE (1) {// fuer immer wiederholen

P1 = 0 x55 ;// toggle Bits an P1 ms_delay(250);// 250ms delay P1 = 0 xAA ;// toggle Bits an P1 ms_delay(250);// 250ms delay } }

VOID ms_delay(UNSIGNEDINT delay) { UNSIGNEDINT start = (UNSIGNEDINT) (65536.0f - (FLOAT)delay * 0.001f * ((11.0592f * 1000000.0f) / 12));

TR0 = 0;// Timer anhalten TH0 = start / 256;// Startwert Hi TL0 = start % 256;// Startwert Lo TMOD = TMOD | 0x01;// Mode 1, 16-Bit, interner Takt TR0 = 1;// Timer starten

WHILE (TF0 == 0);// warte bis Timer abgelaufen TF = 0;// loesche Ueberlauf-Flag

}

Dieser Code scheint zun¨achst komplexer, fuhrt¨ jedoch zu einer h¨oheren Genauigkeit bei der Einhaltung der einzustellenden Zeitspanne. Es ist jedoch zu beachten, dass mit Genauigkeit hier nur die Zeitspanne vom Start des Timers bis hin zum Stoppen gemeint ist. Vorteilhaft in der Programmierung in C ist, dass die Berechnung des Startwertes direkt vom Compiler ubernommen¨ werden kann. Die aufwendige Berechnung des Startwerts bedingt allerdings, dass die Initialisierung des Timers mehr Takte ben¨otigt als die reine Angabe vorab berechneter Werte. Alternativ kann diese Berechnung aber in einer anderen Funktion durchgefuhrt¨ werden, um die Gesamtpr¨azision weiter zu erh¨ohen.

8.2.5 Interrupt-Steuerung Die Interrupt Service Routine (ISR) wird in C durch eine Funktion repr¨asentiert. Um dem Compiler mitzuteilen, dass es sich um eine ISR handelt, wird zus¨atzlich noch das Schlusselwort¨ interrupt“ angehangen. Der Compiler ist somit in der Lage das Interrupt ” Register entsprechend zu programmieren. Die als Interrupt-Funktion deklarierte Funktion muss naturlich¨ mit der jeweiligen Ein- sprungadresse des Interrupts verbunden werden. Diese Aufgabe ubernimmt¨ das Makro IRQ VECTOR“, das in der Header-Datei irq52.h“ definiert ist. Das Makro wird ” ”

Beuth Hochschule fur¨ Technik Berlin 207 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C aufgerufen in der Form IRQ VECTOR(funktion,adresse)“. ” Zur Wiederholung sei in diesem Zusammenhang angemerkt, dass die Interrupt-Logik des Standard-8051 5 Interrupt-Quellen kennt. Derivate k¨onnen weitere Quellen haben, so dass die Header-Datei um zus¨atzliche Quellen erweiterbar ist. Die entsprechenden Bezeichnungen der Interrupt-Quellen und deren Einsprungadressen sind dem jeweiligen Datenblatt zu entnehmen. Hier ist zun¨achst die Header-Datei fur¨ die Interrupt-Adress-Zuordnung gezeigt.

/*------IRQ52.h ------*/

#asm .macro _irq_vector . show .segment @1, org @2 ljmp @3 . hide . endmacro #endasm

#DEFINE _asmline #asmline #DEFINE IRQ_VECTOR(name,loc) _asmline _irq_vector _irq_##name,loc,_##name

// Available Interrupts on 8051/52 with known names(IRQ_ added to avoid conflicts) #DEFINE IRQ_INT0 0x3 #DEFINE TIMER0 0xB #DEFINE IRQ_INT1 0x13 #DEFINE TIMER1 0x1B #DEFINE SERIAL 0x23 #DEFINE TIMER2 0x2B

//END

Das nachfolgende Beispiel soll verdeutlichen wie der Timer eine ISR ausl¨osen kann und somit die Anzahl der while-Schleifen gegenuber¨ dem vorigen Beispiel reduziert wird. Das Zeitintervall wurde fur¨ diesen Fall fest definiert. Das Inkludieren der Header-Datei irq52.h“ zu Beginn des Programms sei zu beachten. ”

#INCLUDE #INCLUDE #DEFINE TIMER_HI (15536 / 256); #DEFINE TIMER_LO (15536 / 256);

IRQ_VECTOR(timer0int, TIMER0);// Festlegen der ZuordnungISR Routine <-> Timer UNSIGNEDCHAR toggle;

VOID timer0int(VOID) interrupt {//ISR Routine TR0 = 0;// Timer stop TH0 = TIMER_HI;// Startwert Hi nachladen TL0 = TIMER_LO;// Startwert Lo nachladen IF (toggle == 1) {// Bits toggeln P1 = 0 x55 ; toggle = 0; }ELSE{ P1 = 0 xAA ; toggle = 1; } TR0 = 1;// Timer wieder starten

Beuth Hochschule fur¨ Technik Berlin 208 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C

}

VOID main(VOID){ toggle = 0;// Globale Variable initialisieren TH0 = TIMER_HI; TL0 = TIMER_LO; TMOD = TMOD | 0x01; TR0 = 1;// Timer starten ET0 = 1;// Timer Interrupt freigeben EA = 1;// Globale Interruptfreigabe

WHILE(1);//"Beenden" verhindern }

In diesem Beispiel wird zun¨achst in main“ die globale Variable “toggle“ und der ” Timer 0 initialisiert. Die nachfolgenden Befehle schalten das Interrupt-System durch die globale sowie individuelle Freigabe ein. Anschließend verharrt das Hauptprogramm in einer Endlosschleife. Die Zuordnung der ISR “timer0int“ zu Timer 0 erfolgt uber¨ die Definition IEQ VECTOR. Bei Ablauf des Timers wird die ISR “timer0int“ aufgerufen, wel- che zun¨achst den Timer zurucksetzt,¨ d.h. anh¨alt und die Startwerte erneut in die Z¨ahlregister l¨adt. Das Uberlaufbit¨ TF0 des Timers muss bei der Verwendung des Inter- rupts nicht vom Programm gel¨oscht werden. Das ist aus der Assemblerprogrammierung ja bereits bekannt. Anschließend wird je nach Status der Variable “toggle“ der Ausgang P1 entsprechend gesetzt. Im Anschluss daran wird der Timer erneut gestartet.

8.2.6 Ansteuerung der RS232-Schnittstelle Aquivalent¨ zur Steuerung der Timer mit C k¨onnen auch Schnittstellen, wie z.B. die RS232-Schnittstelle des 8051 mit C gesteuert werden. Hierzu werden entsprechend die Special Function Register der seriellen Schnittstelle mit den gewunschten¨ Parametern beschrieben. Eine Besonderheit stellt die M¨oglichkeit dar, Zeichenketten direkt mittels printf an die RS232-Schnittstelle zu senden. Dies wird im nachfolgenden Beispiel gezeigt.

#INCLUDE #INCLUDE

VOID main(VOID){ WHILE (1) {

SCON = 0 x52 ;// Mode 1, 8-BitUART, Receive Enable TMOD = TMOD | 0x20;// Timer 1, Mode 2, 8-bit Auto-Reload TH1 = 253;// TH1: Reload-Wert fuer 9600 Baud TR1 = 1;// TR1: Timer1 Run

printf("Hallo Welt\n"); getc ();// Warten auf eine Taste fuer Restart... } }

Hier wird die serielle Schnittstelle in Modus 1 (asynchrone Ubertragung,¨ 8 Datenbits,

Beuth Hochschule fur¨ Technik Berlin 209 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C

1 Start- und 1 Stop Bit) betrieben, die Baudrate liefert Timer 1 (Referenzfrequenz 11,0592 MHz).

8.2.7 Inline-Assembler Neben der reinen Programmierung in C erm¨oglicht die Sprache auch die Verwendung von Assembler innerhalb des Programmcodes. Somit k¨onnen zeitkritische Operatio- nen, die nur durch den Programmierer selbst optimiert werden k¨onnen und nicht dem Compiler uberlassen¨ werden sollen, direkt in Assemblersprachbefehlen im C-Quelltext integriert werden. Die Anwendung kann sich dann auf die Situationen beschr¨anken, in denen es aus funktionalen oder Effizienzgrunden¨ notwendig ist, maschinennah zu programmieren. Generell gibt es zwei M¨oglichkeiten der Integration von Assembler in C: 1. Inline-Assembler: Assembleranweisungen werden direkt in den C-Code integriert (Quellcode enth¨alt somit sowohl C- als auch Assembler-Anweisungen) 2. Assembler-Dateien: Assemblercode befindet sich in eigenen Quellcodedateien; As- semblierung zu Object-Dateien und anschließendes Linken Die Verwendung von Inline-Assembler unterscheidet sich in der Regel je nach eingesetz- tem Compiler. Im Allgemeinen stellt der Compiler ein Schlusselwort¨ zur Verfugung,¨ das den Assembler-Codeblock identifiziert. Uber¨ dieses Schlusselwort¨ kann der Assembler- Codeblock direkt in den C-Quelltext eingefugt¨ werden. Innerhalb dieses Codeblocks gelten dann die Regeln der Assembler-Programmierung, welche ebenfalls abh¨angig vom Compiler sind. Zu beachten ist ebenfalls, dass verschiedene Prozessorarchitekturen grundverschiedene Assembler- und Maschinensprachen haben, so dass jeweils ein zur aktuellen Archi- tektur passender Assembler ben¨otigt wird und die Programme nicht mehr (oder nur unter großen Einschr¨ankungen) portierbar sind. Dies gilt fur¨ beide genannten Varianten (Inline-Assembler und Assembler-Dateien). Aus der Assembler-Umgebung heraus kann auf Variablen und Funktionsnamen des C- Codes zugegriffen werden. Hierzu sind die entsprechenden Namen mit jeweils einem vorangestellten Unterstrich zu versehen. Die Verwendung von Inline-Assembler soll kurz dargestellt werden. Im Beispiel wird der Compiler von Wickenh¨auser verwendet. Dieser stellt zur Kennzeichnung des Assembler- Codeblocks die Schlusselw¨ ¨orter #asm und #endasm bereit. Das folgende Beispiel zeigt die Realisierung einer einfachen Warteschleife als Inline-Assembler Aufruf.

VOID delay(VOID) { # asm// Schluesselwort Assembler, Compiler-spezifisch MOV R0 , DPL Count1: MOV R1, #250 Count2 : NOP NOP DJNZ R1, Count1 DJNZ R0, Count2 RET # endasm// Assembler-Operationen zuende(uC51 Syntax) }

Beuth Hochschule fur¨ Technik Berlin 210 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 8. HARDWARENAHE PROGRAMMIERUNG IN C

Die gezeigte Implementierung stellt ein sehr einfaches aber effektives Mittel dar, um eine definierte Wartezeit zu generieren. Diese wird durch Anwendung zweier verschach- telter Schleifen realisiert. Die Register R0 und R1 fungieren als Schleifenz¨ahler. In der inneren Schleife kommen zwei NOP-Anweisungen zur Anwendung. DJNZ z¨ahlt die Anzahl der Wiederholungen fur¨ jede Schleife. Fur¨ eine einzelne Assembler-Zeile kann ¨aquivalent auch #asmline verwendet werden. In der Anwendung sieht das wie folgt aus.

CHAR c;

VOID AssemblerInCTest(VOID) { c = 100; # asm MOV A, _c INCA MOV _c , A # endasm #asmline NOP }

Damit sind hier nun die Grundlagen der Mikrocontroller-Programmierung in C aus- reichend skizziert. Zum weiteren Studium sei auf die entsprechende Sekund¨arliteratur verwiesen. Entscheidend ist eine ad¨aquate Systematik bei der Entwicklung von C-Code, damit dieser effizient in Assembler ubersetzt¨ werden kann und die limitierten Ressour- cen eines Mikrocontrollers effizient ausnutzt. Letztlich kann nichts die Erfahrung aus vielen Projekten ersetzen. Hier sind bereits einige Denkanst¨oße vermittelt worden, die sich durch eigene Erfahrungen ausbauen lassen.

Beuth Hochschule fur¨ Technik Berlin 211 Prof. Dr.-Ing. Sven-Hendrik Voß 9 Multitasking mit dem 8051

9.1 Idee und Zweck des Multitasking

In vielen Applikationen widmen sich die verwendeten Mikrocontroller einer fest definier- ten Aufgabe und fuhren¨ ein einziges Programm aus, eventuell bestehend aus weiteren Unterprogrammen und Interrupt Service Routinen. Es ist jedoch auch denkbar und je nach Einsatzumgebung sinnvoll, mehrere Aufgaben gleichzeitig zu bearbeiten. Multitasking ist eine Methode, bei der sich mehrere Tasks gemeinsame Verarbei- tungsressourcen, wie etwa den Prozessor, teilen. Der Begriff Task“ ist dabei gleichzu- ” setzen mit dem Begriff Prozess“ oder Aufgabe“. Da hier von einem relativ simplen ” ” Mikrocontroller (mit einer CPU) ausgegangen wird, k¨onnen die Verarbeitungstasks selbstverst¨andlich nicht gleichzeitig, sondern nur zeitlich verschachtelt (quasi-parallel) ausgefuhrt¨ werden. Zwischen den Verarbeitungstasks wird allerdings so schnell hin und her gewechselt, dass der Eindruck entsteht, dass verschiedene Operationen zur selben Zeit durchgefuhrt¨ werden. Diese Methode ist mit und ohne Betriebssystem realisierbar. Gegenstand der im folgenden dargelegten Ausfuhrungen¨ ist der letztgenannte Fall. In verschiedenen Szenarien kann Multitasking nutzlich¨ sein. Insbesondere erm¨oglicht dieses Konzept: • eine Optimierung der CPU-Auslastung • eine ausgeglichene Ressourcenverteilung • alternativ: eine priorit¨atsbasierte Ressourcenverteilung Bezuglich¨ einer Optimierung der Auslastung sind zwei F¨alle zu unterscheiden, die im Folgenden charakterisiert sind. Fall 1: Geringe Auslastung der Rechenressourcen • Der uberwiegende¨ Teil der Rechenzeit bleibt hier ungenutzt • Dieser Fall ist gekennzeichnet durch Inaktivit¨at, d.h. Warten auf (langsame) ex- terne Ereignisse (z.B. Benutzereingaben, Eingabe/Ausgabe-Operationen von Pe- ripheriekomponenten, o.¨a.) • Multitasking erm¨oglicht die Nutzung der Wartezeit eines Prozesses von anderen Prozessen

212 KAPITEL 9. MULTITASKING MIT DEM 8051

Fall 2: Hohe Auslastung der Rechenressourcen • Die Rechenkapazit¨at bzw. -zeit ist hier gr¨oßtenteils ausgelastet • Dieser Fall ist mit dem Warten auf das Ende von laufenden Verarbeitungen ver- bunden • Multitasking erm¨oglicht die Verteilung der Rechenkapazit¨at auf mehrere Pro- zesse (anteilige Rechenzeit) und verhindert so Verz¨ogerungen durch Warten auf Rechenkapazit¨at Fur¨ beide F¨alle gestattet eine ad¨aquate Multitasking-Implementierung also einen Ge- schwindigkeitszuwachs. Dabei gibt es unterschiedliche Methoden der Ressourcenvertei- lung, auf die hier nicht n¨aher eingegangen werden soll.

9.1.1 Konzept des Multitasking Multitasking bedeutet ein quasi-paralleles Ausfuhren¨ von mehreren Prozessen (Pro- grammen, Funktionen) auf einem Prozessor. Da eine echte Parallelit¨at auf einem ein- zelnen CPU-Kern nicht m¨oglich ist, bedient man sich eines Tricks. Dieser Trick besteht in der zyklische Bearbeitung einzelner Prozesse fur¨ jeweils einen kurzen Zeitraum (zwi- schen 1 und 50 ms) und nachfolgender Umschaltung auf den jeweils anderen Prozess. Die verschiedenen Prozesse werden so in kurzen Abst¨anden immer abwechselnd akti- viert, dass der Eindruck der Gleichzeitigkeit entsteht. Man spricht von einer verschach- telten Bearbeitung (engl. Interleaving). Fur¨ den zeitlichen Ablauf dieser verschachtelten Abarbeitung mehrerer Prozesse gibt es unterschiedliche Prinzipien, die im nachfolgenden Unterkapitel erl¨autert werden. Tech- nisch kann die Illusion der Nebenl¨aufigkeit durch Verwendung von Interrupts umge- setzt werden. Den Prozessen wird nach einem festdefinierten Schema anteilig die CPU (also Rechenzeit) zur Verfugung¨ gestellt. Der Wechsel der Prozesse erfolgt dabei in- terruptbasiert, beispielsweise durch Vergabe von Zeitscheiben mittels Timer-Uberlauf.¨ Real bearbeitet der Mikrocontroller immer nur eine Aufgabe zu einem Zeitpunkt. Die Taskumschaltung mittels ISR ist die am h¨aufigsten verwendete Form der Taskums- chaltung (z.B. Ubergang¨ zum n¨achsten Task nach Ablauf der aktuellen Zeitscheibe (Timer-Interrupt).

9.1.2 Schedulingalgorithmen Zur Verteilung und Zuweisung von begrenzten Ressourcen an konkurrierende Prozesse existieren unterschiedliche Methoden. Diese werden durch spezifische Schedulingalgo- rithmen beschrieben, die im Folgenden n¨aher erl¨autert werden. Abbildung 9.1 skizziert zun¨acht die Rolle des Schedulers zur Zuweisung der CPU (also Rechenzeit).

Beuth Hochschule fur¨ Technik Berlin 213 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 9. MULTITASKING MIT DEM 8051

Task 1 Task 2 ... Task n

Scheduler

CPU

Abbildung 9.1: Rolle des Schedulers zur Taskumschaltung

Die Schedulingarten werden nun durch ihre Charakteristika kurz beschrieben.

First Come First Served Dies ist der simpelste Schedulingalgorithmus. Alle Prozesse werden in der Reihenfolge ihres Erscheinens abgearbeitet. Dies ist zwar relativ einfach zu implementieren, lie- fert allerdings schlechte Ergebnisse, wenn beispielsweise zun¨achst sehr lange Prozesse berechnet werden und erst danach kurzere¨ Prozesse zum Zuge kommen.

Shortest Job First Bei diesem Algorithmus wird der Prozess mit der kurzesten¨ Rechenzeit als erstes bear- beitet. Damit kann die durchschnittliche Laufzeit der Prozesse theoretisch zwar deutlich reduziert werden. Allerdings gilt als Voraussetzung fur¨ die Anwendung dieses Algorith- mus, dass die Rechenzeit im Voraus bekannt sein muss. Dies ist bei dem typischen Mikrocontroller-Einsatz in Steuerungs- und Regelungsaufgaben aber leider meist nicht der Fall (vgl. auch Pipelining-Problematik auf Mikrocontrollern in Abschnitt 3.4).

Shortest Remaining Time Next Bei dieser Variante wird der Prozess mit der kurzesten¨ verbleibenden Rechenzeit jeweils als n¨achstes bearbeitet. Auch hier muss diese Zeit naturlich¨ vorab bekannt sein, was problematisch sein kann.

Round Robin Die grundlegende Idee bei diesem Algorithmus besteht darin, jedem Prozess eine be- stimmte (gleich große) Zeitspanne zuzuweisen, in der er aktiv sein darf. Ist diese Zeit abgelauen, so wird der n¨achste Prozess ausgew¨ahlt. Sind alle Prozesse einmal aktiv ge- wesen, beginnt der Scheduler wieder von vorne. Realisierbar ist solch ein Algorithmus beispielsweise uber¨ eine Liste, die periodisch vom Scheduler durchlaufen wird.

Priority Scheduling Diese Variante erg¨anzt das Round Robin Verfahren durch die Vergabe von Priorit¨aten an Prozesse. Damit sind die abzuarbeitenden Prozesse nicht mehr gleichwertig, sondern h¨oher priorisierte Prozesse werden vom Scheduler bevorzugt behandelt. Damit haben diese Prozesse eine h¨ohere Wahrscheinlichkeit beim n¨achsten Aufruf des Schedulers

Beuth Hochschule fur¨ Technik Berlin 214 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 9. MULTITASKING MIT DEM 8051 ausgew¨ahlt zu werden. Die hier dargelegten Ausfuhrungen¨ sind in der Darstellung naturlich¨ stark vereinfacht. Zur weiteren Vertiefung empfiehlt es sich auf Sekund¨arliteratur zuruckzugreifen.¨

9.2 Multitasking auf dem 8051

Im Folgenden wird die Multitasking-Programmierung anhand eines Beispiels auf dem 8051 Mikrocontroller behandelt. In diesem Zusammenhang sei darauf hingewiesen, dass es sich um eine rudiment¨are Programmierung direkt auf Maschinenebene auf dem 8051 Controller ohne Einsatz eines Betriebssystems handelt. In diesem Beispiel sollen drei Aufgaben, also drei Tasks quasi gleichzeitig ausgefuhrt¨ werden: • Task 1: Ausgabe der aktuellen Uhrzeit auf dem Bildschirm • Task 2: Blinken einer on-board LED im Sekundentakt • Task 3: Stellen von Stunde/Minute, w¨ahrend die ausgegebene Uhrzeit weiterl¨auft

Serielles Kabel

Abbildung 9.2: Beispielapplikation mit drei quasi-parallelen Aufgaben

Abbildung 9.2 illustriert den Aufbau. Da eine CPU zu einem bestimmten Zeitpunkt nur eine Aufgabe bearbeiten kann, ist bei mehreren Tasks eine geeignete Form der Ver- mittlung erforderlich. Ein ubliches¨ Vermittlungsprinzip ist wie bereits zuvor erl¨autert die Vergabe von Zeitscheiben. Dabei belegt beispielsweise Task A den Prozessor fur¨ 5 ms, Task B fur¨ 20 ms usw. Jeder Task bekommt die CPU also fur¨ eine bestimmte Zeit zugeteilt. Der Zeitraum wird in Scheiben definierter L¨ange unterteilt. Dieses Verfahren nennt man pr¨aemptives Multitasking ( pr¨aemptiv“ fur¨ die Eigenschaft, dass vorsorglich“ eine Zeitspanne fur¨ ” ” die jeweilige Aufgabe zur Verfugung¨ gestellt wird). Das Umschalten von einem Task auf einen anderen erfolgt unabh¨angig von der Aktion, die der aktive Task gerade ausfuhrt.¨ L¨auft die Zeitscheibe eines Prozesses ab, so wird dieser unterbrochen und ein anderer Prozess erh¨alt eine Zeitscheibe. Ein Task kann fur¨ die vollst¨andige Abarbeitung einer Aufgabe selbstverst¨andlich mehrere Zeitscheiben ben¨otigen. Der Scheduler weist den einzelnen Prozessen die Zeitscheiben zu. Die Zeitscheiben werden in den folgenden Darstellungen auch als Ticks“ benannt. ” Die Rechenkapazit¨at der CPU wird in eine Vielzahl von Zeitscheiben unterteilt. Diese werden nach einem festen Zeitschema (hier 10ms) rundherum zugewiesen. Dies ist im oberen Teil von Abbildung 9.3 dargestellt. Darunter sieht man wie dieses Zeitsche- ma zur Umschaltung zwischen mehreren Tasks verwendet werden k¨onnen. Gem¨aß des

Beuth Hochschule fur¨ Technik Berlin 215 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 9. MULTITASKING MIT DEM 8051 pr¨aemptiven Verhaltens geschieht dies als Zwangsumschaltung im Round Robin Ver- fahren, was relativ leicht uber¨ die Counter/Timer Bl¨ocke des 8051 realisiert werden kann.

10 ms 10 ms 10 ms

10 ms 10 ms 10 ms

Abbildung 9.3: Task-Steuerung anhand von Ticks

Abbildung 9.4 stellt den unteren Teil der soeben gezeigten Grafik noch etwas genauer da. Hier sieht man einen Ausschnitt aus dem 10ms Raster, das in mehrere Zeitscheiben unterteilt ist. Pro Zeitscheibe wird ein Task bearbeitet. Nach Ausfuhrung¨ der drei Tasks nacheinander innerhalb des 10ms-Zeitintervalls beginnt das Schema wieder von vorne.

Task 1 Task 2 Task 3

10 ms

Abbildung 9.4: 10ms Zeitscheibe mit mehreren Tasks

Fur¨ die Umsetzung dieses Schemas wird fur¨ alle Tasks eine Endlosschleife ben¨otigt. Somit wird keiner der Tasks je aus der Bereitschaftskette heraustreten, sondern immer ans Ende wieder angehangen werden, wie in Abbildung 9.4 verdeutlicht. Die Generie- rung des 10ms-Rasters ubernimmt¨ eine eigene Funktionseinheit, die sich eines Timers bedient. Als erstes muss ein Hauptprogramm geschrieben werden, dass zum einen Initialisie- rungsaufgaben ubernimmt,¨ zum anderen den regelm¨aßigen Wechsel zwischen den Tasks innerhalb der 10ms-Schleife vollzieht. Mit dem CALL-Befehl werden die einzelnen Funktionen nacheinander aufgerufen, mit dem RET-Befehl kehren alle aufgerufenen Funktionen schließlich wieder zur Hauptschleife zuruck.¨ Im Folgenden ist das Hauptprogramm dargestellt. Es besteht aus der bereits graphisch dargestellten 10ms-Schleife, sowie einigen Initialisierungsaufgaben.

Beuth Hochschule fur¨ Technik Berlin 216 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 9. MULTITASKING MIT DEM 8051

ORG 00h JMP Main; Sprung in das Hauptprogramm

ORG 30h; Codespeicher ab der Adresse 30h, daISR ; benutzt wird Main :ORL TMOD,#1; Modus1 fuer Timer 0, 16-Bit SETB TR0; Timer0 starten MOV R3,#0; Uhrzeit laden mit konstanten Werten MOV R4,#55h MOV R5,#17h MOV R2,#0 CALL Newline; Ausgabe Wagenruecklauf und Zeilenvorschub

Loop :CALL Wait_Tick; ab hier werden die Tasks alle 10ms ; ausgefuehrt: CALL Tick_LED CALL Update_Clock CALL Getchar CALL Print_Time CALL Hour_Key CALL Min_Key JMP Loop

Abschnitt 9.2 zeigt eine Ubersicht¨ der fur¨ Vermittlungsaufgaben zwischen den Pro- grammteilen verwendeten Register.

Im Quellcode In der Beschreibung R0 Flag a (fur¨ die Ausgabe der Zeit) R1 Flag b (fur¨ das Blinken der LEDs) R2 Tick (Z¨ahler des Timer-0-Flags) R3 Sekunde R4 Minute R5 Stunde R6 Timer1 (selbst definiert) R7 Befehl

Tabelle 9.1: Verwendung von Registern im Programm

Die einzelnen aus dem Hauptprogramm aufgerufenen Routinen werden hier im Folgen- den nun gezeigt. Diese liegen im Programmspeicher an Adresse 40h und folgenden. Fur¨ das scheibchenweise Abarbeiten von Teilaufgaben ist die Erstellung der einzelnen 10ms Zeitintervalle entscheidend. Daher wird zun¨achst deren Generierung betrach- tet.

;____|____|____|____|____ Generierung

Wait_Tick : JNB TF0, Wait_Tick; solange in der Schleife verweilen wie ; das Timer-Flag TF0LOW ist CLR TF0; ansonsten das Timer-Flag TF0 loeschen MOV TH0, #0DCh; Wert fuer 10ms(High Byte) INC R2; Tick erhoehen RET; Ruecksprung zum Hauptprogramm

Beuth Hochschule fur¨ Technik Berlin 217 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 9. MULTITASKING MIT DEM 8051

Diese Funktion dient als Zeitgeber fur¨ die Zeitbasis Tick (10ms). Sie nutzt den Timer0, der uber¨ das zugeh¨orige Timer-Flag alle 10 ms eine Unterbrechung ausl¨ost. Zu diesem Zweck wird jeweils darauf gewartet, dass das Timer-Flag 0 auf High gesetzt wird. Solange dies nicht geschieht, bleibt es in der Schleife. Wird jedoch nach 10ms beim Ubergang¨ des Maximalwertes auf 0 im Z¨ahlregister das Flag TF0 gesetzt, kann das Programm weiterlaufen, das Z¨ahlregister wieder neu auf 10ms gesetzt und der Tick (Z¨ahler) erh¨oht werden. Task-Perioden sind Vielfache der Zeitbasis (10ms, 20ms, 30ms, ...). Fur¨ 10 ms gilt folgender Startwert:

 1  216 − 10 · 10−3s · (11, 0592 · 106 )/12 = 56320 = DC00h (9.1) s Die Funktion Tick LED ist fur¨ das Blinken zust¨andig. Der Abstand betr¨agt hier jeweils eine Sekunde. Dies wird durch Flags realisiert, wie in Abbildung 9.5 verdeutlicht.

LED = an

1000 ms (= 100 ticks)

50 ms (= 5 ticks)

Flag b = 1 Flag b = 0 Flag b = 1 Timer1 = 0

bei jedem Tick: Timer1 ++

Abbildung 9.5: Steuerung des LED Blinkens anhand von Ticks

Zu Beginn einer jeden Sekunde wird in das Register Flag b im Unterprogramm Upda- te Clock eine 1 geschrieben. Das Unterprogramm Tick Led uberpr¨ uft¨ bei jedem neuen Tick ob dieses Register nun den Inhalt 1 hat oder nicht. Ist es nicht der Fall, dann verl¨asst es sofort wieder dieses Programm. Ist jedoch die 1 vorhanden, wird die LED eingeschaltet und der Timer 1 hochgez¨ahlt, bis er die 5 erreicht, was 50ms entspricht. Anschließend wird die LED wieder ausgeschaltet, das Flag b gel¨oscht und der Timer 1 zuruckgesetzt.¨ Dabei zu beachten ist, dass die LEDs active low“ angesteuert werden. ”

Tick_LED : CJNE R1, #1, Exit1; wenn das Flagb nicht den Inhalt1 hat, ; wird sofort abgebrochen CLR P1.7; ansonsten(Flagb= 1)LED an INC R6; den Timer1 um1 erhoehen MOV A, R6; den Timer1 in den Akku laden CJNE A, #5, Exit1; Pruefung ob der Akku die5 erreicht hat,

Beuth Hochschule fur¨ Technik Berlin 218 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 9. MULTITASKING MIT DEM 8051

; wenn nicht: Sprung zum Exit1 SETB P1.7; nach den 50ms wird dieLED angemacht MOV R1, #0; das Flagb geloescht MOV R6, #0; und der Timer1 auf0 zurueckgesetzt

Exit1 : RET; Ruecksprung zum Hauptprogramm

Update Clock ist jenes Element des Programmes, das fur¨ die Aktualisierung zust¨andig ist. Hier werden sowohl die beiden selbstdefinierten Flags, als auch der Tick-Z¨ahler auf ihre Ursprungswerte zuruckgesetzt¨ und die Zeit jede volle Sekunde erh¨oht.

Update_Clock: MOV A, R2; Tick in Akku laden CJNE A, #100, Exit_Clock; Ueberpruefung ob bereits 100 Ticks ;(also 1000ms=1s) abgelaufen sind, ; falls nicht, Abbruch MOV R2, #0; ansonsten Tick wieder auf0 setzen MOV R0, #1; Flag fuer die Ausgabe der Zeit MOV R1, #1; Flag fuerLED blinken MOV A, R3; Sekunde in Akku laden ADD A, #1;1 zum Akku addieren DAA; Dezimalkorrektur des Akkus fuer die ;BCD-Ausgabe MOV R3, A; Akku zurueck in Sekunde laden CJNE A, #60H, Exit_Clock; Ueberpruefung ob 60(Sekunden) ; erreicht sind, falls nicht, Abbruch MOV R3, #0; ansonsten die Sekunden zuruecksetzen

MOV A, R4; gleiches Verfahren fuer Minute ADD A, #1 DAA MOV R4, A CJNE A, #60H, Exit_Clock MOV R4, #0

MOV A, R5; gleiches Verfahren fuer Stunde ADD A, #1 DAA MOV R5, A CJNE A, #24H, Exit_Clock MOV R5, #0

Exit_Clock: RET

Der folgende Ausschnitt zeigt die Funktion zur Ausgabe der Zeit auf dem Terminal.

Print_Time: CJNE R0, #1, Exit_Print; wenn das Flaga nicht den Inhalt1 ; hat,Abbruch MOV R0, #0; ansonsten Flaga loeschen

Update : MOV A, #13;CR(Wagenruecklauf) in den Akku laden CALL Cout; Ausgabe an der seriellen Schnittstelle

MOV A, R5; die Stunde in den Akku laden CALL Phex; Ausgabe der umcodierten Zeit an der ; seriellen Schnittstelle MOVA,#’:’;’:’ in den Akku laden CALL Cout; Ausgabe an der seriellen Schnittstelle

Beuth Hochschule fur¨ Technik Berlin 219 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 9. MULTITASKING MIT DEM 8051

MOV A, R4; gleiche Verfahren fuer Minute CALL Phex MOVA,#’:’ CALL Cout

MOV A, R3; gleiche Verfahren fuer Sekunde CALL Phex

Exit_Print: RET; Ruecksprung zum Hauptprogramm

Zur Aktualisierung der Zeitausgabe im Sekundentakt wird Flag a wie in Abbildung 9.6 gezeigt jede Sekunde gesetzt. Die Abbildung verdeutlicht zudem wie die Unterpro- gramme Wait Tick, Update Clock und Print Time zusammenarbeiten. Denn nach 100 Ticks (also 1000ms = 1s), die in Wait Tick in jedem Schleifendurchgang um eins erh¨oht werden, wird innerhalb des Unterprogramms Update Clock das Register Flag a mit 1 geladen, um dem Unterprogramm Print Time zu signalisieren, dass jetzt eine Sekun- de vergangen ist. Ist diese Information vom Unterprogramm verarbeitet, l¨oscht es das Flag a sofort wieder und die Zeit wird neu auf dem Bildschirm im Format 17:55:00 ausgegeben.

1000 ms (= 100 ticks)

Flag a = 1 Flag a = 0 nach 100 Ticks gelöscht durch PRINT_TIME Flag a = 1 (noch vor dem ersten Tick)

Abbildung 9.6: Aktualisierung der Zeit anhand von Ticks

Um das Einstellen von Stunde/Minute zu erm¨oglichen (w¨ahrend die Ausgabe der ak- tuellen Uhrzeit naturlich¨ weiterl¨auft), muss die serielle Schnittstelle im entsprechenden Raster ebenfalls abgefragt werden. Der im Folgenden gezeigte Ausschnitt dient der zyklischen Uberpr¨ ufung¨ des seriellen Ports im Abstand von 10ms.

Getchar : JNB RI,Exit2; wennRI-BitLOW ist, Abbruch CLRRI; falls nicht, wird es geloescht MOVA,SBUF; Daten werden empfangen MOV R7,A; der Akku wird nach Befehl kopiert RET; Ruecksprung zum Hauptprogramm

Exit2 : MOV R7,#-1; -1 wird in Befehl geladen RET

Dieses Unterprogramm wird mit einer Fallunterscheidung beendet. Entweder es wurden keine Daten empfangen, dann wird im Befehl eine -1 (No Character) geschrieben oder es wurden Daten empfangen, dann wird ein Zeichen im ASCII-Code geschrieben. Zur

Beuth Hochschule fur¨ Technik Berlin 220 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 9. MULTITASKING MIT DEM 8051

Erinnerung: fur¨ den Empfang von neuen Daten muss immer wieder die Bedingung RI=0 (Receive Interrupt) zutreffend sein. Das Kommando h“ zum Stellen der Uhrzeit (Stunde, engl. hour“) l¨asst sich folgen- ” ” dermaßen auswerten.

Hour_Key : MOV A, R7; in den Akku den Befehl laden CJNE A, #’h’, Exit_Hour; Ueberpruefung ob im Akku’h’ steht, ; wenn nicht, Abbruch MOV A, R5; Stunde in Akku laden ADD A, #1; Akku um eins erhoehen DAA; Dezimalkorrektur des Akkus fuer ; dieBCD-Ausgabe MOV R5, A; Akkuinhalt zurueck in Stunde CJNE A, #24h, Skip_h; Ueberpruefung ob im Akku 24 steht, ; wenn nicht Sprung zu Skip MOV R5, #0; ansonsten wird die Stunde auf0 ; gesetzt

Skip_h : CALL Update; Aufruf des Unterprogrammes Update ; um die neu eingestellte Uhrzeit ; anzuzeigen(beiRET hier zurueck) Exit_Hour : RET; Ruecksprung zum Hauptprogramm

Analog verh¨alt es sich mit dem Kommando m“ zum Stellen der Uhrzeit (Minuten, ” engl. minute“). ”

Min_Key :; gleicher Vorgang mit Minuten MOV A, R7 CJNE A, #’m’, Exit_Min MOV A,R4 ADD A, #1 DAA MOV R4, A CJNE A, #60h, Skip_m MOV R4, #0

Skip_m : CALL Update

Exit_Min : RET

Mit jedem eingegebenen h“ wird jeweils die Stunde inkrementiert und dasselbe ge- ” schieht beim Bet¨atigen der m“-Taste mit den Minuten. Das Besondere hierbei besteht ” darin, dass nach der Inkrementierung das Unterprogramm zum Label Update des Un- terprogramms Print Time springt und die Zeit dadurch sofort neu ausgegeben wird. Abschließend seien hier noch die drei Unterprogramme Newline, Cout und Phex dar- gestellt. Sie werden von den bereits erl¨auterten Programmteilen aufgerufen. Die Funktion Newline gibt direkt am Anfang des Hauptprogramms einen Wa- genrucklauf¨ und Zeilenvorschub aus, d.h. es wird die Erstellung der n¨achsten Zeile bewirkt (vgl. Abschnitt 1.2.4)

Beuth Hochschule fur¨ Technik Berlin 221 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 9. MULTITASKING MIT DEM 8051

Newline : PUSHACC MOV A,#13 ACALL Cout MOV A,#10 ACALL Cout POPACC RET

Die Funktion Cout gibt den Inhalt des Akkus uber¨ die serielle Schnittstelle aus.

Cout : JNB TI, Cout CLRTI MOVSBUF,A RET

Die Funktion Phex wird im Unterprogramm Print Time verwendet, um die Hexade- zimalzahlen in BCD umzuwandeln und uber¨ die serielle Schnittstelle, wiederum mit Hilfe des Unterprogrammes Cout, zu Ubertragen.¨

Phex : Phex8 : PUSHACC SWAPA ANL A,#15 ADD A, #246 JNC Phex_B ADD A,#7

Phex_B : ADD A,#58 ACALL Cout POPACC

Phex1 : PUSHACC ANL A,#15 ADD A, #246 JNC Phex_C ADD A,#7

Phex_C : ADD A,#58 ACALL Cout POPACC RET

Phex16 : PUSHACC MOVA,DPH ACALL Phex MOVA,DPL ACALL Phex POPACC RET

Nachdem alle wesentlichen Bestandteile der Implementierung eines einfachen Multitasking-Schemas auf einem 8051 Mikrocontroller gezeigt wurden, seien hier noch

Beuth Hochschule fur¨ Technik Berlin 222 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 9. MULTITASKING MIT DEM 8051 einmal alle wesentlichen Punkte bzw. Eigenschaften zusammengefasst: • Es sind keine Endlosschleifen fur¨ jeden Task n¨otig • Die Abstimmung und Kommunikation zwischen einzelnen Tasks wurde durch Flags realisiert • Die gesamte Task-Ausfuhrung¨ muss kurzer¨ als 10ms sein • Es wurde das Round-Robin-Verfahren als klassischer Vertreter eines Scheduling- Algorithmus benutzt Die Vorteile dieses Konzepts lassen sich wie folgt umreissen: • Kleine H¨appchen sind verdaulicher als große“ ” • Gr¨oßere Aufgaben werden in kleine Teilaufgaben zerlegt und durch mehrfaches Aufrufen der Funktion abgearbeitet • Tasks haben eine garantierte, maximale Durchlaufzeit • Die maximale Durchlaufzeit der einzelnen Funktionen ist drastisch reduziert • Anstatt beispielsweise bei der LED-Ausgabe einmal 50 ms zu warten wird 5x 10ms gewartet, zwischendurch werden aber 5x die anderen Tasks bearbeitet • Anstatt auf ein ankommendes UART-Zeichen zu warten, wird nur dann etwas bearbeitet, wenn auch wirklich etwas zur Bearbeitung vorliegt

9.3 Multitasking mit Kontextwechsel

Die bisher dargelegten Ausfuhrungen¨ zum Multitasking waren relativ einfach gehal- ten. Fur¨ die gezeigten Aufgaben reichte das auch aus. Sollen diese Prinzipien jedoch allgemein gelten, so muss das Gezeigte auch fur¨ das zyklische Umschalten zwischen komplexeren Aufgaben gelten. Im Idealfall muss der Prozess, der fur¨ einen anderen unterbrochen wird, nichts uber¨ den oder die anderen Prozesse wissen. Das setzt voraus, dass dem Prozess beim Wiederein- setzen erneut eine definierte Umgebung zur Verfugung¨ gestellt wird. Diese Umgebung wird Kontext genannt und umfasst im Wesentlichen die Prozessor-Register des aktuel- len Prozesses, sowie ggf. Informationen uber¨ den Zustand der aktuellen Verarbeitung und Daten. Dieser Kontext wird vor Ablauf der aktuellen, fur¨ den Prozess vorgesehenen Zeitscheibe gesichert und beim Wiedereinsetzen restauriert. Dazu wird sinnvollerweise der Stack genutzt. Beim Umschalten von einem Prozess zum anderen entsteht so ein gewisser Verwal- tungsaufwand (Overhead). Der Overhead, der bei der quasiparallelen Abarbeitung von mehreren Tasks durch die Taskwechsel entsteht, ist im Vergleich zum Geschwindig- keitszuwachs allerdings zu vernachl¨assigen. Abbildung 9.7 symbolisiert die Umschaltung zwischen n Tasks fur¨ die Abarbeitung auf einer CPU. In den sog. TCBs (Task Control Blocks) sind die jeweiligen Taskzust¨ande gespeichert, in den sog. TCDs (Task Control Data) die Daten, Attribute, etc. des jeweilgen Tasks. Jeder Task legt dabei idealerweise seine TCBs und TCDs in einem eigenen Bereich im Datenspeicher ab. Die Vermittlung zwischen den aufzurufenden Tasks l¨auft dann wie folgt ab: • Der Prozessorzustand wird auf den Stack gerettet • Verwendete Register (Daten, Variablen) werden ebenfalls auf den Stack gerettet

Beuth Hochschule fur¨ Technik Berlin 223 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 9. MULTITASKING MIT DEM 8051

1 2 TCD 0 TCD TCB TCD TCB Stack TCB Stack Daten Stack Daten Code Daten Code Code 3 TCD TCB Stack Daten CPU Code 4 n TCD TCD TCB TCB Stack Stack Daten Daten Code Code

Abbildung 9.7: Abarbeitung von Tasks mit gespeichertem Kontext

• Alternativ kann einfach die aktive Registerbank gewechselt werden (geht naturlich¨ nicht mit dem Akkumulator) • Die gew¨ahlte Funktion (Code) wird ausgefuhrt¨ • Variablen (die sich ggf. ge¨andert haben) mussen¨ aus den zugeordneten Registern in den RAM kopiert werden • Registerinhalte werden wieder vom Stack geholt • Der Prozessorzustand wird wieder vom Stack geholt • Mittels RETI-Befehlt wird aus der (Interrupt)-Routine zuruckgekehrt¨ An dieser Stelle sei auf einen kleinen Trick hingewiesen. Durch geschickte Stack- Manipulation plus RETI-Befehl kann nach einer Unterbrechung zu einer beliebigen Adresse verzweigt werden. Dies ist wichtig bei Kontextwechseln fur¨ mehrere Tasks, muss jedoch mit ¨außerster Sorgfalt umgesetzt werden. Berucksichtigt¨ man nun den entstehenden Overhead, so stellt sich naturlich¨ die Frage nach einem m¨oglichst sinnvollen Kompromiss bei der Zeitscheibenzuteilung: Je kurzer¨ die Zeitscheibe, desto geringer die Latenzzeiten, desto l¨anger der Overhead (fur¨ das Retten und Einstellen). Hier muss fur¨ den Einzelfall individuell ein gesunder Kompro- miss gefunden werden.

Beuth Hochschule fur¨ Technik Berlin 224 Prof. Dr.-Ing. Sven-Hendrik Voß 10 Ausblick

10.1 Mikrocontroller-Plattformvarianten

Die Realisierung von Applikationen im Embedded-Bereich kann grunds¨atzlich auf verschiedenen Architekturen erfolgen. Bisher standen ausschließlich Mikrocontroller- Plattformen im Fokus. Beispielhaft wurden hier alle Grundlagen zu Aufbau und Anwen- dung von Mikrocontrollern anhand des 8051 als klassischer 8-Bit Controller erl¨autert.

10.1.1 Wahl der Zielplattform Bereits im Abschnitt Abschnitt 3.4 wurden Mikrocontroller-Klassen unterschiedlicher Komplexit¨at und mit unterschiedlichen Leistungsparametern umrissen. Zusammenfas- send stellt Abschnitt 10.1.1 die Gr¨oßenordnung verschiedener Parameter fur¨ unter- schiedliche Komplexit¨aten dar.

Einfache Anwendungen Komplexe Anwendungen 8 Bit CPU 32 Bit CPU geringe Taktfrequenz (< 15MHz) mittlere Taktfrequenz (< 100MHz) Assemblerprogrammierung Hochsprachprogrammierung (evtl. BASIC oder C) (z.B. C++, Java) nur ganzzahliges Rechenwerk Fließkommarechenwerk sehr kleiner RAM-Bereich (< 1kB) kleiner RAM-Bereich (< 32kB) kleiner (EPR)ROM-Bereich (< 16kB) großer ROM-Bereich (< 512kB) Chip mit ca. 40 - 80 Pins Chip mit ca. 200 - 300 Pins

Tabelle 10.1: Implementierungsvarianten bei unterschiedlicher Komplexit¨at

Die Auswahl einer geeigneten Mikrocontroller-Zielplattform ergibt sich letztlich nach folgenden Kriterien, wobei die Gewichtung der einzelnen Punkte je nach Projekt un- terschiedlich ausfallen kann: • Kosten • Performance • integrierte Peripherie • Stromverbrauch • Programmierbarkeit (Unterstutzung¨ von Hochsprachen) • Support & Entwicklungsumgebung Der nachfolgende Abschnitt liefert zun¨achst eine Ubersicht¨ uber¨ aktuelle, zur Verfugung¨ stehende Mikrocontroller-Plattformen. Anschließend werden alternative Bausteine vor- gestellt.

225 KAPITEL 10. AUSBLICK

10.1.2 Ubersicht¨ g¨angiger Mikrocontroller Fur¨ die Entwicklung kleinerer Systeme werden heute nach wie vor 8-Bit Mikrocontroller bzw. 16-Bit Mikrocontroller mit beschr¨ankten Ressourcen eingesetzt. Die prominentesten Vertreter von 8-Bit Mikrocontrollern sind: • Intel 8051 • Motorola / Freescale 68HC05, 68HC11 • Microchip PIC • Atmel AVR Zu den g¨angigen 16-Bit Mikrocontrollern z¨ahlen folgende konkrete Typen: • Intel 8061 / 8xC196 Familie • Texas Instruments MSP430 • Infineon XC166 Anspruchsvollere Applikationen werden zunehmend auf 32-Bit Plattformen implemen- tiert. Zu diesen z¨ahlen: • Intel XScale • Motorola / Freescale MPC555, MPC860 • ARM / DEC StrongARM • AMD Elan-SC520 (x86-kompatibel) Es sei dabei anzumerken, dass Entscheidungen zugungsten oder gegen eine bestimmte Plattform nicht immer nur durch die fur¨ die Applikation geforderte Performance und Komponentengr¨oße zustande kommen, sondern in der Industrie vielfach auch durch den Preis getrieben sind. Daher kann es u.U. vorkommen, dass z.B. 16-Bit Mikrocontroller zur Anwendung kommen, auch wenn die Applikation dies technisch nicht erfordert, die verwendete Plattform aber in entsprechenden Stuckzahlen¨ kostengunstiger¨ ist als eine 8-Bit Plattform.

10.2 Rekonfigurierbare Hardware als Alternative

Wesentliche Auswahlkriterien fur¨ eine konkrete Zielplattform ergeben sich meist un- mittelber aus der fur¨ die Anwendung relevanten Leistungsparameter und der offerierten Flexibilit¨at der Zielarchitektur. Ganzheitlich betrachtet stellt ein Mikrocontroller nur eine von vielen Implementierungsvarianten dar. Abbildung 10.1 stellt die Flexibilit¨at verschiedener Architekturen ihrer Rechenleistung gegenuber.¨ Gr¨oßtm¨ogliche Flexibilit¨at bieten Universalprozessoren (General Purpose CPUs). Die Rechenleistung ist durch die fest vorgegebene Hardware-Struktur und die sequentielle Programmausfuhrung¨ allerdings begrenzt. Durch die Anpassung und Spe- zialisierung auf bestimmte Algorithmenklassen und Anwendungen lassen sich Rechen- leistung und Ressourcennutzung bei dennoch fester Hardwarearchitektur und sequen- tieller Abarbeitung verbessern. Dieses Konzept wird bei Digitalen Signalprozessoren (DSPs) und Prozessoren mit anwendungsspezifischem Instruktionssatz (Application Specific Instruction Set Processors, ASIPs) zu Lasten einer verringerten Flexibilit¨at umgesetzt. Eine Optimierung auf maximale Rechenleistung und Datendurchsatz liefern rekonfi- gurierbare oder fest verdrahtete Logikbausteine, die s¨amtliche Funktionalit¨at direkt

Beuth Hochschule fur¨ Technik Berlin 226 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 10. AUSBLICK

General-Purpose Prozessoren

Mikrocontroller · DSP · ASIP Spezialisierung, Flexibilität Leistung Programmierbare Hardware · FPGA

ASIC

Abbildung 10.1: Flexibilit¨at vs. Leistung in Hardware implementieren. Unter letztgenannten versteht man kunden- und an- wendungsspezifische integrierte Schaltungen (Application Specific Integrated Circuits, ASICs), die nach der Fertigung nicht mehr modifiziert werden k¨onnen. Die Flexibilit¨at von ASICs ist stark eingeschr¨ankt. Prominente Vertreter rekonfigurierbarer Hardware sind Field Programmable Gate Arrays (FPGAs), deren Leistungsf¨ahigkeit in die N¨ahe anwendungsspezifischer Bausteine kommt und die zudem den Vorteil bieten in ihrer im- plementierten Funktionalit¨at auch nach der Fertigung angepassbar bzw. konfigurierbar zu sein. Die Entwicklung der letzten Jahre l¨asst erkennen, dass der Umfang der zu bew¨altigenden Aufgaben und Anwendungen - insbesondere bei eingebetteten Syste- men - deutlich ansteigen wird. Dies macht die Wahl der richtigen Zielplattform pro Anwendungsfall umso bedeutender.

10.2.1 Unterschiede im Entwurf Je nach gew¨ahlter Implementierungsvariante sind unterschiedliche Design Flows erfor- derlich. Mikroprozessoren zeichnen sich durch eine feste Hardwarearchitektur aus und basie- ren auf der sequentiellen Abarbeitung von Maschinenbefehlen, die auf der Prozessor- Hardware ausgefuhrt¨ werden. Die zu implementierende Funktionalit¨at wird in Software abgebildet. Die Software muss sich der verwendeten Hardware anpassen und kann nur im Rahmen der vorhandenen Hardware-Ressourcen arbeiten. Eine Software-L¨osung erm¨oglicht schnelle Anpassungen an neue Anforderungen und ist damit sehr flexibel. Bei komplexeren Systemen werden h¨aufig Betriebssysteme (z.B. Embedded Linux) ein- gesetzt. Hier muss u.a. der enstehende Overhead (z.B. durch Scheduling) berucksichtigt¨ werden. Je h¨oher der Abstraktionsgrad der Programmiersprache ist, desto geringer f¨allt die Kontrolle uber¨ die Hardware aus. Programmierbare Logikbausteine wie FPGAs bieten dagegen Anpassungsm¨oglichkeiten

Beuth Hochschule fur¨ Technik Berlin 227 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 10. AUSBLICK

Software Hardware Hochsprache C VHDL

Verhaltenssynthese Compiler Register-Transfer-Level

Assemblerbefehle RT-Synthese

Logikgleichungen/FSM Assembler, Linker Logik-Synthese

Maschinenbefehle Logikgatter

Mikroprozessor ASIC, FPGA

Abbildung 10.2: Design-Ebenen der unterschiedlichen Implementierungsvarianten an ver¨anderliche Hardwareanforderungen20, stellen also keine feste Hardwarearchi- tektur dar, sondern sind in Ihrer Logikumsetzung relativ frei konfigurierbar. So erm¨oglichen FPGAs eine parallele Informationsverarbeitung direkt in der Hardware mit sehr hoher Rechenleistung und harter Echtzeitf¨ahigkeit. Neben der hohen Rechenleis- tung stellen FPGAs sehr große Kommunikations- und I/O-Leistungen zur Verfugung.¨ Nur die maskenprogrammierten und damit nicht rekonfigurierbaren ASICs bieten noch mehr Leistungsf¨ahigkeit und Freiheit in der Gestaltung der Hardware. Diese sind je- doch mit erheblich h¨oheren Entwicklungskosten und aufgrund der vollen Kontrolle uber¨ das Silizium mit sehr viel l¨angeren Entwicklungszeiten verbunden. FPGAs und ASICs haben einige Gemeinsamkeiten im Entwurfsprozess. Abbildung 10.2 zeigt die unterschiedlichen Ebenen im Entwurf und der Implementierung. Es existieren Ans¨atze, die Vorzuge¨ von Hardware-basierten L¨osungen wie Geschwin- digkeit, Parallelit¨at und Leistungsverbrauch mit der hohen Flexibilit¨at von Software- basierten L¨osungen zu vereinen. Dies zu erreichen streben sog. Hardware / Software Co- Designs an. Die Herausforderung verlagert sich dabei in die sinnvolle und zielfuhrende¨ Partitionierung zwischen dem Hardware- und dem Software-Teil, d.h. in die Abw¨agung was in Software und was in Hardware realisiert werden muss.

10.2.2 Designentscheidungen im Co-Design Die gesamte Funktionalit¨at eines digitalen Hardware / Software-Systems wird in Software- und bzw. oder Hardwarekomponenten implementiert. Die Entwurfsmetho- dik unterscheidet sich entsprechend von der des klassischen Software- oder Hardware- Entwurfs. Am Anfang des Entwurfsprozesses steht die Spezifikation des Systems. Sie ist Aus-

20Die konkreten Anforderungen k¨onnen Rechen-, Kommunikations- oder I/O-Bedarf betreffen.

Beuth Hochschule fur¨ Technik Berlin 228 Prof. Dr.-Ing. Sven-Hendrik Voß KAPITEL 10. AUSBLICK

Spezifikation

Systemanalyse

HW/SW Partitionierung

Software-Entwurf Hardware-Entwurf

Abbildung 10.3: Design Flow eines HW/SW Co-Design gangspunkt und Grundlage fur¨ die Beschreibung der Funktionalit¨at des Systems und enth¨alt noch keine Informationen uber¨ die konkrete Implementierung bzw. Art und Weise der Realisierung. Diese Informationen werden durch die nachfolgende Systemanalyse gewonnen, in der die Komponenten der Architektur funktional bestimmt und ausgew¨ahlt werden. Dies liefert die Grundlage fur¨ die anschließende Hardware- / Software-Partitionierung, die letztlich definiert welche der Funktionseinheiten in Software und welche in Hardware abgebildet werden sollen. Wesentliche Bewertungskriterien sind dabei die resultierende Gr¨oße (Fl¨ache) und Zeit (Verz¨ogerung) der Implementierung. Sowohl Hardware- als auch Software-Komponenten lassen sich durch eine Vielzahl von Parametern charakterisieren. Dazu z¨ahlen beispielsweise die Anzahl zu verarbeitender Instruktionen pro Zeiteinheit bei Prozessoren, die Gr¨oße der Siliziumfl¨ache bei an- wendungsspezifischen integrierten Schaltungen oder Zugriffszeiten bei Speichern. Die Software-Komponenten k¨onen auf verschiedensten Prozessoren implementiert werden, von einfachen Microcontrollern oder digitalen Signalprozessoren bis hin zu anwendungs- spezifischen Befehlsssatz-Prozessoren. Die Hardware-Komponenten k¨onnen entweder als ASICs oder auch in Form von pro- grammierbaren Hardwarebausteinen wie FPGAs realisiert werden. Fur¨ den Prozess der HW/SW-Partitionierung k¨onnen spezielle Algorithmen herangezogen werden, auf die hier jedoch nicht n¨aher eingegangen werden soll. Hardware / Software Co-Designs werden besonders durch komplexe und zeitkritische Anwendungen motiviert.

ENDE

Beuth Hochschule fur¨ Technik Berlin 229 Prof. Dr.-Ing. Sven-Hendrik Voß Literaturverzeichnis

[Scholz 05] Scholz, P.: Softwareentwicklung eingebetteter Systeme: Grundlagen, Mo- dellierung, Qualit¨atssicherung (Xpert.Press), Springer, Berlin; Auflage: 1, 2005 [Parnas 75] Parnas, D. L. ; Siewiorek, D. P.: Use of the Concept of Transparency in the Design of Hierarchically Structured Systems. In: Communications of the ACM 18 (1975), Jul., Nr. 7, S. 401-408 [Patterson 05] Patterson, David A.: Rechnerorganisation und -entwurf. Munchen:¨ El- sevier GmbH, S. 20, 2005 [Amdahl 64] Amdahl, Gene: Architecture of the IBM system 360. IBM Journal of Research and Development, S. 87-101, 1964 [Hennessy 03] Hennessy, John L.: Computer Architecture - A quantitative approach (3. Ausg.). San Francisco: Elsevier Science (USA), S. 9-10., 2003 [Maertin 03]M ¨artin, C.: Einfuhrung¨ in die Rechnerarchitektur. Leipzig: Fachbuchver- lag Leipzig, S. 11., 2003 [Oberschelp 00] Oberschelp, W.; Vossen, G.: Rechneraufbau und Rechnerstrukturen, 8. Auflage Munchen,¨ Wien: R. Oldenbourg-Verlag, 2000 [Lipp 08] Lipp, Hans Martin; Becker, Jurgen:¨ Grundlagen der Digitaltechnik, 6. Auf- lage, Oldenbourg Verlag, 2008 [Wiegelmann 05] Wiegelmann, J¨org; Klußmann, Niels: Lexikon Elektronik / Grundla- gen, Technologien, Bauelemente, Digitaltechnik, 1. Auflage, Huthig¨ Verlag, 2005 [Herold 10] Herold, Helmut; Arndt, J¨org: C-Programmierung unter Linux, Unix und Windows, 2.Auflage, Nicolaus Millin Verlag GmbH, 2010 [Gulbins 88] Gulbins, Jurgen:¨ UNIX, 3.Auflage, Berlin Heidelberg Springer Verlag, 1988 [Kernighan 78] Kernighan, Brian; Ritchie, Dennis: The C Programming Language, Prentice Hall 1978 (2nd Ed. 1988; deutsch: Programmieren in C) [ANSI 89] ANSI, American National Standard for Information Systems / Program- ming Language C, ANSI X3.159-1989, American National Standards Institute, New York, 1989

230 Beuth Hochschule f ¨urTechnik Berlin

Prof. Dr.-Ing. Sven-Hendrik Voß FB VI, Informatik und Medien

E-mail: [email protected]