Der Makrocompiler MC ist ein Werkzeug zur vereinfachten Programmierung von Mikrocontrollern. Der Anwender kann auch ohne Vorerfahrungen nach geringer Einarbeitungszeit bereits einfache Programme entwickeln. Insbeson-dere kleine und mittlere Aufgaben lassen sich daher mit sehr geringem Zeitaufwand lösen. Der erzeugte Programmcode ist extrem kurz und schnell, so daß sich auch zeitkritische Programme schreiben lassen. Einige höhere Programmstrukturen stellen eine erhebliche Erleichterung gegenüber der Assembler-Programmierung dar. Zudem werden zahlreiche mögliche Fehlerquellen ausgeschlossen und typische Probleme der Programmentwicklung durch die feste Zuordnung von Prozessor-Ressourcen und Programmstrukturen vermieden.
Der Compiler ist als Vollversion und als Freeware mit leicht eingeschränktem Funktionsumfang für spezielle Prozessoren und Systeme erhältlich. Die freien Versionen können hier geladen werden:
MC48 für das ES48 mit 8048-Controller (ES48.zip, 124K)
MC51 für das ES51 und beliebige 8051-Controller (ES51.zip 190K)
MC535 für das ES535 mit 80C535-Controller (ES535.zip 228 K)
MCSIOS für das SIOS-Interface (MCSIOS.zip 86 K)
MC2051 für beliebige Systme mit dem Flash-Controller 89C2051 (MC2051.zip, 59K)
Handbuch der MC-Vollversion
Das Programm MC.EXE stellt eine integrierte Entwicklungsumgebung mit Editor, Compiler, Übertragungspro-gramm, Terminalprogramm und Code-Editor für beliebige Mikrocontroller-Systeme mit 8048-, 5051- und 80535-Prozessoren bereit. Insbesondere werden die Entwicklungssysteme ES48, ES51 und ES535 von Modul-Bus unterstützt.
Der Makrocompiler ist für die Mikrocontroller 8048, 8051 oder 80535 konfigurierbar. Alle relevanten Einstellungen sind in der Configurationsdatei MC.CFG eingetragen und können im Option-Menü verändert werden. Bei der Aus-lieferung enthält MC.CFG die Einstellungen für MC535 und das Entwicklungssystem ES535.
Vor dem ersten Gebrauch sollten Sie eine Sicherheitskopie der Programmdiskette machen. Soll das Programm auf einer Festplatte installiert werden, dann kann es z.B. mit COPY *.* in das entsprechende Verzeichnis (z.B. C:\MC) kopiert werden. Für eine ordnungsgemäße Funktion müssen mindestens die Dateien MC.EXE, MCxx.HLP MC.CFG und die Code-Tabellen MC48.TAB bis MC535.TAB im selben Verzeichnis stehen.
Dateien: MC.EXE : Das Compilerprogramm MCxx.TAB : Die Übersetzungstabellen des Compilers MCxx.HLP : Hilfetexte *.M48 : MC48-Quelltexte für 8048 *.M51 : MC51-Quelltexte für 8051 *.M35 : MC535-Quelltexte für 80535 *.BIN : Ausgabefile des Compilers im Binärformat
Der Programmaufruf MC startet das Programm mit den Einstellungen in MC.CFG. Voreingestellt ist der 80535-Prozessor und der Betrieb über die zweite serielle Schnittstelle (COM2). Die entsprechenden Dateien MC48.CFG, MC51.CFG und MC535.CFG stellen geeignete Muster für die Entwicklungssysteme ES48, ES51 und ES535 dar und können im Option-Menü geladen werden.
Bei der Programmentwicklung sind typisch folgende Schritte zu durchlaufen.
1.Ein Quelltext wird geladen oder neu eingegeben.
2. Das Programm wird compiliert. Falls der Compiler einen Fehler erkennt,
wird mit einer Fehlermeldung in den Editor verzweigt. Ein übersetztes
Programm kann als Binärfile abgespeichert werden.
3. Wenn ein Entwicklungssystem (ES48...ES535) angeschlossen ist, kann das
compilierte Programm ins RAM des Systems übertragen und unmittelbar
gestartet werden.
4. Zu Testzwecken kann über die Terminalfunktion ein Datenaustausch
mit dem Entwicklungssystem durchgeführt werden.
5. Bei Badarf läßt sich das compilierte Programm im Hexedit-Menü
editieren. Es können auch bereits compilierte oder assemblierte Programme
geladen und gestartet werden.
Nach dem Start befindet sich das Programm im Hauptmenü. Menüpunkte können durch ihre Anfangsbuchstaben oder durch Verschieben des Leuchtbalkens mit den Pfeiltasten und <Return> ausgewählt werden. Alternativ kann eine einfache Maussteuerung verwendet werden, wobei die linke Maustaste der Return-Taste entspricht und die rechte Maustaste der Esc- Taste.
File Laden und Speichern von MC-Quelltexten. File/Load Ein Dateimenü erlaubt die Auswahl eines Quelltextes *.M35 (bzw. M51, M48, je nach eingestelltem Prozessor). Verläßt man das Menü mit Esc, dann kann eine beliebige andere Datei direkt angegeben und geladen werden. Nach dem Laden eines Quelltextes springt das Programm in den Editor. File/New Der Editor wird für ein neues Programm mit leerem Text aufgerufen. Dem zu bearbeitenden neuen Quelltext wird der Name "NEW.M35" (bzw. NEW.M51, NEW.M48) zugewiesen, der aber auch geändert werden kann. File/Save Der Quelltext wird unter dem aktuellen Namen abgespeichert. Der Name kann auch verändert werden. File/Help Der aktuelle Hilfetext zum Sprachumfang von MC wird gezeigt. File/Quit Rückkehr ins Betriebssystem. Edit Der Editor dient zum Eingeben oder Verändern von Quelltexten. Die Bedienung ist weitgehend WordStar- kompatibel. Nur die Blockoperationen funktionieren etwas anders: ein Block wird nicht vorher markiert, sondern man gibt Anfang und Ende des Blocks durch die Cursorposition an. Aus dem Editor heraus kann mit <F1> das Hilfesystem aufgerufen werden. Beim Verlassen des Editors mit Esc wird der Text in der Datei WORK.M35 (bzw. WORK.M48, WORK.M51) abgespeichert. Diese Datei enthält also immer die letzte Version eines bearbeiteten Programms, so daß sich die aktuelle Arbeit im Notfall wiederherstellen läßt. Die folgende Übersicht zeigt die verfügbaren Editor-Kommandos: Editor verlassen : Esc oder F10 Hilfe aufrufen : F1 Einfügen/Überschreiben : Ins (Einfg) - Taste Zeile löschen : Ctr-Y Blockbefehle: Block kopieren : Ctr-K C Block verschieben : Ctr-K V Block löschen : Ctr-K Y Block laden : Ctr-K R Block speichern : Ctr-K W Compile Übersetzung des Quelltextes in lauffähigen Programmcode. Compile/Compile Der Compiler übersetzt den Quelltext unter Verwendung der Übersetzungstabelle MC353.TAB (bzw. MC48.TAB, MC51.TAB). Der Übersetzungsvorgang kann am Bildschirm verfolgt werden. Er kann mit einer beliebigen Taste angehalten und fortgesetzt werden. Bei fehlerfreiem Quelltext erscheint am Ende der Übersetzung eine Liste des erzeugten Programmcodes. Wenn während der Übersetzung ein Fehler festgestellt wird, bricht MC den Vorgang ab, springt automatisch in den Editor und stellt den Cursor auf die fehlerhafte Zeile. Compile/Save Das compilierte Programm wird mit der Kennung .BIN als reines Binärfile abgespeichert. In dieser Form kann es später im Hexedit-Menü erneut geladen und gestartet werden. Run Compilierte Programme werden über die serielle Schnittstelle in das angeschlossene Entwicklungssystem übertragen und gestartet. Es stehen verschiedene Übertragungsprotokolle zur Verfügung, die im Option-Menü ausgewählt werden können und weiter unten genauer erläutert werden. Die Funktion Run kann zeitsparend sofort nach dem Verlassen des Editors unter Umgehung des Compiler-Menüs aufgerufen werden, wobei der Quelltext automatisch und mit erhöhter Geschwindigkeit compiliert wird. Für schnelle Testläufe genügt also <Esc, R>, um den Editor zu verlassen und das Programm zu starten. Terminal Direkter Datenaustausch mit dem angeschlossenen Entwicklungssystem. Es können beliebige Bytes in dezimaler Schreibweise eingegeben und mit der voreingestellten Baudrate übertragen werden. Alle vom System gesendeten Bytes werden in einem eigenen Fenster dezimal angezeigt. Programme, die die serielle Schnittstelle eines Mikrocontrollers verwenden, um Daten zu empfangen und zu senden, können direkt getestet werden. Wird das Terminal sofort nach dem Verlassen des Editors aufgerufen, dann wird das editierte MC-Programm zuerst compiliert, geladen und gestartet. Für schnelle Testläufe genügt also die Tastenfolge Esc, T. Hexedit Direkte Bearbeitung des Programmcodes. Hexedit/Edit Hexdump eines compilierten Programms. Das Programm kann editiert werden, um Maschinenprogramme direkt einzugeben oder zu verändern. Hexedit/Run Ein Programm im Editorpuffer wird in das Entwicklungssystem übertragen und gestartet. Nach dem direkten Editieren eines Programms ist das zuletzt übertragene Byte das, auf dem der Editor-Cursor steht. Ein Programm, das zuvor durch den Makrocompiler compiliert wurde, wird bis zum letzten compilierten Byte übertragen. Ein von Diskette geladenen Binärfile wird ebenfalls bis zum letzen geladenen Byte übertragen. Hexedit/Load Eine binäre Programmdatei *.BIN wird in den Editorpuffer geladen. Hexedit/Save Der Speicherinhalt der Editorpuffers wird bis zum Ende des zuletzt editierten 256-Byte-Bereichs mit der Kennung .BIN als Binärdatei abgespeichert. Option Im Option-Menü lassen sich alle relevanten Einstellungen des Makrocompilers überprüfen und verändern. Alle Einstellungen werden beim Start aus der Configurationsdatei MC.CFG gelesen. Sie können einzeln verändert oder aus einer anderen CFG-Datei nachgeladen werden. Der Anwender kann sich eigene CFG-Dateien für besondere Aufgaben erstellen. Im folgenden werden jeweils in Klammern die Voreinstellungen für 80535-Controller und das ES535-Entwicklungssystem (MC535.CFG) mit angegeben. Option/COM (2) Wahl der seriellen Schnittstelle COM1 bis COM4 Option/Baud (9600) Wahl der Übertragungsrate zum Entwicklungssystem. Option/Prozessor (80535) Wahl des Zielprozessors 8048, 8051 oder 80535. Entsprechend dem eingestellten Prozessor enthalten die MC-Quelltexte die Kennungen M48, M51 und M35. Während 8051 und 80535 zueinander insoweit kompatibel sind, daß die Code-Tabellen MC51.TAB und MC535.TAB ausgetauscht werden können, verfügt MC48 für den 8048 über eigene Übersetzungsregeln und kann nur mit der Tabelle MC48.TAB verwendet werden. Option/Startseite (128) Die Startseite ist derjenige 256-Byte-Bereich, auf der der Programmcode beginnen soll. Bei der Einstellung "128" (80h) erwartet der Compiler, daß das compilierte Programm bei Adresse 8000h gestartet wird und setzt dort einen Sprungbefehl zum Beginn das Hauptprogramms ein. Alle EPROM-basierten Systeme benötigen im Normalfall einen Programmstart bei Seite 0. Es kann aber sinnvoll sein, ein Programm als eigenständiges Programm-Modul an einer höheren Startadresse einem bestehenden Programm anzufügen. Für Testläufe mit den Entwicklungssystemen ES48 und ES51 ist grundsätzlich die Startseite 0 zu wählen, da ein Programm durch Hardware-Reset gestartet wird. Beim ES535 muß dagegen im Standard-Modus 0 die Startseite 128 gewählt werden. Die Startseite kann als Hexadezimalzahl in der Schreibweise $80 eigegeben werden. Option/Startadresse (80) Hier wird die Startadresse der ersten Prozedur relativ zum Anfang der Startseite angegeben. Die ersten Adressen werden oft für Interrupt-Einsprünge benötigt und müssen deshalb freigehalten werden. Der Compiler füllt die Adressen bis zur Startadresse mit Nullen auf, die bei Bedarf durch Interrupt-Sprungvektoren überschrieben werden. Option/Tabelle (MC535.TAB) Alle Makrobefehle des Compilers werden über die externen Tabellen MC48.TAB, MC51.TAB und MC535.TAB definiert. Der Programmierer kann sich eigene, z.B. erweiterte Tabellen erstellen und unter einem eigenen Namen bereithalten. Ebenso ist es möglich, auf dem ES535 mit der Tabelle MC51.TAB reine 8051-Programme zu entwickeln. Option/Hilfe (MC535.HLP) Hier sollte die zur Übersetzungtabelle passende Hilfedatei MC48.HLP, MC51.HLP oder 80535.HLP gewählt werden. Option/Protokoll (2) Auswahl des Übertragungsprotokolls zwischen MC und Entwicklungssystem: 1: ROM/RAM-Umschaltung für ES48 und ES51 2: Download ab 8000h für ES535 (Modus 0) 3: Download ab 0000h für ES535 (Modus 1) 4: Download ab 0000h für ES535 (Modus 2) Das ES535 kann nur im Modus 0 mit dem Protokoll 2 die erweiterten Makrobefehle der Tabelle MC535.TAB als Aufrufe von Betriebssystem-Routinen ausführen. Im Modus 1 mit dem Übertragungsprotokoll 3 dagegen ist das ES535 zum ES51 kompatibel, so daß sich reine 8081-Programme entwickeln lassen. Die Übertragungsprotokolle werden weiter unten genauer beschrieben. Option/Delay (0) Für die Datenübertragung mit dem Protokoll 1 kann eine Wartezeit in Millisekunden angegeben werden, um mit dem ES48 oder dem ES51 Programmcode in EEPROMs zu laden. Option/Load Config Hier kann eine beliebige .CFG-Datei geladen werden, um MC mit neuen Einstellungen zu versehen. Option/Save Config Alle Einstellungen des Option-Menüs werden in einer Config-Datei gespeichert. Der voreingestellte Dateiname ist MC.CFG.
Der Makrocompiler verarbeitet ähnlich wie ein Assembler einzelne Befehle, die in Zeilen angeordnet sind. Fast alle Befehle verwenden den Akku A des Prozessors als universelle Varable. Daneben verwenden viele Rechenoperatio-nen das Register B. Das folgende Beispiel zeigt den direkten Zugriff auf einen Port des Mikrocontrollers. Kom-mentartexte werden durch ein Semikolon abgetrennt.
;Test1: Portausgabe im Hauptprogramm Begin WrP1 11110000b End
Alle Befehle sind mit ihren Schüsselworten und dem zu erzeugenden Programmcode in den Übersetzungstabellen MC48.TAB, MC51.TAB und MC535,TAB definiert.
Für den Makrocompiler existieren folgende Sprachregeln:
Die folgende Auflistung zeigt alle Makrobefehle des Compilers, wie sie in den mitgelieferten Befehlstabellen MC48.TAB, MC51.TAB und MC535.TAB definiert sind. Die Tabellen können leicht um weitere Makrobefehle erweitert werden. Neben den gemeinsamen Befehlen gibt es spezielle Befehle für die einzelnen Prozessoren. In der Übersicht sind sie wie folgt gekennzeichnet:
8048 : Nur in MC48.TAB für 8048-Prozessoren 8051 : In MC51.TAB und MC535.TAB für alle 8051-Derivate 80535 : Nur in MC535.TAB für alle 80535-Systeme ES535 : Betriebssystem-Aufruf, nur für ES535, Modus 0
A Byte Eine Konstante in A Laden (z.B. A 100) B Byte Eine Konstante in B Laden WrB Den Inhalt von A nach B schreiben RdB Den Inhalt von B nach A lesen SwapAB Die Inhalte in A und B tauschen WrMem Nummer A in einen Speicher (0...31) schreiben RdMem Nummer Einen Speicher auslesen RdMem(A) Durch A adressierten Speicher lesen 8051: WrRAM Ein Byte in das Daten-RAM schreiben 8051: RdRAM Ein Byte aus dem Daten-RAM lesen 8051: ResetRAM Das Daten-RAM zurücksetzen 8051: Wr@DPTR Ein durch DPTR addressiertes Byte ins RAM schreiben 8051: Rd@DPTR Ein durch DPTR addressiertes Byte aus dem RAM lesen
WrP0 Byte Ausgabe eines Byte über den Port 0 RdP0 Einlesen vom Port 0 WrP1 Byte Ausgabe eines Byte über den Port 1 RdP1 Einlesen vom Port 1 WrP2 Byte Ausgabe eines Byte über den Port 2 RdP2 Einlesen vom Port 2 8051: WrP3 Byte Ausgabe eines Byte über den Port 3 8051: RdP3 Einlesen vom Port 3 80535: WrP4 Byte Ausgabe eines Byte über den Port 4 80535: RdP4 Einlesen vom Port 4 80535: WrP5 Byte Ausgabe eines Byte über den Port 5 80535: RdP5 Einlesen vom Port 5 80535: RdP6 Einlesen vom Port 6
Die durch Schreibbefehle (Wr...) übergebenen Bytes werden immer über den Akku transportiert, können aber wahl-weise auch als Konstante hinter den Befehl geschrieben werden. In diesen Fall wird das Byte zuerst in A geschrie-ben. A 15 ... WrP1 und WrP1 15 haben also die selbe Wirkung. Zahlen dürfen auch hexadezimal (FFh) oder binär (11110000b) geschrieben werden.
8051: WrSBUF Byte SBUF beschreiben 8051: RdSBUF SBUF auslesen 8051: WrSCON Byte SCON beschreiben 8051: WrTH1 Byte TH1 beschreiben 8051: RdTH1 TH1 auslesen 8051: WrTL1 Byte TL1 beschreiben 8051: RdTL1 TL1 auslesen 8051: WrTH0 Byte TH0 beschreiben 8051: RdTH0 TH0 auslesen 8051: WrTL0 Byte TL0 beschreiben 8051: RdTL0 TL0 auslesen 8051: WrTMOD Byte TMOD beschreiben 8051: WrTCON Byte TCON beschreiben 8051: WrSP Byte SP beschreiben 8051: RdSP SP auslesen 8051: WrDPH Byte DPH beschreiben 8051: RdDPH DPH auslesen 8051: WrDPL Byte DPL beschreiben 8051: RdDPL DPL auslesen 8051: WrIE Byte IE beschreiben 8051: RdIE IE auslesen 8051: DPTR Hi Lo DPTR als 16-Bit-Register beschreiben
Für den 80535 werden in gleicher Weise die folgenden Register gelesen (Rd) und beschrieben (Wr): IEN0 IP0 IEN1 IP1 IRCON CCEN CCL1 CCH1 CCL2 CCH2 CCL3 CCH3 T2CON CRCL CRCH TL2 TH2 ADCON ADDAT DAPR ADCON ADDAT
+ Byte A mit einer Konstanten addieren +B A mit B addieren - Byte Von A eine Konstante subtrahieren -B B von A subtrahieren A+1 A um 1 erhöhen A-1 A um 1 verkleinern B+1 B um 1 erhöhen B-1 B um 1 verkleinern AND Byte A UND Konstante AndB A UND B OR Byte A ODER Konstante OrB A ODER B XOR Byte A EXKLUSIV-ODER Konstante XorB A EXKLUSIV-ODER B NOT NICHT A (invertieren) ShiftLeft Bits in A um eine Stelle nach links verschieben ShiftRight Bits in A um eine Stelle nach rechts verschieben SwapNibbles Bit 0...3 mit Bit 4...7 tauschen 8051: *B Multiplikation A * B, Übertrag in B 8051: /B Division A/B, Rest in B Prozeduren Procedure Name Anfang einer eigenen Prozedur EndProc Ende der eigenen Prozedur ExitProc Eine Prozedur verlassen
Der Name der Prozedur wird wie ein Befehl behandelt. Er kann in weiter unten definierten Prozeduren aufgerufen werden. Maximal sind beim 8048 acht geschachtelte Aufrufe erlaubt, beim 8051 16. Ein Name darf bis zu 20 Zei-chen lang sein. Prozedurnamen dürfen wahlweise mit einer Konstanten aufgerufen werden, die dabei in A geladen wird.
IfA=B Name Aufruf der Prozedur Name, wenn A und B gleich IfA<>B Name Aufruf, wenn A und B ungleich IfA>=B Name Aufruf, wenn A größer oder gleich B IfA<B Name Aufruf, wenn A kleiner als B IfA=0 Name Aufruf, wenn A gleich Null IfA>0 Name Aufruf, wenn A größer als Null 8051: IfA= Byte Name Aufruf, wenn A = Byte Außer Prozeduren dürfen mit MC48 nur solche Befehle aufgerufen werden, die keinen Parameter haben. Mit MC51 und MC535 dagegen dürfen auch Befehle mit eigenen Parametern aufgerufen werden. Zählschleifen (Zähler 1...8) Count1 Byte Schleifenzähler 1 mit einer Zahl laden WrCount1 Schleifenzähler 1 mit A laden Loop1 Name Zähler-1-mal Prozedur Name aufrufen RdCount1 Schleifenzähler 1 auslesen Loop Name Endlosschleife Es gibt insgesamt acht Schleifenzähler, mit denen man Zählschleifen aufbauen kann. Außer Prozedurnamen können auch Befehle aufgerufen werden. Bedingte Programmschleifen WhileNotDone Schleifenanfang ... (Programmzeilen) EndWhile Schleifenende Done Den Schleifendurchlauf verhindern NotDone Den Schleifendurchlauf freigeben WhileA=0 Schleifenbedingung: A gleich Null WhileA>0 Schleifenbedingung: A größer Null
In einer Schleife dürfen beliebig viele Programmzeilen stehen. Schleifen dürfen achtfach geschachtelt werden.
Begin Anfang des Hauptprogramms Stop Einfrieren des Programmzustandes End Ende des Hauptprogramms ;Text Kommentartext Nop 2,5µs (8048) bzw. 1µs (8051) warten Inline Text Maschinencode oder Tabellen einfügen 8051: Define Deklaration einer Konstanten 8051: CodeAdr Hi Lo Das Programm bei der Adresse (Hi.Lo) fortsetzen
Der Text nach dem Inline-Befehl muß in hexadezimaler Form geschrieben
werden. Als Trennzeichen zwischen Bytes ist das Komma erlaubt, also Inline
FF00FF oder Inline FF,00,FF.
Interrupts und Timerbefehle
8048: StartTimer Zeitgeber starten 8048: StartCounter Ereigniszähler starten 8048: StopCounter Zeitgeber/Zähler stoppen 8048: WrCounter Zähler laden 8048: RdCounter Zähler auslesen 8048: CounterInterrupt Interruptprozedur Zähler/Timer 8048: HardInterrupt Interruptprozedur /Int-Pin 8048: EnableHardInt Hardware-Interrupt freigeben 8048: DisableHardInt Hardware-Interrupt sperren 8048: EnableCounterInt Zählerinterrupt freigeben 8048: DisableCounterInt Zählerinterrupt sperren 8051: Interrupt Adr Interruptprozedur des Vektors Adr EndInterrupt Ende einer Interruptprozedur
Die folgenden Makrobefehle gehören zum erweiterten Sprachumfang für
8051-Prozessoren für harwarenahe Pro-grammierung und direkte Speicherzugriffe.
Sie setzen eine besondere Vorsicht des Programmierers voraus, weil Adressenkonflikte
durch Programmierfehler vom Compiler nicht mehr verhindert werden können.
8051: WrAdr Adr Den Inhalt von A in Adr schreiben 8051: RdAdr Adr Die Adresse Adr auslesen 8051: MovAdr Adr Byte Die Konstante Byte in Adr schreiben 8051: AndAdr Adr Byte Adr mit Byte UND-verknüpfen 8051: OrAdr Adr Byte Adr mit Byte ODER-verknüpfen 8051: IncAdr Adr Den Inhalt von Adr um 1 erhöhen 8051: DecAdr Adr Den Inhalt von Adr um 1 verkleinern
8051: LoopAdr Adr Byte Schleifenzähler Adr mit Byte laden ... 8051: EndLoopAdr Adr verkleinern, Rücksprung wenn > 0 (Sprungweite bis -127) 8051: WhileDecAdr Adr verkleinern, Schleife solange > 0 (Sprungweite beliebig)
8051: ClearBit Adr Bit(Adr)= 0 8051: SetBit Adr Bit(Adr)= 1 8051: IfBit Adr Name Prozeduraufruf, wenn Bit(Adr)= 1 8051: IfNotBit Adr Name Prozeduraufruf, wenn Bit(Adr)=0 8051: WhileBit Adr Wiederholung, solange Bit(Adr)=1 8051: WhileNotBit Adr Wiederholung, solange Bit(Adr)=0
ES535: WrCOM serielle Ausgabe mit 9600 Baud ES535: RdCOM serielle Eingabe mit 9600 Baud ES535: Delay Zeit Wartezeit (Zeit * 0,1 ms) ES535: RdAD Kanal 8-Bit-Messung an AN0...AN7 ES535: RdAD10 Kanal 10-Bit-Messung, Highbyte in B
Der Delay-Befehl stellt ein genaues Zeitraster bereit, d.h. es wird
immer bis zur nächsten abgelaufenen Zeiteinheit gewartet. Solange
die Rechenzeiten zwischen den Delay-Aufrufen kleiner als 0,1ms bleiben,
wirken sie sich nicht aus.
Jedes MC-Programm besteht wie ein Pascal-Programm aus Prozeduren und einem Hauptprogramm. Prozeduren können im Hauptprogramm und in weiteren Prozeduren genau wie vordefinierte Befehle und Funktionen aufgerufen werden. Damit Prozedurnamen leichter vom vorhandenen Sprachumfang unterschieden werden können, sollte man alle Prozedurnamen klein schreiben, während alle Befehle auch Großbuchstaben enthalten. Der Compiler unter-scheidet grundsätzlich nicht zwischen Groß- und Kleinbuchstaben, sondern die Unterscheidung dient allein der besseren Lesbarkeit der Programme. Kommentare können an jede Zeile angefügt werden und müssen mit einem Semikolon beginnen.
Der grundsätzliche Aufbau eine MC-Programms wird im Programm Test2 gezeigt. Die Prozedur "ausgeben" wird vom Hauptprogramm mit einer Konstanten aufgerufen. In diesem Fall wird Bit 6 des Ports aktiv low. Die ersten Programmbeispiele gehen alle davon aus, daß man eine LED-Reihe mit acht LEDs und Vorwiderständen von z.B. 470 Ohm an den Port P1 des Prozessors gegen +5V angeschlossen hat. Dies ist bei allen drei Entwicklungssystemen ES48, ES51 und ES535 in gleicher Weise möglich.
;Test2: Portausgabe in einer Prozedur Procedure ausgeben Not ;invertieren für LEDs gegen +5V WrP1 ;an Port P1 ausgeben EndProc Begin ausgeben 64 End
Oft müssen Vorgänge in einer endlosen Schleife durchlaufen werden. Dann bietet es sich an, eine Prozedur mit Loop immer wieder aufzurufen. Das folgende Beispiel verschiebt laufend ein Bit am Ausgabeport. Der globale Hilfsspeicher Mem 1 wird im Hauptprogramm zunächst initialisiert und dann in der Ausgabeprozedur laufend verändert. Hier zeigt sich neben der Übergabe im Akku A bzw. dem Aufruf einer Prozedur mit einer Konstanten, die ebenfalls im Akku übergeben wird, eine weitere Möglichkeit, Daten an eine Prozedur zu übergeben.
Die hohe Geschwindigkeit im Mikrosekundenbereich führt dazu, daß alle am Port angeschlossenen LEDs nur schwach leuchten. Die Ausgabegeschwindigkeit ist vom verwendeten Prozessor und der Taktfrequenz abhängig und kann z.B. mit einem Oszilloskop ermittelt werden.
;Test3: Verschieben und Ausgeben in einer Schleife Procedure ausgeben RdMem 1 ;globale Variable Mem 1 ShiftLeft ;Bit verschieben WrMem 1 ;abspeichern Not ;invertieren für LEDs gegen +5V WrP1 ;an Port P1 ausgeben EndProc Begin A 1 WrMem 1 ;Mem 1 = 1 Loop ausgeben ;Endlosschleife End
Für eine verlangsamte und optisch erkennbare Ausgabe über die LEDs ist eine Warteschleife erforderlich. Hierzu stellt der Makrocompiler die Zählschleifen 1 bis 8 zur Verfügung. Eine Schleife muß zunächst mit einer Konstanten geladen werden (Count1 255) und kann dann einen Makrobefehl oder eine Prozedur mehrfach aufrufen (Loop1 NOP). Im folgenden Programmbeispiel wird eine Zählschleife in der Prozedur "warten" gebildet, die dann selbst 255 mal in der Prozedur "ausgeben" aufgerufen wird.
;Test4: langsames Lauflicht Procedure warten Count1 255 ;Wiederholschleife 1 laden Loop1 Nop ;255 mal Nichts EndProc Procedure ausgeben RdMem 1 ;globale Variable Mem 1 ShiftLeft ;Bit verschieben WrMem 1 ;abspeichern Not ;invertieren für LEDs gegen +5V WrP1 ;an Port P1 ausgeben Count2 255 ;Wiederholschleife 2 laden Loop2 warten ;255 mal warten EndProc Begin A 1 WrMem 1 ;Mem 1 = 1 Loop ausgeben ;Endlosschleife End
Um mit einer einfachen Zählschleife ein definiertes Zeitraster einzuhalten, müßte man genaue Messungen vorneh-men. Es ist daher besser, eine Prozedur zu verwenden, die auf einen Hardware-Timer zugreift. Die Prozedur Delay ist für alle drei Prozessoren verfügbar und wird auf unterschiedliche Weise realisiert. Programme für das Entwick-lungssystem ES535 greifen auf eine Systemroutine zurück und erlauben ein genaues Zeitraster in Einheiten von 0,1ms. Für den 8051 und den 8048 werden Runtime-Prozeduren hinzugeladen, die die Prozedur Delay mit einer Zeiteinheit von 1ms bereitstellen.
In gleicher Weise werden auch die Prozeduren zum seriellen Senden (WrCOM) und Empfangen (RdCOM) im Run-time-System bereitgestellt. Hier wird immer eine Baudrate von 9600 Baud eingehalten.
Das folgende Programmbeispiel zeigt die Verwendung des Delay-Befehls und der seriellen Ausgabe für den 80535:
;Test5: Anwendung der seriellen Schnittstelle ;und des Delay-Befehls mit MC535 Procedure ausgeben RdMem 1 ;globale Variable Mem 1 ShiftLeft ;Bit verschieben WrMem 1 ;abspeichern WrCOM ;zum Terminal senden Not ;invertieren für LEDs gegen +5V WrP1 ;an Port P1 ausgeben Delay 100 ;10 ms warten EndProc Begin A 1 WrMem 1 ;Mem 1 = 1 Loop ausgeben ;Endlosschleife End
Dasselbe Programm für den 8051 muß die seriellen Übertragungsroutinen und die Delay-Prozedur in einem Runtime-System SYSTEM51.M51 bereitstellen, das bei Bedarf in eigene Programme eingebunden werden muß. Hier muß im Hauptprogramm zunächst die Initialisierungsroutine Init aufgerufen werden.
;Test5: Anwendung des Runtime-Systems für MC51 ;Basisroutinen für MC51 (SYSTEM51.M51) Procedure Init Define RI 98h ;SCON.0 Define TI 99h ;SCON.1 WrTH1 FAH ;6 bis Überlauf: 9600 Baud WrTL1 FAH WrTH0 252 ;942 bis Überlauf: ca. 1ms WrTL0 122 WrTMOD 00100001b ;Timer1: 8-Bit-Auto-Reload, Timer0: 16 Bit WrTCON 01010000b ;beide Timer starten WrSCON 01010010b ;InitRS232 (50H + TI) WrPCON 10000000b ;80H, SMOD=1 EndProc Procedure RdCOM WhileNotBit RI ;Warten bis RI EndWhile ClearBit RI ;RI zurücksetzen RdSBUF EndProc Procedure WrCOM WhileNotBit TI ;Warten bis letztes Byte gesendet EndWhile WrSBUF EndProc Procedure Delay ;0...255ms Define TF0 8Dh ;TCON.5 Define TR0 8Ch ;TCON.4 Define TH0 8Ch Define TL0 8Ah WhileA>0 WhileNotBit TF0 EndWhile ClearBit TR0 ;Timer0 stoppen ClearBit TF0 MovAdr TH0 252 ;922 bis Überlauf: ca. 1ms MovAdr TL0 112 ;122 - 10 Zyklen Zeitausgleich SetBit TR0 ;Timer neu starten A-1 EndWhile EndProc Procedure ausgeben RdMem 1 ;globale Variable Mem 1 ShiftLeft ;Bit verschieben WrMem 1 ;abspeichern WrCOM ;zum Terminal senden Not ;invertieren für LEDs gegen +5V WrP1 ;an Port P1 ausgeben Delay 100 ;100 ms warten EndProc Begin Init ;RS232 und Timer initialisieren A 1 WrMem 1 ;Mem 1 = 1 Loop ausgeben ;Endlosschleife End
Für den 8048 existiert ein vergleichbares Runtime-System, das durch Einbinden passender Maschinenprogramme realisiert wurde. Hier ist zu beachten, daß diese Prozeduren am Anfang des Programms stehen müssen und nicht verschoben werden dürfen. Der Code muß bei Adresse 0009h (Startadresse 9 im Option-Menü) beginnen. Vor der Verwendung des Delay-Befehls muß mit StartTimer der interne Zeitgeber eingeschaltet werden. Dem Runtime-System liegt das Assemblerprogramm SYSTEM48.ASM zugrunde. Es findet sich zusammen mit der Datei SY-STEM48.M48 auf der MC-Diskette.
;Runtimesystem für MC48-Programme (SYSTEM48.M48) Procedure WrCOM ;9600 Baud Inline BA,08,9A,7F,BB,10,EB,0F Inline 97,67,F6,19,9A,7F,E6,1D Inline 8A,80,8A,80,BB,0F,EB,1F Inline EA,11,23,00,23,00,8A,80 Inline BB,01,EB,2B EndProc Procedure RdCOM ;9600 Baud Inline 86,33,97,E6,2E,BA,19,EA Inline 35,BB,08,97,86,49,00,A7 Inline 2C,67,2C,BA,0F,EA,43,EB Inline 39,FC,83,00,97,2C,67,2C Inline BA,0F,EA,50,EB,39,FC EndProc Procedure Delay ;A * 1 ms Inline AD,16,5C,97,E6,57,AE,23 Inline F4,62,23,00,23,00,23,00 Inline 23,00,FE,55,ED,57 EndProc
Eine der höheren Programmstrukturen des Makrocompilers sind die While-Schleifen. Die Schleife kann beliebig viele Zeilen enthalten und wird mit EndWhile abgeschlossen. Die Bedingung, unter der die Schleife wiederholt wird, ist durch den While-Befehl festgelegt. Im folgenden Beispiel wird eine Taste an P1.7 abgefragt. Die Schleife wird mit WhileA>0 solange durchlaufen, bis A durch einen Tastendruck Null wird.
;Test6, Demonstration der While-Schleifen ;Tatenabfrage an P1.7, aktiv low Procedure taste-erwarten WhileA>0 ;solange P1.7 = high RdP1 ;Port P1 auslesen And 10000000b ;P1.7 maskieren EndWhile ;beendet, wenn P1.7 = low EndProc Begin WrP1 FFh taste-erwarten WrP1 11110000b End
Eine weitere hilfreiche Programmstruktur sind die IF-Abfragen. Ein Befehl oder eine Prozedur wird unter einer definierten Bedingung ausgeführt. Im folgenden Beispiel soll ein Kommando von der seriellen Schnittstelle emp-fangen und decodiert werden. Der Mikrocontroller wird zu einem Interface, das auf Kommandos des PC reagiert und einen Datenaustausch zum Port P1 durchführt. "16" steht für Portausgaben und "32" für Porteingaben. Hier wird mit IfA=B ein Vergleich des empfangenen Kommandos mit einem Vergleichswert durchgeführt.
;Test7, Demonstration von If-Abfragen ;Serielles Interface mit Commando-Dekodierung ;für MC51 oder MC48 hier das Runtime-System einfügen Procedure ausgeben RdCOM ;Ausgabebyte empfangen WrP1 ;An Port P1 ausgeben A 16 ;altes Kommando wiederherstellen EndProc Procedure einlesen RdP1 ;Port P1 auslesen WrCOM ;Ergebnis senden A 32 ;altes Kommando wiederherstellen EndProc Procedure kommando-erwarten RdCOM ;Kommando empfangen WrMem 1 ;zwischenspeichern B 16 ;Vergleichswert IfA=B ausgeben ;Kommando 16 = Ausgeben RdMem 1 ;Kommando lesen B 32 IfA=B einlesen ;Kommando 32 = Einlesen EndProc Begin ;Init ;Init nur für MC51 ;StartTimer ;nur für MC48 Loop kommando-erwarten End
Komplexe Bedingungen lassen sich durch die WhileNotDone-Schleife berücksichtigen. Sie verwendet ein globales Flag Done (Done steht hier für "ausgeführt"), das mit Done gesetzt und mit NotDone zurückgesetzt werden kann. Meist wird vor der Schleife NotDone verwendet, während Done in der Schleife nach einer Bedingung ausgeführt wird. Möglich ist es aber auch, Done in einer untergeordneten Prozedur auszuführen, die innerhalb der While-Schleife aufgerufen wird. Das Beispielprogramm Test8 fragt sieben Eingabetasten ab. Sobald eine der Tasten ge-drückt wird, erfolgt eine Meldung an das Terminal.
;Test8, Demonstration von WhileNotDone-Schleifen ;Auswertung von sieben Meldeleitungen an P1.1...P1.7 ;über P1.0 könnan alle Meldeleitungen gesperrt werden ;für MC51 oder MC48 hier das Runtime-System einfügen Procedure signal-erwarten NotDone WhileNotDone RdP1 WrMem 1 ;zwischenspeichern B 11111110b IfA<B Done ;ein Signal an P1.1 ... P1.7 ? RdP1 AND 1 IfA=0 NotDone ;alle Signale über P1.0 gesperrt? EndWhile RdMem 1 ;Portzustand lesen NOT ;aktiv-high invertieren And FEh ;alle Meldeleitungen maskieren WrCOM ;Meldung senden RdCOM ;Bestätigung erwarten EndProc Begin ;Init ;Init nur für MC51 ;StartTimer ;nur für MC48 Loop signal-erwarten End
Auf der Programmdiskette befinden sich drei größere Programmbeispiele, die typische Einsatzmöglichkeiten des Makrocompilers demonstrieren. Zahlreiche weitere Anwendungen werden im unten angegebenen Buch beschrieben.
- Das Programm TIMER.M48 stellt einen einfachen Zeitgeber vor, der in seiner Funktion etwa mit einer Eieruhr vergleichbar ist. Der Timer verwendet eine Leuchtbandanzeige aus acht LEDs am Port P1, die eine Restzeit von Null bis acht Minuten anzeigen. Als einziges Bedienelement kommt ein Tastschalter an P2.3 zum Einsatz, über den der Timer "geladen" werden kann. Dabei soll der Benutzer durch einzelne Tastendrücke oder die Länge des Tasten-drucks die Timer-Zeit einstellen. Jeweils eine halbe Sekunde steht für eine Minute. Die eingestellte Zeit erscheint gleichzeitig in der Leuchtbandanzeige, so daß die Einstellung nicht schwerfällt. Der Timmer erlaubt auch ein nach-trägliches Höherstellen der Restzeit. Mit dem Ablauf der Uhr beginnt ein Blinken aller LEDs, das entweder nach einer Minute aufhört oder durch neues Laden des Timers beendet wird.
Die genaue Zeitsteuerung der Uhr gestaltet sich dank der oben vorgestellten Delay-Prozedur recht einfach. Regel-mäßige Aufrufe ergeben ein genaues Millisekundenraster, wobei die eigentliche Rechenzeit dazwischen kürzer als eine Millisekunde ist und nicht nicht den Zeitablauf beeinflußt. Es wurde darauf geachtet, daß in regelmäßigen Abständen die Taste abgefragt wird.
- Das Programm MORSEN.M51 liest und dekodiert die Eingaben über eine Morsetaste, die an Port 1.7 gegen Masse angeschlossen ist. Die Morsezeichen werden mit fest eingestellter Geschwindigkeit verarbeitet, wobei Striche ab einer Länge von 200ms erkannt werden. Damit ergibt sich eine optimale Geschwindigkeit von 60 BpM (Buchsta-ben pro Minute), also 100ms Punktlänge und 300ms Strichlänge, und ein Arbeitsbereich von ca. 50 BpM bis 80 BpM.
Alle erkannten Morsezeichen werden auf einer zweizeiligen LCD-Anzeige dargestellt. Die Anzeige scrollt mit jeder vollen Zeile nach oben. Gleichzeitig wird ein Mithörton generiert, der als Rechtecksignal mit 500Hz an P1.0 bis P1.3 ansteht. Hier kann ohne weitere Elektronik ein Piezo-Schallgeber angeschlossen werden. Das Programm ver-zichtet auf jeden Datenzugriff auf das externe RAM. Deshalb ist es möglich, es auf dem ES51 in einem EEPROM einzusetzen, also permanent bereitzuhalten. Der gesamte Code benötigt weniger als ein Kilobyte und zeigt damit die speicherökonomische Arbeitsweise des Makrocompilers.
Das Programm liefert zugleich alle erforderlich Basisroutinen zur Ansteuerung des LCD-Displays mit dem ES51 oder ES535. Die Prozeduren wurden als systemnahe Ressourcen geschrieben, wobei keine Mem-Speicher belegt wurden und alle wichtigen Register (z.B. der Datapointer DPTR) wiederhergestellt werden. Als Zwischenspeicher werden hier die internen RAM-Adressen 02h bis 05h eingesetzt.
- Das Programm ROBOT.M35 steuert zwei Fernsteuer-Servos über die interne PWM-Einheit des 80535. Der Anwender bewegt die Servos über zwei Potis an den Analogeingängen AN0 und AN1. Die Steuerspannungen werden in Pulsbreiten zwischen 1ms und 2ms umgesetzt, wobei alle 10 Millisekunden eine Aktualisierung der Steuerdaten erfolgt. Gleichzeitig werden alle Daten im RAM gespeichert. Mit den gegebenen Einstellungen dauert die Aufnah-me von Meßdaten etwa eine Minute. Nach Ablauf dieser Zeit werden die gespeicherten Daten wieder aus dem RAM gelesen und erneut in PWM-Signale umgesetzt. Das Programm erlaubt die Realisierung eines einfachen Robotor-Modells mit Teach-Modus. Gewünschte Steuersequenzen werden einfach über Potis erzeugt und stehen dann für endlose Wiederholungen zur Verfügung.
Das Programm demonstriert die direkte Programmierung von Spezialfunktionsregistern zur Steuerung der Capture-Compare- Einheit. Es können Impulse bis zu 65 Millisekunden bei einer Auflösung von einer Mikrosekunde erzeugt werden. Der 80535 generiert Impulse im Abstand von 4 ms. Die Variation der Pulslänge erfolgt mit einer Auflösung von 10 Bit in etwa 1000 Schritten. Dememtsprechend wird der AD-Wandler des 80535 über den Befehl RdAna-log10 mit einer Auflösung von 10 Bit betrieben.
Alle Makrobefehle des Compilers werden durch Übersetzungstabellen (z.B. MC51.TAB) definiert. Diese Tabellen lassen sich mit einem beliebigen ASCII-Editor bearbeiten und erweitern. So kann der Anwender eigene Makrobe-fehle erzeugen, um z.B. seinen Programmcode für bestimmte Aufgaben zu optimieren. Weiterhin lassen sich leicht die erforderlichen Erweiterungen für weitere Prozessoren wie z.B. 80552, 87C752 usw. anfügen. Erweiterungen können als kurze Assemblerrountinen geschrieben und assembliert werden. Der Anwender muß dann einen neuen Befehlsnamen definieren und zusammen mit dem Code an die Befehlstabelle anfügen. Außerdem ist es möglich, abgeänderte oder erweiterte Tabellen unter eigenen Namen bereitzuhalten und bei Bedarf im Option-Menü einzu-tragen.
Befehlserweiterungen setzen eine genaue Kenntnis des Makrocompilers voraus. Es ist nützlich, sich die bereits defi-nierten Makrobefehle genau anzusehen. Der folgende Ausschnitt zeigt die Behandlung des Ports P1 in MC51.TAB. Der Port wird über das SFR P1 an der Adresse 90h erreicht. Der angefügte Assemblertest im Kommentar verdeut-licht, daß die Portzugriffe über den Akku laufen. Der Makrobefehl WrP1 enthält aber zusätzlich die spezielle Com-piler-Anweisung PA (für Parameter- Übergabe). PA bewirkt, daß der Compiler überprüft, ob hinter dem Makrobe-fehl eine Konstante angegeben wurde (z.B. WrP1 255). In diesem Fall wird die Konstante zunächst in den Akku geladen und darauf erst der eigentliche Befehl ausgeführt. Steht hinter WrP1 kein Wert, dann bleibt PA ohne Wir-kung, d.h. es wird der gerade im Akku vorhandene Wert übergeben.
WrP1 PA F5 90 ;mov P1,A RdP1 E5 90 ;mov A,P1
Eine andere wichtige Compileranweisung ist XX. Sie bewirkt, daß eine hinter dem Befehl angegebene Konstante direkt in den Code eingesetzt wird. Auf diese Weise werden z.B. A und B geladen:
A 74 XX ;mov A,#XX B 75 F0 XX ;mov B,#XX
In Assembler-Programmen wird oft direkt mit AND- oder OR-Verkmüpfungen auf Ports zugegriffen. Falls dies auch für MC-Programme erwünscht wird, können z.B. die folgenden Makrobefehle neu gebildet und an die Tabelle angehängt werden:
AndP1 53 90 XX ;anl P1,#XX OrP1 43 90 XX ;orl P1,#XX
Auf diese Weise lassen sich sehr einfach neue Kommandos bilden, die z.B. auch aus mehreren Assembleranweisun-gen bestehen können. Etwas komplizierter wird es, wenn der Compiler höhere Programmstrukturen wie z.B. Wie-derholschleifen oder Fallabfragen übersetzen soll. In diesem Fall müssen nämlich Sprungadressen berechnet wer-den, die über weitere Compileranweisungen gesteuert werden. Sie sind durch zwei Buchstaben gekennzeichnet und liegen oberhalb von FF, während die direkten OP-Codes in hexadezimaler Schreibweise zwischen 00 und FF liegen. Die folgende Liste zeigt alle definierten Compileranweisungen, wobei einige sich je nach Zielprozessor unterschei-den:
XX Die Konstante nach dem Befehl wird hier eingesetzt. 8051: YY Die zweite Konstante nach dem Befehl wird hier eingesetzt. RR Angabe des Mem-Speichers: Die Konstante wird mit 32 (8048) bzw. 48 (8051) addiert und hier eingesetzt. PA Optionale Parameterübergabe: Wird hinter dem Befehl ein Wert angegeben, wird dieser zuvor in A geladen. PD Definition einer Prozedur. Der Prozedurname wird zusammen mit dem Befehlscode zu seinem Aufruf an die Befehlsliste angefügt. HA Hauptprogramm-Anfang. Ein Sprungbefehl auf die aktuelle Adresse wird nachträglich an den Anfang der Startseite (Reset-Vektor) gesetzt. HH Der Compiler merkt sich die aktuelle Adresse für einen späteren Rücksprung. SS An dieser Stelle wird die bei "HH" gespeicherte Adresse als Rücksprungadresse eingetragen. 8051: SR Hier wird die bei "HH" gespeicherte Adresse als relative Srungweite eingetragen.. PR Hier wird ein Befehl oder ein Prozeduraufruf eingesetzt. 8048: NN Das zweite Wort der Programmzeile ist ein Prozedurname oder ein Befehl. Es wird die Länge des Maschinencodes festgestellt und die Vorwärts-Sprung- adresse zum bedingten Überspringen des Befehls an dieser Stelle eingesetzt. 8051: NR Für die bedingte Ausführung eines Befehls wird die Länge des Maschinencodes festgestellt und die Vorwärts-Sprungadresse zum bedingten Überspringen des Befehls an dieser als relative Sprungweite eingetragen. 8048: JP An dieser Stelle wird der JMP-Befehl 04, 24, 44 usw. je nach aktueller Seite (0...7) des Programmspeichers eingesetzt. HS Für While-Schleifen wird der Schleifenzähler inkrementiert, und die aktuelle Adresse wird für einen späteren Rücksprung in einer bedingten Programmschleife gespeichert. JS Es werden die Befehle zum Rücksprung an die mit HS bezeichnete Stelle eingesetzt. 8048: J3 Es wird die Adresse für einen drei Byte weiten Vorwärtssprung berechnet und hier eingesetzt. JZ In die aktuelle Adresse wird das vorläufige Sprungziel "00" eingesetzt, und die Adresse wird für das spätere Einsetzen der richtigen Sprungadresse gespeichert. JE Die aktuelle Sprungadresse wird in die bei "JZ" gespeicherte Adresse eingesetzt. Der Schleifenzähler wird dekrementiert. SO Es wird am Ende einer Prozedur oder des Hauptprogramms geprüft, ob noch Schleifen geöffnet sind. HX Es werden die folgenden hexadezimalen Bytes in das Programm eingesetzt (Inline-Code). 8048: TI Timer-Interruptprozedur: Ein Sprungbefehl auf die aktuelle Adresse wird in Adresse 03 eingetragen. 8048: HI Hardware-Interruptprozedur: Ein Sprungbefehl auf die aktuelle Adresse wird in Adresse 07 eingetragen. 8051: IN Ein Sprungbefehl auf die Startadresse einer Interruptprozedur wird an der angegebenen Interrupt-Einsprungadresse eingesetzt. 8051: XD Definition einer Konstanten mit dem Define-Kommando. 8051: XO Codeadresse hi, lo festlegen, unter der die Übersetzung fortgesetzt wird.
Zur Verdeutlichung seien hier einige Programmstukturen als Assemblerlisting wiedergegeben:
Assemblerlisting der Wiederholschleifen in MC48 0002 83 Name ret 0003 D5 Count1 sel rb1 0004 B8 05 mov r0,#05 0006 C5 sel rb0 0007 D5 WrCount1 sel rb1 0008 A8 mov r0,a 0009 C5 sel rb0 000A D5 RdCount1 sel rb1 000B F8 mov a,r0 000C C5 sel rb0 000D C5 Loop1 sel rb0 ;HH 000E 94 02 call Name 0010 D5 sel rb1 0011 E8 0D djnz r0,Loop1 ;SS 0013 C5 sel rb0 0014 94 02 Loop call Name 0016 84 14 jmp Loop
Alle Zählschleifen werden mit Registern der Registerbank 1 gebildet, die sonst in MC48 nicht verwendet wird. Deshalb ist eine Bankumschaltung erforderlich. Mit MC51 vereinfachen sich die Wiederholschleifen, weil auf die entsprechenden Register über ihre Adressen zugegriffen werden kann.
Assemblerlisting der While-Schleifen in MC48 0003 85 Done clr F0 ;F0=0 0004 85 NotDone clr F0 0005 95 cpl F0 ;F0=1 0006 WhileNotDone 0006 B6 0A HS jF0 J3 0008 04 0D jmp JZ 000A J3 ... ;Programm- ... ;zeilen 000B 04 06 EndWhile jmp HS 000D JZ nop
Während beim 8048 das allgemeine Flag F0 als Done-Flag dient, wird beim 8051 die Bitadresse 00h verwendet. Weitere Strukturen lassen sich aus den Kommentaren in der Übersetzungstabelle entnehmen.
Assemblerlisting der While-Schleife in MC51 0002 D2 00 Done setb 00 0004 C2 00 NotDone clrb 00 0006 WhileNotDone 0006 30 00 03 HS jnb 00 03 0009 02 00 0F JZ ljmp JZ ... ;Programm- ... ;zeilen 000C 02 00 06 EndWhile ljmp HS 000F JZ nop
Der Makrocompiler verwendet eine feste Zuordnung von Adreßbereichen und vordefinierten Programmstruktuen. Dies erleichtert die sichere Programmierung, weil Adressenkonflikte nahezu ausgeschlossen sind. Für eigene Er-weiterungen oder zusätzliche Programmteile in Assembler ist es jedoch wichtig, die Speicherbelegung zu kennen. Sie unterscheidet sich je nach Zielprozessor, wobei MC535 sich an die Speicherbelegung von MC51 hält.
Internes RAM 8048 Externes RAM 8048 +-------------------------------+ +-------------------------------+ ¦ 3Fh ¦ ¦ 03FFh ¦ ¦ ... MEM-Speicher 0...31 ¦ ¦ ... Programmcode ¦ ¦ 20h reserviert ¦ ¦ 0009h ¦ +-------------------------------¦ +-------------------------------¦ ¦ 1Fh Registerbank 1 ¦ ¦ 0008h frei für ¦ ¦ ... Count1...Count8 ¦ ¦ ... Interrupt-Vektoren ¦ ¦ 18h Loop1...Loop8 ¦ ¦ 0000h Reset-Vektor ¦ +-------------------------------¦ +-------------------------------+ ¦ 17h ¦ ¦ ... Stack für 8 Ebenen ¦ ¦ 08h ¦ +-------------------------------¦ ¦ 07h R7 reserviert für ¦ ¦ ... Systemroutinen ¦ ¦ 00h R0 R0, R6 gesperrt ¦ +-------------------------------+ Internes RAM 8051 Externes RAM 8051 +-------------------------------+ +-------------------------------+ ¦ 7Fh ¦ ¦ 7FFFh ¦ ¦ ... Stack für 16 Ebenen ¦ ¦ ... Datenspeicher ¦ ¦ 60h ¦ ¦ 2000h ¦ +-------------------------------¦ +-------------------------------¦ ¦ 5Fh ¦ ¦ 1FFFh ¦ ¦ ... MEM-Speicher 0...47 ¦ ¦ ... Programmcode ¦ ¦ 30h reserviert ¦ ¦ 0033h ¦ +-------------------------------¦ +-------------------------------¦ ¦ 2Fh Bitadressen 0...7F ¦ ¦ 0032h frei für ¦ ¦ ... reserviert ¦ ¦ ... Interrupt-Vektoren ¦ ¦ 20h Bit 00h gesperrt ¦ ¦ 0000h Reset-Vektor ¦ +-------------------------------¦ +-------------------------------+ ¦ 1Fh ¦ ¦ ... reserviert ¦ ¦ 10h ¦ +-------------------------------¦ ¦ 0Fh Count1 ... Count8 ¦ ¦ ... Loop1 ... Loop8 ¦ ¦ 08h ¦ +-------------------------------¦ ¦ 07h R7 reserviert für ¦ ¦ ... Systemroutinen ¦ ¦ 00h R0 R0, R7 gesperrt ¦ +-------------------------------+
Die Übertragung eines compilierten Programms erfolgt nach einem festgelegten Protokoll, das im Option-Menü ausgewählt werden kann. Die Entwicklungssysteme ES48 und RS51 verwenden das Protokoll 1. Hierbei wird über zwei Handshakeleitungen der seriellen Schnittstelle ein Reset ausgelöst (RTS) und eine Umschaltung in den Down-load-Modus des Systems (DTR) vorgenommen. Die im Option-Menü einstellbare Delay-Zeit ist nur im Protokoll 1 wirksam und dient der verlangsamten Übertragung in EEPROMs im ES48 und ES51.
Download Protokoll 1 für ES48 und ES51:
- RTS = 1, Reset - DTR = 1, Download-Modus einschalten - RTS = 0, Reset beenden - 100ms warten - Übertragung der Programmbytes über TXD mit 9600 Baud (nach jedem Byte ein Delay von 0...20ms einhalten) - RTS = 1, Reset - DTR = 0, Download-Modus ausschalten - RTS = 0, Reset beenden
Alle folgenden Modi sind für das Entwicklungssystem ES535 vorgesehen. Im Protokoll 2 wird der Betriebsmodus 0 unterstützt, bei dem Software im RAM-Bereich ab 8000h gestartet wird. Für den Ladevorgang wird das RAM als Datenspeicher im Adreßbereich 0000h bis 7FFFh angesprochen.
Download Protokoll 2 für ES535, Modus 0:
- RTS = 1, Master-Reset - RTS = 0, Reset beenden - 100ms warten - Download des Programms ab der RAM-Adresse 0000h - Programmstart bei Adresse 8000h
Der Betriebsmodus 1 des ES535 arbeitet ohne EPROM und stellt jeweils 16kB Daten- und Programmspeicher ab Adresse 0000h bereit. Das Download-Protokoll 2 schaltet diesen Modus durch einen Programmsprung nach 7400h ein. Er eignet sich zur Programmentwicklung für EPROM-basierte 8051- und 80535-Systeme, die einen vergleich-baren Speicheraufbau besitzen. Alle Makrobefehle in MC535.TAB, die auf das System-EPROM zurückgreifen, dürfen hier nicht verwendet werden.
Download Protokoll 3 für ES535, Modus 1:
- RTS = 1, Master-Reset - RTS = 0, Reset beenden - 100ms warten - Download des Programms ab der RAM-Adresse 0000h - Sprungbefehl (ljmp 0000h) nach 3400h laden - Programmsprung zur Adresse 7400h
Das Download-Protokoll 4 unterstützt den Modus 2 des ES535. Der Programmcode beginnt ebenfalls ab Adresse 0000h im RAM, wobei jedoch das ganze RAM als gemeinsamer Programm- und Datenspeicher fungiert.
Download Protokoll 4 für ES535, Modus 2:
- RTS = 1, Master-Reset - RTS = 0, Reset beenden - 100ms warten - Download des Programms ab der RAM-Adresse 0000h - Sprungbefehl (ljmp 0000h) nach 7800h laden - Programmsprung zur Adresse 7800h
Die gesamte Konfiguration des Compilers und des Download- Protokolls erfolgt im Option-Menü und kann in der Datei MC.CFG abgespeichert werden. Hier gibt es zahlreiche Möglichkeiten der Anpassung an das Zielsystem. Als Beispiel seien hier die erforderlichen Einstellungen für die Entwicklung von 8051-Programmen auf dem ES535 gezeigt. Obwohl das ES535 den 80535-Prozessor verwendet, wird hier der 8051 mit der Tabelle MC51.TAB eingetragen. Der Programmcode beginnt bei 0000h und muß mit dem Download-Protokoll 3 in das ES535 geladen werden. Falls das Zielsystem getrennten Programm- und Datenspeicher verwendet, sollte das Protokoll 4 gewählt werden.
Das folgende Buch aus dem Franzis-Verlag beschreibt ausführlich die Arbeit mit dem Makrocompiler und den Ent-wicklungssystemen:
B. Kainka, Erfolgreich Messen, Steuern und Regeln mit Mikrocontrollern, Franzis 2. Auflage 1998
Die Entwicklungssysteme ES48, ES51 und ES535 werden in technischen Anwenderhandbüchern beschrieben, die auch einzeln bei Modul-Bus bezogen werden können. Die entsprechenden Texte finden sich außerdem auf der MC-Programmdiskette im Verzeichnis ES.
Das Inteface-System SIOS von Modulbus kann ebenfalls mit dem Makrocompiler programmiert werden. Nähere Informationen zu SIOS und passende MC-Steuerdateien befinden sich auf der MC-Diskette im Verzeichnis SIOS.