OpenPLC-Ladder-Editor/ldmicro-rel2.2/ldmicro/manual-de.txt

1076 lines
51 KiB
Plaintext
Raw Normal View History

EINF<EFBFBD>HRUNG
===========
LDmicro erzeugt einen systemspezifischen Code f<>r einige Microchip PIC16
und Atmel AVR Mikroprozessoren. <20>blicherweise wird die Software f<>r diese
Prozessoren in Programmsprachen, wie Assembler, C oder BASIC geschrieben.
Ein Programm, welches in einer dieser Sprachen abgefasst ist, enth<74>lt
eine Anweisungsliste. Auch sind die diese Sprachen sehr leistungsf<73>hig
und besonders gut geeignet f<>r die Architektur dieser Prozessoren,
welche diese Anweisungsliste intern abarbeiten.
Programme f<>r speicherprogrammierbare Steuerungen (SPS) andererseits,
werden oftmals im Kontaktplan (KOP = ladder logic) geschrieben.
Ein einfaches Programm, k<>nnte 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 Anzugsverz<72>gerung, TOF eine Abfallverz<72>gerung.
Die --] [-- Anweisungen bedeuten Eing<6E>nge, die sich <20>hnlich, wie Relais-
kontakte verhalten. Die --( )-- Anweisungen bedeuten Ausg<73>nge, die sich
<20>hnlich, wie Relaisspulen verhalten. Viele gute Bezugsquellen werden f<>r
KOP im Internet oder sonst wo angeboten; Einzelheiten zu dieser speziellen
Ausf<73>hrung 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 zun<75>chst als besser verst<73>ndlich auffassen.
* Diese Programme erscheinen wie einfachste Schaltpl<70>ne, mit
Relaiskontakten (Eing<6E>ngen) and Spulen (Ausg<73>ngen). Dies ist recht
intuitiv f<>r Programmierer, die <20>ber Kenntnisse der Theorie von
Elektroschaltpl<70>nen verf<72>gen.
* Der <20>ladder logic compiler<65> <20>bernimmt was wo berechnet wird.
Es ist nicht notwendig einen Code zu schreiben, um zu errechnen, wann
der Status (Zustand) der Ausg<73>nge neu bestimmt werden muss, z.B. auf
Grund einer <20>nderung eines Eingangs oder Timers. Auch braucht man die
Reihenfolge der Berechnungen nicht anzugeben; die SPS-Hilfsprogramme
<20>bernehmen dies.
LDmicro kompiliert <20>ladder logic<69> (KOP) in PIC16- oder AVR-Code.
Die folgenden Prozessoren werden unterst<73>tzt:
* PIC16F877
* PIC16F628
* PIC16F876 (ungetestet)
* PIC16F88 (ungetestet)
* PIC16F819 (ungetestet)
* PIC16F887 (ungetestet)
* PIC16F886 (ungetestet)
* ATmega8 (ungetestet)
* ATmega16 (ungetestet)
* ATmega32 (ungetestet)
* ATmega128
* ATmega64
* ATmega162 (ungetestet)
Es w<>re einfach noch weitere AVR- oder PIC16-Prozessoren zu unterst<73>tzen,
aber ich habe keine M<>glichkeit diese zu testen. Falls Sie einen
bestimmten ben<65>tigen, so nehmen Sie Kontakt mit mir auf und ich werde
sehen, was ich tun kann.
Mit LDmicro k<>nnen Sie ein Kontaktplan-Programm zeichnen bzw. entwickeln.
Auch k<>nnen Sie dies in Realzeit mit Ihrem Computer simulieren. Wenn
Sie dann <20>berzeugt sind, dass Ihr Programm korrekt ist, so k<>nnen
Sie die Pins, entsprechend dem Programm als Ein- oder Ausg<73>nge, dem
Mikroprozessor zuweisen. Nach der Zuweisung der Pins k<>nnen Sie den PIC-
oder AVR-Code f<>r Ihr Programm kompilieren. Der Compiler erzeugt eine
Hex-Datei, mit dem Sie dann Ihren Mikroprozessor programmieren. Dies
ist mit jedem PIC/AVR-Programmer m<>glich.
LDmicro wurde entworfen, um in etwa mit den meisten kommerziellen
SPS-Systemen <20>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 Ausf<73>hrungszyklus,
Eing<EFBFBD>nge lesen, rechnen und Ausg<73>nge setzen).
WEITERE ZIELE
=============
Es ist auch m<>glich einen ANSI C - Code zu erzeugen. Diesen k<>nnen
Sie dann f<>r jeden Prozessor verwenden, f<>r den Sie einen C-Compiler
besitzen. Sie sind dann aber selbst verantwortlich, den Ablauf zu
bestimmen. Das hei<65>t, LDmicro erzeugt nur ein Stammprogramm f<>r einen
Funktions- SPS-Zyklus. Sie m<>ssen den SPS-Zyklus bei jedem Durchlauf
aufrufen und auch die Ausf<73>hrung (Implementierung) der E/A-Funktionen,
die der SPS-Zyklus abruft (wie: lesen/schreiben, digitaler Eingang usw.).
F<EFBFBD>r mehr Einzelheiten: Siehe die Kommentare in dem erzeugten Quellcode.
Ganz zuletzt kann LDmicro auch f<>r eine virtuelle Maschine einen
prozessor-unabh<62>ngigen 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 k<>nnte f<>r solche Anwendungen n<>tzlich
sein, f<>r die Sie KOP (ladder logic) als Datentransfer-Sprache verwenden
m<EFBFBD>chten, um ein gr<67><72>eres Programm anzupassen. F<>r weitere Einzelheiten:
Siehe die Kommentare in dem Beispiel-Interpreter.
OPTIONEN DER BEFEHLSZEILEN
==========================
ldmicro.exe l<>uft normalerweise ohne eine Befehlszeilen-Option.
Das hei<65>t, dass Sie nur ein Tastenk<6E>rzel zu dem Programm ben<65>tigen
oder es auf dem Desktop abspeichern und dann auf das Symbol (die Ikone)
doppelklicken, um es laufen zu lassen. Danach k<>nnen Sie alles ausf<73>hren,
was das GUI (Graphical User Interface) zul<75>sst.
Wenn man an LDmicro einen alleinstehenden Dateinamen in der Befehlszeile
vergeben hat (z. B. <20>ldmicro.exe asd.ld<6C>), wird LDmicro versuchen <20>asd.ld<6C>
zu <20>ffnen, falls diese existiert. Dies bedeutet, dass man ldmicro.exe
mit .ld Dateien verbinden kann, sodass dies automatisch abl<62>uft, wenn
man auf eine .ld Datei doppelklickt.
Wenn man an LDmicro das Argument in der Befehlszeile in folgender Form
vergeben hat: <20>ldmicro.exe /c src.ld dest.hex<65>, so wird es versuchen
<EFBFBD>src.ld<6C> zu kompilieren und unter <20>dest.hex<65> abzuspeichern. LDmicro endet
nach dem Kompilieren, unabh<62>ngig 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 l<>sst.
GRUNDLAGEN
==========
Wenn Sie LDmicro ohne Argumente aufrufen, so beginnt es als ein leeres
Programm. Wenn Sie LDmicro mit dem Namen eines <20>ladder<65> (KOP)-Programms
(z.B. xxx.ld) in der Befehlszeile <20>ffnen, dann wird es versuchen dieses
Programm am Anfang zu laden.
LDmicro verwendet sein eigenes internes Format f<>r 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 k<>nnen Sie
einen Befehl einf<6E>gen; z. B. k<>nnten Sie auch eine Reihe von Kontakten
einf<EFBFBD>gen (Anweisung -> Kontakte Einf<6E>gen), die zun<75>chst mit <20>Xneu<65>
bezeichnet werden. <20>X<EFBFBD> bedeutet, dass der Kontakt auf einen Eingang
des Mikroprozessors festgelegt ist. Diesen Pin k<>nnen Sie sp<73>ter zuweisen,
nachdem Sie den Mikroprozessor gew<65>hlt 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 Abfallverz<72>gerung
* CName -- Ein Z<>hler, Aufw<66>rts- oder Abw<62>rtsz<73>hler
* AName -- Eine Ganzzahl, von einem A/D-Wandler eingelesen
* Name -- Eine Allzweck-Variable als Ganzzahl
W<EFBFBD>hlen 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 w<>re zum
Beispiel falsch eine Anzugsverz<72>gerung (TON) <20>TVerz<72>g<EFBFBD> zu nennen und im
selben Programm eine Abfallverz<72>gerung <20>TVerz<72>g<EFBFBD> (TOF), weil jeder Z<>hler
(oder Timer) seinen eigenen Speicher ben<65>tigt. Andererseits w<>re es
korrekt einen <20>Speichernden Timer<65> (RTO) <20>TVerz<72>g<EFBFBD> zu nennen und eine
entsprechende R<>cksetz-Anweisung (RES) = <20>TVerz<72>g<EFBFBD>, weil in diesem
Fall beide Befehle dem gleichen Timer gelten.
Die Namen von Variablen k<>nnen aus Buchstaben, Zahlen und Unter-
strichen (_) bestehen. Der Name einer Variablen darf nicht mit einer
Nummer beginnen. Die Namen von Variablen sind fallabh<62>ngig.
Ein Befehl f<>r eine gew<65>hnliche Variable (MOV, ADD, EQU, usw.), kann
mit Variablen mit jedem Namen arbeiten. Das bedeutet, dass diese Zugang
zu den Timer- und Z<>hler-Akkumulatoren haben. Das kann manchmal recht
hilfreich sein; zum Beispiel kann man damit pr<70>fen, ob die Z<>hlung eines
Timers in einem bestimmten Bereich liegt.
Die Variablen sind immer 16-Bit Ganzzahlen. Das hei<65>t sie k<>nnen von
-32768 bis 32767 reichen. Die Variablen werden immer als vorzeichen-
behaftet behandelt. Sie k<>nnen auch Buchstaben als Dezimalzahlen festlegen
(0, 1234, -56). Auch k<>nnen Sie ASCII-Zeichenwerte (<28>A<EFBFBD>, <20>z<EFBFBD>) festlegen,
indem Sie die Zeichen in <20>Auslassungszeichen<65> einf<6E>gen. Sie k<>nnen
ein ASCII-Zeichen an den meisten Stellen verwenden, an denen Sie eine
Dezimalzahl verwenden k<>nnen.
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 ben<65>tigen
keine Konfiguration. <20>XName<6D>, <20>YName<6D>, und <20>AName<6D> Objekte allerdings,
m<EFBFBD>ssen einem Pin des Mikroprozessors zugeordnet werden. W<>hlen 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 k<>nnen das Programm ver<65>ndern, indem Sie Anweisungen (Befehle)
einf<EFBFBD>gen oder l<>schen. Die Schreibmarke (cursor)im Programm blinkt,
um die momentan gew<65>hlte Anweisung und den Einf<6E>gungspunkt anzuzeigen.
Falls diese nicht blinkt, so dr<64>cken Sie den <Tabulator> oder klicken
Sie auf eine Anweisung. Jetzt k<>nnen Sie die momentane Anweisung l<>schen
oder eine neue Anweisung einf<6E>gen; links oder rechts (in Reihenschaltung)
oder <20>ber oder unter (in Parallelschaltung) mit der gew<65>hlten Anweisung.
Einige Handhabungen sind nicht erlaubt, so zum Beispiel weitere
Anweisungen rechts von einer Spule.
Das Programm beginnt mit nur einem Netzwerk. Sie k<>nnen mehr Netzwerke
hinzuf<EFBFBD>gen, indem Sie <20>Netzwerk Einf<6E>gen Davor/Danach<63> im Programm-Men<65>
w<EFBFBD>hlen. Den gleichen Effekt k<>nnten Sie erzielen, indem Sie viele
komplizierte parallele Unterschaltungen in einem einzigen Netzwerk
unterbringen. Es ist aber <20>bersichtlicher, mehrere Netzwerke zu verwenden.
Wenn Sie Ihr Programm fertig geschrieben haben, so k<>nnen Sie dieses
mit der Simulation testen. Danach k<>nnen Sie es in eine Hex-Datei f<>r
den zugedachten Mikroprozessor kompilieren.
SIMULATION
==========
Um den Simulationsbetrieb einzugeben, w<>hlen Sie <20>Simulieren ->
Simulationsbetrieb<EFBFBD> oder dr<64>cken Sie <Strg+M>. Das Programm wird
im Simulationsbetrieb unterschiedlich dargestellt. Es gibt keine
Schreibmarke (cursor) mehr. Die <20>erregten<65> Anweisungen erscheinen hellrot,
die <20>nicht erregten<65> erscheinen grau. Dr<44>cken Sie die Leertaste, um das
SPS-Programm nur einen einzelnen Zyklus durchlaufen zu lassen. W<>hlen
Sie f<>r einen kontinuierlichen Umlauf in Echtzeit <20>Simulieren -> Start
Echtzeit-Simulation<6F> oder dr<64>cken Sie <Strg+R>. Die Maske (Bildanzeige)
des Programms wird jetzt in Echtzeit, entsprechend der <20>nderungen des
Status (des Zustands) des Programms aktualisiert.
Sie k<>nnen 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 <20>XName<6D>
Kontakt-Anweisung im Programm. Wenn Sie den Status (Zustand) eines
Eingangs-Pins <20>ndern, so wird diese <20>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 l<>uft, oder wenn Sie die Leertaste
dr<EFBFBD>cken.
KOMPILIEREN ZUM SYSTEMSPEZIFISCHEN CODE
=======================================
Letztlich ist es dann nur sinnvoll eine .hex Datei zu erzeugen, mit
der Sie Ihren Mikroprozessor programmieren k<>nnen. Zun<75>chst m<>ssen
Sie die Teilenummer des Mikroprozessors im Men<65> <20>Voreinstellungen ->
Prozessor<EFBFBD> w<>hlen. Danach m<>ssen jedem <20>XName<6D> oder <20>YName<6D> 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
k<EFBFBD>nnen daraufhin einen noch nicht vergebenen Pin von der Liste aussuchen.
Als n<>chstes m<>ssen Sie die Zykluszeit w<>hlen, mit der Sie das
Programm laufen lassen wollen, auch m<>ssen Sie dem Compiler mitteilen
mit welcher Taktgeschwindigkeit der Prozessor arbeiten soll. Diese
Einstellungen werden im Men<65> <20>Voreinstellungen -> Prozessor Parameter...<2E>
vorgenommen. <20>blicherweise sollten Sie die Zykluszeit nicht <20>ndern,
denn diese ist auf 10ms voreingestellt, dies ist ein guter Wert f<>r
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 k<>nnen Sie einen Code von Ihrem Programm erzeugen. W<>hlen Sie
<EFBFBD>Kompilieren -> Kompilieren<65> oder <20>Kompilieren -> Kompilieren unter...<2E>,
falls Sie vorher Ihr Programm schon kompiliert haben und einen neuen Namen
f<EFBFBD>r die Ausgangsdatei vergeben wollen. Wenn Ihr Programm fehlerfrei ist,
wird LDmicro eine Intel IHEX Datei erzeugen, mit der sich Ihr Prozessor
programmieren l<>sst.
Verwenden Sie hierzu irgendeine Programmier Soft- und Hardware, die Sie
besitzen, um die Hex-Datei in den Mikroprozessor zu laden. Beachten Sie
die Einstellungen f<>r die Konfigurationsbits (fuses)! Bei den PIC16
Prozessoren sind diese Konfigurationsbits bereits in der Hex-Datei
enthalten. Die meisten Programmiersoftwares schauen automatisch nach
diesen. F<>r die AVR-Prozessoren m<>ssen Sie die Konfigurationsbits von
Hand einstellen.
ANWEISUNGS-VERZEICHNIS
======================
> KONTAKT, SCHLIESSER XName RName YName
----] [---- ----] [---- ----] [----
Wenn ein <20>unwahres<65> Signal diese Anweisung erreicht, so ist das
Ausgangssignal <20>unwahr<68>. Wenn ein <20>wahres<65> Signal diese Anweisung
erreicht, so ist das Ausgangssignal <20>wahr<68>. Dies nur, falls der
vorliegende Eingangspin, Ausgangspin oder eines Merkers (Hilfsrelais)
<EFBFBD>wahr<EFBFBD> ist, anderenfalls ist es unwahr. Diese Anweisung fragt den Status
(Zustand) eines Eingangspins, Ausgangspins oder Merkers (Hilfsrelais) ab.
> KONTAKT, <20>FFNER XName RName YName
----]/[---- ----]/[---- ----]/[----
Wenn ein <20>unwahres<65> Signal diese Anweisung erreicht, so ist das
Ausgangssignal <20>unwahr<68>. Wenn ein <20>wahres<65> Signal diese Anweisung
erreicht, so ist das Ausgangssignal <20>wahr<68>. Dies nur, falls der
vorliegende Eingangspin, Ausgangspin oder der Merker (= internes
Hilfsrelais) <20>unwahr<68> ist, anderenfalls ist es <20>unwahr<68>. Diese Anweisung
fragt den Status (Zustand) eines Eingangspins, Ausgangspins oder Merkers
(Hilfsrelais) ab. Dies ist das Gegenteil eines Schlie<69>ers.
> SPULE, NORMAL (MERKER,AUSGANG) RName YName
----( )---- ----( )----
Wenn ein <20>unwahres<65> Signal diese Anweisung erreicht, so wird der
vorliegende Merker (Hilfsrelais) oder Ausgangspin nicht angesteuert. Wenn
ein <20>wahres<65> 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 <20>wahres<65> Signal diese Anweisung erreicht, so wird der vorliegende
Merker (Hilfsrelais)oder Ausgangspin nicht angesteuert. Wenn ein
<EFBFBD>unwahres<EFBFBD> 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 <20>wahres<65> Signal diese Anweisung erreicht, so wird der vorliegende
Merker (Hilfsrelais)oder Ausgangspin auf <20>wahr<68> gesetzt. Anderenfalls
bleibt der Status (Zustand) des Merkers (Hilfsrelais) oder Ausgangspins
unver<EFBFBD>ndert. Diese Anweisung kann nur den Status (Zustand) einer Spule
von <20>unwahr<68> nach <20>wahr<68> ver<65>ndern, insofern wird diese <20>blicherweise in
einer Kombination mit einer R<>cksetz-Anweisung f<>r eine Spule verwendet.
Diese Anweisung muss ganz rechts im Netzwerk stehen.
> SPULE, R<>CKSETZEN RName YName
----(R)---- ----(R)----
Wenn ein <20>wahres<65> Signal diese Anweisung erreicht, so wird der vorliegende
Merker (Hilfsrelais) oder Ausgangspin r<>ckgesetzt. Anderenfalls bleibt der
Status (Zustand) des Merkers (Hilfsrelais) oder Ausgangspins unver<65>ndert.
Diese Anweisung kann nur den Status (Zustand) einer Spule von <20>wahr<68> nach
<EFBFBD>unwahr<EFBFBD> ver<65>ndern, insofern wird diese <20>blicherweise in einer Kombination
mit einer Setz-Anweisung f<>r eine Spule verwendet. Diese Anweisung muss
ganz rechts im Netzwerk stehen.
> ANZUGSVERZ<52>GERUNG Tdon
-[TON 1.000 s]-
Wenn ein Signal diese Anweisung erreicht, welches seinen Status
(Zustand) von <20>unwahr<68> nach <20>wahr<68> <20>ndert, so bleibt das Ausgangssignal
f<EFBFBD>r 1,000 s <20>unwahr<68>, dann wird es <20>wahr<68>. Wenn ein Signal diese
Anweisung erreicht, welches seinen Status (Zustand) von <20>wahr<68> nach
<EFBFBD>unwahr<EFBFBD> <20>ndert, so wird das Ausgangssignal sofort <20>unwahr<68>. Der Timer
wird jedes Mal r<>ckgesetzt (bzw. auf Null gesetzt), wenn der Eingang
<EFBFBD>unwahr<EFBFBD> wird. Der Eingang muss f<>r 1000 aufeinanderfolgende Millisekunden
<EFBFBD>wahr<EFBFBD> bleiben, bevor auch der Ausgang <20>wahr<68> wird. Die Verz<72>gerung
ist konfigurierbar.
Die <20>TName<6D> Variable z<>hlt, in der Einheit der jeweiligen Zykluszeit,
von Null ab hoch. Der Ausgang der TON-Anweisung wird wahr, wenn die
Z<EFBFBD>hlervariable gr<67><72>er oder gleich der vorliegenden Verz<72>gerung ist.
Es m<>glich die Z<>hlervariable an einer anderen Stelle im Programm zu
bearbeiten, zum Beispiel mit einer TRANSFER-Anweisung (MOV).
> ABFALLVERZ<52>GERUNG Tdoff
-[TOF 1.000 s]-
Wenn ein Signal diese Anweisung erreicht, welches seinen Status
(Zustand) von <20>wahr<68> nach <20>unwahr<68> <20>ndert, so bleibt das Ausgangssignal
f<EFBFBD>r 1,000 s <20>wahr<68>, dann wird es <20>unwahr<68>. Wenn ein Signal diese
Anweisung erreicht, welches seinen Status (Zustand) von <20>unwahr<68> nach
<EFBFBD>wahr<EFBFBD> <20>ndert, so wird das Ausgangssignal sofort <20>wahr<68>. Der Timer wird
jedes Mal r<>ckgesetzt (bzw. auf Null gesetzt), wenn der Eingang <20>unwahr<68>
wird. Der Eingang muss f<>r 1000 aufeinanderfolgende Millisekunden <20>unwahr<68>
bleiben, bevor auch der Ausgang <20>unwahr<68> wird. Die Verz<72>gerung ist
konfigurierbar.
Die <20>TName<6D> Variable z<>hlt, in der Einheit der jeweiligen Zykluszeit,
von Null ab hoch. Der Ausgang der TOF Anweisung wird wahr, wenn die
Z<EFBFBD>hlervariable gr<67><72>er oder gleich der vorliegenden Verz<72>gerung ist.
Es m<>glich die Z<>hlervariable 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 <20>wahr<68> gewesen
ist. Wenn der Eingang f<>r mindestens 1.000 s <20>wahr<68> gewesen ist, dann
wird der Ausgang <20>wahr<68>. Andernfalls ist er <20>unwahr<68>. Der Eingang muss
f<EFBFBD>r 1000 aufeinanderfolgende Millisekunden <20>wahr<68> gewesen sein; wenn
der Eingang f<>r 0,6 s <20>wahr<68> war, dann <20>unwahr<68> f<>r 2,0 s und danach f<>r
0,4 s wieder <20>wahr<68>, so wird sein Ausgang <20>wahr<68>. Nachdem der Ausgang
<EFBFBD>wahr<EFBFBD> wurde, so bleibt er <20>wahr<68>, selbst wenn der Eingang <20>unwahr<68>
wird, so lange der Eingang f<>r l<>nger als 1.000 s <20>wahr<68> gewesen ist.
Der Timer muss deshalb von Hand mit Hilfe der R<>cksetz-Anweisung
r<EFBFBD>ckgesetzt (auf Null gesetzt) werden.
Die <20>TName<6D> Variable z<>hlt, in der Einheit der jeweiligen Zykluszeit,
von Null ab hoch. Der Ausgang der RTO-Anweisung wird wahr, wenn die
Z<EFBFBD>hlervariable gr<67><72>er oder gleich der vorliegenden Verz<72>gerung ist.
Es m<>glich die Z<>hlervariable an einer anderen Stelle im Programm zu
bearbeiten, zum Beispiel mit einer TRANSFER-Anweisung (MOV).
> R<>CKSETZEN Trto Citems
----{RES}---- ----{RES}----
Diese Anweisung r<>cksetzt einen Timer oder Z<>hler. TON oder TOF Timer
werden automatisch r<>ckgesetzt, wenn ihr Eingang <20>wahr<68> oder <20>unwahr<68>
wird, somit ist die RES-Anweisung f<>r diese Timer nicht erforderlich. RTO
Timer und CTU/CTD Z<>hler werden nicht automatisch r<>ckgesetzt, somit
m<EFBFBD>ssen diese von Hand mit Hilfe der RES-Anweisung r<>ckgesetzt (auf Null)
werden. Wenn der Eingang <20>wahr<68> ist, so wird der Timer oder Z<>hler
r<EFBFBD>ckgesetzt; wenn der Eingang <20>unwahr<68> ist, so erfolgt keine Aktion.
Diese Anweisung muss ganz rechts im Netzwerk stehen.
_
> ONE-SHOT RISING, STEIGENDE FLANKE --[OSR_/ ]--
Diese Anweisung wird normalerweise <20>unwahr<68> ausgewiesen. Wenn der Eingang
der Anweisung w<>hrend des momentanen Zyklus <20>wahr<68> ist und w<>hrend des
vorgehenden <20>unwahr<68> war, so wird der Ausgang <20>wahr<68>. Daher erzeugt diese
Anweisung bei jeder steigenden Flanke einen Impuls f<>r einen Zyklus.
Diese Anweisung ist hilfreich, wenn Sie Ereignisse an der steigenden
Flanke eines Signals ausl<73>sen wollen.
_
> ONE-SHOT FALLING, FALLENDE FLANKE --[OSF \_ ]--
Diese Anweisung wird normalerweise <20>unwahr<68> ausgewiesen. Wenn der Eingang
der Anweisung w<>hrend des momentanen Zyklus <20>unwahr<68> ist und w<>hrend des
vorgehenden <20>wahr<68> war, so wird der Ausgang <20>wahr<68>. Daher erzeugt diese
Anweisung bei jeder fallenden Flanke einen Impuls f<>r einen Zyklus.
Diese Anweisung ist hilfreich, wenn Sie Ereignisse an der fallenden
Flanke eines Signals ausl<73>sen wollen.
> BR<42>CKE, <20>FFNUNG ----+----+---- ----+ +----
Der Eingangszustand einer Br<42>cke ist immer gleich seinem Ausgangszustand.
Der Ausgangszustands einer <20>ffnung ist immer <20>unwahr<68>. 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
<EFBFBD>wahr<EFBFBD>. Wenn eine <20>Master Control Relais<69> Anweisung ausgef<65>hrt wird dessen
Eingang <20>unwahr<68> ist, so werden die Anf<6E>nge (die linke Stromschiene)
aller folgenden Netzwerke <20>unwahr<68>. Das setzt sich fort bis die n<>chste
<EFBFBD>Master Control Relais<69> Anweisung erreicht wird (unabh<62>ngig von dem
Anfangszustand dieser Anweisung). Diese Anweisungen m<>ssen daher als Paar
verwendet werden: Eine (vielleicht abh<62>ngige), um den <20>gegebenenfalls
gesperrten<EFBFBD> Abschnitt zu starten und eine weitere, um diesen zu beenden.
> TRANSFER, MOV {destvar := } {Tret := }
-{ 123 MOV}- -{ srcvar MOV}-
Wenn der Eingang dieser Anweisung <20>wahr<68> ist, so setzt diese die
vorliegende Zielvariable gleich der vorliegenden Quellvariablen
oder Konstanten. Wenn der Eingang dieser Anweisung <20>unwahr<68> ist, so
geschieht nichts. Mit der TRANSFER-Anweisung (MOV) k<>nnen Sie jede
Variable zuweisen; dies schlie<69>t Timer und Z<>hler Statusvariablen ein,
welche mit einem vorgestellten <20>T<EFBFBD> oder <20>C<EFBFBD> unterschieden werden. Eine
Anweisung zum Beispiel, die eine <20>0<EFBFBD> in einen <20>TBewahrend<6E> transferiert,
ist <20>quivalent mit einer RES-Anweisung f<>r 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 <20>wahr<68> ist, so setzt diese
die vorliegende Zielvariable gleich dem vorliegenden arithmetischem
Ausdruck. Die Operanden k<>nnen entweder Variabelen (einschlie<69>lich Timer-
und Z<>hlervariabelen) oder Konstanten sein. Diese Anweisungen verwenden
16-Bitzeichen Mathematik. Beachten Sie, dass das Ergebnis jeden Zyklus
ausgewertet wird, wenn der Eingangszustand <20>wahr<68> 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 w<>rden Sie einen Impuls (one-shot) verwenden,
sodass die Variable nur bei einer steigenden oder fallenden Flanke des
Eingangszustands ausgewertet wird. Dividieren k<>rzt: D.h. 8 / 3 = 2.
Diese Anweisungen m<>ssen ganz rechts im Netzwerk stehen.
> VERGLEICHEN [var ==] [var >] [1 >=]
-[ var2 ]- -[ 1 ]- -[ Ton]-
> [var /=] [-4 < ] [1 <=]
-[ var2 ]- -[ vartwo]- -[ Cup]-
Wenn der Eingang dieser Anweisung <20>unwahr<68> ist, so ist der Ausgang
auch <20>unwahr<68>. Wenn der Eingang dieser Anweisung <20>wahr<68> ist, dann ist
Ausgang <20>wahr<68>; dies aber nur, wenn die vorliegende Bedingung <20>wahr<68>
ist. Diese Anweisungen k<>nnen zum Vergleichen verwendet werden, wie:
Auf gleich, auf gr<67><72>er als, auf gr<67><72>er 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.
> Z<>HLER CName CName
--[CTU >=5]-- --[CTD >=5]<5D>
Ein Z<>hler inkrementiert (CTU, aufw<66>rtsz<73>hlen) oder dekrementiert
(CTD, abw<62>rtsz<73>hlen) die bezogene Z<>hlung bei jeder steigenden Flanke
des Eingangszustands des Netzwerks (d.h. der Eingangszustand des
Netzwerks geht von <20>unwahr<68> auf <20>wahr<68> <20>ber). Der Ausgangszustand des
Z<EFBFBD>hlers ist <20>wahr<68>, wenn die Z<>hler- variable ist gr<67><72>er oder gleich 5
und andernfalls <20>unwahr<68>. Der Ausgangszustand des Netzwerks kann <20>wahr<68>
sein, selbst wenn der Eingangszustand <20>unwahr<68> ist; das h<>ngt lediglich
von Z<>hlervariablen ab. Sie k<>nnen einer CTU- und CTD-Anweisung den
gleichen Namen zuteilen, um den gleichen Z<>hler zu inkrementieren und
dekrementieren. Die RES-Anweisung kann einen Z<>hler r<>cksetzen oder auch
eine gew<65>hnliche Variablen-Operation mit der Z<>hlervariablen ausf<73>hren.
> ZIRKULIERENDER Z<>HLER CName
--{CTC 0:7}--
Ein zirkulierender Z<>hler arbeitet wie ein normaler CTU-Z<>hler, au<61>er
nach der Erreichung seiner Obergrenze, r<>cksetzt er seine Z<>hlervariable
auf Null. Zum Beispiel w<>rde der oben gezeigte Z<>hler, wie folgt z<>hlen:
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 Variablen<65>CName<6D>;
Sie k<>nnen dies als eine Folgeschaltung verwenden. CTC-Z<>hler 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 best<73>nde
zum Beispiel ein Schieberegister aus den Variablen <20>reg0<67>, <20>reg1<67>,
<EFBFBD>reg2<EFBFBD>, and <20>reg3<67>. Der Eingang des Schieberegisters ist <20>reg0<67>. Bei
jeder steigenden Flanke der Eingansbedingung des Netzwerks, schiebt das
Schieberegister nach rechts. Dies bedeutet es wie folgt zuweist: <20>reg3<67>
nach <20>reg2<67>, <20>reg2<67> nach <20>reg1<67> und <20>reg1<67> nach <20>reg0<67>. <20>reg0<67> bleibt
unver<EFBFBD>ndert. Ein gro<72>es 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 <20>wahr<68> ist, so wird die Ganzzahl-Variable
<EFBFBD>dest<EFBFBD> mit dem Eintrag in der Nachschlag-Tabelle gleichgesetzt, der der
Ganzzahl-Variablen <20>i<EFBFBD> entspricht. Das Verzeichnis beginnt bei Null,
insofern muss sich <20>i<EFBFBD> zwischen 0 und (n-1) befinden. Das Verhalten
dieser Anweisung ist undefiniert, wenn sich die Werte des Verzeichnisses
au<EFBFBD>erhalb dieses Bereichs befinden.
> N<>HERUNGS-LINEAR-TABELLE {yvar :=}
-{PWL[xvar] }-
Dies ist eine gute Methode f<>r die N<>herungsl<73>sung einer komplizierten
Funktion oder Kurve. Sie k<>nnte zum Beispiel hilfreich sein, wenn Sie
versuchen eine Eichkurve zu verwenden, um die rohe Ausgangsspannung
eines F<>hlers in g<>nstigere Einheiten zu wandeln.
Angenommen Sie versuchen eine N<>herungsl<73>sung f<>r eine Funktion zu finden,
die eine Eingangs-Ganzzahlvariable <20>x<EFBFBD> in Ausgangs-Ganzzahlvariable <20>y<EFBFBD>
wandelt. Einige Punkte der Funktion sind Ihnen bekannt; so w<>rden 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 k<>nnen Sie in die Tabelle der
<EFBFBD>N<EFBFBD>herungs-Linear<61>-Anweisung eintragen. Die <20>N<EFBFBD>herungs-Linear<61>-Anweisung
wird dann auf den Wert von <20>xvar<61> schauen und legt den Wert von <20>yvar<61>
fest. Sie stellt <20>yvar<61> so ein, dass die <20>N<EFBFBD>herungs-Linear<61>-Kurve sich
durch alle Punkte bewegt, die Sie vorgegeben haben. Wenn Sie z.B. f<>r
<EFBFBD>xvar<EFBFBD> = 10 vorgegeben haben, dann stellt die Anweisung <20>yvar<61> auf gleich
50 ein.
Falls Sie dieser Anweisung einen Wert <20>xvar<61> zuweisen, der zwischen zwei
Werten von <20>x<EFBFBD> liegt, denen Sie Punkte zugeordnet haben, dann stellt die
Anweisung <20>yvar<61> so ein, dass (<28>xvar<61>, <20>yvar<61>) in der geraden Linie liegt;
diejenige die, die zwei Punkte in der Tabelle verbindet. Z.B. erzeugt
<EFBFBD>xvar<EFBFBD> = 55 bei <20>yvar<61> = 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 m<>ssen in aufsteigender Reihenfolge der x-Koordinaten
angegeben werden. Einige mathematische Operationen, erforderlich f<>r
bestimmte Nachschlag-Tabellen mit 16-Bit-Mathematik, kann man ggf. nicht
ausf<EFBFBD>hren. In diesem Falle gibt LDmicro eine Warnmeldung aus. So w<>rde
z.B. die folgende Nachschlag-Tabelle eine Fehlermeldung hervorrufen:
(x0, y0) = ( 0, 0)
(x1, y1) = (300, 300)
Sie k<>nnen diesen Fehler beheben, indem sie den Abstand zwischen den
Punkten kleiner machen. So ist zum Beispiel die n<>chste Tabelle <20>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 f<>nf oder sechs Punkte
zu verwenden. Falls Sie mehr Punkte hinzuf<75>gen, so vergr<67><72>ert dies
Ihren Code und verlangsamt die Ausf<73>hrung. Falls Sie f<>r <20>xvar<61> einen
Wert vergeben, der gr<67><72>er ist, als die gr<67><72>te 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 erm<72>glicht, die A/D-Wandler
zu verwenden, die in manchen Mikroprozessoren vorgesehen sind.
Wenn der Eingangszustand dieser Anweisung <20>wahr<68> ist, dann wird eine
Einzellesung von dem A/D-Wandler entnommen und in der Variablen <20>AName<6D>
gespeichert. Diese Variable kann anschlie<69>end mit einer gew<65>hnlichen
Ganzzahlvariablen bearbeitet werden (wie: Kleiner als, gr<67><72>er als,
arithmetisch usw.). Weisen Sie <20>Axxx<78> in der gleichen Weise einen Pin
zu, wie Sie einen Pin f<>r einen digitalen Ein- oder Ausgang vergeben
w<EFBFBD>rden, indem auf diesen in der Liste unten in der Maske (Bildanzeige)
doppelklicken. Wenn der Eingangszustand dieses Netzwerks <20>unwahr<68> ist,
so wird die Variable <20>AName<6D> unver<65>ndert belassen.
F<EFBFBD>r alle derzeitig unterst<73>tzten 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 Induktivit<69>t von 100<30>H empfohlen). Sie k<>nnen
arithmetische Operationen verwenden, um einen g<>nstigeren Ma<4D>stabfaktor
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 erm<72>glicht, die PWM-Peripherie
zu verwenden, die in manchen Mikroprozessoren vorgesehen ist. Wenn die
Eingangsbedingung dieser Anweisung <20>wahr<68> ist, so wird der Zyklus der
PWM-Peripherie mit dem Wert der Variablen <20>duty cycle<6C> gleichgesetzt. Der
<EFBFBD>duty cycle<6C> muss eine Zahl zwischen 0 und 100 sein. 0 entspricht immer
<EFBFBD>low<EFBFBD> und 100 entsprechend immer <20>high<67>. (Wenn Sie damit vertraut sind,
wie die PWM-Peripherie funktioniert, so bemerken Sie, dass dies bedeutet,
dass LDmicro die <20>duty cycle<6C>-Variable automatisch prozentual zu den
PWM-Taktintervallen skaliert [= den Ma<4D>stabfaktor festlegt].)
Sie k<>nnen die PWM-Zielfrequenz in Hz definieren. Es kann vorkommen, dass
die angegebene Frequenz nicht genau erreicht wird, das h<>ngt davon ab,
wie sich diese innerhalb der Taktfrequenz des Prozessors einteilt. LDmicro
w<EFBFBD>hlt dann die n<>chst erreichbare Frequenz; falls der Fehler zu gro<72> ist,
so wird eine Warnung ausgegeben. H<>here Geschwindigkeiten k<>nnen die
Aufl<EFBFBD>sung beeintr<74>chtigen.
Diese Anweisung muss ganz rechts im Netzwerk stehen. Die <20>ladder
logic<EFBFBD>-Laufzeit verbraucht (schon) einen Timer, um die Zykluszeit
zu messen. Dies bedeutet, dass die PWM nur bei den Mikroprozessoren
verf<EFBFBD>gbar 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 <20>wahr<68> 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
<EFBFBD>ndert. Bei Spannungswiederkehr wird die Variable automatisch vom
EEPROM zur<75>ckgespeichert. Falls eine Variable, die h<>ufig ihren Wert
<EFBFBD>ndert, remanent (dauerhaft) gemacht wird, so k<>nnte Ihr Prozessor sehr
rasch verschlei<65>en, weil dieser lediglich f<>r eine begrenzte Anzahl von
Schreibbefehlen konstruiert ist (~100 000). Wenn der Eingangszustand des
Netzwerks <20>unwahr<68> ist, so geschieht nichts. Diese Anweisung muss ganz
rechts im Netzwerk stehen.
> UART (SERIELL) EMPFANGEN var
--{UART RECV}--
LDmicro kann einen Code erzeugen, der erm<72>glicht UART zu verwenden,
welcher in manchen Mikroprozessoren vorgesehen ist.
Bei AVR-Prozessoren mir mehrfachem UART, wird nur UART1 (nicht UART0)
unterst<EFBFBD>tzt. Konfigurieren Sie die Baudrate, indem Sie <20>Voreinstellungen
-> Prozessor-Parameter<65> verwenden. Bestimmte Baudraten werden mit
bestimmten Quarzfrequenzen nicht erreichbar sein. In diesem Fall gibt
LDmicro eine Warnmeldung.
Wenn der Eingangszustand dieser Anweisung <20>unwahr<68> ist, so geschieht
nichts. Wenn der Eingangszustand <20>wahr<68> ist, so versucht diese Anweisung
ein einzelnes Schriftzeichen vom UART-Eingang zu empfangen. Wenn
kein Schriftzeichen eingelesen wird, dann ist der Ausgangszustand
<EFBFBD>unwahr<EFBFBD>. Wenn ein ASCII-Zeichen eingelesen wird, so wird sein Wert in
<EFBFBD>var<EFBFBD> abgespeichert und der Ausgangszustand wird f<>r einen einzelnen
Zyklus <20>wahr<68>.
> UART (SERIELL) SENDEN var
--{UART SEND}--
LDmicro kann einen Code erzeugen, der erm<72>glicht UART zu verwenden,
welcher in manchen Mikroprozessoren vorgesehen ist.
Bei AVR-Prozessoren mir mehrfachem UART, wird nur UART1 (nicht UART0)
unterst<EFBFBD>tzt. Konfigurieren Sie die Baudrate, indem Sie <20>Voreinstellungen
-> Prozessor-Parameter<65> verwenden. Bestimmte Baudraten werden mit
bestimmten Quarzfrequenzen nicht erreichbar sein. In diesem Fall gibt
LDmicro eine Warnmeldung.
Wenn der Eingangszustand dieser Anweisung <20>unwahr<68> ist, so geschieht
nichts. Wenn der Eingangszustand <20>wahr<68> ist, so schreibt diese
Anweisung ein einzelnes Schriftzeichen zum UART. Der ASCII-Wert des
Schriftzeichens, welches gesendet werden soll, muss vorher in <20>var<61>
abgespeichert worden sein. Der Ausgangszustand dieses Netzwerks ist
<EFBFBD>wahr<EFBFBD>, wenn UART besch<63>ftigt ist (gerade dabei ein Schriftzeichen zu
<EFBFBD>bermitteln) und andernfalls <20>unwahr<68>.
Denken Sie daran, dass einige Zeit zum Senden von Schriftzeichen
beansprucht wird. <20>berpr<70>fen Sie den Ausgangszustand dieser Anweisung,
sodass das erste Schriftzeichen bereits <20>bermittelt wurde, bevor Sie
versuchen ein zweites Schriftzeichen zu <20>bermitteln. Oder verwenden Sie
einen Timer, um eine Verz<72>gerung zwischen die Schriftzeichen f<>gen. Sie
d<EFBFBD>rfen den Eingangszustand dieser Anweisung nur dann auf <20>wahr<68> setzen
(bzw. ein Schriftzeichen <20>bermitteln), wenn der Ausgangszustand <20>unwahr<68>
ist (bzw. UART unbesch<63>ftigt ist).
Untersuchen Sie die <20>Formatierte Zeichenfolge<67>-Anweisung, bevor Sie
diese Anweisung verwenden. Die <20>Formatierte Zeichenfolge<67>- Anweisung
ist viel einfacher in der Anwendung und fast sicher f<>hig, das zu tun,
was Sie beabsichtigen.
> FORMATIERTE ZEICHENFOLGE <20>BER UART var
-{"Druck: \3\r\n"}-
LDmicro kann einen Code erzeugen, der erm<72>glicht UART zu verwenden,
welcher in manchen Mikroprozessoren vorgesehen ist.
Bei AVR-Prozessoren mir mehrfachem UART, wird nur UART1 (nicht UART0)
unterst<EFBFBD>tzt. Konfigurieren Sie die Baudrate, indem Sie <20>Voreinstellungen
-> Prozessor-Parameter<65> verwenden. Bestimmte Baudraten werden mit
bestimmten Quarzfrequenzen nicht erreichbar sein. In diesem Fall gibt
LDmicro eine Warnmeldung.
Wenn der Eingangszustand des Netzwerks f<>r diese Anweisung von <20>unwahr<68>
auf <20>wahr<68> <20>bergeht, so beginnt diese eine vollst<73>ndige Zeichenfolge
<EFBFBD>ber den seriellen Anschluss zu senden. Wenn die Zeichenfolge die
besondere Reihenfolge <20>\3<> enth<74>lt, dann wird diese Folge durch den Wert
von <20>var<61> ersetzt, welcher automatisch in eine Zeichenfolge gewandelt
wird. Die Variable wird formatiert, sodass diese exakt 3 Schriftzeichen
<EFBFBD>bernimmt. Falls die Variable zum Beispiel gleich 35 ist, dann wird die
exakte ausgegebene Zeichenfolge, wie folgt aussehen: <20>Druck: 35\r\n<>
(beachten Sie das zus<75>tzliche Freizeichen). Wenn stattdessen die Variable
gleich 1432 ist, so w<>re das Verhalten der Anweisung undefiniert,
weil 1432 mehr als drei Stellen hat. In diesem Fall w<>re es notwendig
stattdessen <20>\4<> zu verwenden.
Falls die Variable negativ ist, so verwenden Sie stattdessen <20>\-3d<33>
(oder <20>\-4d<34>). LDmicro wird hierdurch veranlasst eine vorgestellte
Freistelle f<>r positive Zahlen und ein vorgestelltes Minuszeichen f<>r
negative Zahlen auszugeben.
Falls mehrere <20>Formatierte Zeichenfolge<67>-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 m<>glich diese Anweisung f<>r eine feste Zeichenfolge zu
verwenden, die <20>ber den seriellen Anschluss gesendet wird, ohne den Wert
einer Ganzzahlvariablen in den Text zu interpolieren. In diesem Fall
f<EFBFBD>gen Sie einfach diese spezielle Steuerungsfolge nicht ein.
Verwenden Sie <20>\\<5C> f<>r einen zeichengetreuen verkehrten Schr<68>gstrich.
Zus<EFBFBD>tzlich zur Steuerungsfolge f<>r die Interpolierung einer Ganzzahl-
Variablen, sind die folgenden Steuerungszeichen erh<72>ltlich:
* \r -- carriage return Zeilenschaltung
* \n -- new line Zeilenwechsel
* \f -- form feed Formularvorschub
* \b -- backspace R<>cksetzen
* \xAB -- character with ASCII value 0xAB (hex)
-- Schriftzeichen mit ASCII-Wert 0xAB (hex)
Der Ausgangszustand des Netzwerks dieser Anweisung ist <20>wahr<68>, w<>hrend
diese Daten <20>bertr<74>gt, ansonsten <20>unwahr<68>. Diese Anweisung ben<65>tigt eine
gro<EFBFBD>e Menge des Programmspeichers, insofern sollte sie sparsam verwendet
werden. Die gegenw<6E>rtige Umsetzung ist nicht besonders effizient, aber
eine bessere w<>rde <20>nderungen an s<>mtlichen Ausl<73>ufern des Programms
ben<EFBFBD>tigen.
EIN HINWEIS ZUR VERWENDUNG DER MATHEMATIK
=========================================
Denken Sie daran, dass LDmicro nur 16-Bit mathematische Operationen
ausf<EFBFBD>hrt. 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 m<>ssen.
Wollen wir zum Beispiel annehmen, dass Sie folgendes berechnen m<>chten
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 w<>re es zumindest theoretisch m<>glich diese Berechnung auszuf<75>hren.
Es gibt zwei M<>glichkeiten, wie Sie dies codieren k<>nnten: Sie k<>nnen
die Reziproke (Kehrwert) ausf<73>hren and dann multiplizieren:
|| {DIV temp :=} ||
||---------{ 1 / x }----------||
|| ||
|| {MUL y := } ||
||----------{ temp * 1200}----------||
|| ||
Oder Sie k<>nnten einfach die Division in einem Schritt direkt vornehmen.
|| {DIV y :=} ||
||-----------{ 1200 / x }-----------||
Mathematisch sind die zwei <20>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
[= resultatabh<62>ngige Kommaverschiebung] ergibt. So sei zum Beispiel x = 3,
(1 / x) = 0.333, dies ist aber keine Ganzzahl; die Divisionsoperation
n<EFBFBD>hert dies, als 'temp = 0'. Dann ist y = temp * 1200 = 0. Im zweiten
Fall gibt es kein Zwischenergebnis, welches einen Unterlauf [= resultats-
abh<EFBFBD>ngige Kommaverschiebung] ergibt, somit funktioniert dann alles.
Falls Sie Probleme bei Ihren mathematischen Operationen erkennen,
dann <20>berpr<70>fen Sie die Zwischenergebnisse auf Unterlauf [eine
resultatabh<EFBFBD>ngige Kommaverschiebung] (oder auch auf <20>berlauf, der dann
im Programm in Umlauf kommt; wie zum Beispiel 32767 + 1 = -32768).
Wann immer m<>glich, w<>hlen Sie Einheiten, deren Werte in einem Bereich
von -100 bis 100 liegen.
Falls Sie eine Variable um einen bestimmten Faktor vergr<67><72>ern m<>ssen, tun
Sie dies, indem Sie eine Multiplikation und eine Division verwenden. Um
zum Beispiel y = 1.8 * x zu vergr<67><72>ern, 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 ausf<73>hren.
|| {MUL temp :=} ||
||---------{ x * 9 }----------||
|| ||
|| {DIV y :=} ||
||-----------{ temp / 5 }-----------||
Dies funktioniert mit allen x < (32767 / 9), oder x < 3640. Bei h<>heren
Werten w<>rde die Variable <20>temp<6D> <20>berflie<69>en. F<>r x gibt es eine
<EFBFBD>hnliche Untergrenze.
KODIER-STIL
===========
Ich gestatte mehrere Spulen in Parallelschaltung in einem einzigen
Netzwerk unterzubringen. Das bedeutet, sie k<>nnen 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 k<>nnten. Und es best<73>nde <20>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 L<>schen 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 h<>tten, es
zeigt aber, dass diese Anweisungen (Logik) verwandt ist, wenn man diese
im Netzwerk-Diagramm betrachtet.
* * *
Im Allgemeinen h<>lt man es f<>r eine schlechte Form, den Code in einer
solchen Weise zu schreiben, dass sein Ergebnis von einer Folge von
Netzwerken abh<62>ngt. So zum Beispiel ist der folgende Code nicht besonders
gut, falls <20>xa<78> und <20>xb<78> jemals <20>wahr<68> w<>rden.
|| 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 bin<69>re Gr<47><72>e von <20>xb3:0<> in eine
Ganzzahl wandeln w<>rde.
|| {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 w<>rde, anstatt auf das obere, so w<>rde der Wert von <20>v<EFBFBD>, an
anderer Stelle im Programm gelesen, gleich Null sein. Das Ergebnis dieses
Codes h<>ngt daher von der Reihenfolge ab, in welcher die Anweisungen
ausgewertet werden. Im Hinblick darauf, wie hinderlich es w<>re, 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
Ausf<EFBFBD>hrung und geht verschwenderisch mit dem Flash- und RAM-Speicher
um. Trotzdem kann ein mittelgro<72>er PIC- oder AVR-Prozessor alles, was
eine kleine SPS kann, somit st<73>rt dies mich nicht besonders.
Die maximale L<>nge 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 L<>sung f<>r diese Angelegenheit.
Falls Ihr Programm zu gro<72> f<>r die Zeit-, Programmspeicher- oder
Datenspeicher-Beschr<68>nkungen des Prozessors ist, den Sie gew<65>hlt haben,
so erhalten Sie keine Fehlermeldung. Es wird einfach irgendwo anders alles
vermasseln. (Anmerkung: Das AVR STK500 gibt hierzu Fehlermeldungen aus.)
Unsorgf<EFBFBD>ltiges Programmieren bei den Datei <20>ffnen/Abspeichern-Routinen
f<EFBFBD>hren wahrscheinlich zu der M<>glichkeit eines Absturzes oder es wird
ein willk<6C>rlicher Code erzeugt, der eine besch<63>digte oder b<>sartige .ld
Datei ergibt.
Bitte berichten Sie zus<75>tzliche Bugs oder richten Sie Anfragen f<>r 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