
EINFHRUNG
===========

LDmicro erzeugt einen systemspezifischen Code fr einige Microchip PIC16
und Atmel AVR Mikroprozessoren. blicherweise wird die Software fr diese
Prozessoren in Programmsprachen, wie Assembler, C oder BASIC geschrieben.
Ein Programm, welches in einer dieser Sprachen abgefasst ist, enthlt
eine Anweisungsliste. Auch sind die diese Sprachen sehr leistungsfhig
und besonders gut geeignet fr die Architektur dieser Prozessoren,
welche diese Anweisungsliste intern abarbeiten.

Programme fr speicherprogrammierbare Steuerungen (SPS) andererseits,
werden oftmals im Kontaktplan (KOP = ladder logic) geschrieben.
Ein einfaches Programm, knnte wie folgt aussehen:

   ||                                                                    ||
   ||    Xbutton1           Tdon           Rchatter           Yred       ||
 1 ||-------]/[---------[TON 1.000 s]-+-------]/[--------------( )-------||
   ||                                 |                                  ||
   ||    Xbutton2           Tdof      |                                  ||
   ||-------]/[---------[TOF 2.000 s]-+                                  ||
   ||                                                                    ||
   ||                                                                    ||
   ||                                                                    ||
   ||    Rchatter            Ton             Tneu           Rchatter     ||
 2 ||-------]/[---------[TON 1.000 s]----[TOF 1.000 s]---------( )-------||
   ||                                                                    ||
   ||                                                                    ||
   ||                                                                    ||
   ||------[END]---------------------------------------------------------||
   ||                                                                    ||
   ||                                                                    ||

 (TON ist eine Anzugsverzgerung, TOF eine Abfallverzgerung.
  Die --] [-- Anweisungen bedeuten Eingnge, die sich hnlich, wie Relais-
  kontakte  verhalten. Die --( )-- Anweisungen bedeuten Ausgnge, die sich
  hnlich,  wie Relaisspulen verhalten. Viele gute Bezugsquellen werden fr
  KOP im Internet oder sonst wo angeboten; Einzelheiten zu dieser speziellen
  Ausfhrung werden weiter unten angegeben.)

Einige Unterschiede sind jedoch offensichtlich:

* Das Programm wird in einem grafischen Format dargestellt
  und nicht mit einer aus Anweisungen bestehenden Textliste. Viele
  Anwender werden dies zunchst als besser verstndlich auffassen.

* Diese Programme erscheinen wie einfachste Schaltplne, mit
  Relaiskontakten (Eingngen) and Spulen (Ausgngen). Dies ist recht
  intuitiv fr Programmierer, die ber Kenntnisse der Theorie von
  Elektroschaltplnen verfgen.

* Der ladder logic compiler bernimmt was wo berechnet wird.
  Es ist nicht notwendig einen Code zu schreiben, um zu errechnen, wann
  der Status (Zustand) der Ausgnge neu bestimmt werden muss, z.B. auf
  Grund einer nderung eines Eingangs oder Timers. Auch braucht man die
  Reihenfolge der Berechnungen nicht anzugeben; die SPS-Hilfsprogramme
  bernehmen dies.

LDmicro kompiliert ladder logic (KOP) in PIC16- oder AVR-Code.
Die folgenden Prozessoren werden untersttzt:

    * PIC16F877
    * PIC16F628
    * PIC16F876 (ungetestet)
    * PIC16F88 (ungetestet)
    * PIC16F819 (ungetestet)
    * PIC16F887 (ungetestet)
    * PIC16F886 (ungetestet)
    * ATmega8 (ungetestet)
    * ATmega16 (ungetestet)
    * ATmega32 (ungetestet)
    * ATmega128
    * ATmega64
    * ATmega162 (ungetestet)

Es wre einfach noch weitere AVR- oder PIC16-Prozessoren zu untersttzen,
aber ich habe keine Mglichkeit diese zu testen. Falls Sie einen
bestimmten bentigen, so nehmen Sie Kontakt mit mir auf und ich werde
sehen, was ich tun kann.

Mit LDmicro knnen Sie ein Kontaktplan-Programm zeichnen bzw. entwickeln.
Auch knnen Sie dies in Realzeit mit Ihrem Computer simulieren. Wenn
Sie dann berzeugt sind, dass Ihr Programm korrekt ist, so knnen
Sie die Pins, entsprechend dem Programm als Ein- oder Ausgnge, dem
Mikroprozessor zuweisen. Nach der Zuweisung der Pins knnen Sie den PIC-
oder AVR-Code fr Ihr Programm kompilieren. Der Compiler erzeugt eine
Hex-Datei, mit dem Sie dann Ihren Mikroprozessor programmieren. Dies
ist mit jedem PIC/AVR-Programmer mglich.

LDmicro wurde entworfen, um in etwa mit den meisten kommerziellen
SPS-Systemen hnlich zu sein. Es gibt einige Ausnahmen und viele Dinge
sind ohnehin kein Standard in der Industrie. Lesen Sie aufmerksam die
Beschreibung jeder Anweisung, auch wenn Ihnen diese vertraut erscheint.
Dieses Dokument setzt ein Grundwissen an Kontaktplan-Programmierung
und der Struktur von SPS-Software voraus (wie: der Ausfhrungszyklus,
Eingnge lesen, rechnen und Ausgnge setzen).


WEITERE ZIELE
=============

Es ist auch mglich einen ANSI C - Code zu erzeugen. Diesen knnen
Sie dann fr jeden Prozessor verwenden, fr den Sie einen C-Compiler
besitzen. Sie sind dann aber selbst verantwortlich, den Ablauf zu
bestimmen. Das heit, LDmicro erzeugt nur ein Stammprogramm fr einen
Funktions- SPS-Zyklus. Sie mssen den SPS-Zyklus bei jedem Durchlauf
aufrufen und auch die Ausfhrung (Implementierung) der E/A-Funktionen,
die der SPS-Zyklus abruft (wie: lesen/schreiben, digitaler Eingang usw.).
Fr mehr Einzelheiten: Siehe die Kommentare in dem erzeugten Quellcode.

Ganz zuletzt kann LDmicro auch fr eine virtuelle Maschine einen
prozessor-unabhngigen Byte-Code erzeugen, welche mit der KOP-Kodierung
(ladder logic) laufen soll. Ich habe eine Beispiel-Anwendung des
VM/Interpreters vorgesehen, in ziemlich gutem C geschrieben. Dieses
Anwendungsziel wird halbwegs auf jeder Plattform funktionieren, so lange
Sie Ihre eigene VM vorsehen. Dies knnte fr solche Anwendungen ntzlich
sein, fr die Sie KOP (ladder logic) als Datentransfer-Sprache verwenden
mchten, um ein greres Programm anzupassen.  Fr weitere Einzelheiten:
Siehe die Kommentare in dem Beispiel-Interpreter.


OPTIONEN DER BEFEHLSZEILEN
==========================

ldmicro.exe luft normalerweise ohne eine Befehlszeilen-Option.
Das heit, dass Sie nur ein Tastenkrzel zu dem Programm bentigen
oder es auf dem Desktop abspeichern und dann auf das Symbol (die Ikone)
doppelklicken, um es laufen zu lassen. Danach knnen Sie alles ausfhren,
was das GUI (Graphical User Interface) zulsst.

Wenn man an LDmicro einen alleinstehenden Dateinamen in der Befehlszeile
vergeben hat (z. B. ldmicro.exe asd.ld), wird LDmicro versuchen asd.ld
zu ffnen, falls diese existiert. Dies bedeutet, dass man ldmicro.exe
mit .ld Dateien verbinden kann, sodass dies automatisch abluft, wenn
man auf eine .ld Datei doppelklickt.

Wenn man an LDmicro das Argument in der Befehlszeile in folgender Form
vergeben hat: ldmicro.exe /c src.ld dest.hex, so wird es versuchen
src.ld zu kompilieren und unter dest.hex abzuspeichern. LDmicro endet
nach dem Kompilieren, unabhngig davon, ob die Kompilierung erfolgreich
war oder nicht. Alle Meldungen werden auf der Konsole ausgegeben. Dieser
Modus ist hilfreich, wenn man LDmicro von der Befehlszeile laufen
aus lsst.


GRUNDLAGEN
==========

Wenn Sie LDmicro ohne Argumente aufrufen, so beginnt es als ein leeres
Programm. Wenn Sie LDmicro mit dem Namen eines ladder (KOP)-Programms
(z.B. xxx.ld) in der Befehlszeile ffnen, dann wird es versuchen dieses
Programm am Anfang zu laden.

LDmicro verwendet sein eigenes internes Format fr das Programm und
man kann kein logisches Zeichen aus einem anderen (Fremd-)Programm
importieren.

Falls Sie nicht ein schon vorhandenes Programm laden, dann wird Ihnen
ein Programm mit einem leeren Netzwerk geliefert. In dieses knnen Sie
einen Befehl einfgen; z. B. knnten Sie auch eine Reihe von Kontakten
einfgen (Anweisung -> Kontakte Einfgen), die zunchst mit Xneu
bezeichnet werden. X bedeutet, dass der Kontakt auf einen Eingang
des Mikroprozessors festgelegt ist. Diesen Pin knnen Sie spter zuweisen,
nachdem Sie den Mikroprozessor gewhlt haben und die Kontakte
umbenannt haben. Der erste Buchstabe zeigt an, um welche Art Objekt es
sich handelt. Zum Beispiel:

    * XName -- Auf einen Eingang des Mikroprozessors festgelegt
    * YName -- Auf einen Ausgang des Mikroprozessors festgelegt
    * RName -- Merker: Ein Bit im Speicher (Internes Relais)
    * TName -- Ein Timer; Anzugs- oder Abfallverzgerung
    * CName -- Ein Zhler, Aufwrts- oder Abwrtszhler
    * AName -- Eine Ganzzahl, von einem A/D-Wandler eingelesen
    * Name  -- Eine Allzweck-Variable als Ganzzahl

Whlen Sie den Rest des Namens, sodass dieser beschreibt, was das Objekt
bewirkt und das dieser auch einmalig im Programm ist. Der gleiche Name
bezieht sich immer auf das gleiche Objekt im Programm. Es wre zum
Beispiel falsch eine Anzugsverzgerung (TON) TVerzg zu nennen und im
selben Programm eine Abfallverzgerung TVerzg (TOF), weil jeder Zhler
(oder Timer) seinen eigenen Speicher bentigt. Andererseits wre es
korrekt einen Speichernden Timer (RTO) TVerzg zu nennen und eine
entsprechende Rcksetz-Anweisung (RES)  =  TVerzg, weil in diesem
Fall beide Befehle dem gleichen Timer gelten.

Die Namen von Variablen knnen aus Buchstaben, Zahlen und Unter-
strichen (_) bestehen. Der Name einer Variablen darf nicht mit einer
Nummer beginnen. Die Namen von Variablen sind fallabhngig.

Ein Befehl fr eine gewhnliche Variable (MOV, ADD, EQU, usw.), kann
mit Variablen mit jedem Namen arbeiten. Das bedeutet, dass diese Zugang
zu den Timer- und Zhler-Akkumulatoren haben. Das kann manchmal recht
hilfreich sein; zum Beispiel kann man damit prfen, ob die Zhlung eines
Timers in einem bestimmten Bereich liegt.

Die Variablen sind immer 16-Bit Ganzzahlen. Das heit sie knnen von
-32768 bis 32767 reichen. Die Variablen werden immer als vorzeichen-
behaftet behandelt. Sie knnen auch Buchstaben als Dezimalzahlen festlegen
(0, 1234, -56).  Auch knnen Sie ASCII-Zeichenwerte (A, z) festlegen,
indem Sie die Zeichen in Auslassungszeichen einfgen. Sie knnen
ein ASCII-Zeichen an den meisten Stellen verwenden, an denen Sie eine
Dezimalzahl verwenden knnen.

Am unteren Ende der Maske (Bildanzeige) sehen Sie eine Liste aller
Objekte (Anweisungen, Befehle) des Programms. Diese Liste wird vom
Programm automatisch erzeugt; es besteht somit keine Notwendigkeit diese
von Hand auf dem Laufenden zu halten. Die meisten Objekte bentigen
keine Konfiguration.  XName, YName, und AName  Objekte allerdings,
mssen einem Pin des Mikroprozessors zugeordnet werden. Whlen Sie zuerst
welcher Prozessor verwendet wird (Voreinstellungen -> Prozessor). Danach
legen Sie Ihre E/A Pins fest, indem Sie in der Liste auf diese jeweils
doppelklicken.

Sie knnen das Programm verndern, indem Sie Anweisungen (Befehle)
einfgen oder lschen. Die Schreibmarke (cursor)im Programm blinkt,
um die momentan gewhlte Anweisung und den Einfgungspunkt anzuzeigen.
Falls diese nicht blinkt, so drcken Sie den <Tabulator> oder klicken
Sie auf eine Anweisung. Jetzt knnen Sie die momentane Anweisung lschen
oder eine neue Anweisung einfgen; links oder rechts (in Reihenschaltung)
oder ber oder unter (in Parallelschaltung) mit der gewhlten Anweisung.
Einige Handhabungen sind nicht erlaubt, so zum Beispiel weitere
Anweisungen rechts von einer Spule.

Das Programm beginnt mit nur einem Netzwerk. Sie knnen mehr Netzwerke
hinzufgen, indem Sie Netzwerk Einfgen Davor/Danach im Programm-Men
whlen.  Den gleichen Effekt knnten Sie erzielen, indem Sie viele
komplizierte parallele Unterschaltungen in einem einzigen Netzwerk
unterbringen. Es ist aber bersichtlicher, mehrere Netzwerke zu verwenden.

Wenn Sie Ihr Programm fertig geschrieben haben, so knnen Sie dieses
mit der Simulation testen. Danach knnen Sie es in eine Hex-Datei fr
den zugedachten Mikroprozessor kompilieren.


SIMULATION
==========

Um den Simulationsbetrieb einzugeben, whlen Sie Simulieren ->
Simulationsbetrieb oder drcken Sie <Strg+M>.  Das Programm wird
im Simulationsbetrieb unterschiedlich dargestellt. Es gibt keine
Schreibmarke (cursor) mehr. Die erregten Anweisungen erscheinen hellrot,
die nicht erregten erscheinen grau.  Drcken Sie die Leertaste, um das
SPS-Programm nur einen einzelnen Zyklus durchlaufen zu lassen. Whlen
Sie fr einen kontinuierlichen Umlauf in Echtzeit Simulieren -> Start
Echtzeit-Simulation oder drcken Sie <Strg+R>. Die Maske (Bildanzeige)
des Programms wird jetzt in Echtzeit, entsprechend der nderungen des
Status (des Zustands) des Programms aktualisiert.

Sie knnen den Status (Zustand) eines Eingangs im Programm einstellen,
indem Sie auf den jeweiligen auf der Liste am unteren Ende der
Maske (Bildanzeige) doppelklicken oder auf die jeweilige XName
Kontakt-Anweisung im Programm. Wenn Sie den Status (Zustand) eines
Eingangs-Pins ndern, so wird diese nderung nicht unmittelbar in
der Maske (Bildanzeige) wiedergegeben, sondern erst wenn sich die
SPS im zyklischen Umlauf befindet. Das geschieht automatisch wenn das
SPS-Programm in Echtzeit-Simulation luft, oder wenn Sie die Leertaste
drcken.


KOMPILIEREN ZUM SYSTEMSPEZIFISCHEN CODE
=======================================

Letztlich ist es dann nur sinnvoll eine .hex Datei zu erzeugen, mit
der Sie Ihren Mikroprozessor programmieren knnen. Zunchst mssen
Sie die Teilenummer des Mikroprozessors im Men Voreinstellungen ->
Prozessor whlen. Danach mssen jedem XName oder YName Objekt
einen E/A-Pin zuweisen. Tun Sie dies, indem auf den Namen des Objekts
doppelklicken, welcher sich in der Liste ganz unten in der Maske
(Bildanzeige) befindet. Ein Dialogfenster wird dann erscheinen und Sie
knnen daraufhin einen noch nicht vergebenen Pin von der Liste aussuchen.

Als nchstes mssen Sie die Zykluszeit whlen, mit der Sie das
Programm laufen lassen wollen, auch mssen Sie dem Compiler mitteilen
mit welcher Taktgeschwindigkeit der Prozessor arbeiten soll. Diese
Einstellungen werden im Men Voreinstellungen -> Prozessor Parameter...
vorgenommen. blicherweise sollten Sie die Zykluszeit nicht ndern,
denn diese ist auf 10ms voreingestellt, dies ist ein guter Wert fr
die meisten Anwendungen. Tippen Sie die Frequenz des Quarzes (oder des
Keramik-Resonators) ein, mit der Sie den Prozessor betreiben wollen und
klicken auf Okay.

Jetzt knnen Sie einen Code von Ihrem Programm erzeugen.  Whlen Sie
Kompilieren -> Kompilieren oder Kompilieren -> Kompilieren unter...,
falls Sie vorher Ihr Programm schon kompiliert haben und einen neuen Namen
fr die Ausgangsdatei vergeben wollen. Wenn Ihr Programm fehlerfrei ist,
wird LDmicro eine Intel IHEX Datei erzeugen, mit der sich Ihr Prozessor
programmieren lsst.

Verwenden Sie hierzu irgendeine Programmier Soft- und Hardware, die Sie
besitzen, um die Hex-Datei in den Mikroprozessor zu laden.  Beachten Sie
die Einstellungen fr die Konfigurationsbits (fuses)!  Bei den PIC16
Prozessoren sind diese Konfigurationsbits bereits in der Hex-Datei
enthalten. Die meisten Programmiersoftwares schauen automatisch nach
diesen. Fr die AVR-Prozessoren mssen Sie die Konfigurationsbits von
Hand einstellen.


ANWEISUNGS-VERZEICHNIS
======================

> KONTAKT, SCHLIESSER           XName        RName        YName
                             ----] [----  ----] [----  ----] [----

Wenn ein unwahres Signal diese Anweisung erreicht, so ist das
Ausgangssignal unwahr. Wenn ein wahres Signal diese Anweisung
erreicht, so ist das Ausgangssignal wahr. Dies nur, falls der
vorliegende Eingangspin, Ausgangspin oder eines Merkers (Hilfsrelais)
wahr ist, anderenfalls ist es unwahr. Diese Anweisung fragt den Status
(Zustand) eines Eingangspins, Ausgangspins oder Merkers (Hilfsrelais) ab.


> KONTAKT, FFNER              XName        RName        YName
                            ----]/[----  ----]/[----  ----]/[----

Wenn ein unwahres Signal diese Anweisung erreicht, so ist das
Ausgangssignal unwahr. Wenn ein wahres Signal diese Anweisung
erreicht, so ist das Ausgangssignal wahr. Dies nur, falls der
vorliegende Eingangspin, Ausgangspin oder der Merker (= internes
Hilfsrelais) unwahr ist, anderenfalls ist es unwahr. Diese Anweisung
fragt den Status (Zustand) eines Eingangspins, Ausgangspins oder Merkers
(Hilfsrelais) ab. Dies ist das Gegenteil eines Schlieers.


> SPULE, NORMAL (MERKER,AUSGANG)    RName           YName
                                  ----( )----     ----( )----

Wenn ein unwahres Signal diese Anweisung erreicht, so wird der
vorliegende Merker (Hilfsrelais) oder Ausgangspin nicht angesteuert. Wenn
ein wahres Signal diese Anweisung erreicht, so wird der vorliegende
Merker (Hilfsrelais) oder Ausgangspin angesteuert. Es ist nicht sinnvoll
dieser Spule eine Eingangsvariable zuzuweisen. Diese Anweisung muss
ganz rechts im Netzwerk stehen.


> SPULE, NEGIERT (MERKER,AUSGANG)   RName          YName
                                  ----(/)----   ----(/)----

Wenn ein wahres Signal diese Anweisung erreicht, so wird der vorliegende
Merker (Hilfsrelais)oder Ausgangspin nicht angesteuert. Wenn ein
unwahres Signal diese Anweisung erreicht, so wird der vorliegende Merker
(Hilfsrelais) oder Ausgangspin angesteuert. Es ist nicht sinnvoll dieser
Spule eine Eingangsvariable zuzuweisen. Dies ist das Gegenteil einer
normalen Spule. Diese Anweisung muss im Netzwerk ganz rechts stehen.


> SPULE, SETZEN      RName           YName
                  ----(S)----     ----(S)----

Wenn ein wahres Signal diese Anweisung erreicht, so wird der vorliegende
Merker (Hilfsrelais)oder Ausgangspin auf wahr gesetzt. Anderenfalls
bleibt der Status (Zustand) des Merkers (Hilfsrelais) oder Ausgangspins
unverndert.  Diese Anweisung kann nur den Status (Zustand) einer Spule
von unwahr nach wahr verndern, insofern wird diese blicherweise in
einer Kombination mit einer Rcksetz-Anweisung fr eine Spule verwendet.
Diese Anweisung muss ganz rechts im Netzwerk stehen.


> SPULE, RCKSETZEN    RName           YName
                    ----(R)----     ----(R)----

Wenn ein wahres Signal diese Anweisung erreicht, so wird der vorliegende
Merker (Hilfsrelais) oder Ausgangspin rckgesetzt. Anderenfalls bleibt der
Status (Zustand) des Merkers (Hilfsrelais) oder Ausgangspins unverndert.
Diese Anweisung kann nur den Status (Zustand) einer Spule von wahr nach
unwahr verndern, insofern wird diese blicherweise in einer Kombination
mit einer Setz-Anweisung fr eine Spule verwendet. Diese Anweisung muss
ganz rechts im Netzwerk stehen.


> ANZUGSVERZGERUNG         Tdon
                      -[TON 1.000 s]-

Wenn ein Signal diese Anweisung erreicht, welches seinen Status
(Zustand) von unwahr nach wahr ndert, so bleibt das Ausgangssignal
fr 1,000 s unwahr, dann wird es wahr. Wenn ein Signal diese
Anweisung erreicht, welches seinen Status (Zustand) von wahr nach
unwahr ndert, so wird das Ausgangssignal sofort unwahr. Der Timer
wird jedes Mal rckgesetzt (bzw. auf Null gesetzt), wenn der Eingang
unwahr wird. Der Eingang muss fr 1000 aufeinanderfolgende Millisekunden
wahr bleiben, bevor auch der Ausgang wahr wird. Die Verzgerung
ist konfigurierbar.

Die TName Variable zhlt, in der Einheit der jeweiligen Zykluszeit,
von Null ab hoch. Der Ausgang der TON-Anweisung wird wahr, wenn die
Zhlervariable grer oder gleich der vorliegenden Verzgerung ist.
Es mglich die Zhlervariable an einer anderen Stelle im Programm zu
bearbeiten, zum Beispiel mit einer TRANSFER-Anweisung (MOV).


> ABFALLVERZGERUNG         Tdoff
                      -[TOF 1.000 s]-

Wenn ein  Signal diese Anweisung erreicht, welches seinen Status
(Zustand) von wahr nach unwahr ndert, so bleibt das Ausgangssignal
fr 1,000 s wahr, dann wird es unwahr. Wenn ein Signal diese
Anweisung erreicht, welches seinen Status (Zustand) von unwahr nach
wahr ndert, so wird das Ausgangssignal sofort wahr. Der Timer wird
jedes Mal rckgesetzt (bzw. auf Null gesetzt), wenn der Eingang unwahr
wird. Der Eingang muss fr 1000 aufeinanderfolgende Millisekunden unwahr
bleiben, bevor auch der Ausgang unwahr wird. Die Verzgerung ist
konfigurierbar.

Die TName Variable zhlt, in der Einheit der jeweiligen Zykluszeit,
von Null ab hoch. Der Ausgang der TOF Anweisung wird wahr, wenn die
Zhlervariable grer oder gleich der vorliegenden Verzgerung ist.
Es mglich die Zhlervariable an einer anderen Stelle im Programm zu
bearbeiten, zum Beispiel mit einer TRANSFER-Anweisung (MOV).


> SPEICHERNDER TIMER         Trto
                      -[RTO 1.000 s]-

Diese Anweisung zeichnet auf, wie lange sein Eingang wahr gewesen
ist. Wenn der Eingang fr mindestens 1.000 s wahr gewesen ist, dann
wird der Ausgang wahr. Andernfalls ist er unwahr. Der Eingang muss
fr 1000 aufeinanderfolgende Millisekunden wahr gewesen sein; wenn
der Eingang fr 0,6 s wahr war, dann unwahr fr 2,0 s und danach fr
0,4 s  wieder wahr, so wird sein Ausgang wahr. Nachdem der Ausgang
wahr wurde, so bleibt er wahr, selbst wenn der Eingang unwahr
wird, so lange der Eingang fr lnger als 1.000 s wahr gewesen ist.
Der Timer muss deshalb von Hand mit Hilfe der Rcksetz-Anweisung
rckgesetzt (auf Null gesetzt) werden.

Die TName Variable zhlt, in der Einheit der jeweiligen Zykluszeit,
von Null ab hoch. Der Ausgang der RTO-Anweisung wird wahr, wenn die
Zhlervariable grer oder gleich der vorliegenden Verzgerung ist.
Es mglich die Zhlervariable an einer anderen Stelle im Programm zu
bearbeiten, zum Beispiel mit einer TRANSFER-Anweisung (MOV).


> RCKSETZEN              Trto             Citems
                     ----{RES}----     ----{RES}----

Diese Anweisung rcksetzt einen Timer oder Zhler. TON oder TOF Timer
werden automatisch rckgesetzt, wenn ihr Eingang wahr oder unwahr
wird, somit ist die RES-Anweisung fr diese Timer nicht erforderlich. RTO
Timer und CTU/CTD Zhler werden nicht automatisch rckgesetzt, somit
mssen diese von Hand mit Hilfe der RES-Anweisung rckgesetzt (auf Null)
werden. Wenn der Eingang wahr ist, so wird der Timer oder Zhler
rckgesetzt; wenn der Eingang unwahr ist, so erfolgt keine Aktion.
Diese Anweisung muss ganz rechts im Netzwerk stehen.

                                            _    _
> ONE-SHOT RISING, STEIGENDE FLANKE    --[_/ OSR/ \_]--

Diese Anweisung wird normalerweise unwahr ausgewiesen. Wenn der Eingang
der Anweisung whrend des momentanen Zyklus wahr ist und whrend des
vorgehenden unwahr war, so wird der Ausgang wahr. Daher erzeugt diese
Anweisung bei jeder steigenden Flanke einen Impuls fr einen Zyklus.
Diese Anweisung ist hilfreich, wenn Sie Ereignisse an der steigenden
Flanke eines Signals auslsen wollen.

                                          _      _
> ONE-SHOT FALLING, FALLENDE FLANKE    --[ \_OSF/ \_]--

Diese Anweisung wird normalerweise unwahr ausgewiesen. Wenn der Eingang
der Anweisung whrend des momentanen Zyklus unwahr ist und whrend des
vorgehenden wahr war, so wird der Ausgang wahr. Daher erzeugt diese
Anweisung bei jeder fallenden Flanke einen Impuls fr einen Zyklus.
Diese Anweisung ist hilfreich, wenn Sie Ereignisse an der fallenden
Flanke eines Signals auslsen wollen.


> BRCKE, FFNUNG     ----+----+----      ----+     +----

Der Eingangszustand einer Brcke ist immer gleich seinem Ausgangszustand.
Der Ausgangszustands einer ffnung ist immer unwahr. Diese Anweisungen
sind bei der Fehlerbehebung (debugging) besonders hilfreich.


> MASTER CONTROL RELAIS   -{MASTER RLY}-


Im Normalfall ist der Anfang (die linke Stromschiene) von jedem Netzwerk
wahr. Wenn eine Master Control Relais Anweisung ausgefhrt wird dessen
Eingang unwahr ist, so werden die Anfnge (die linke Stromschiene)
aller folgenden Netzwerke unwahr. Das setzt sich fort bis die nchste
Master Control Relais Anweisung erreicht wird (unabhngig von dem
Anfangszustand dieser Anweisung). Diese Anweisungen mssen daher als Paar
verwendet werden: Eine (vielleicht abhngige), um den gegebenenfalls
gesperrten Abschnitt zu starten und eine weitere, um diesen zu beenden.


> TRANSFER, MOV           {destvar :=  }      {Tret :=     }
                         -{ 123     MOV}-    -{ srcvar  MOV}-

Wenn der Eingang dieser Anweisung wahr ist, so setzt diese die
vorliegende Zielvariable gleich der vorliegenden Quellvariablen
oder Konstanten. Wenn der Eingang dieser Anweisung unwahr ist, so
geschieht nichts. Mit der TRANSFER-Anweisung (MOV) knnen Sie jede
Variable zuweisen; dies schliet Timer und Zhler Statusvariablen ein,
welche mit einem vorgestellten T oder C unterschieden werden. Eine
Anweisung zum Beispiel, die eine 0 in einen TBewahrend transferiert,
ist quivalent mit einer RES-Anweisung fr diesen Timer. Diese Anweisung
muss ganz rechts im Netzwerk stehen.


> ARITHMETISCHE OPERATIONEN   {ADD  kay  :=}       {SUB  Ccnt :=}
                             -{ 'a' + 10   }-     -{ Ccnt - 10  }-

>                             {MUL  dest :=}       {DIV  dv :=  }
                             -{ var * -990 }-     -{ dv / -10000}-

Wenn der Eingang einer dieser Anweisungen wahr ist, so setzt diese
die vorliegende Zielvariable gleich dem vorliegenden arithmetischem
Ausdruck. Die Operanden knnen entweder Variabelen (einschlielich Timer-
und Zhlervariabelen) oder Konstanten sein. Diese Anweisungen verwenden
16-Bitzeichen Mathematik. Beachten Sie, dass das Ergebnis jeden Zyklus
ausgewertet wird, wenn der Eingangszustand wahr ist. Falls Sie eine
Variable inkrementieren oder dekrementieren (d.h., wenn die Zielvariable
ebenfalls einer der Operanden ist), dann wollen Sie dies vermutlich
nicht; normalerweise wrden Sie einen Impuls (one-shot) verwenden,
sodass die Variable nur bei einer steigenden oder fallenden Flanke des
Eingangszustands ausgewertet wird. Dividieren krzt: D.h. 8 / 3 = 2.
Diese Anweisungen mssen ganz rechts im Netzwerk stehen.


> VERGLEICHEN           [var ==]        [var >]        [1 >=]
                       -[ var2 ]-      -[ 1   ]-      -[ Ton]-

>                       [var !=]        [-4 <   ]      [1 <=]
                       -[ var2 ]-      -[ vartwo]-    -[ Cup]-

Wenn der Eingang dieser Anweisung unwahr ist, so ist der Ausgang
auch unwahr. Wenn der Eingang dieser Anweisung wahr ist, dann ist
Ausgang wahr; dies aber nur, wenn die vorliegende Bedingung wahr
ist. Diese Anweisungen knnen zum Vergleichen verwendet werden, wie:
Auf gleich, auf grer als, auf grer als oder gleich, auf ungleich,
auf kleiner als, auf kleiner als oder gleich, eine Variable mit einer
Variablen oder eine Variable mit einer 16-Bitzeichen-Konstanten.


> ZHLER        CName          CName
              --[CTU >= 5]--  --[CTD > -5]--

Ein Zhler inkrementiert (CTU, aufwrtszhlen) oder dekrementiert
(CTD, abwrtszhlen) die bezogene Zhlung bei jeder steigenden Flanke
des Eingangszustands des Netzwerks (d.h. der Eingangszustand des
Netzwerks geht von unwahr auf wahr ber).  Der Ausgangszustand des
Zhlers ist wahr, wenn die Zhler- variable ist grer oder gleich 5
und andernfalls unwahr. Der Ausgangszustand des Netzwerks kann wahr
sein, selbst wenn der Eingangszustand unwahr ist; das hngt lediglich
von Zhlervariablen ab. Sie knnen einer CTU- und CTD-Anweisung den
gleichen Namen zuteilen, um den gleichen Zhler zu inkrementieren und
dekrementieren. Die RES-Anweisung kann einen Zhler rcksetzen oder auch
eine gewhnliche Variablen-Operation mit der Zhlervariablen ausfhren.


> ZIRKULIERENDER ZHLER       CName
                          --{CTC 0:7}--

Ein zirkulierender Zhler arbeitet wie ein normaler CTU-Zhler, auer
nach der Erreichung seiner Obergrenze, rcksetzt er seine Zhlervariable
auf Null. Zum Beispiel wrde der oben gezeigte Zhler, wie folgt zhlen:
0, 1, 2, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2,....  Dies ist
hilfreich in Kombination mit bedingten Anweisungen der VariablenCName;
Sie knnen dies als eine Folgeschaltung verwenden. CTC-Zhler takten
mit der aufsteigenden Flanke der Eingangsbedingung des Netzwerks.
Diese Anweisung muss ganz rechts im Netzwerk stehen.


> SCHIEBEREGISTER          {SHIFT REG   }
                          -{ reg0..3    }-

Ein Schieberegister besteht aus einer Reihe von Variablen. So bestnde
zum Beispiel ein Schieberegister aus den Variablen reg0, reg1,
reg2, and reg3. Der Eingang des Schieberegisters ist reg0. Bei
jeder steigenden Flanke der Eingansbedingung des Netzwerks, schiebt das
Schieberegister nach rechts. Dies bedeutet es wie folgt zuweist: reg3
nach reg2, reg2 nach reg1 und reg1 nach reg0.  reg0 bleibt
unverndert. Ein groes Schieberegister kann leicht viel Speicherplatz
belegen. Diese Anweisung muss ganz rechts im Netzwerk stehen.


> NACHSCHLAG-TABELLE       {dest :=     }
                          -{ LUT[i]     }-

Eine Nachschlag-Tabelle ist eine Anordnung von n Werten. Wenn die
Eingangsbedingung des Netzwerks wahr ist, so wird die Ganzzahl-Variable
dest mit dem Eintrag in der Nachschlag-Tabelle gleichgesetzt, der der
Ganzzahl-Variablen i entspricht. Das Verzeichnis beginnt bei Null,
insofern muss sich i zwischen 0 und (n-1) befinden. Das Verhalten
dieser Anweisung ist undefiniert, wenn sich die Werte des Verzeichnisses
auerhalb dieses Bereichs befinden.


> NHERUNGS-LINEAR-TABELLE    {yvar :=}
                             -{PWL[xvar] }-

Dies ist eine gute Methode fr die Nherungslsung einer komplizierten
Funktion oder Kurve. Sie knnte zum Beispiel hilfreich sein, wenn Sie
versuchen eine Eichkurve zu verwenden, um die rohe Ausgangsspannung
eines Fhlers in gnstigere Einheiten zu wandeln.

Angenommen Sie versuchen eine Nherungslsung fr eine Funktion zu finden,
die eine Eingangs-Ganzzahlvariable x in Ausgangs-Ganzzahlvariable y
wandelt. Einige Punkte der Funktion sind Ihnen bekannt; so wrden Sie
z.B. die folgenden kennen:

    f(0)     = 2
    f(5)     = 10
    f(10)     = 50
    f(100) = 100

Dies bedeutet, dass sich die Punkte

    (x0, y0)    = (  0,    2)
    (x1, y1)    = (  5,   10)
    (x2, y2)    = ( 10,   50)
    (x3, y3)    = (100,  100)

in dieser Kurve befinden. Diese 4 Punkte knnen Sie in die Tabelle der
Nherungs-Linear-Anweisung eintragen. Die Nherungs-Linear-Anweisung
wird dann auf den Wert von xvar schauen und legt den Wert von yvar
fest. Sie stellt yvar so ein, dass die Nherungs-Linear-Kurve sich
durch alle Punkte bewegt, die Sie vorgegeben haben.  Wenn Sie z.B. fr
xvar = 10 vorgegeben haben, dann stellt die Anweisung yvar auf gleich
50 ein.

Falls Sie dieser Anweisung einen Wert xvar zuweisen, der zwischen zwei
Werten von x liegt, denen Sie Punkte zugeordnet haben, dann stellt die
Anweisung yvar so ein, dass (xvar, yvar) in der geraden Linie liegt;
diejenige die, die zwei Punkte in der Tabelle verbindet. Z.B. erzeugt
xvar = 55 bei yvar = 75. Die beiden Punkte in der Tabelle sind (10,
50) und (100, 100). 55 liegt auf halbem Weg zwischen 10 und 100 und 75
liegt auf halbem Weg zwischen 50 und 100, somit liegt (55, 75) auf der
Linie, die diese zwei Punkte verbindet.

Die Punkte mssen in aufsteigender Reihenfolge der x-Koordinaten
angegeben werden. Einige mathematische Operationen, erforderlich fr
bestimmte Nachschlag-Tabellen mit 16-Bit-Mathematik, kann man ggf. nicht
ausfhren. In diesem Falle gibt LDmicro eine Warnmeldung aus. So wrde
z.B. die folgende Nachschlag-Tabelle eine Fehlermeldung hervorrufen:

    (x0, y0)    = (  0,    0)
    (x1, y1)    = (300,  300)

Sie knnen diesen Fehler beheben, indem sie den Abstand zwischen den
Punkten kleiner machen. So ist zum Beispiel die nchste Tabelle quivalent
zur vorhergehenden, ruft aber keine Fehlermeldung hervor.

    (x0, y0)    = (  0,    2)
    (x1, y1)    = (150,  150)
    (x2, y2)    = (300,  300)

Es wird kaum einmal notwendig sein, mehr als fnf oder sechs Punkte
zu verwenden. Falls Sie mehr Punkte hinzufgen, so vergrert dies
Ihren Code und verlangsamt die Ausfhrung. Falls Sie fr xvar einen
Wert vergeben, der grer ist, als die grte x-Koordinate der Tabelle
oder kleiner, als die kleinste x-Koordinate in der Tabelle, so ist das
Verhalten der Anweisung undefiniert. Diese Anweisung muss ganz rechts
im Netzwerk stehen.


> A/D-WANDLER EINLESEN      AName
                        --{READ ADC}--

LDmicro kann einen Code erzeugen, der ermglicht, die A/D-Wandler
zu verwenden, die in manchen Mikroprozessoren vorgesehen sind.
Wenn der Eingangszustand dieser Anweisung wahr ist, dann wird eine
Einzellesung von dem A/D-Wandler entnommen und in der Variablen AName
gespeichert. Diese Variable kann anschlieend mit einer gewhnlichen
Ganzzahlvariablen bearbeitet werden (wie: Kleiner als, grer als,
arithmetisch usw.). Weisen Sie Axxx in der gleichen Weise einen Pin
zu, wie Sie einen Pin fr einen digitalen Ein- oder Ausgang vergeben
wrden, indem auf diesen in der Liste unten in der Maske (Bildanzeige)
doppelklicken.  Wenn der Eingangszustand dieses Netzwerks unwahr ist,
so wird die Variable AName unverndert belassen.

Fr alle derzeitig untersttzten Prozessoren gilt: Eine 0 Volt Lesung
am Eingang des A/D-Wandlers entspricht 0. Eine Lesung gleich der
Versorgungsspannung (bzw. Referenzspannung) entspricht 1023. Falls Sie
AVR-Prozessoren verwenden, so verbinden Sie AREF mit Vdd.  (Siehe Atmel
Datenblatt, dort wird eine Induktivitt von 100H empfohlen). Sie knnen
arithmetische Operationen verwenden, um einen gnstigeren Mastabfaktor
festzulegen, aber beachten Sie, dass das Programm nur Ganzzahl-Arithmetik
vorsieht. Allgemein sind nicht alle Pins als A/D-Wandler verwendbar. Die
Software gestattet Ihnen nicht, einen Pin zuzuweisen, der kein A/D
bzw. analoger Eingang ist. Diese Anweisung muss ganz rechts im Netzwerk
stehen.


> PULSWEITEN MODULATIONSZYKLUS FESTLEGEN    duty_cycle
                                          -{PWM 32.8 kHz}-

LDmicro kann einen Code erzeugen, der ermglicht, die PWM-Peripherie
zu verwenden, die in manchen Mikroprozessoren vorgesehen ist. Wenn die
Eingangsbedingung dieser Anweisung wahr ist, so wird der Zyklus der
PWM-Peripherie mit dem Wert der Variablen duty cycle gleichgesetzt. Der
duty cycle muss eine Zahl zwischen 0 und 100 sein. 0 entspricht immer
low und 100 entsprechend  immer high. (Wenn Sie damit vertraut sind,
wie die PWM-Peripherie funktioniert, so bemerken Sie, dass dies bedeutet,
dass LDmicro die duty cycle-Variable automatisch prozentual zu den
PWM-Taktintervallen skaliert [= den Mastabfaktor festlegt].)

Sie knnen die PWM-Zielfrequenz in Hz definieren. Es kann vorkommen, dass
die angegebene Frequenz nicht genau erreicht wird, das hngt davon ab,
wie sich diese innerhalb der Taktfrequenz des Prozessors einteilt. LDmicro
whlt dann die nchst erreichbare Frequenz; falls der Fehler zu gro ist,
so wird eine Warnung ausgegeben. Hhere Geschwindigkeiten knnen die
Auflsung beeintrchtigen.

Diese Anweisung muss ganz rechts im Netzwerk stehen. Die ladder
logic-Laufzeit verbraucht (schon) einen Timer, um die Zykluszeit
zu messen. Dies bedeutet, dass die PWM nur bei den Mikroprozessoren
verfgbar ist, bei denen mindestens zwei geeignete Timer vorhanden sind.
PWM verwendet den PIN CCP2 (nicht CCP1) bei den PIC16-Prozessoren und
OC2 (nicht OC1A) bei den AVR-Prozessoren.


> REMANENT MACHEN     saved_var
                    --{PERSIST}--

Wenn der Eingangszustand dieser Anweisung wahr ist, so bewirkt
dies, dass eine angegebene Ganzzahl-Variable automatisch im EEPROM
gespeichert wird. Dies bedeutet, dass ihr Wert bestehen bleiben wird,
auch wenn der Prozessor seine Versorgungsspannung verliert. Es ist
nicht notwendig, die Variable an klarer Stelle im EEPROM zu speichern,
dies geschieht automatisch, so oft sich der Wert der Variablen
ndert. Bei Spannungswiederkehr wird die Variable automatisch vom
EEPROM zurckgespeichert. Falls eine Variable, die hufig ihren Wert
ndert, remanent (dauerhaft) gemacht wird, so knnte Ihr Prozessor sehr
rasch verschleien, weil dieser lediglich fr eine begrenzte Anzahl von
Schreibbefehlen konstruiert ist (~100 000). Wenn der Eingangszustand des
Netzwerks unwahr ist, so geschieht nichts. Diese Anweisung muss ganz
rechts im Netzwerk stehen.


> UART (SERIELL) EMPFANGEN      var
                            --{UART RECV}--

LDmicro kann einen Code erzeugen, der ermglicht UART zu verwenden,
welcher in manchen Mikroprozessoren vorgesehen ist.
Bei AVR-Prozessoren mir mehrfachem UART, wird nur UART1 (nicht UART0)
untersttzt. Konfigurieren Sie die Baudrate, indem Sie Voreinstellungen
-> Prozessor-Parameter verwenden. Bestimmte Baudraten werden mit
bestimmten Quarzfrequenzen nicht erreichbar sein. In diesem Fall gibt
LDmicro eine Warnmeldung.

Wenn der Eingangszustand dieser Anweisung unwahr ist, so geschieht
nichts. Wenn der Eingangszustand wahr ist, so versucht diese Anweisung
ein einzelnes Schriftzeichen vom UART-Eingang zu empfangen. Wenn
kein Schriftzeichen eingelesen wird, dann ist der Ausgangszustand
unwahr. Wenn ein ASCII-Zeichen eingelesen wird, so wird sein Wert in
var abgespeichert und der Ausgangszustand wird fr einen einzelnen
Zyklus wahr.


> UART (SERIELL) SENDEN       var
                          --{UART SEND}--

LDmicro kann einen Code erzeugen, der ermglicht UART zu verwenden,
welcher in manchen Mikroprozessoren vorgesehen ist.
Bei AVR-Prozessoren mir mehrfachem UART, wird nur UART1 (nicht UART0)
untersttzt. Konfigurieren Sie die Baudrate, indem Sie Voreinstellungen
-> Prozessor-Parameter verwenden. Bestimmte Baudraten werden mit
bestimmten Quarzfrequenzen nicht erreichbar sein. In diesem Fall gibt
LDmicro eine Warnmeldung.

Wenn der Eingangszustand dieser Anweisung unwahr ist, so geschieht
nichts. Wenn der Eingangszustand wahr ist, so schreibt diese
Anweisung ein einzelnes Schriftzeichen zum UART. Der ASCII-Wert des
Schriftzeichens, welches gesendet werden soll, muss vorher in var
abgespeichert worden sein. Der Ausgangszustand dieses Netzwerks ist
wahr, wenn UART beschftigt ist (gerade dabei ein Schriftzeichen zu
bermitteln) und andernfalls unwahr.

Denken Sie daran, dass einige Zeit zum Senden von Schriftzeichen
beansprucht wird. berprfen Sie den Ausgangszustand dieser Anweisung,
sodass das erste Schriftzeichen bereits bermittelt wurde, bevor Sie
versuchen ein zweites Schriftzeichen zu bermitteln. Oder verwenden Sie
einen Timer, um eine Verzgerung zwischen die Schriftzeichen fgen. Sie
drfen den Eingangszustand dieser Anweisung nur dann auf wahr setzen
(bzw. ein Schriftzeichen bermitteln), wenn der Ausgangszustand unwahr
ist (bzw. UART unbeschftigt ist).

Untersuchen Sie die Formatierte Zeichenfolge-Anweisung, bevor Sie
diese Anweisung verwenden. Die Formatierte Zeichenfolge- Anweisung
ist viel einfacher in der Anwendung und fast sicher fhig, das zu tun,
was Sie beabsichtigen.


> FORMATIERTE ZEICHENFOLGE BER UART            var
                                        -{"Druck: \3\r\n"}-

LDmicro kann einen Code erzeugen, der ermglicht UART zu verwenden,
welcher in manchen Mikroprozessoren vorgesehen ist.
Bei AVR-Prozessoren mir mehrfachem UART, wird nur UART1 (nicht UART0)
untersttzt. Konfigurieren Sie die Baudrate, indem Sie Voreinstellungen
-> Prozessor-Parameter verwenden. Bestimmte Baudraten werden mit
bestimmten Quarzfrequenzen nicht erreichbar sein. In diesem Fall gibt
LDmicro eine Warnmeldung.

Wenn der Eingangszustand des Netzwerks fr diese Anweisung von unwahr
auf wahr bergeht, so beginnt diese eine vollstndige Zeichenfolge
ber den seriellen Anschluss zu senden. Wenn die Zeichenfolge die
besondere Reihenfolge \3 enthlt, dann wird diese Folge durch den Wert
von var ersetzt, welcher automatisch in eine Zeichenfolge gewandelt
wird. Die Variable wird formatiert, sodass diese exakt 3 Schriftzeichen
bernimmt. Falls die Variable zum Beispiel gleich 35 ist, dann wird die
exakte ausgegebene Zeichenfolge, wie folgt aussehen: Druck:  35\r\n
(beachten Sie das zustzliche Freizeichen). Wenn stattdessen die Variable
gleich 1432 ist, so wre das Verhalten der Anweisung undefiniert,
weil 1432 mehr als drei Stellen hat. In diesem Fall wre es notwendig
stattdessen \4 zu verwenden.

Falls die Variable negativ ist, so verwenden Sie stattdessen \-3d
(oder \-4d). LDmicro wird hierdurch veranlasst eine vorgestellte
Freistelle fr positive Zahlen und ein vorgestelltes Minuszeichen fr
negative Zahlen auszugeben.

Falls mehrere Formatierte Zeichenfolge-Anweisungen zugleich ausgegeben
werden (oder wenn eine neue Zeichenfolge ausgegeben wird bevor die
vorherige vollendet ist), oder auch wenn diese mit UART TX Anweisungen
vermischt, so ist das Verhalten undefiniert.

Es ist auch mglich diese Anweisung fr eine feste Zeichenfolge zu
verwenden, die ber den seriellen Anschluss gesendet wird, ohne den Wert
einer Ganzzahlvariablen in den Text zu interpolieren. In diesem Fall
fgen Sie einfach diese spezielle Steuerungsfolge nicht ein.

Verwenden Sie \\ fr einen zeichengetreuen verkehrten Schrgstrich.
Zustzlich zur Steuerungsfolge fr die Interpolierung einer Ganzzahl-
Variablen, sind die folgenden Steuerungszeichen erhltlich:

        * \r   -- carriage return      Zeilenschaltung
        * \n   -- new line             Zeilenwechsel
        * \f   -- form feed            Formularvorschub
        * \b   -- backspace            Rcksetzen
        * \t   -- horizontal tab
        * \v   -- vertical tab
        * \a   -- alert
        * \xAB -- character with ASCII value 0xAB (hex)
               -- Schriftzeichen mit ASCII-Wert 0xAB (hex)

Der Ausgangszustand des Netzwerks dieser Anweisung ist wahr, whrend
diese Daten bertrgt, ansonsten unwahr. Diese Anweisung bentigt eine
groe Menge des Programmspeichers, insofern sollte sie sparsam verwendet
werden. Die gegenwrtige Umsetzung ist nicht besonders effizient, aber
eine bessere wrde nderungen an smtlichen Auslufern des Programms
bentigen.


> FORMATIERTE ZEICHENFOLGE                   dest
                                       -{"Zeichenkette", var}-

Fr Zielplattformen (z.B. Netzer) auf denen bereits ein printf
verfgbar ist, kann dieser Befehl verwendet werden.

Wenn der Eingangszustand des Netzwerks fr diese Anweisung von unwahr
auf wahr bergeht, so beginnt diese die Zeichenfolge mittels printf
zu bearbeiten und gibt sie auf der Zielvariablen aus.

Die Zeichenkette wird vollstndig in das Kompilat eingebettet. Es gelten
die Formatierungsregeln von printf.

Die Variable kann eine beliebige Variable aus dem Programmbereich
sein. Die printf Funktion der Zielplatform wird auf sie zugreifen,
sobald ein Platzhalter in der Zeichenkette gefunden wird (z.B. %d).

Dest ist ein Register, auf das das Ergebnis geschrieben wird. Das sollte
das obere Ende eines Ringpuffers oder FiFo-Speichers sein.
d des Netzwerks dieser Anweisung ist wahr,
Der Ausgangszustand des Netzwerks dieser Anweisung ist immer wahr,


EIN HINWEIS ZUR VERWENDUNG DER MATHEMATIK
=========================================

Denken Sie daran, dass LDmicro nur 16-Bit mathematische Operationen
ausfhrt. Dies bedeutet, dass das Endresultat jeder Berechnung,
die Sie vornehmen, eine Ganzzahl zwischen -32768 und 32767 sein muss.
Dies bedeutet auch, dass die Zwischenergebnisse Ihrer Berechnungen alle
in diesem Bereich liegen mssen.

Wollen wir zum Beispiel annehmen, dass Sie folgendes berechnen mchten
y = (1/x) * 1200, in der x zwischen 1 und 20 liegt.
Dann liegt y zwischen 1200 und 60, was in eine 16-Bit Ganzzahl passt,
so wre es zumindest theoretisch mglich diese Berechnung auszufhren.
Es gibt zwei Mglichkeiten, wie Sie dies codieren knnten: Sie knnen
die Reziproke (Kehrwert) ausfhren and dann multiplizieren:

   ||         {DIV  temp  :=}          ||
   ||---------{ 1 / x       }----------||
   ||                                  ||
   ||          {MUL  y  :=  }          ||
   ||----------{ temp * 1200}----------||
   ||                                  ||

Oder Sie knnten einfach die Division in einem Schritt direkt vornehmen.

   ||           {DIV  y  :=}           ||
   ||-----------{ 1200 / x }-----------||


Mathematisch sind die zwei quivalent; aber wenn Sie diese ausprobieren,
so werden Sie herausfinden, dass die erste ein falsches Ergebnis von
y = 0 liefert. Dies geschieht, weil die Variable einen Unterlauf
[= resultatabhngige Kommaverschiebung] ergibt.  So sei zum Beispiel x = 3,
(1 / x) = 0.333, dies ist aber keine Ganzzahl; die Divisionsoperation
nhert dies, als 'temp = 0'. Dann ist y = temp * 1200 = 0. Im zweiten
Fall gibt es kein Zwischenergebnis, welches einen Unterlauf [= resultats-
abhngige Kommaverschiebung] ergibt, somit funktioniert dann alles.

Falls Sie Probleme bei Ihren mathematischen Operationen erkennen,
dann berprfen Sie die Zwischenergebnisse auf Unterlauf [eine
resultatabhngige Kommaverschiebung] (oder auch auf berlauf, der dann
im Programm in Umlauf kommt; wie zum Beispiel 32767 + 1 = -32768).
Wann immer mglich, whlen Sie Einheiten, deren Werte in einem Bereich
von -100 bis 100 liegen.

Falls Sie eine Variable um einen bestimmten Faktor vergrern mssen, tun
Sie dies, indem Sie eine Multiplikation und eine Division verwenden. Um
zum Beispiel y = 1.8 * x zu vergrern, berechnen Sie y = (9/5) * x,
(was dasselbe ist, weil 1,8 = 9/5 ist), und codieren Sie dies als
y = (9 * x)/5, indem Sie die Multiplikation zuerst ausfhren.

   ||         {MUL  temp  :=}          ||
   ||---------{ x * 9       }----------||
   ||                                  ||
   ||           {DIV  y  :=}           ||
   ||-----------{ temp / 5 }-----------||


Dies funktioniert mit allen x < (32767 / 9), oder x < 3640.  Bei hheren
Werten wrde die Variable temp berflieen. Fr x gibt es eine
hnliche Untergrenze.


KODIER-STIL
===========

Ich gestatte mehrere Spulen in Parallelschaltung in einem einzigen
Netzwerk unterzubringen. Das bedeutet, sie knnen ein Netzwerk, wie
folgt schreiben:

   ||       Xa               Ya        ||
 1 ||-------] [--------------( )-------||
   ||                                  ||
   ||       Xb               Yb        ||
   ||-------] [------+-------( )-------||
   ||                |                 ||
   ||                |       Yc        ||
   ||                +-------( )-------||
   ||                                  ||

Anstatt diesem:

   ||       Xa               Ya        ||
 1 ||-------] [--------------( )-------||
   ||                                  ||
   ||                                  ||
   ||                                  ||
   ||                                  ||
   ||       Xb               Yb        ||
 2 ||-------] [--------------( )-------||
   ||                                  ||
   ||                                  ||
   ||                                  ||
   ||                                  ||
   ||       Xb               Yc        ||
 3 ||-------] [--------------( )-------||
   ||                                  ||

Rein theoretisch bedeutet das, dass Sie irgendein Programm, als ein
gigantisches Netzwerk, schreiben knnten. Und es bestnde berhaupt
keine Notwendigkeit mehrere Netzwerke zu verwenden. In der Praxis ist
dies aber eine schlechte Idee, denn wenn Netzwerke komplexer werden, so
werden sie auch schwieriger zu editieren, ohne Lschen und neu Schreiben
von Anweisungen.

Jedoch, ist es manchmal ein guter Einfall, verwandte Logik in einem
einzelnen Netzwerk zusammenzufassen. Dies erzeugt einen beinahe
identischen Code, als ob sie getrennte Netzwerke entworfen htten, es
zeigt aber, dass diese Anweisungen (Logik) verwandt ist, wenn man diese
im Netzwerk-Diagramm betrachtet.

            *                *                *

Im Allgemeinen hlt man es fr eine schlechte Form, den Code in einer
solchen Weise zu schreiben, dass sein Ergebnis von einer Folge von
Netzwerken abhngt. So zum Beispiel ist der folgende Code nicht besonders
gut, falls xa und xb jemals wahr wrden.

   ||       Xa         {v  :=       }  ||
 1 ||-------] [--------{ 12      MOV}--||
   ||                                  ||
   ||       Xb         {v  :=       }  ||
   ||-------] [--------{ 23      MOV}--||
   ||                                  ||
   ||                                  ||
   ||                                  ||
   ||                                  ||
   ||      [v >]             Yc        ||
 2 ||------[ 15]-------------( )-------||
   ||                                  ||

Ich werde diese Regel brechen und indem ich dies so mache, entwerfe ich
einen Code-Abschnitt, der erheblich kompakter ist. Hier zum Beispiel,
zeige ich auf, wie ich eine 4-Bit binre Gre von xb3:0 in eine
Ganzzahl wandeln wrde.

   ||                                   {v  :=       }  ||
 3 ||-----------------------------------{ 0       MOV}--||
   ||                                                   ||
   ||       Xb0                  {ADD  v  :=}           ||
   ||-------] [------------------{ v + 1    }-----------||
   ||                                                   ||
   ||       Xb1                  {ADD  v  :=}           ||
   ||-------] [------------------{ v + 2    }-----------||
   ||                                                   ||
   ||       Xb2                  {ADD  v  :=}           ||
   ||-------] [------------------{ v + 4    }-----------||
   ||                                                   ||
   ||       Xb3                  {ADD  v  :=}           ||
   ||-------] [------------------{ v + 8    }-----------||
   ||                                                   ||

Falls die TRANSFER-Anweisung (MOV) an das untere Ende des Netzwerks
gebracht wrde, anstatt auf das obere, so wrde der Wert von v, an
anderer Stelle im Programm gelesen, gleich Null sein. Das Ergebnis dieses
Codes hngt daher von der Reihenfolge ab, in welcher die Anweisungen
ausgewertet werden.  Im Hinblick darauf, wie hinderlich es wre, diesen
Code auf eine andere Weise zu schreiben, nehme ich dies so hin.


BUGS
====

LDmicro erzeugt keinen sehr effizienten Code; es ist langsam in der
Ausfhrung und geht verschwenderisch mit dem Flash- und RAM-Speicher
um. Trotzdem kann ein mittelgroer PIC- oder AVR-Prozessor alles, was
eine kleine SPS kann, somit strt dies mich nicht besonders.

Die maximale Lnge der Variabelen-Bezeichnungen (-Namen) ist sehr
begrenzt. Dies ist so, weil diese so gut in das KOP-Programm (ladder)
passen. Somit sehe ich keine gute Lsung fr diese Angelegenheit.

Falls Ihr Programm zu gro fr die Zeit-, Programmspeicher- oder
Datenspeicher-Beschrnkungen des Prozessors ist, den Sie gewhlt haben,
so erhalten Sie keine Fehlermeldung. Es wird einfach irgendwo anders alles
vermasseln. (Anmerkung: Das AVR STK500 gibt hierzu Fehlermeldungen aus.)

Unsorgfltiges Programmieren bei den Datei ffnen/Abspeichern-Routinen
fhren wahrscheinlich zu der Mglichkeit eines Absturzes oder es wird
ein willkrlicher Code erzeugt, der eine beschdigte oder bsartige .ld
Datei ergibt.

Bitte berichten Sie zustzliche Bugs oder richten Sie Anfragen fr neue
Programm-Bestandteile an den Autor (in Englisch).

Thanks to:
    * Marcelo Solano, for reporting a UI bug under Win98
    * Serge V. Polubarjev, for not only noticing that RA3:0 on the
      PIC16F628 didn't work but also telling me how to fix it
    * Maxim Ibragimov, for reporting and diagnosing major problems
      with the till-then-untested ATmega16 and ATmega162 targets
    * Bill Kishonti, for reporting that the simulator crashed when the
      ladder logic program divided by zero
    * Mohamed Tayae, for reporting that persistent variables were broken
      on the PIC16F628
    * David Rothwell, for reporting several user interface bugs and a
      problem with the "Export as Text" function

Particular thanks to Heinz Ullrich Noell, for this translation (of both
the manual and the program's user interface) into German.


COPYING, AND DISCLAIMER
=======================

DO NOT USE CODE GENERATED BY LDMICRO IN APPLICATIONS WHERE SOFTWARE
FAILURE COULD RESULT IN DANGER TO HUMAN LIFE OR DAMAGE TO PROPERTY. THE
AUTHOR ASSUMES NO LIABILITY FOR ANY DAMAGES RESULTING FROM THE OPERATION
OF LDMICRO OR CODE GENERATED BY LDMICRO.

This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.


Jonathan Westhues

Rijswijk      -- Dec 2004
Waterloo ON   -- Jun, Jul 2005
Cambridge MA  -- Sep, Dec 2005
                 Feb, Mar 2006

Email: user jwesthues, at host cq.cx


