Achtung: an dieser Seite wird noch gearbeitet.

Die MCS-51 Mikrocontrollerfamilie

Inhalt

Anhang

Der MCS-51 Standard

Lange Zeit wurde aus den vorhandenen Bauteilen, erst Relais, dann Röhren, später Transistoren und schließlich standard-IC's für jedes Schaltungsproblem eine logische Schaltung entwickelt ohne daß jedoch ein Bauteil zur Verfügung stand, das viele Standardfunktionen ausführen konnte. Als dann universell programmierbare Mikroprozessoren verfügbar wurden, setzte man diese auch in Steuerungen ein. Der wachsende Bedarf nach Steuerungen führte schließlich zur Entwicklung von einfach anwendbaren Prozessoren, die die wesentlichen Mikrokomputerkomponenten wie CPU mit deren Takterzeugung, Timer, Speicher (RAM/ROM/EPROM/EEPROM/FLASH), serielle Schnittstelle und - für Steuerungen besonders wichtig - Interrupts und digitale I/O Ports schon enthalten. Man nennt diese ''Computer auf einem Chip'' Mikrocontroller. Da sie nur Komponenten besitzen, die für Steuerungsaufgaben interessant sind und da durch die Integration auf einem Chip das Gehäuse klein gehalten werden kann, sind die Bauteile relativ billig. Durch ihren Einsatz läßt sich häufig diskrete Hardware durch Software ersetzen , was Schaltungen vereinfacht und so Designkosten und Kosten für Änderungen teilweise erheblich reduziert. Mikrocontroller werden beispielsweise eingesetzt in HiFi- und Haushaltsgeräten (Mikrowelle, Waschmaschine, Fernseher, Videorecorder), Computerzubehör (Drucker, Modem), Meßgeräten, in der Meß- Steuer- Regelungstechnik zur Erfassung von Meßdaten und zur Steuerung, in Klimaanlagen und in zunehmendem Maße auch im Automobil (Motorregelung, ABS, Armaturenbrett mit digitalen Displays). Der Einsatz von Kleincomputern im Automobil ist heute teilweise soweit fortgeschritten, daß die Recheneinheiten schon durch ein kleines Netzwerk (meist CAN-Standard) untereinander verbunden werden. Je nach Anforderungen gibt es 4, 8, 16 und 32 Bit Mikrocontroller mit unterschiedlichen Taktraten und Zusatzkomponenten, wie PWM, Schnittstellen (CAN, I2C), A/D Wandler, Watchdog, DSP u.a. Den größten Anteil am Markt haben jedoch die 8-Bit Mikrocontroller und sie werden von ihren Herstellern weiter gefördert. Die wichtigsten Mikrocontrollerfamilien sind Motorola 68hc11, Intel 8051 (MCS-51) und Microchip PIC mit ihrem bekannten low-cost Abkömmling, der BASIC-Briefmarke. Der Motorola 68hc11 ist ein 8-Bit Mikrocontroller, der jedoch 16Bit Arithmetik kennt. Er hat sich aus den Motorola Prozessoren 6502, 6805, 6809 entwickelt, ist aber zu diesen nicht kompatibel. Bei ihm sind PWM Ausgänge Standard. Auch Microcontroller mit 68000 Kern sind erhältlich (683xx). Intels MCS-51 Architektur ist eine Weiterentwicklung der MCS-48 Reihe (eingeführt 1976), dem ersten Mikrocontroller überhaupt, der lange in Tastaturen für Computer eingesetzt wurde. Auch Intel bietet 16-Bit (MCS-96) und 32-Bit (80386EX) Mikrocontroller an. Es gibt viele andere Prozessor Hersteller, darunter National Semiconductor, Zilog, Atmel, Dallas, Siemens, Mitsubishi und NEC, die entweder eigene Architekturen entworfen haben, oder aber zu den vorher genannten kompatible Prozessoren anbieten.

Der original 8051 als Basis des MCS-51 Standards wurde von Intel 1980 entwickelt und hat sich zur erfolgreichsten und größten Mikrocontrollerfamilie entwickelt. Seine Fähigkeiten zur Bit-Manipulation und die große Menge an freier Software und Beispielprogrammen, die es für diese Architektur gibt, sowie die jüngsten Weiterentwicklungen anderer Hersteller (Atmel: FLASH, Dallas: High-speed, Philips, Siemens ...) machen diese Familie besonders interessant. Sie deckt den weitesten Bereich von Mikrocontrollerapplikationen bei Binärkompatibilität untereinander ab, d.h. bei unvorhergesehenen Problemen oder Weiterentwicklungen findet man wahrscheinlich einen Mikrocontroller von irgendeinem anderen Hersteller, der genau dieses Problem löst, ohne daß man neue Schaltungen entwickeln, neue Software kaufen und sich neu einarbeiten muß.

Die Familie MCS-51 ist sehr groß. Verschiedene Hersteller bieten Typen an, die sich in der Art und Anzahl von on-chip Zusatzkomponenten unterscheiden. Der Grundtyp ist der 8051, ein 8-Bit Rechner mit vier 8-Bit Ports, 128 Bytes internem RAM für Daten, 4k maskenprogrammierbarem ROM für Programmcode, internem Oszillator, zwei Timern/Countern, serieller bidirektionaler Schnittstelle und Harvard-Architektur, die getrennt je 64 kBytes externen Daten- und Programmspeicher ansprechen kann. Die traditionelle von Neumann Architektur mit gemeinsamem Programm- und Datenbereich ist bei Mikrocontrollern problematisch, da die Programme anders als bei Heimcomputern oft nicht aus dem RAM, sondern aus dem ROM ausgeführt werden. Daten können dort aber nicht verändert werden, so daß dafür ein separater Datenbereich zur Verfügung steht.

Aufgrund des maskenprogrammierbaren ROM's wird der original 8051 natürlich nur von größeren Firmen eingesetzt. Die ROM-lose Version heißt 8031 und es gibt auch Mikrocontroller mit EPROM mit Quarzglasfenster zum Löschen des Programmes oder als billigere OTP (one time programmable) Version für Kleinserien in denen der Code nur einmal geschrieben wird, ein maskenprogrammierbarer Speicher sich aber nicht lohnt. Die EPROM und OTP Versionen heißen 87Cxxx und elektrisch löschbare EEPROM Varianten in der Regel 89Cxxx. Der 8052 besitzt doppelt soviel RAM und ROM wie der 8051 und einen zusätzlichen Timer, der 8032 ist wiederum dessen ROM-lose Version, womit die Beschreibung der Grundtypen auch schon abgeschlossen ist.

Alle anderen haben mindestens die Eigenschaften des 8031, wenn man von den neuesten Chips Atmel 89C2051 und 89C1051 absieht, die ein nur 20 poliges Gehäuse, keine Möglichkeit zum Anschluß externen Speichers und daher nur 2 Ports haben. Versionen mit stark erweiterten Funktionen haben mehr Pins und dann auch andere Gehäuse. Der am einfachsten anzuwendende Typ ist sicher der 8052 AH-BASIC mit internem BASIC-Interpreter, der bei entsprechender Platine auch gleich die Programmiermöglichkeit für EPROMS bietet. Beim Aufbau eines Systems fällt also der externe Speicher für den Startup-Code weg und die Programmierung vereinfacht sich auch, setzt aber zeitunkritische Anwendungen voraus. Der Quellcode zum Basic-51 1.1 ist von intel als Public Domain freigegeben und kann daher selbst in ein EPROM gebrannt werden. Die derzeit schnellsten MCS-51 Mikrocontroller werden von Dallas angeboten (DS80C320, DS80C520), sie besitzen Taktraten bis 33MHz, bei optimiertem Prozessorkern. Die wohl komfortabelsten werden von Siemens hergestellt (SAB 80C517, SAB 80C537), die auch 16 Bit Arithmetik kennen, 6 Ports besitzen und standardmäßig über 4 PWM Ausgänge verfügen, dem 68HC11 also überlegen sind.

Im weiteren bezieht sich der Ausdruck 8051 auf alle Mitglieder der MCS-51 Familie, soweit nicht näher bezeichnet.

Der 8051 besitzt einen umfangreichen Befehlssatz mit logischen Befehlen, den üblichen Datentransport- und Sprungbefehlen, und auch arithmetischen Befehlen SUB, ADD, MUL, DIV. Die Stärke des Prozessors liegt jedoch in der direkten Bit Manipulation. Es müssen also nicht Bits mit z.B. OR 00001000B maskiert werden, sondern sie können direkt adressiert werden (nicht bei allen Adressen). Im Unterschied zu anderen Prozessoren, beispielsweise dem Vorgänger 8048, werden zur Steuerung von Timer und serieller Schnittstelle keine speziellen Befehle verwendet. Vielmehr gibt es spezielle Register, die im Datenbereich des 8051 angeordnet sind, die special function register (SFR). So sind Erweiterungen der Architektur leicht möglich, denn Compiler oder Assembler ändern sich nicht, der Programmierer kann aber die erweiterten Funktionen seines Prozessors über SFR Adressen ansprechen [15], [9], [13], [12], [2].

Der eingesetzte Einplatinencomputer

Das minimale MCS-51 System besteht aus einem 8751 mit eingebranntem Programmcode, einem Schwingquarz, zwei Keramik- und einem Elektrolytkondensator, und einem Widerstand. Programmänderungen sind dann aber nur durch Bestrahlung des Quarzfensters mit UV-Licht und anschließendem Beschreiben des Mikrocontrollers in einem speziellen EPROM-Brenner möglich, das Rücksetzen nur indem man die Versorgungsspannung abschaltet. Als Steuerplatine eines Mikrowellenofens wäre das völlig ausreichen, als Experimentalsystem zur Programmentwicklung jedoch völlig ungeeignet.


Drawing by Paul Stoffregen

Besser ist eine Schaltung, bei der man eine externe EPROM Emulation hat, in die man Programme laden und austesten kann und bei der Resetschalter und RS232 Pegelwandlung zum Anschluß an einen Computer vorhanden sind. Im Gegensatz zu TTL-Pegeln, bei denen eine logische null 0 bis 0.8V eine eins 2.4-5V entspricht, arbeitet die RS-232C Schnittstelle mit -3 bis -15 V als logischer eins und +3 bis +15V als logischer null, was sie unempfindlich gegenüber elektromagnetischer Einstreuung macht. Um den 8051 nicht zu zerstören braucht man jedoch eine Pegelwandlung. Diese, wie auch die Erzeugung einer symmetrischen Spannung +/- 10V übernimmt ein MAX232, der mit vier Kondensatoren 1 uF, 16V beschaltet werden muß, oder ein MAX233, der die Kondensatoren nicht benötigt.

(Drawing by Paul Stoffregen)

Legt man den EA pin des Mikrocontrollers auf null, so spricht der 8051 externen Speicher über seine Ports P0 und P2 an, diese sind dann nicht mehr als I/O Ports nutzbar. P0 enthält dabei zuerst die unteren 8 Adreßbits und dann die Daten. Man nennt dieses Verfahren multiplexen. Es wird angewendet um Anschlüsse zu sparen. Port P2 enthält die oberen 8 Adreßbits. Um die Adresse vollständig zuückzugewinnen benutzt man ein Latch, einen Zwischenspeicher, der mit dem ALE-pin des Prozessors angesteuert wird. Das ist in der Regel ein 74373 oder 74573, wegen der hohen Geschwindigkeit im Mikrocontrollersystem am Besten als HCT Version. Nun läßt sich externer Speicher über 16 Bit Adress- und 8 Bit Datenbus ansprechen. Um in einem Experimentalsystem Programme im RAM zu speichern und dort abarbeiten zu lassen, macht man die Trennung des Speichers in Daten- und Programmteil durch den Prozessor wieder rückgängig. Das geschieht durch logische OR Verknüpfung des PSEN und RD Signales. Da diese Pins aktiv eine Null führen wird dazu ein AND Gatter verwendet. Dieses Signal steuert dann das RAM. Der Adressdecodierung dient üblicherweise ein 74138. Die an den Adress-/Datenbus verlorenen Ports gewinnt man durch Einsatz eines I/O Bausteines 8255 zurück, hat dann sogar einen Port mehr als vorher, d.h. 40 I/O Leitungen von denen normalerweise zwei für die serielle Schnittstelle verwendet werden, also netto 38 Pins. Ein Resetschalter ermöglicht den Neustart des Rechners, dabei bleibt der RAM Inhalt übrigens erhalten.

Das hier benutzte Schaltungslayout und die Platine stammt von einem Lichtorgelprojekt aus [4]. Es handelt sich um einen Einplatinencomputer (EPC). Die Platine ist einseitig und die Schaltung entspricht dem eben beschriebenen experimentellen Minimalsystem mit EPROM Emulation zum schnellen Austesten von Programmen. Es besitzt keine serielle Pegelwandlung, da vom Entwickler die Ansteuerung über ein 11 poliges paralleles Kabel vorgesehen war, und kann mit einem beliebigen 40poligen 8051 Derivat mit passendem Quarz, einem EPROM 2764 oder 27128, einem 32K RAM 62256 und dem I/O Baustein 8255 bestückt werden. Es wurde der Dallas Prozessor 80C320 mit 24MHz Quarz und das 16K EPROM 27C128 gewählt. Bei den Speichern muß auf kurze Zugriffszeiten geachtet werden, da der Prozessor recht schnell ist. Das EPROM besitzt 150ns Zugriffszeit, das statische RAM üblicherweise 70ns, 166ns sind Maximum beim 80C320 mit 24MHz.

Der 80C320 von Dallas besitzt zusätzlich zu den Austattungsmerkmalen des 8032 einen Power-fail Reset und Frühwarninterrupt, sieben zusätzliche Interrupts, einen zweiten Datenzeiger (DPTR1), der Blockverschiebungen beschleunigt, Verbesserungen bei den Stromsparmodi, sowie einen programmierbaren Watchdog und ist in Versionen erhältlich, die bis 25 oder 33MHz betrieben werden können. Da die Architektur des CPU Kerns verbessert wurde, führt er einen Maschinenzyklus in nur 4 Taktzyklen aus. Ein Standard 80C32 braucht 12 Taktzyklen für einen Maschinenzyklus und wird üblicherweise mit 12MHz getaktet. Der eingesetzte Prozessor ist bei 24 MHz bis zu 6 mal schneller als ein Standardcontroller und erreicht eine theoretische peak performance von 6 Mips. Ein 8032 müßte mit 60MHz laufen um dieselbe Leistung zu erreichen. Um trotz der hohen Leistung langsame Peripherie ansprechen zu können, ist die Speicherzugriffsgeschwindigkeit bei externen Datenspeicherzugriffen wählbar von 2-9 Maschinenzyklen (80-1120 ns bei 25Mhz).

Die Speicheraufteilung des EPC ist bewußt einfach gehalten:

Der Multiplexer unterteilt den Speicherbereich in 16k Blöcke. Über die beiden Dioden, die ein OR Gatter darstellen werden aus 2x16k zusammenhängende 32k für das RAM[4].

Dabei ein Paar grundlegende Worte zu Speichern: Die Speicher teilen sich grob in ROM, read ony memory - Nur Lesespeicher, und RAM , random access memory - Speicher mit wahlfreiem Zugriff auf. Für die beschreibbaren Speicher werden kleine Kondensatoren verwendet, deren Ladung schnell verlorengeht und die daher immer neu aufgefrischt werden müssen. Man nennt diese dynamische RAM's. Solche, die den Schaltzustand mit Flip-Flop's halten und nicht aufgefrischt werden müssen heißen statische RAM's. Sie besitzen typischerweise kleinere Zugriffszeiten, eine geringere Speicherdichte und sie sind teuerer als die dynamischen [3].

Einmal programmierbare PROMS besitzen durchschmelzende Sicherungen, maskenprogrammierbare ROM's werden ab Fabrik bei der Herstellung durch Einätzen des Bitmusters programmiert. Die Herstellung der Masken lohnt sich nur bei großen Stückzahlen. Der in Kleinserien, im Labor- und Hobbybereich beliebteste Festspeicher ist das EPROM, erasable programmable read only memory. Er kann in einem speziellen Gerät beschrieben und mit UV Licht wieder gelöscht werden. Er ist folgendermaßen aufgebaut: jedes Bit besitzt zwei Transistoren, einen für die Adreßdecodierung und einen FAMOS-Transistor, der die Information speichert. FAMOS bedeutet ''Floating Avalanche injection Metal Oxide Semiconductor''. Das Gate dieses Transistors ist rundum in Siliziumoxyd eingebettet und somit vollständig isoliert. Bei der Programmierung wird zwischen Gate und Substrat eine im Verhältnis zur Betriebsspannung relativ hohe Programmierspannung von 12 bis 21V angelegt, wodurch es zum Avalanche- oder Lawinendurchbruch durch die Isolierschicht kommt. Die so auf das Gate aufgebrachten Ladungsträger bleiben einige Jahre erhalten.

Auskunft über Hersteller und Programmierspannung gibt die silicon signature, die aus vielen EPROM's ausgelesen werden kann. Zur Löschung besitzen EPROM's UV-Licht durchlässige Quarzglasfenster. Bei Bestrahlung mit energiereichem UV-Licht entsteht nämlich ein fotoelektrischer Strom über den die Gate-Ladung abfließen kann. Im Freien bei Sonnenlicht kann ein EPROM bereits in einer Woche einzelne Bits verlieren. Man deckt daher das Fenster mit einem Selbstklebeetikett ab, das idealerweise metallisiert ist, ein Papieraufkleber schützt aber auch schon. Das Löschen im Löschgerät dauert etwa 15 bis 45 Minuten und man sollte eher großzügig sein, da ein unzureichend gelöschtes EPROM kurz nach dem Löschen leer erscheint, nach einiger Zeit aber das ursprüngliche Bitmuster wieder auftaucht! Nach korrektem Löschen ist das EPROM mit Einsen gefüllt, d.h. mit 0xFF in allen Zellen. Der Programmiervorgang besteht also darin, Bits zu löschen. Mit einem Programmiergerät ist es nicht möglich, Bits zu setzen, ein Speicherbereich der mit 0xFF gefüllt ist, läßt sich allerdings auch später programmieren ohne das EPROM erneut löschen zu müssen. Dadurch kann man ein kleines Monitorprogramm in ein großes EPROM brennen, wobei ein großer Teil des Speichers frei bleibt, den man später mit anderen Daten oder Programmen füllt.

Der Standardprogrammieralgorithmus sieht Programmierimpulse von 50 ms vor, d.h. an Vpp liegt die Programmierspannung an und Adreß- und Datenleitungen ändern sich während dieser Zeit nicht. Bei einem 27128, einem 16 kByte EPROM beträgt die Programmierzeit dann 13 Minuten und 40 Sekunden. Um das Verfahren zu beschleunigen wurden modifizierte Programmieralgorithmen entwickelt. Viele Speicherzellen sollen mit dem Wert 0xFF programmiert werden, den sie aber schon besitzen. Durch Auslassung dieser Speicherzellen läßt sich das Verfahren etwas verkürzen. Der intelligente Algorithmus geht jedoch weiter. Er benutzt Impulse vom 1ms, prüft danach, ob das Byte fehlerfrei zurückgelesen werden kann und wenn dies der Fall ist, maximal jedoch nach 15ms, wird mit der drei- bis vierfachen verstrichenen Zeit nachprogrammiert, um den Datenerhalt über längere Zeit sicherzustellen. Noch schneller ist eine Programmierung mit 0.5ms Impulsen und Nachprogrammierung mit nur der doppelten Dauer. Dieses Verfahren entspricht jedoch nicht mehr der Herstellerspezifikation und die Daten sind eventuell nicht ganz so lange haltbar [6], [7].

In [2] ist eine RAM Backup Schaltung beschrieben: eine 3,6V Lithium Zelle liefert über eine Diode und einen 1k Widerstand Strom an den 62256. Pin 28 aber auch Pin 20 (CE) werden über einen weiteren 1k Widerstand versorgt. Im Normalbetrieb liegt dieser Pin über einen selbstsperrenden MOSFET BS170 auf Masse, so daß der Baustein selektiert ist. Fällt die Betriebsspannung aus, so sperrt der FET und CE liegt auf Betriebsspannung, was dem Stand by modus des Chips entspricht.

Doch zurück zum benutzten Einplatinencomputer.

Die 8 LEDs des Ports B müssen nicht bestückt werden, erweisen sich jedoch als hilfreich, da sie Programmzustände anzeigen können, ähnlich dem Einfügen von printf() statements in C Quellcode beim Debuggen. Sie sind außer der seriellen Schnittstelle die einzige Möglichkeit, dem Benutzer etwas mitzuteilen. Abweichend von der Baubeschreibung sollte man jedoch Low current LEDs mit entsprechenden Vorwiderständen benutzen, da der 8255 normale LEDs gar nicht treiben darf (offenbar schafft er das doch).

Monitor

Die Software im EPROM stellt das BIOS (Basic input output System) und auch gleich das Betriebssystem des EPC dar. Sie ist das Grundprogramm des Computers und ermöglicht die Benutzerkommunikation und das Aufladen von eigener Software ins RAM und somit überhaupt die Benutzbarkeit des Systems. Sie stellt darüber hinaus ihre Funktionen dem Benutzerprogramm zur Verfügung, d.h. vom aufgeladenen Programm im RAM können Routinen im EPROM aufgerufen werden um Standardfunktionen auszuführen. Die im Elektor Artikel [4] beschriebene Software ROM-V1 benutzt wie erwähnt die parallele centronics Schnittstelle des PC und ist sehr einfach. Sie wurde nicht verwendet um das EPROM zu brennen. Statt dessen wurde der Freeware Monitor/Debugger von Paul Stoffregen PAULMON1 benutzt. Der Monitor wurde ursprünglich 1991 am OSU (Oregon State University) entwickelt und von vielen Studenten für ihre Projekte wie X-Y Raster Grafiken, Audio Sampling und auch Robotersteuerungen benutzt. Er belegt fast 8k, braucht also mindestens ein EPROM 2764 oder zwei 2732, besitzt aber Fähigkeiten, die weit über das normale Maß hinausgehen. Da wären:

Die voreingestellten Adressen für den PAULMON Start und den Anfang des RAM's sind 0x0000 und 0x2000, können jedoch leicht geändert werden. Für den EPC wird der RAM Bereich auf 0x8000 gelegt. Die Einschaltmeldung und der Prompt wurden gekürzt, die Benutzerführung ins Deutsche übersetzt, mehrere Bugs entfernt und einige Routinen ergänzt. Darunter die INI8032 Routine, welche Timer 2 für die Baudratenerzeugung benutzt und einige andere hardwarespezifische Verbesserungen enthält, darunter das Wechselblinken der Einschalt LED und die Erweiterung der Interruptvektoren am Anfang des Speicherbereichs auf alle dem 80C320 bekannten Interrupts. Die Zieladressen der Interruptvektoren wurden an das Ende des Speichers gelegt, wobei für jede Routine 256 Byte zur Verfügung stehen. Im Gegensatz zur Original INIT Routine darf sie mit einem Standardprozessor, einem anderen Quarz oder mit einem anderen Platinenlayout nicht verwendet werden. Es wird nämlich eine starre Baudratenerzeugung verwendet, wodurch mit einem 24MHz Quarz Baudraten von 19200 möglich sind, was die INIT Routine nicht mehr leistet. Damit der Monitor wieder mit allen Prozessoren, Quarzen und Bordlayouts zusammenarbeitet, muß in der Routine poweron der Aufruf ACALL INI8032 ersetzt werden durch LCALL INIT. Um Platz zu sparen kann dann die INI8032 Routine, die Rauschroutine und die Routinen zur LED Ansteuerung entfernt werden. Die Routinen STIME und MSTIME, die Zeitverzögerungsschleifen sind, sind Prozessor- und quarzspezifisch, können also angepaßt werden und einige Interruptvektoren am Anfang des Programms sind nur benutzbar mit dem 80C320, können also auch entfernt werden.

Assembler

Der verwendete Assembler ist der AS31 der von Ken Stauffer von der University of Calgary entwickelt und von Paul Stoffregen modifiziert wurde. Auch er ist Freeware, klein und liegt im Quellcode vor, der sich auf den meisten Systemen problemlos kompilieren lassen sollte (Linux, Solaris, HP-UX, OS/2, DOS mit Abstrichen), ist also sehr sauber programmiert. Die meisten anderen Assembler sind groß, da sie teilweise mehrere Dutzend Mikrocontroller und CPU's unterstützen, nicht portabel geschrieben oder der Quellcode wird nicht mitgeliefert. Im Internet finden sich Pakete mit Disassembler, Linker und anderen Tools, oftmals Freeware aber dennoch ohne Quellcode oder von zweifelhafter Qualität. Beim Paket WISC beispielsweise versteht der Assembler die vom Disassembler ausgegebene Syntax nicht! Außer AS31 ist ASM51 der MetaLink Corporation qualitativ sehr gut. Er ist macrofähig und versteht die Syntax des original ASM51 von intel fast vollständig. Auch ihn gibt es leider nur als .exe für DOS. Negativ am verwendeten AS31 ist die fehlende Macrofähigkeit und die veränderte Syntax. Pseudo Opcodes, wie ORG und EQU werden mit einem Punkt gekennzeichnet und die Parameter beide nachgestellt. Üblich ist

Variable      EQU Wert
AS31 verlangt hingegen
           .EQU Variable, Wert

Das kann man als Verbesserung des Sprachstandards ansehen, da Opcodes von Pseudo Opcodes durch den Punkt klar unterschieden sind. Von anderen Programmen übernommene Teile muß man jedoch meist leicht modifizieren. Die Kompatibilität der anderen getesteten Assembler ist jedoch ähnlich begrenzt. Mit einigen Änderungen des Quelltextes kann natürlich jeder andere 8051 Assembler verwendet werden. Es gibt außerdem auch FORTH51 Systeme im Internet oder aber kommerzielle C Compiler und Assembler.

Bestückung der Platine

Die Bestückung der Platine geschieht wie üblich von den niedrigen zu den höheren hin, d.h. beginnend bei den Drahtbrücken über die Sockel zu den Elkos. Dabei ist auf das richtig gepolte Einlöten der Elkos und Dioden zu achten und darauf, daß die 28 poligen Sockel der Speicherbausteine gegenüber den 40 poligen Sockeln des 8051 und 8255 um 180 Grad gedreht sind, worauf vor allem nachher beim Einsetzen der Bausteine zu achten ist. Es werden erfahrungsgemäß mehr Bausteine durch falsches Einsetzen zerstört, als durch statische Entladung. Um die Schaltung wirklich zum laufen zu bringen ist die visuelle Kontrolle der beste Weg. Es ist dabei sowohl auf kalte oder schlecht ausgeführte Lötstellen, auf Verbindung von Leiterbahnen untereinander durch abgeschnittene Drahtenden oder Lötzinn zu achten, als auch auf verbogene Pins, die sich beim Einsetzen am Sockel ''vorbeigemogelt'' haben. Danach prüft man zwischen GND und +5V den Widerstand, der unendlich sein muß, sonst liegt irgendwo ein Kurzschluß vor. Bei der vorgestellten Platine macht man das nach dem Spannungsregler. Man sollte sich dabei vom Elko oder anderen in die Versorgungsspannung geschalteten Bauteilen nicht irreführen lassen, diese ziehen kurz Strom bis sie sich aufgeladen haben. Der dritte Schritt ist der Test auf unterbrochene oder fälschlicherweise verbundene Pins mit einem Ohmmeter. Besonders bei Adress- und Datenbus kann das ein langwieriger Prozess sein. Noch ohne Chips wird die Schaltung unter Spannung gesetzt und ALLE Leitungen darauf untersucht, ob sie entweder auf Masse oder + 5V liegen und im Schaltplan verglichen, ob dies auch so sein soll. Nach diesem Test ist es bei Nichtfunktionieren der Schaltung unwahrscheinlich, daß man ein Bauteil beschädigt. Falsch angeschlossene Busleitungen sind weit weniger kritisch, die Bausteine werden meist nicht zerstört.

Nun wird das serielle Interface mit dem MAX232 getestet, das auf der separaten Steuerplatine aufgebaut ist. Pin 16 führt die 5V Versorgungsspannung, pin 15 Ground. An Pin 2 müssen 8 bis 10V liegen, an Pin 6 -8 bis -10V. Der RS232 TxD Ausgang Pin 14 (Pin 7) hat normalerweise -9V und sollte auf +9V springen, wenn man den TTL Eingang Pin 11 (Pin 10) auf Ground legt. Analog liegt der TTL Ausgang Pin 12 (Pin 9) auf Eins und geht beim Anlegen einer positiven Spannung an RxD Pin 13 (Pin 8) auf Null. Pin 12 (Pin 9) des MAX232 geht an Pin 10 des 8051 und Pin 11 des MAX 232 wie des 8051 sind verbunden. Ohne Spannung werden jetzt der Prozessor, das EPROM mit eingebranntem Monitorprogramm, der 74373/573, 74138 und 7408 eingesetzt.

Die Kommunikation mit dem EPC geschieht über jedes Terminal oder Terminalprogramm, wie Kermit, ProComm, Windows oder OS/2 Terminal, mit dem auch die Uploads von Testprogrammen möglich sind. Die Verbindung erfolgt über ein normales dreiadriges Nullmodemkabel mit Kreuzung von RxD und TxD, der dritte Anschluß ist GND.

Die Datenübertragung bei RS232 erfolgt seriell, d.h. die einzelnen Bits werden nacheinander über eine Leitung übertragen. Da die Schnittstelle bidirektional ist, benötigt man eine Hin-, eine Rückleitung und die Masseleitung. Die vollständige RS232 Schnittstelle hat allerdings andere Leitungen, die Steuerungs- und Kontrollfunktion besitzen. Die Übertragung beginnt laut Norm mit einem logischen MARK (logisch 1) Zustand der Sender Ausgangsleitung. Diese Zustand liegt nach dem Einschalten vor und wird auch nach jeder Übertragung wieder eingenommen. Zur Benachrichtigung des Empfängers dient das Startbit: Für die Dauer eines Bits gibt der Sender SPACE (logisch 0) aus, wodurch der Empfänger seine Abfragelogik vorbereitet. Die Datenbits folgen dann von LSB bis MSB. Die elektrische Spezifikation sieht vor, Leitungen bis 30m anzuschließen, dies bei eingeschaltetem Rechner zu tun und erlaubt es, die Ausgänge kurzzuschließen. Der RS232 Standard ist auch als V.24 bekannt, mit der elektrischen Spezifikation in der V.28 und ist ebenfalls in der DIN66020 definiert. Eine solche Schnittstelle ist meist in irgendeiner Form an einem Computer, Drucker oder Terminal vorhanden. Dabei unterscheidet man zwischen DTE, data terminal equipment, oder Datenendeinrichtung und DCE, data communication equipment, also Datenübertragungseinrichtung. Bei DCE und DTE sind RxD und TxD gleich bezeichnet, bedeuten aber beim sendenden DCE, daß der Pin als solcher fungiert, beim DTE, daß hier der entsprechende Pin des DCE angeschlossen werden soll. DTE besitzt dabei einen männlichen Steckanschluß und die Pins sind von vornherein vertauscht, so daß man nur ein 1:1 Kabel mit einem männlichen und einem weiblichen Stecker benötigt um die Beiden zu verbinden. Zwei solcher Kabel lassen sich einfach zu einem längeren verbinden. Bei EPC Projekten ist es gängige Praxis eine weibliche Buchse benutzen, den EPC also als DCE zu sehen, die Pins aber trotzdem zu vertauschen. Das entspricht nun gar keiner Norm mehr und es ist schwierig, festzulegen ob denn nun der EPC oder der PC mehr sendet, also eher als DCE bezeichnet werden soll. Daher und da man ein ''richtiges'' Nullmodemkabel z.B. auch zur Kommunikation mit anderen Rechnern einsetzen kann, wird in den EPC eine RS232 Schnittstelle mit der Belegung des IBM PC eingebaut. Die RS232 arbeitet mit +/-3 bis 15V, die gegen Masse gemessen wird, und inverser Logik, d.h. dem hohen Spannungspegel für eine logische Null. Die Normen RS422 und RS485 hingegen benutzen zwei Leitungen auf denen +/- 2V anliegen, die differentiell gemessen werden, was eine höhere Übertragungssicherheit schafft. Während die RS232 nur zwei Geräte miteinander verbindet, können bei der RS422 mehrere Empfänger angeschlossen werden, bei der RS485 auch mehrere Sender, daher wird die elektrische Spezifikation RS485 gerne bei Netzwerken eingesetzt. Da bei einem Bussystem die Steckverbinder die größte Fehlerquelle darstellen sind übrigens serielle Busse und Netzwerke weniger fehleranfällig als parallele, da sie einfach weniger Kontakte besitzen. Selbst bei Kopplung mehrerer CPU's in einem Mehrprozessorsystem geht man teilweise ab von der parallelen Verbindung und benutzt statt dessen serielle Hochgeschwindigkeitslinks, einfach weil die heutigen CPU's ohnehin weit über hundert Pins besitzen. Gegen elektromagnetische Einstreuung schützt Abschirmung oder die Übertragung per Lichtleiter, der systembedingt dagegen resistent ist.

Belegung der seriellen Schnittstelle für einen 25 poligen Stecker und den 9 poligen IBM Standard

25 pol. 9 pol. Ein-/ Ausgang Bezeichnung Funktion
2 3 Aus TxD (Transmit Data) Sendedaten
3 2 Ein RxD (Receive Data) Empfangsdaten
4 7 Aus RTS (Request to send) Sendeteil einschalten
5 8 Ein CTS (Clear to send) Sendebereitschaft
6 6 Ein DSR (Data set ready) Betriebsbereitschaft
7 5 GND GND (Ground) Erde
8 1 Ein DCD (Data carrier detect) Empfangssignalpegel
20 4 Aus DTR (Data Terminal Ready) Endgerät bereit
22 9 Ein RI (Ring Indicator) Ankommender Ruf

So angeschlossen muß man bei PAULMON nur ein Carriage Return an den EPC senden und er müßte sich melden, dabei sollte man den EPC nicht überfordern, sondern erst eine geringere Baudrate, wie 1200 Baud einstellen. Die Schnittstelle wird dabei mit 8 Datenbits ohne Parität mit einem Start- und einem Stopbit betrieben, es werden also immer 10 Bit als Datenpaket übertragen. Dabei soll nicht unerwähnt bleiben, daß die automatische Baudratenerkennung nur bis etwa 4800 Baud funktioniert wenn nicht ein spezieller Quarz eingesetzt wird. Diese erkennt man am ''krummen'' Wert, oft wird beispielsweise ein solcher mit 11.05920 MHz eingesetzt. Damit sind auch Datenraten von 9600 und 19200 Baud erreichbar, da der Baudratentakt dann exakt berechnet werden kann. Das ist besonders bei PAULMON von Vorteil, da er im Vergleich zu anderen Monitoren viel Text über die Schnittstelle sendet, aber auch beim Intel-Hex download von Programmen ist eine hohe Baudrate vorteilhaft. Timer 2, der nur bei 8032 und besser vorhanden ist, kann Baudraten mit feinerer Stufung generieren. Die bei der 80C320 Version von Paulmon eingesetzte Routine INI8032 generiert mit 24MHz Takt eine Baudrate von 19230.769 Baud. Die korrekte Bitbreite von 52.1ms wird dabei nur um 0,1ms oder 1.9% verfehlt. Da aber nach 10 übertragenen Bit ohnehin wieder auf das nächste Stopbit gewartet wird ist das belanglos. Damit ein Fehler aufritt müßten 521 Bit ohne Stobit übertragen werden. Sogar eine Baudrate von 20270.27, also eine Abweichung von 5.6% auf dem EPC bringt einwandfreie Übertragung bei 19200 Baud.

Meldet sich der EPC, so setzt man das RAM und den 8255 ein, lädt ein Testprogramm welches prüft ob RAM und externe Ports funktionieren. Wenn das nicht der Fall ist, muß man sich noch einmal die Hardware genauer anschauen.

Hardware debugging

Fertig gekaufte Bausätze funktionieren oft nach dem Zusammenbau. Bei selbst geätzten oder modifizierten Schaltungen oder gar Eigenentwicklungen ist die Wahrscheinlichkeit schon viel geringer. Selten jedoch ist der Grund für das Nichtfunktionieren ein defekter Baustein. Ausnahme davon sind falsch herum eingesetzte Bauteile, die meist den Hitzetod erleiden. Wenn die Schaltung also nicht funktioniert, prüft man erneut visuell auf Lötbrücken und kalte oder gar vergessene Lötstellen, dann mit Ohmmeter und Voltmeter, diesmal wirklich gründlich. Vertauschte RxD und TxD Leitungen, ein EPROM im RAM Sockel oder der 8255 anstelle des 8051 sind sichere Mittel die Schaltung nicht zum laufen zu bringen.

Nun prüft man die angeschlossene Schaltung, bei einem High-speed Prozessor wie dem Dallas chip zweckmäßigerweise mit einem langsameren Quarz. So kommt man mit einem billigeren Oszilloskop aus und die Schaltung funktioniert auch, wenn man unglücklicherweise zu langsame Speicher eingesetzt hat. Mit einem Oszilloskop prüft man, ob der Oszillator schwingt. Das kann man mit einem 1/10 Tastkopf direkt an den Pins 18/19 tun, wobei man aber eventuell die Schwingung zum Erliegen bringt, oder man testet die Pins ALE und PSEN, die ständig arbeiten sollten. Die Pins haben eine Frequenz von 1/6 des Oszillators (beim Standard 8051!) und ALE hat ein Tastverhältnis von 1:3 und PSEN eines von 1:1. Auch ein Frequenzzähler hilft also weiter, wenn man kein Oszilloskop zur Verfügung hat. ALE ist der address latch enable Pin, taktet also das Latch 74373, PSEN bedeutet program store enable, ist also der Lesetakt für den externen Propgrammspeicher.

Zu diesen Messungen ist anzumerken, daß der Oszillator nicht selbst starten kann, wenn er nicht gut abgestimmt ist, sondern dazu muß ein Reset Impuls ausgelöst werden. Man sollte also von Zeit zu Zeit die Reset Taste drücken. Auch wird der Oszillator nicht bei andauerndem Reset schwingen, d.h. hat man beim Resetschalter den Öffner statt des Schließers angeschlossen passiert gar nichts. Beim Reset, wie beim Anlegen der Versorgungsspannung geht der Reset Eingang RST auf Eins um dann sofort wieder auf Null zu fallen. Wegen des internen pull-down Widerstandes am RST Pin genügt ein Kondensator an seinem Eingang für den power on reset. Wenn ein externes EPROM eingesetzt wird, muß der EA Pin des 8051 auf Null gelegt werden. Dann sollte der Prozessor das EPROM ansprechen, indem er den CS Pin des EPROM's auf Null legt. Das kann schon mit einem einfachen Voltmeter überprüft werden, da der Prozessor alle Instruktionen vom EPROM holen sollte und der Pin daher fast immer auf Null liegen sollte. Bei allen Tests prüft man die Schaltung von oben und setzt die Tastköpfe direkt auf die Beinchen der Chips. Erstens ist auch der Schaltplan und die Pinbelegung von oben gezeichnet und außerdem werden so die Verbindungen der Sockel gleich mitgetestet und verbogene Pins erkannt. Bei einem eingesetzten EPROM mit Monitorprogramm sollten die höheren Adressleitungen inaktiv bleiben, da der Prozessor eine kleine Schleife in einem eng umgrenzten Speicherbereich abarbeitet.

Ersetzt man das Programm EPROM durch ein NOP EPROM, also eines, das mit lauter Nullen gefüllt ist, so sollte der Prozessor durch seinen kompletten Adreßraum laufen und die Adressleitungen ein Muster aufweisen, bei dem jede Leitung die halbe Frequenz der vorherigen führt. Das gilt meist auch bei völlig fehlendem Speicher. Die niederwertigen Bits der Adresse mißt man natürlich nach dem Latch. Als nächsten Test setzt man ein EPROM mit einer Endlosschleife ein.


                            ; Test fuer 8051

0000:                       .org 0x0000
0000: 04           start:   inc A
0001: F5 90                 mov P1, A
0003: 80 FB                 sjmp start

Das Programm gibt ansteigend die Werte 0x00 bis 0xFF ab Port P1 des Prozessors aus. Tut sich immer noch nichts, kann man jetzt daran denken, die Bausteine nacheinander auszuwechseln, oder bei selbst entwickelten Schaltungen sollte man sich noch einmal prinzipielle Gedanken über die Schaltung machen [14], [5], [6].

MCS-51 Assembler

In Maschinensprache zu programmieren ist praktisch unzumutbar. Das bedeutet nämlich, daß der Programmierer für jeden Befehl in einer Tabelle einen Zahlenwert, den operation code, kurz Opcode nachschlägt und eingibt. Schon bei der Fehlersuche jedoch muß der Programmierer alle Opcodes auswendig wissen um das Programm verfolgen zu können. Faßt man aber Opcodes die ähnliche Funktion haben mit einem Merkkürzel, einem Mnemonic zusammen, und überläßt das Nachschauen des Opcodes einem einfachen Programm, so kann der Programmierer alle Maschinenbefehle gezielt einsetzen, muß sie aber nicht als Zahl auswendig lernen. Sowohl die entstandene Sprache als auch das Übersetzungsprogramm heißen Assembler. Übersetzt der Assembler in die Maschinensprache einer anderen Systemarchitektur, beispielsweise Übersetzung eines MCS-51 Assemblerprogramms auf einem IBM kompatiblen PC, so heißt der Assembler Crossassembler. Da heute niemand mehr in Maschinensprache programmiert, wird leider gelegentlich der Begriff Maschinensprache für die Assemblerprogrammierung benutzt.

Auch in Assembler kann man stukturiert programmieren. Aussagekräftige Label für Sprungmarken und Variablen und das Anlegen von wiederverwendbaren Unterroutinen, die natürlich entsprechend kommentiert sind, sind dafür unabdingbar, genau wie in jeder anderen Sprache. Strukturiert heißt in jedem Fall, daß ein möglichst kurzes, leicht durchschaubares Hauptprogramm existiert, das die Funktionen des Programms als Unterroutinen aufruft. Man kann also schon daran erkennen, wie das Programm arbeitet, wenn man auch noch nicht die einzelnen Lösungen versteht. Dafür muß man sich dann die Unterroutinen anschauen. Früher galt ein Assemblerprogrammierer als gut, wenn er die komliziertesten Algorithmen in ein paar Byte packen konnte. Verstehen oder ändern konnte solch eine Routine oft nur der Programmierer selbst. Heute hat man schon auf einem kleinen EPC meist genügend Speicherplatz und Rechengeschwindigkeit, so daß ein paar Befehle mehr uns nicht vor Speicherplatzprobleme stellen. Programmiertricks sollte man daher nur in Ausnahmefällen anwenden. Dort muß dann besonderer Wert auf Dokumentation gelegt werden.

Nun zum Befehlssatz des 8051: Die 44 Mnemonics eines MCS-51 Assemblers ermöglichen bei einigen Befehlen sowohl Bit- als auch Bytemanipulationen (ANL, ORL, CLR, CPL) oder Operationen auf den Datenzeiger DPTR, das einzige 16Bit Register (MOV byte/bit/DPTR, INC), so daß diese als zwei oder drei unterschiedliche Befehle gerechnet werden müssen. Es ergeben sich 51 Grundbefehle (Daher MCS-51). Dafür gibt es wiederum bei Speicherzugriffen unterschiedliche Adressierungsarten, also muß der Programmierer 111 Befehle unterscheiden. 49 davon bestehen aus nur einem Byte, 45 aus zwei und 17 aus dreien. Wie in Assembler üblich folgt dem Mnemonic erst der Ziel- dann der Quelloperand. Für schnellen Zugriff stehen vier Bänke zu acht Registern R0 bis R7 zur Vefügung, die vom Prozessorkern unterschiedlich angesprochen werden. Dadurch spalten sich Befehle die darauf zugreifen noch einmal in je acht Opcodes auf. Insgesamt besteht die MCS-51 Maschinensprache aus 255 Opcodes, also ist nur einer der 256 möglichen 8Bit Opcodes nicht genutzt. Es ist der Opcode 0xA5. Die vier arithmetischen Operationen erlauben nur 8 Bit Arithmetik, höhere Mathematikfunktionen werden nicht direkt unterstützt. Genauere oder Fließkommaarithmetik, sowie Trigonometrische Funktionen u.s.w. lassen sich nur durch entsprechende Routinen auf Kosten der Laufzeit erreichen. Der Prozessor unterstützt jedoch BCD Berechnungen. Bei BCD (binary coded digit) Zahlen, auch gepackte Dezimalzahlen genannt, enthält ein Nybble (Nybble=4 Bit) jeweils eine Dezimalziffer, man benutzt also die Codes 0xA bis 0xF nicht. Das ist vorteilhaft bei Ansteuerung von Anzeigen, da die dezimale Struktur der Zahl nicht vollständig verlorengeht. Bei arithmetischen Operationen treten jedoch Fehler auf, die mit dem speziellen Maschinenbefehl DA korrigiert werden können. Der Status der Berechnung läßt sich im Prozessorstatuswort (PSW) abfragen, das folgende Flags enthält:

Das Carry CY, PSW.7 oder C wird gesetzt, wenn ein Übertrag in Bitposition 7 entsteht, andernfalls wird es gelöscht. Es wird benutzt bei Addition von vorzeichenlosen Zahlen.

Zur BCD Addition gibt es das Auxiliary Carry AC, PSW.6, das gesetzt wird, wenn ein Übertrag in Bitposition 3 entsteht, d.h. von der ersten Stelle zur zweiten.

Das Überlauf Flag OV, PSW.2 wird gesetzt wenn ein Übertrag an Bitposition 6 entsteht aber keiner an Position 7 oder aber an Position 7 und keiner an Position 6. Es ist zur Addition vorzeichenbehafteter Zahlen gedacht.

Prüfsummenberechnungen führt der Mikrocontroller im Akkumulator selbständig durch. Das Parity Flag P, PSW.0 wird automatisch entsprechend gerader Parität gesetzt.

Das Flag F0, PSW.5 kann vom Benutzer frei genutzt werden.

Die Flags PSW.4, RS1 und PSW.3, RS0 selektieren die Registerbank, wie im Anhang beschrieben.

Obwohl der Mikrocontroller 8051 eine CISC CPU enthält und daher Stack- und Akkumulatororientiert arbeitet, d.h. bei arithmetischen Operationen enthält der Akkumulator ACC oder A den Quelloperand und auch nach Ausführung des Befehls das Ergebnis, ist es möglich viele Operationen am Akkumulator vorbei direkt an Registern auszuführen. Die jeweils aktive Registerbank R0-R7 wird durch PSW.4 (RS1) und PSW.3 (RS0) selektiert (siehe Anhang). Die Bänke belegen die ersten 32 Byte 0x00 bis 0x1F des internen Speichers. Man könnte bei der Programmierung auch diese Adressen angeben, der Befehl belegt dann aber mehr Speicher und wird langsamer ausgeführt. Gleiches gilt für den Akkumulator: ACC ist die Speicheradresse des Akkumulator, die Angabe von A generiert einen speziellen, auf den Akkumulator ausgerichteten Befehl wenn das möglich ist. Einen speziellen Opcode für PUSH A gibt es beispielsweise nicht, dort muß man die Adresse des Akkumulators angeben: PUSH ACC. Der Unterschied in der Opcodegenerierung ist im Motorola Assembler deutlicher: dort gibt es einen eigenen Befehl um den Akkumulator zu laden - LDA XXX. Bei intel heißt dieser Befehl MOV A, XXX.

Das B Register dient bei MUL und DIV als zweites Arbeitsregister, kann aber sonst einfach als neuntes Register genutzt werden. Im Gegensatz zu diesen ist B Bit adressierbar, d.h. es gibt die Bit Adresse B.3 (Bit drei des Bytes B), aber nicht die Adresse R0.3.

Stapelspeicher

Der Stack oder Stapelspeicher ist ein Datenbereich, der vom Prozessor verwaltet wird und die Aufgabe hat Rücksprungadressen zwischenzuspeichern. Bei einem Unterprogrammaufruf oder bei der Interruptverarbeitung wird der Stackpointer erhöht und dann die Adresse des nächsten Befehls auf den Stack geschoben. Dann wird zum Unterprogramm, bzw. der Interruptroutine verzweigt. Bei Beendigung der Unterroutine mit RET wird die Adresse automatisch vom Stack geholt und dann der Stackpointer erniedrigt. An dieser Adresse fährt der Prozessor dann mit der Abarbeitung fort, also direkt nach dem Unterprogrammaufruf. Aber auch der Programmierer kann den Stack benutzen. Er kann den Stack beispielsweise verwenden um Parameter an Funktionen zu übergeben oder um Register zu sichern. Dazu dienen die Befehle PUSH und POP. Auch PUSH und POP erhöhen und erniedrigen den SP und schieben das angegebene Datum auf den Stack oder holen es von dort (wieder in dieser Reihenfolge: SP erhöhen dann Datentransfer oder Datentransfer, dann SP erniedrigen. Der Stack wächst also nach oben).

Der Stackpointer SP zeigt nach einem Reset auf die Adresse 0x07, wodurch der Stack bei 0x08 beginnt, also bei Registerbank 1. Im Speicher folgen die Registerbank 2 und 3 und dann der Bit adressierbare Speicherbereich. Die Registerbänke und der Bit adressierbare Bereich würden daher bei höherer Stapeltiefe vom Stack überschrieben, können so also nicht benutzt werden. Es ist daher sinnvoll den Stackpointer bei der Initialisierung darüber zu legen, d.h. ab 0x30 oder höher. Bei den Mikrocontrollern mit 256 Byte internem RAM bietet sich der Bereich ab Adresse 0x80 an. Dieser Bereich ist zweigeteilt. Bei direkter Adressierung erfolgt der Zugriff auf SFR, bei indirekter Adressierung auf die zweite Hälfte des internen RAM, der Stack benutzt natürlich das RAM.

Der Datenzeiger DPTR besteht aus den Bytes DPH (data pointer high) und DPL (data pointer low) und ermöglicht Zugriff auf den gesamten 64kByte Speicher. Er wird wie ein 16 Bit Register verwaltet, es gibt also Befehle mit denen direkt ein Wort in den DPTR geschrieben werden kann.

Diese Zusammenhänge werden klarer, wenn man die Adressierungsarten des 8051 versteht.

Die Adressierungsarten

Bei Sprüngen unterscheidet man drei Adressierungsarten

Die Sprungmarken werden dabei als Bezeichner mit nachgestelltem Doppelpunkt definiert und ohne Doppelpunkt referenziert.

label:
        .
        .
        SJMP  label

Der intel Assembler asm51 erlaubt im Gegensatz zum as31 die Verwendung des Pseudo Mnemonics JMP. Der Assembler entscheidet dann selbst, welcher der drei Sprünge ausgeführt wird.

Bei Unterprogrammaufrufen ist es nicht sinnvoll einen eigenen Opcode für kurze Sprünge zu reservieren, es gibt daher nur ACALL und LCALL, keinen SCALL [15], [9], [2].

Auch die Ports können bitweise adressiert werden. Sie sind bidirektional, können also sowohl als Eingang, als auch als Ausgang dienen. Wenn ein Pin als Eingang benutzt werden soll, so muß eine Eins in das Bit des betreffenden Ports geschrieben werden. Dabei ist zu beachten, daß Port 0 im Gegensatz zu den anderen drei Ports Open drain Ausgänge hat, also bei Ausgabe einer Eins stromlos ist. Die anderen Ports besitzen interne Pullups, bei Port 0 muß man diese selbst ergänzen. Bei Benutzung von externem EPROM und/oder RAM werden jedoch ohnehin die Ports 0 und 2 als Adress-/Datenbus benutzt, stehen also zur Ausgabe nicht zur Verfügung. Einige Operationen lesen den Status des Latches am Port, andere geben den Pegel der Pins zurück. Die Operationen, die Werte vom Port lesen, verändern und zurückschreiben sind solche, die das Latch lesen. Dazu zählen die logischen Operationen ANL, ORL, XRL, CPL, sowie INC, DEC, DJNZ und die Bit-Operationen "MOV PX.Y, C", "CLR PX.Y", und "SETB PX.Y". Man nennt das read-modify-write feature. Ein einfaches "MOV var, PX" liest nur das Level der Portpins.

Zeitgeber/Zähler

Eine weitere Einrichtung aller Mikrocontroller sind die Timer, die auch als Counter verwendet werden können. Alle MCS-51 Controller besitzen mindestens die Timer 0 und 1, die 16 Bit breit sind. Die Zählregister des Timers 0, die natürlich 8 Bit Register sind, heißen TL0 und TH0, also TimerLow0 und TimerHigh0 und wirken zusammen als 16 Bit Register wie z.B. auch der DPTR. In der Timer Funktion werden sie mit 1/12 der Oszillatorfrequenz erhöht, ''zählen'' also Maschinenzyklen. Als Zähler werden sie bei einer negativen Flanke inkrementiert. Die Betriebsart wird durch Bits im SFR TMOD eingestellt. Gestartet werden die Timer durch Bits im SFR TCON, das auch die Steuerbits für die entsprechenden Interrupts enthält. Timer 0 und 1 können in vier Betriebsmodi benutzt werden (Einstellung in TCON). In Mode 0 funktionieren sie als 13 Bit Zähler, die Bits 5 bis 7 des TH0 sind also nicht genutzt. Dieser Modus existiert aus Kompatibilitätsgründen zum 8048. In Mode 1 laufen alle 16 Bit. Mode 2 ist der 8 Bit auto reload mode, in dem nur das untere Byte läuft und bei Überlauf das obere Byte in das untere geladen wird. Damit lassen sich z.B. in kurzen Zeitabständen Interrupts auslösen. Enhält das TH0 beispielsweise den Wert 0xF0, so wird dieser in TL0 nachgeladen und der Timer läuft weiter. Erreicht TL0 den Wert 0xFF+1=0x00, läuft also über, dann wird das Flag TF0 gesetzt, das einen Interrupt generieren kann. Das geschieht aber schon nach 0x0F Schritten (0xF0+0x0F=0xFF), die 0x0F*12=192 Oszillatorzyklen dauern, bei 12 MHz sind das 16 mikrosekunden. Es werden also mit 62.5 KHz Interrupts ausgelöst. In Mode 3 ist der Timer angehalten. Der 8052/32 besitzt einen weiteren Timer, den Timer 2. Sein einziges Kontrollregister heißt T2CON. Er kann auch der Baudratengenerierung dienen. Im Siemens SAB80C537 gibt es noch einen weiteren Timer, den compare timer CT, der maximal mit der halben Oszillatorfrequenz laufen kann und in Verbindung mit den Compare Registern CM0 bis CM3 und der compare capture unit ohne Prozessorbelastung PWM Signale generieren kann, näheres dazu natürlich in entsprechenden Handbüchern.

Interrupts

Mikrocontroller der 8051 Reihe besitzen eine Reihe von Interruptmöglichkeiten. Das bedeutet, daß bei Eintreten eines bestimmten Ereignisses die Programmausführung unterbrochen (engl. interrupted) und per LCALL an einer bestimmten Speicheradresse weitergeführt wird. Nach Abarbeitung dieser interrupt service routine wird mit RETI zum unterbrochenen Programm zurückgesprungen und die Interruptbedingung gelöscht. Der Befehl RET würde ebenfalls zurückspringen, die Interruptbedingung würde aber nicht gelöscht. Das würde bei einigen Interrupts dazu führen, daß dieser Interrupt oder auch andere Interrupts gesperrt bleiben. Bei erneutem Auftreten der Interruptbedingung würde dann nicht zur Interruptroutine verzweigt, dann muß die Interruptbedingung in der Interruptroutine per Software gelöscht werden.

Welche Ereignisse aber können Interruptauslöser sein? Das legt die Hardware des Prozessors fest. Beim 8051 gibt es fünf Interruptquellen, beim 8052 sechs. Dazu gehören die externen Interrupts, also Pins des Prozessorchips, die Timer und der serielle Port. Werden die Pins P3.2 und P3.3, auch INT0 und INT1 genannt, auf low gelegt, so verzweigt der Prozessor an die Adressen 0x0003 bzw. 0x0013. Diese Adressen werden auch Interruptvektoren genannt. Auch die Timer lösen bei einem Zählerüberlauf einen Interrupt aus und bei Empfang eines Zeichens über die serielle Schnittstelle oder nach erfolgtem Senden eines Zeichens wird zum seriellen Interrupt verzweigt. Beim seriellen Interrupt muß in der service Routine anhand der Bits RI und TI entschieden werden, ob empfangen, oder erfolgreich gesendet wurde. Je nach Ausstattungsmerkmalen besitzt der Prozessor eine unterschiedliche Anzahl an Interrupts, so erklärt sich schnell das der 8051 nur fünf Interruptquellen, nämlich zwei externe, die Timer 0 und 1 und den seriellen Interrupt besitzt, beim 8052 aber auch der Timer2 Interrupts auslösen kann. Der Dallas 80C320 besitzt statt sechs Interrupts dreizehn. Die zusätzlichen Interrupts sind vier externe Interrupts und weitere von der zweiten seriellen Schnittstelle, vom Watchdog und Power fail. Eine Tabelle der Interruptvektoren findet sich im Anhang. Damit wirklich zur Interruptroutine gesprungen wird, muß nicht nur die Interruptbedingung eintreten, sondern auch der Interrupt eingeschaltet (enabled) sein. Das geschieht einerseits durch Setzen des globalen Interrupt enable Bits EA (enable all) im Register IE (interrupt enable) und dann durch Setzen des individuellen enable Bits, beim Timer0 interrupt beispielsweise das Bit ET0 (IE.1).

Beim Einschalten des Rechners beginnt der Prozessor mit der Programmabarbeitung an der Stelle 0x0000, d.h. an dieser Stelle muß sich bereits ein Programm befinden (Monitorprogramm). Das kann nur ein ROM oder EPROM sein. Kurz darüber liegen aber die Interruptvektoren, so daß auch diese im ROM liegen. Benutzerprogramme könnten also nie Interrupts benutzen. Hinzu kommt, daß zwischen den Vektoren nur wenige Bytes frei sind. Man schreibt daher üblicherweise ins ROM an diese Adressen LJMP's, die in die EPROM Emulation springen. Ein Ausschnitt aus PAULMON sieht folgendermaßen aus:

        .EQU    start,0x0000            ; EPROM start
        .EQU    interrupt, 0xF300       ; interrupt mapping
        .ORG    start+0x0B              ; Timer 0 interrupt
        LJMP    interrupt+0x0200        ; Jump to service Routine

Wenn also der Timer0 überläuft, so verzweigt der Prozessor ins EPROM an die Adresse 0x000B, an der der Befehl LJMP 0xF500 steht. Verwendet man die deutsche PAULMON Version für den 80C320 Prozessor, so steht diese Sequenz bereits im Speicher. Das folgende Programm INTRDEMO.A51, startet den Timer 0, ermöglicht den Interrupt und plaziert eine Interrupt service Routine an der Stelle interrupt+0x0200, die in diesem Fall beispielsweise die LED's blinken läßt. Das Programm zeigt in Kürze die Programmierung des 8255, eines Timers und eines Interrupts und einiges mehr, es lohnt sich also, ein wenig Zeit aufzuwenden um es zu verstehen.

Beispielprogramm

; Ein paar Definitionen
        .EQU    FlagReg, 0x7E
        .FLAG   Linksflag, B.0
        .EQU    Muster, 0x7F
        .EQU    Mod8255, 0x4003         ; 8255 Steuerregister
        .EQU    PortA, 0x4000           ; Port A des 8255
        .EQU    PortB, 0x4001           ; ...
        .EQU    PortC, 0x4002

        .ORG    0x8000                  ; Programmstart
        MOV     dptr, #Mod8255          ; Adresse laden
        MOV     A, #10001001b           ; Ports A und B als Ausgang
        MOVX    @dptr, A                ; Steuerregister schreiben
        MOV     Muster, #00000001b      ; Start-LED Muster

        MOV     TH0,  #0x00             ; 65536*12=786432 Taktzyklen
        MOV     TL0,  #0x00             ; => Frequenz 30.5Hz
        MOV     TMOD, #00000001b        ; Timer0 16 Bit mode
        MOV     TCON, #00010000b        ; Timer0 starten
        MOV     IE,   #10000010b        ; Bits EA und ET0 gesetzt
        RET                             ; Das war's schon
; ******************************************************************
; Jetzt die Interrupt service Routine. 
        .ORG     0xF500                 ; Timer 0 Interrupt
; Da ein Interrupt immer auftreten kann, muessen alle benutzten
; Register durch PUSH gesichert werden
        PUSH    PSW
        PUSH    Acc
        PUSH    B
        PUSH    DPL
        PUSH    DPH
; ============================ cut here ============================
; Jetzt die eigentliche Routine. Sie laesst die 8 LED's der
; Prozessorplatine nach Art des Knight Rider blinken, d.h. eine
; LED laeuft wie ein Ping Pong Ball von links nach rechts und
; wieder zurueck. Fuer das Verstaendnis der Interruptprogrammierung
; ist die eigentliche Routine aber nicht wichtig.
        MOV     B, FlagReg
        MOV     A, Muster               ; LED-Muster laden
        MOV     C, Acc.7                ; erstes und
        ORL     C, Acc.0                ; letztes Bit verodern
        JNC     weiter
        JB      Acc.7, clrl             ; Linkes Ende => rechts
        SETB    Linksflag               ; andernfalls links rollen
        SJMP    weiter
clrl:   CLR     Linksflag
weiter: JB      Linksflag, links
rechts: RR      A                       ; Nach rechts schieben
        SJMP    Ausgab
links:  RL      A			; Nach links schieben
Ausgab: MOV     Muster, A               ; Muster wieder speichern
        MOV     dptr, #PortB            ; Adresse Port B laden
        MOVX    @dptr, A                ; Port B schreiben
        MOV     FlagReg, B
; ============================ cut here ============================
; Die gesicherten Register wiederherstellen
        POP     DPH
        POP     DPL
        POP     B
        POP     Acc
        POP     PSW
        RETI                            ; und zurueckspringen
; ******************************************************************

Nach Programmstart kann mit PAULMON ganz normal weitergearbeitet werden, die LED's blinken interruptgesteuert weiter. Zum Verständnis kann man einmal das RETI ändern in ein normales RET. Das Programm funktioniert dann nicht mehr. Zwischen den beiden Zeilen ''cut here'' kann eigentlich jede beliebige Routine stehen, die nur die Register A, B und DPTR benutzt. sonst müssen zusätzliche PUSH und POP eingefügt werden. Das PSW sollte immer gerettet werden, da man oft Befehle einfügt, die das Carry Flag C benutzen, das im PSW liegt, was leicht vergessen wird.

Zur Programmierung der seriellen Schnittstelle und Arithmetik sei hier auf Paulmon verwiesen.

Literatur

  1. Murray Sargent III: Assemblersprache und Hardware des IBM PC/XT/AT; Bonn: Addison Wesley, 1988
  2. Dr. Ing. Martin Ohsmann: 8051 Mikrocontroller und Assembler Kursus; 3. Auflage. Aachen: Elektor-Verlag, 1993
  3. Prof. Dr.-Ing. D. Zühlke: Script zur Vorlesung Rechneranwendung im Maschinenbau vom Lehrstuhl für Produktionsautomatisierung; Kaiserslautern, 1995
  4. Stefan Seidenberg: Lichtorgel mit Einplatinencomputer; In: Elektor Sonderheft uC-Projekte 2 (Elektor Sonderheft Plus 23) S.10-20, 43
  5. 8031 Fehlerdiagnose; In: Elektor Sonderheft uC-Projekte 2 (Elektor Sonderheft Plus 23) S. 5-9
  6. Rolf-Dieter Klein: Mikrocomputer selbstgebaut und programmiert: vom Baustein zum fertigen Z-80 Computer; 2 Auflage. München, Franzis, 1983
  7. Helmut Weidner: Aktuelles IC-Datenbuch IV
  8. Burkhard Kainka: PC Schnittstellen Angewandt; 3 Auflage. Aachen, Elektor, 1994
  9. intel corporation: Microcontroller Handbook; 1984
  10. Günter Klotz: Bits im Gänsemarsch; In: c't (1986), Nr. 12, S. 185-190
  11. Dallas semiconductors: DS 80C320 High-Speed Micro Data Sheet; http://www.dalsemi.com, 1995
  12. Russ Hersch, russ@silicom.co.il: 8051 FAQ; To be found on:
    	  comp.sys.intel
    	  comp.arch.embedded
    	  comp.robotics
    	  sci.electronics
    	  alt.comp.hardware.homebuilt
    	
    And various FTP sites ..., 1995
  13. Russ Hersch: Microcontroller primer and FAQ; Internet, 1995
  14. Paul Stoffregen: Paul's Sample 8051 Development Board Design. Testing and Getting It To Work: http://www.ece.orst.edu/~paul/8051-goodies/dev-board-testing.html, 1996
  15. Werner Hennig-Roleff: Hardware-Beschreibung des 8051 Mikrocontrollers; Teil der Dokumentation zu SIM51, einem 8051 Simulator. Aus dem Internet. Esslingen: 1991

Anhang

Bauteile Einplatinencomputer

Stück Best. Nr. Bezeichnung Einzelp. Preis
1 - DS80C320 DIL40 18.80 18.80
1 - 62256 CMOS SRAM 8.91 8.91
1 - 74HCT573 1.15 1.15
1 150150 74HCT08 -.95 -.95
1 150398 74CHT138 1.25 1.25
2 - Dioden 1N4148 o.ä. -.20 -.20
1 - Taster für Reset 2.50 2.50
1 - Quarz 24 MHz 1.77 1.77
1 179345 2A 5V Spannungsregler 1.95 1.95
1 528560 Euro beschichtet Epoxy 3.60 3.60
1 162051 27C128 EPROM 7.95 7.95
1 181587 8255AP PIO 6.30 6.30
8 146005 LED, low current, rot -.35 2.80
8 400289 1.8 k -.15 1.20
1 403377 10k -.15 -.15
2 451673 22pF -.30 -.60
1 - Elko 10uF 16V -.50 -.50
1 - Elko 100uF 16V -.50 -.50
2 189588 Sockel 40pol -.90 1.80
2 189570 Sockel 28pol -.70 1.40
1 - Sockel 20pol -.35 -.35
1 - Sockel 16pol -.35 -.35
1 189510 Sockel 14pol -.30 -.30
1 - Buchse 13 pol 3.60 3.60
1 - Stecker 25 pol 4.- 4.-

MCS-51 Opcodes

Code Bytes Zyklus Mnemonic Code Bytes Zyklus Mnemonic
00 1 1 NOP 30 3 2 JNB bitAdr, cAdr
01 2 2 AJMP cAdr 31 2 2 ACALL cAdr
02 3 2 LJMP cAdr 32 1 2 RETI
03 1 1 RR A 33 1 1 RLC A
04 1 1 INC A 34 2 1 ADDC A, #data
05 2 1 INC dAdr 35 2 1 ADDC A, dAdr
06 1 1 INC @R0 36 1 1 ADDC A, @R0
07 1 1 INC @R1 37 1 1 ADDC A, @R1
08 1 1 INC R0 38 1 1 ADDC A, R0
09 1 1 INC R1 39 1 1 ADDC A, R1
0A 1 1 INC R2 3A 1 1 ADDC A, R2
0B 1 1 INC R3 3B 1 1 ADDC A, R3
0C 1 1 INC R4 3C 1 1 ADDC A, R4
0D 1 1 INC R5 3D 1 1 ADDC A, R5
0E 1 1 INC R6 3E 1 1 ADDC A, R6
0F 1 1 INC R7 3F 1 1 ADDC A, R7
10 3 2 JBC bitAdr, cAdr 40 2 2 JC cAdr
11 2 2 ACALL cAdr 41 2 2 AJMP cAdr
12 3 2 LCALL cAdr 42 2 1 ORL dAdr, A
13 1 1 RRC A 43 3 2 ORL dAdr, #data
14 1 1 DEC A 44 2 1 ORL A, #data
15 2 1 DEC dAdr 45 2 1 ORL A, dAdr
16 1 1 DEC @R0 46 1 1 ORL A, @R0
17 1 1 DEC @R1 47 1 1 ORL A, @R1
18 1 1 DEC R0 48 1 1 ORL A, R0
19 1 1 DEC R1 49 1 1 ORL A, R1
1A 1 1 DEC R2 4A 1 1 ORL A, R2
1B 1 1 DEC R3 4B 1 1 ORL A, R3
1C 1 1 DEC R4 4C 1 1 ORL A, R4
1D 1 1 DEC R5 4D 1 1 ORL A, R5
1E 1 1 DEC R6 4E 1 1 ORL A, R6
1F 1 1 DEC R7 4F 1 1 ORL A, R7
20 3 2 JB bitAdr, cAdr 50 2 2 JNC cAdr
21 2 2 AJMP cAdr 51 2 2 ACALL cAdr
22 1 2 RET 52 2 1 ANL dAdr, A
23 1 1 RL A 53 3 2 ANL dAdr, #data
24 2 1 ADD A, #data 54 2 1 ANL A, #data
25 2 1 ADD A, dAdr 55 2 1 ANL A, dAdr
26 1 1 ADD A, @R0 56 1 1 ANL A, @R0
27 1 1 ADD A, @R1 57 1 1 ANL A, @R1
28 1 1 ADD A, R0 58 1 1 ANL A, R0
29 1 1 ADD A, R1 59 1 1 ANL A, R1
2A 1 1 ADD A, R2 5A 1 1 ANL A, R2
2B 1 1 ADD A, R3 5B 1 1 ANL A, R3
2C 1 1 ADD A, R4 5C 1 1 ANL A, R4
2D 1 1 ADD A, R5 5D 1 1 ANL A, R5
2E 1 1 ADD A, R6 5E 1 1 ANL A, R6
2F 1 1 ADD A, R7 5F 1 1 ANL A, R7
Code Bytes Zyklus Mnemonic Code Bytes Zyklus Mnemonic
60 2 2 JZ cAdr 90 3 2 MOV DPTR, #data16
61 2 2 AJMP cAdr 91 2 2 ACALL cAdr
62 2 1 XRL dAdr, A 92 2 2 MOV bitAdr, C
63 3 2 XRL dAdr, #data 93 1 2 MOVC A, @A+DPTR
64 2 1 XRL A, #data 94 2 1 SUBB A, #data
65 2 1 XRL A, dAdr 95 2 1 SUBB A, dAdr
66 1 1 XRL A, @R0 96 1 1 SUBB A, @R0
67 1 1 XRL A, @R1 97 1 1 SUBB A, @R1
68 1 1 XRL A, R0 98 1 1 SUBB A, R0
69 1 1 XRL A, R1 99 1 1 SUBB A, R1
6A 1 1 XRL A, R2 9A 1 1 SUBB A, R2
6B 1 1 XRL A, R3 9B 1 1 SUBB A, R3
6C 1 1 XRL A, R4 9C 1 1 SUBB A, R4
6D 1 1 XRL A, R5 9D 1 1 SUBB A, R5
6E 1 1 XRL A, R6 9E 1 1 SUBB A, R6
6F 1 1 XRL A, R7 9F 1 1 SUBB A, R7
70 2 2 JNZ cAdr A0 2 2 ORL C, /bitAdr
71 2 2 ACALL cAdr A1 2 2 AJMP cAdr
72 2 2 ORL C, bitAdr A2 2 1 MOV C, bitAdr
73 1 2 JMP @A+DPTR A3 1 2 INC DPTR
74 2 1 MOV A, #data A4 1 4 MUL AB
75 3 2 MOV dAdr, #data A5 - - reserved
76 2 1 MOV @R0, #data A6 2 2 MOV @R0, dAdr
77 2 1 MOV @R1, #data A7 2 2 MOV @R1, dAdr
78 2 1 MOV R0, #data A8 2 2 MOV R0, dAdr
79 2 1 MOV R1, #data A9 2 2 MOV R1, dAdr
7A 2 1 MOV R2, #data AA 2 2 MOV R2, dAdr
7B 2 1 MOV R3, #data AB 2 2 MOV R3, dAdr
7C 2 1 MOV R4, #data AC 2 2 MOV R4, dAdr
7D 2 1 MOV R5, #data AD 2 2 MOV R5, dAdr
7E 2 1 MOV R6, #data AE 2 2 MOV R6, dAdr
7F 2 1 MOV R7, #data AF 2 2 MOV R7, dAdr
80 2 2 SJMP cAdr B0 2 2 ANL C, /bitAdr
81 2 2 AJMP cAdr B1 2 2 ACALL cAdr
82 2 2 ANL C, bitAdr B2 2 1 CPL bitAdr
83 1 2 MOVC A, @A+PC B3 1 1 CPL C
84 1 4 DIV AB B4 3 2 CJNE A, #data, cAdr
85 3 2 MOV dAdr, dAdr B5 3 2 CJNE A, dAdr, cAdr
86 2 2 MOV dAdr, @R0 B6 3 2 CJNE @R0, #dat, cAdr
87 2 2 MOV dAdr, @R1 B7 3 2 CJNE @R1, #dat, cAdr
88 2 2 MOV dAdr, R0 B8 3 2 CJNE R0, #data, cAdr
89 2 2 MOV dAdr, R1 B9 3 2 CJNE R1, #data, cAdr
8A 2 2 MOV dAdr, R2 BA 3 2 CJNE R2, #data, cAdr
8B 2 2 MOV dAdr, R3 BB 3 2 CJNE R3, #data, cAdr
8C 2 2 MOV dAdr, R4 BC 3 2 CJNE R4, #data, cAdr
8D 2 2 MOV dAdr, R5 BD 3 2 CJNE R5, #data, cAdr
8E 2 2 MOV dAdr, R6 BE 3 2 CJNE R6, #data, cAdr
8F 2 2 MOV dAdr, R7 BF 3 2 CJNE R7, #data, cAdr
Code Bytes Zyklus Mnemonic Code Bytes Zyklus Mnemonic
C0 2 2 PUSH dAdr E0 1 2 MOVX A, @DPTR
C1 2 2 AJMP cAdr E1 2 2 AJMP cAdr
C2 2 1 CLR bitAdr E2 1 2 MOVX A, @R0
C3 1 1 CLR C E3 1 2 MOVX A, @R1
C4 1 1 SWAP A E4 1 1 CLR A
C5 2 1 XCH A, dAdr E5 2 1 MOV A, dAdr
C6 1 1 XCH A, @R0 E6 1 1 MOV A, @R0
C7 1 1 XCH A, @R1 E7 1 1 MOV A, @R1
C8 1 1 XCH A, R0 E8 1 1 MOV A, R0
C9 1 1 XCH A, R1 E9 1 1 MOV A, R1
CA 1 1 XCH A, R2 EA 1 1 MOV A, R2
CB 1 1 XCH A, R3 EB 1 1 MOV A, R3
CC 1 1 XCH A, R4 EC 1 1 MOV A, R4
CD 1 1 XCH A, R5 ED 1 1 MOV A, R5
CE 1 1 XCH A, R6 EE 1 1 MOV A, R6
CF 1 1 XCH A, R7 EF 1 1 MOV A, R7
D0 2 2 POP dAdr F0 1 2 MOVX @DPTR, A
D1 2 2 ACALL cAdr F1 2 2 ACALL cAdr
D2 2 1 SETB bitAdr F2 1 2 MOVX @R0, A
D3 1 1 SETB C F3 1 2 MOVX @R1, A
D4 1 1 DA A F4 1 1 CPL A
D5 2 2 DJNZ dAdr, cAdr F5 2 1 MOV dAdr, A
D6 1 1 XCHD A, @R0 F6 1 1 MOV @R0, A
D7 1 1 XCHD A, @R1 F7 1 1 MOV @R1, A
D8 2 2 DJNZ R0, cAdr F8 1 1 MOV R0, A
D9 2 2 DJNZ R1, cAdr F9 1 1 MOV R1, A
DA 2 2 DJNZ R2, cAdr FA 1 1 MOV R2, A
DB 2 2 DJNZ R3, cAdr FB 1 1 MOV R3, A
DC 2 2 DJNZ R4, cAdr FC 1 1 MOV R4, A
DD 2 2 DJNZ R5, cAdr FD 1 1 MOV R5, A
DE 2 2 DJNZ R6, cAdr FE 1 1 MOV R6, A
DF 2 2 DJNZ R7, cAdr FF 1 1 MOV R7, A
Basierend auf [9].

MCS-51 Mnemonics

Angabe der Oszillatorzyklen bezogen auf Dallas 80C320. Nach [9], [11].

Arithmetic Operations

Mnemonic Description Byte Osc. Period
ADD A,Rn Add register to Accumulator 1 4
ADD A,direct Add direct byte to Accumulator 2 8
ADD A,@Ri Add indirect RAM to Accumulator 1 4
ADD A,#data Add immediate data to Accumulator 2 8
ADDC A,Rn Add register to Acc. with Carry 1 4
ADDC A,direct Add direct byte to Acc. with Carry 2 8
ADDC A,@Ri Add indirect RAM to Acc. with Carry 1 4
ADDC A,#data Add immediate data to Acc. / Carry 2 8
SUBB A,Rn Subtract reg. from Acc. with borrow 1 4
SUBB A,direct Sub. direct byte from Acc. / borrow 2 8
SUBB A,@Ri Sub. indirect RAM from Acc./ borrow 1 4
SUBB A,#data Sub. imm. data from Acc. / borrow 2 8
INC A Increment Accumulator 1 4
INC Rn Increment register 1 4
INC direct Increment direct byte 2 8
INC @Ri Increment indirect RAM 1 4
INC DPTR Increment Data Pointer 1 12
DEC A Decrement Accumulator 1 4
DEC Rn Decrement register 1 4
DEC direct Decrement direct byte 2 8
DEC @Ri Decrement indirect RAM 1 4
MUL AB Multiply A and B 1 20
DIV AB Divide A by B 1 20
DA A Decimal adjust Accumulator 1 4

Logical Operations

Mnemonic Description Byte Osc. Period
ANL A,Rn AND register to Accumulator 1 4
ANL A,direct AND direct byte to Accumulator 2 8
ANL A,@Ri AND indirect RAM to Accumulator 1 4
ANL A,#data AND immediate data to Accumulator 2 8
ANL direct,A AND Accumulator to direct byte 2 8
ANL direct,#data AND immediate data to direct byte 3 12
ORL A,Rn OR register to Accumulator 1 4
ORL A,direct OR direct byte to Accumulator 2 8
ORL A,@Ri OR indirect RAM to Accumulator 1 4
ORL A,#data OR immediate data to Accumulator 2 8
ORL direct,A OR Accumulator to direct byte 2 8
ORL direct,#data OR immediate data to direct byte 3 12
XRL A,Rn Exc-OR register to Accumulator 1 4
XRL A,direct Exc-OR direct byte to Accumulator 2 8
XRL A,@Ri Exc-OR indirect RAM to Accumulator 1 4
XRL A,#data Exc-OR immediate data to Acc. 2 8
XRL direct,A Exc-OR Accumulator to direct byte 2 8
XRL direct,#data Exc-OR imm. data to direct byte 3 12
CLR A Clear Accumulator 1 4
CPL A Complement Accumulator 1 4
RL A Rotate Accumulator left 1 4
RLC A Rotate Acc. left through Carry 1 4
RR A Rotate Accumulator right 1 4
RRC A Rotate A right through Carry flag 1 4
SWAP A Swap nibbles within the Accumulator 1 4

Data Transfer

Mnemonic Description Byte Osc. Period
MOV A,Rn Move register to Accumulator 1 4
MOV A,direct Move direct byte to Accumulator 2 8
MOV A,@Ri Move indirect RAM to Accumulator 1 4
MOV A,#data Move immediate data to Accumulator 2 8
MOV Rn,A Move Accumulator to register 1 4
MOV Rn,direct Move direct byte to register 2 8
MOV Rn,#data Move immediate data to register 2 8
MOV direct,A Move Accumulator to direct byte 2 8
MOV direct,Rn Move register to direct byte 2 8
MOV direct,direct Move direct byte to direct byte 3 12
MOV direct,@Ri Move indirect RAM to direct byte 2 8
MOV direct,#data Move immediate data to direct byte 3 12
MOV @Ri,A Move Accumulator to indirect RAM 1 4
MOV @Ri,direct Move direct byte to indirect RAM 2 8
MOV @Ri,#data Move immediate data to indirect RAM 2 8
MOV DPTR,#data16 Load Data Pointer with 16-bit const 3 12
MOVC A,@A+DPTR Move Code byte rel. to DPTR to Acc. 1 12
MOVC A,@A+PC Move Code byte rel. to PC to Acc. 1 12
MOVX A,@Ri Move Ext. RAM (8-bit addr.) to Acc. 1 8-36
MOVX A,@DPTR Move Ext. RAM (16-bit addr) to Acc. 1 8-36
MOVX @Ri,A Move Acc. to Ext. RAM (8-bit addr.) 1 8-36
MOVX @DPTR,A Move Acc. to Ext. RAM (16-bit addr) 1 8-36
PUSH direct Push direct byte onto stack 2 8
POP direct Pop direct byte from stack 2 8
XCH A,Rn Exchange register with Accumulator 1 4
XCH A,direct Exchange direct byte with Acc. 2 8
XCH A,@Ri Exchange indirect RAM with Acc. 1 4
XCHD A,@Ri Exchange low order digit indirect RAM with Accumulator 1 4

Boolean Variable Manipulation

Mnemonic Description Byte Osc. Period
CLR C Clear Carry 1 4
CLR bit Clear direct bit 2 8
SETB C Set Carry 1 4
SETB bit Set direct bit 2 8
CPL C Complement Carry 1 4
CPL bit Complement direct bit 2 8
ANL C,bit AND direct bit to Carry 2 8
ANL C,/bit AND complement of dir. bit to Carry 2 8
ORL C,bit OR direct bit to Carry 2 8
ORL C,/bit OR complement of dir. bit to Carry 2 8
MOV C,bit Move direct bit to Carry 2 8
MOV bit,C Move Carry to direct bit 2 8

Program and Machine Control

Mnemonic Description Byte Osc. Period
ACALL addr11 Absolute subroutine call 2 12
LCALL addr16 Long subroutine call 3 16
RET Return from subroutine 1 16
RETI Return from interrupt 1 16
AJMP addr11 Absolute jump 2 12
LJMP addr16 Long jump 3 16
SJMP rel Short jump (relative address) 2 12
JMP @A+DPTR Jump indirect relative to the DPTR 1 12
JZ rel Jump if Accumulator is zero 2 12
JNZ rel Jump if Accumulator is not zero 2 12
DJNZ Rn,rel Decr. register and jump if not zero 2 12
DJNZ direct,rel Decrement direct byte and jump if not zero 3 16
CJNE A,direct,rel Compare direct byte to Accumulator and jump if not equal 3 16
CJNE A,#data,rel Compare immediate data to Accumulator and jump if not equal 3 16
CJNE Rn,#data,rel Compare immediate data to register and jump if not equal 3 16
CJNE @Ri,#data,rel Compare immediate data to indirect RAM and jump if not equal 3 16
JC rel Jump if Carry is set 2 12
JNC rel Jump if Carry not set 2 12
JB bit,rel Jump if direct bit is set 3 16
JNB bit,rel Jump if direct bit is not set 3 16
JBC bit,rel Jump if dir. bit is set & clear bit 3 16
NOP No operation 1 4
Notes on Instruction Set and Addressing Modes

Special Function Registers (SFR's)

Symbol Name Address
* ACC Accumulator 0xE0
* B B Register 0xF0
* PSW Program Status Word 0xD0
SP Stack Pointer 0x81
DPTR Data Pointer (2 bytes)
DPH Data Pointer High Byte 0x83
DPL Data Pointer Low Byte 0x82
! DPTR1 Data Pointer 1 (2 bytes)
! DPH1 Data Pointer 1 High Byte 0x85
! DPL1 Data Pointer 1 Low Byte 0x84
! DPS Data Pointer select 0x86
* P0 Port 0 0x80
* P1 Port 1 0x90
* P2 Port 2 0xA0
* P3 Port 3 0xB0
* IP Interrupt Priority Control 0xB8
* IE Interrupt Enable Control 0xA8
* TCON Timer/Counter Control 0x88
TMOD Timer/Counter Mode Control 0x89
+* T2CON Timer/Counter 2 Control 0xC8
TH0 Timer/Counter 0 High Byte 0x8C
TL0 Timer/Counter 0 Low Byte 0x8A
TH1 Timer/Counter 1 High Byte 0x8D
TL1 Timer/Counter 1 Low Byte 0x8B
! CKCON Clock control 0x8E
+ TH2 Timer/Counter 2 High Byte 0xCD
+ TL2 Timer/Counter 2 Low Byte 0xCC
+ RCAP2H Timer/Counter 2 Capture Register High Byte 0xCB
+ RCAP2L Timer/Counter 2 Capture Register Low Byte 0xCA
! EXIF Extended interrupt flag Register 0x91
* SCON Serial Control 0x98
SBUF Serial Data Buffer 0x99
! SCON1 Serial Control 1 0xC0
! SBUF1 Serial Data Buffer 1 0xC1
! TA Timed access register 0xC7
! WDCON Watch Dog Control 0xD8
! EIE Extended Interrupt Enable 0xE8
! EIP Extended Interrupt Priority 0xF8
PCON Power Control 0x87
where

PSW - Program Status Word

bit description symbol
B7 carry flag CY
B6 auxiliary carry flag AC
B5 general purpose status flag F0
B4 register bank select bit 1 RS1
B3 register bank select bit 0 RS0
B2 overflow flag OV
B1 user definable FL
B0 parity of accumulator P

  • Carry Flag: This is the carry bit used in many 8051 instructions. Thus, the instruction CLR CY is functionally identical to the instruction CLR C, although the first option requires 2 bytes of code whereas the second option requires only 1.

  • Auxiliary Carry Flag: This bit is used when adding BCD values. The bit is set when a carry from bit 3 to bit 4 occurs, or when the value of bits 0-3 is in the 0A-0F range. Either of these conditions indicate an invalid BCD number.

  • Flag 0: This flag is not used by the 8051, so may be used in user applications however the programmer desires.

  • Register Bank Select bits 1/0: These two bits select which "R" Register bank is currently active.

    RS1 RS0 Register Bank Address
    0 0 0 0x00..0x07
    0 1 1 0x08..0x0F
    1 0 2 0x10..0x17
    1 1 3 0x18..0x1F

  • Overflow Flag: The overflow flag indicates an overflow in an arithmetic operation when the operands are signed values. For example, if you are working with a signed value of 120 and add a signed value of 50, the result is 170. However, 170 is outside the range of a signed byte and thus the result is invalid. In this case, the overflow flag would be set. If you are dealing with unsigned values the contents of the Overflow flag can and should be ignored.

  • Parity Flag: This flag is a parity bit that always establishes even parity with the contents of the accumulator. The number of set bits in the accumulator plus the parity bit is always an even number. Thus, if the accumulator contains the value 0x41 (which is 01000001 in binary), the parity bit would contain a 0 (two 1-bits in the accumulator + 0 in the partiy bit = 2, an even number). If the accumulator contains the value 0x43 (which is 01000011 in binary) the parity bit would contain a 1 (three 1-bits in the accumulator + 1 in the parity bit = 4, an even number). This is very useful when calculating parity bits for communications.

    DPS - Data Pointer select

    bit description symbol
    B7-B1 reserved none
    B0 Select DPRT0 or DPTR1 SEL

    IE - Interrupt Enable Control

    This register controls whether each Interrupt will jump to a corresponding Interrupt Service Routine. If an Interrupt is not enabled, software can still test for it's Interrupt Flag to validate whether or not an Interrupt would have happened. However, if the Interrupt is enabled the Interrupt flag will automatically provoke the corresponding Interrupt Service Routine.

    bit description symbol
    B7 EA=0: disable all interrupts EA
    B6 enable serial port 1 interrupt ES1 *
    B5 enable timer 2 interrupt ET2 *
    B4 enable serial port interrupt ES0 (ES)
    B3 enable timer 1 overflow interrupt ET1
    B2 enable external interrupt 1 EX1
    B1 enable timer 0 overflow interrupt ET0
    B0 enable external interrupt 0 EX0

    IP - Interrupt Priority Control

    The 8051 works with two interrupt priority levels. The register IP defines the priority levels for each interrupt. A logical one selects the higher priority level. Interrupts cannot be interrupted by another interrupt of the same or lower priority. Yet it can be interrupted by an interrupt with higher priority.

    bit description symbol
    B7 reserved none
    B6 priority of serial port1 interrupt PS1 *
    B5 priority of timer 2 interrupt PT2
    B4 priority of serial port interrupt PS0 (PS)
    B3 priority of timer 1 interrupt PT1
    B2 priority of external interrupt 1 PX1
    B1 priority of timer 0 interrupt PT0
    B0 priority of external interrupt 0 PX0

    TCON - Timer/Counter Control

    The flags are set by hardware if overflow occurs. They are cleared by hardware when Processor vectors to interrupt routine. TR1 is used by software to turn on the timer. The trigger control bits select if interrupt occurs on falling edge or on low level (counter mode).

    bit description symbol
    B7 timer 1 overflow flag TF1
    B6 timer 1 run (on/off) control TR1
    B5 timer 0 overflow flag TF0
    B4 timer 0 run (on/off) control TR0
    B3 interrupt 1 edge flag IE1
    B2 interrupt 1 trigger control bit IT1
    B1 interrupt 0 edge flag IE0
    B0 interrupt 0 trigger control bit IT0

  • Timer 1 Overflow Flag: This bit is automatically set by the 8051 whenever Timer 1 overflows; that is, whenever Timer 1 is incremented from 0xFFFF back to 0x0000. If Interrupt Service Routines are enabled, this flag is automatically cleared by the 8051. If ISRs are not enabled, the software is responsible for clearing the Overflow Flag.

  • Timer 1 Run (On/Off): This bit controls whether or not Timer 1 is currently running. If the bit is set, Timer 1 will be running. If the bit is not set, Timer 1 will be stopped.

  • Timer 0 Overflow Flag/Timer 0 Run (On/Off): These two bits serve the same purpose as the first two described, but apply to Timer 0.

    T2CON - Timer/Counter 2 Control

    bit description symbol
    B7 Timer 2 overflow flag TF2
    B6 Timer 2 external flag set when either a capture or reload is caused by a negative transition on T2EX end EXEN=1. CPU vectors to Timer2 interrupt routine. Flag must be cleared by software EXF2
    B5 Receive clock flag RCLK
    B4 Transmit clock flag TCLK
    B3 Timer 2 external enable flag EXEN2
    B2 start/stop Timer2. 1 -> start TR2
    B1 timer or counter select C/T2
    B0 capture reload flag CP/RL2
    RCLK+ TCLK CP/ RL2 TR2 Mode descr.
    0 0 1 16 Bit auto reload
    0 1 1 16 Bit capture
    1 X 1 baud rate generator
    X X 0 (off)

    TMOD - Timer/Counter Mode Control

    bit description symbol
    B7 0 = t/c 1 enabled via TR1 1 = t/c enabled via INT1 + TR1 GATE
    B6 Type: timer = 0, counter = 1 T/C
    B5 operating modes t/c 1 M1
    B4 operating modes t/c 1 M0
    B3 0 = t/c 0 enabled via TR0 1 = t/c enabled via INT0 + TR0 GATE
    B2 Type: timer = 0, counter = 1 T/C
    B1 operating modes t/c 0 M1
    B0 operating modes t/c 0 M0

    Code Mode descr.
    00 TLx serves as 5-bit prescaler
    01 16-bit t/c THx & TLx are cascaded
    10 8-bit auto reload, valTHx is loaded in TLx when TLx overflows
    11 TL0 is an 8-bit t/c controlled by Timer 0 controlbits. TH0 is an 8-bit t/c controlled by Timer 1 controlbits. (two independent 8 Bit counters). t/c 1 stopped

    CKCON - Clock Control

    bit description symbol
    B7 Watchdog timing Bit 1 WD1
    B6 Watchdog timing Bit 0 WD0
    B5 Timer 2 mode. The original 8051 uses 12 clock per cycle scheme for timers. The 80C320 timers can be set to run at 4 clocks. T2M
    B4 Timer 1 mode T1M
    B3 Timer 0 mode T0M
    B2 Mode flag for RAM access MD2
    B1 Mode flag for RAM access MD1
    B0 Mode flag for RAM access MD0
    MD2 MD1 MD0 Memory cycles RD/WR strobe width in clocks Strobe width @ 25 MHz
    0 0 0 2 2 80ns
    0 0 1 3 (default) 4 160ns
    0 1 0 4 8 320ns
    0 1 1 5 12 480ns
    1 0 0 6 16 640ns
    1 0 1 7 20 800ns
    1 1 0 8 24 960ns
    1 1 1 9 28 1120ns
    WD1 WD0 Interrupt time out Time (@ 25 MHz)
    0 0 2^17 clocks 5.243ms
    0 1 2^20 clocks 41.94ms
    1 0 2^23 clocks 335.54ms
    1 1 2^26 clocks 2684.35ms
    If enabled, the Watchdog generates an interrupt after the time specified above. After another 512 clocks, the Microcontroller is reset if the Watchdog is not cleared. This can be used as a convenient time-base generator or to wake up the processor from idle mode.

    WDCON - Watch dog Control

    bit description symbol
    B7 Double baud rate bit SMOD1
    B6 ? POR
    B5 Power fail interrupt enable EPFI
    B4 Power fail interrupt PFI
    B3 interrupt flag set when there are 512 clocks left until reset WDIF
    B2 flag is set when reset has occured WTRF
    B1 enable watchdog timer EWT
    B0 restart (clear) Watchdog RWT
    The Bits EWT, RWT, WDIF, POR and BGS and are protected against an accidental write operation by Timed Access. This procedure requires that the write of a protected bit be preceded by the following instructions:
            MOV 0xC7, #0xAA
            MOV 0xC7, #0x55
    
    The hardware opens a two cycle window that allows software to modify one of the protected bits. If the instruction that seeks to modify the protected bit is not immediately proceeded by these instructions, the write will not take effect.

    EIE - Extended Interrupt Enable

    bit description symbol
    B7 reserved none
    B6 reserved none
    B5 reserved none
    B4 Enable Watch dog interrupt EWDI
    B3 enable external interrupt 5 EX5
    B2 enable external interrupt 4 EX4
    B1 enable external interrupt 3 EX3
    B0 enable external interrupt 2 EX2

    EIP - Extended Interrupt Priority

    bit description symbol
    B7 reserved none
    B6 reserved none
    B5 reserved none
    B4 priority of Watch dog interrupt PWDI
    B3 priority of external interrupt 5 PX5
    B2 priority of external interrupt 4 PX4
    B1 priority of external interrupt 3 PX3
    B0 priority of external interrupt 2 PX2

    EXIF - Extended interrupt flag

    bit description symbol
    B7 interrupt 5 edge flag IE5
    B6 interrupt 4 edge flag IE4
    B5 interrupt 3 edge flag IE3
    B4 interrupt 2 edge flag IE2
    B3 reserved none
    B2 Ring mode flag set by hardware RGMD
    B1 Ring select. Come out of stop mode with ring osc. RGSL
    B0 Band gap reference enable during stop mode BGS

    SCON0/SCON1 - Serial Control

    bit description symbol
    B7 serial port mode bit 0 SM0
    B6 serial port mode bit 1 SM1
    B5 enable multiprocessorfeature in modes 2 & 3, RI will not be activated if RB8=0 & SM2=1. In mode 1 RI will not be activated if stop bit was invalid & SM2=1. SM2 should be 0 in mode 0 SM2
    B4 enable reception REN
    B3 in modes 2 & 3 9-th bit tx TB8
    B2 in modes 2 & 3 9-th bit rx mode1 ; if SM2=0 RB8=stop bit value mode0 ; not used RB8
    B1 Tx interrupt flag mode0 : set by 8-th bit time other modes : set by beginning of stop bit TI
    B0 Rx interrupt flag RI
    SM0 SM1 Mode descr. Baudrate
    0 0 1: shift register f_osc/12
    0 1 2: 8-bit UART variable
    1 0 3: 9-bit UART f_osc/64 or f_osc/32
    1 1 4: 9-bit UART variable

  • Multiprocessor Operation: When the serial port is in a 9-bit UART mode (selected with SM1 and SM0) above), selecting Multiprocessor Operation is a powerful way to control other 8051 slaves. This will be discussed at greater length later.

  • Receiver Enable: This bit must be set in order for the serial port to accept input. Generally, you will want to set this whenever you are using the serial port.

  • Transmit Bit 8/Receive Bit 8: These are used in conjunction with the Multiprocessor Operation mode. They will be discussed at greater length later.

  • Transmit Interrupt Flag: This bit is automatically set by the 8051 when it has completed the transmission of the last byte you sent to the Serial Port. Sending bytes to the serial port basically requires the following process: 1) Wait until the Transmit Interrupt bit is set. 2) Clear the Transmit Interrupt bit. 3) MOV the next character to send into the SBUF register. It is important to wait for the Transmit Interrupt bit to be set before sending the next character; otherwise, you'll send output to the Serial Port faster than the port can send it out and you'll get garbled results.

  • Receive Interrupt Flag: This bit is automatically set by the 8051 when it has completely received a full character in the input buffer. When the bit is set you may read the contents of SBUF to get the value of the character received. Receiving bytes on the serial port requires the following basic process: 1) Wait until the Receive Interrupt bit is set. 2) Clear the Receive Interrupt bit. 3) Read the SBUF register for the value of the character received.

    PCON - Power Control

    The power control register is only available in CMOS versions. The highest bit SMOD selects if the baud rate is divided by two (SMOD = 0) or not.
    bit description symbol
    B7 Double baud rate bit SMOD
    B6 reserved none
    B5 reserved none
    B4 reserved none
    B3 General purpose flag GF1
    B2 General purpose flag GF0
    B1 Power down bit PD (STOP)
    B0 Idle mode bir IDL

    Interrupts

    Address description minimum
    0x33 Power Fail interrupt 80C320
    0x03 External interrupt 0 all
    0x0B Timer 0 all
    0x13 External interrupt 1 all
    0x1B Timer 1 all
    0x23 TI0 or RI0 from serial port 0 all
    0x2B Timer 2 8052
    0x3B TI1 or RI1 from serial port 1 80C320
    0x43 External interrupt 2 80C320
    0x4B External interrupt 3 80C320
    0x53 External interrupt 4 80C320
    0x5B External interrupt 5 80C320
    0x63 Watchdog Time-out interrupt 80C320

    8051 Pinout

    The 8051 follows the standard convention for numbering pins: Pin #1 is indicated by "the dot," and numbering continues sequentially counter-clockwise around the chip.

    PinNameDescriptionType
    1P1.0 or T2Port 1 Bit 0 or Timer 2 External InputInput/Output
    2P1.1 or T2CAPPort 1 Bit 1 or Timer 2 External Reload/CaptureInput/Output
    3P1.2Port 1 Bit 2Input/Output
    4P1.3Port 1 Bit 3Input/Output
    5P1.4Port 1 Bit 4Input/Output
    6P1.5Port 1 Bit 5Input/Output
    7P1.6Port 1 Bit 6Input/Output
    8P1.7Port 1 Bit 7Input/Output
    9ResetSystem ResetInput
    10P3.0 or RXDPort 3 Bit 0 or Serial ReceiveInput/Output
    11P3.1 or TXDPort 3 Bit 1 or Serial TransmitInput/Output
    12P3.2 or INT0Port 3 Bit 2 or External Interrupt 0Input/Output
    13P3.3 or INT1Port 3 Bit 3 or External Interrupt 1Input/Output
    14P3.4 or T0Port 3 Bit 4 or Timer 0 External InputInput/Output
    15P3.5 or T1Port 3 Bit 5 or Timer 1 External InputInput/Output
    16P3.6 or WRPort 3 Bit 6 or Write Strobe for External MemoryInput/Output
    17P3.7 or RDPort 3 Bit 7 or Read Strobe for External MemoryInput/Output
    18XTAL1Crystal InputInput
    19XTAL2Crystal OutputOutput
    20VSSCircuit GroundInput
    21P2.0 or Addr8Port 2 Bit 0 or Address bit 8Input/Output
    22P2.1 or Addr9Port 2 Bit 1 or Address bit 9Input/Output
    23P2.2 or Addr10Port 2 Bit 2 or Address bit 10Input/Output
    24P2.3 or Addr11Port 2 Bit 3 or Address bit 11Input/Output
    25P2.4 or Addr12Port 2 Bit 4 or Address bit 12Input/Output
    26P2.5 or Addr13Port 2 Bit 5 or Address bit 13Input/Output
    27P2.6 or Addr14Port 2 Bit 6 or Address bit 14Input/Output
    28P2.7 or Addr15Port 2 Bit 7 or Address bit 15Input/Output
    29PSENProgram Store Enable (Read Strobe for External Code Memory)Output
    30ALEAddress Latch EnableOutput
    31EAExternal Access for Program MemoryInput
    32P0.7 or Addr7/Data7Port 0 Bit 7 or Address bit 7/Data bit 7Input/Output
    33P0.6 or Addr6/Data6Port 0 Bit 6 or Address bit 6/Data bit 6Input/Output
    34P0.5 or Addr5/Data5Port 0 Bit 5 or Address bit 5/Data bit 5Input/Output
    35P0.4 or Addr4/Data4Port 0 Bit 4 or Address bit 4/Data bit 4Input/Output
    36P0.3 or Addr3/Data3Port 0 Bit 3 or Address bit 3/Data bit 3Input/Output
    37P0.2 or Addr2/Data2Port 0 Bit 2 or Address bit 2/Data bit 2Input/Output
    38P0.1 or Addr1/Data1Port 0 Bit 1 or Address bit 1/Data bit 1Input/Output
    39P0.0 or Addr0/Data0Port 0 Bit 0 or Address bit 0/Data bit 0Input/Output
    40VCCSupply VoltageInput



    System Reset: Pin 9 is the System Reset trigger. A logical high on this pin causes the chip to reset.



    Write Strobe for External Memory: Whenever an instruction is executed by the 8051 which requires that external data memory (RAM) be written to, pin 16 is strobed to execute the write operation.



    Read Strobe for External Memory: Whenever an instruction is executed by the 8051 which requires that external data memory (RAM) be read from, pin 17 is strobed to execute the write operation.



    Program Store Enable: Whenever the 8051 needs to access External Code Memory (to get an instruction, etc.), pin 29 is strobed to execute the read operation.



    Address Latch Enable: As one of the steps of accessing external memory (both code and data memory), the 8051 stores the low-byte of the address on pins 32 through 39. Whenever the low-byte of an address is being stored on pins 32 through 39 the ALE pin will be strobed. Whenever the ALE pin is strobed, the contents of pins 32 through 39 should be "latched" with an Octal Latch.



    External Access: Pin 31 is used to tell the 8051 whether to run code from within the 8051 chip or to use External Code Memory (such as an EPROM or whatever storage device is connected to External Code Memory). If +5 Volts is applied to this pin, the 8051 will run the program stored within the chip. Otherwise, External Code Memory will be used. Note: It only makes sense to apply +5 Volts (i.e. run the program stored within the 8051) if you are using some version of the 8051 that actually allows you to store a program within the chip, like the 8051AH-BASIC. A true 8051 has no on-chip code memory and it is undefined what happens if you tell it to run the on-chip code if there isn't any.


    Intel-HEX-Format

    Der vom Crossassembler erzeugte Objektcode muß ins Zielsystem geladen werden. Als Zielsystem dient entweder ein EPROM oder die EPROM Emulation eines Einplatinencomputers oder aber ein Emulator oder Simulator. Üblich ist die Übertragung des Objektfiles in hexadezimalem Format, eher selten als binärfile. Es gibt verschiedene Standards, ein hex File abzulegen, die wichtigsten sind das intel und das Motorola hex File Format, die von jedem guten EPROM Brenner verstanden werden. Elektor und Tektronix haben ihre eigenen Formate entwickelt.

    Beim intel hex Format ist das erste Zeichen einer Zeile ein Doppelpunkt. Es signalisiert den Start der Datenübertragung. Das folgende Byte gibt die Anzahl der in dieser Zeile enthaltenen Code Bytes an. Danach folgt ein Wort (4 Ascii-Ziffern) mit der Adresse des ersten in dieser Zeile enthaltenen Code-Bytes.

    Das nachfolgende Byte gibt Über den Typ dieses Records Aufschluß:

    Danach folgen soviele Code Bytes wie im 1. Byte angegeben. Das letzte Byte ist eine PrÜfsumme, gebildet aus dem Zweierkomplement der Quersumme Über alle Bytes dieser Zeile (ohne high Byte).

    Beispiele:
    :03FF0A000204D21C = Zeile mit 03 Codebytes ab Adresse 0xFF0Ah: 02 04 D2
    :00000001FF = Ende-Flag mit 0 Code-Bytes, Kennung 01

    Copyright und Haftung

    Diese mcs-51 Dokumentation ist geschrieben und Copyright ©1996 Arnd Kobus.

    Hiermit erlaube ich die Nutzung, Vervielfältigung und Veränderung ohne Gebühr für private, nichtkommerzielle Nutzung, solange die Copyrightnotiz, mein Name und diese Kopiererlaubnis und die Haftungsbestimmungen in allen Kopien unverändert erscheint und die Veränderungen am Werk namentlich gekennzeichnet werden.

    Der Autor Arnd Kobus ist unter keinen Umständen verantwortlich für Schäden, gleich welcher Art, ob finanziell oder persönlich, die durch die Benutzung der präsentierten Information und Software ergeben und macht keine Aussage über die Nützlichkeit und Richtigkeit der Information oder Brauchbarkeit zu irgendeinem Zweck. Die Information wird in vorliegender Form zur Verfügung gestellt, jedoch tragen SIE, der Benutzer allein die Risiken bei deren Benutzung.


    Back to my home page

    Fragen, Kommentare, Kritik und Fehlermeldungen betreffend der vorgestellten Information bitte an Arnd Kobus/ kobus@student.uni-kl.de.

    Diese Seite ist http://www.student.uni-kl.de/~kobus/8051doc.html