Funktionen und Sonderfunktionen einfach schalten PIC ...
Funktionen und Sonderfunktionen einfach schalten PIC ...
Funktionen und Sonderfunktionen einfach schalten PIC ...
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
Dirk Lübbesmeyer<br />
<strong>Funktionen</strong> <strong>und</strong> <strong>Sonderfunktionen</strong> <strong>einfach</strong> <strong>schalten</strong><br />
<strong>PIC</strong>-Mikroprozessoren im Schiffsmodell
<strong>Funktionen</strong> <strong>und</strong><br />
<strong>Sonderfunktionen</strong><br />
<strong>einfach</strong> <strong>schalten</strong><br />
<strong>PIC</strong>-Mikroprozessoren im Schiffsmodell<br />
Dirk Lübbesmeyer
I Fachbuch<br />
Best-Nr.: 310 2119<br />
Redaktion: Oliver Bothmann<br />
Lektorat: Claus Keller<br />
Wichtiger Hinweis:<br />
Die in diesem Buch angegebenen Verfahren <strong>und</strong> Schaltungen werden<br />
ohne Rücksicht auf die Patentlage mitgeteilt. Sie sind ausschließlich<br />
für Amateurzwecke gedacht <strong>und</strong> dürfen nicht gewerblich genutzt werden.<br />
Autor <strong>und</strong> Verlag weisen darauf hin, dass sie weder eine Garantie<br />
noch juristische Verantwortung oder irgendwelche Haftung für Folgen,<br />
die auf fehlerhafte Angaben zurückgehen, übernehmen können.<br />
Die Deutsche Bibliothek - CIP-Einheitsaufnahme<br />
ISBN 3-88180-719-5<br />
© 1. Auflage 2002 by Verlag für Technik <strong>und</strong> Handwerk<br />
Postfach 22 74,76492 Baden-Baden<br />
Alle Rechte, besonders das der Übersetzung, vorbehalten. Nachdruck <strong>und</strong><br />
Vervielfältigung von Text <strong>und</strong> Abbildungen, auch auszugsweise,<br />
nur mit ausdrücklicher Genehmigung des Verlages.<br />
Printed in Germany<br />
Druck: WAZ-Druck, Duisburg
Inhaltsverzeichnis<br />
Über den Autor 9<br />
Vorwort 10<br />
1 Der Mikroprozessor 12<br />
1.1 Überblick 12<br />
1.2 Gr<strong>und</strong>sätzliche Wirkungsweise <strong>und</strong> Takterzeugung 14<br />
1.2.1 Gr<strong>und</strong>sätzliche Wirkungsweise 14<br />
1.2.2 Takterzeugung 14<br />
1.3 <strong>PIC</strong>-Typen <strong>und</strong> ihre Eigenschaften 15<br />
1.3.1 <strong>PIC</strong>-12C509A 16<br />
1.3.2 <strong>PIC</strong>-12C672 17<br />
1.3.3 <strong>PIC</strong>-16C505 17<br />
1.3.4 <strong>PIC</strong>-16C71 18<br />
1.3.5 <strong>PIC</strong>-16F872 18<br />
1.3.6 <strong>PIC</strong>-16F876 19<br />
1.4 Notwendige Gr<strong>und</strong>ausstattung 20<br />
2 Die Programmierung 21<br />
2.1 Überblick 21<br />
2.2 Allgemeiner Programmaufbau 21<br />
2.2.1 Der Programmkopf 23<br />
2.2.2 Der Definitionsblock 23<br />
2.2.2.1 Konstanten (Literais) 23<br />
2.2.2.2 Register 24<br />
2.2.3 Die Programmzeilen 25<br />
2.3 Der <strong>PIC</strong>-Befehlssatz 26<br />
2.3.1 Überbück 26<br />
2.3.2 Der Befehlssatz in alphabetischer Reihenfolge 26<br />
2.4 Anwendung des Befehlssatzes <strong>und</strong> spezielle Programmierungstricks 29<br />
2.4.1 Registerbank- <strong>und</strong> Seitenumschaltung 29<br />
2.4.1.1 Registerbankumschaltung 29<br />
2.4.1.2 Programmseitenwechsel 29<br />
2.4.2 Die konditioneile Verzweigung 30
2.4.2.1 Arithmetische konditionale Verzweigung 30<br />
2.4.2.2 Wertbegrenzung 30<br />
2.4.2.3 Arithmetische Sprunganweisung 30<br />
2.4.3 Rechnen mit großen <strong>und</strong> mit negativen Zahlen 31<br />
2.4.3.1 Große Zahlen 31<br />
2.4.3.2 Negative Zahlen 31<br />
Kleine Zahlen 32<br />
Große Zahlen 32<br />
2.4.4 Indirekte Adressierung 33<br />
2.4.5 Unterprogramme <strong>und</strong> Tabellen 33<br />
2.4.5.1 Einfache Unterprogramme 34<br />
2.4.5.2 Tabellen 34<br />
2.4.6 Timer 34<br />
2.4.7 Watch Dog Timer <strong>und</strong> Sleep 35<br />
2.4.7.1 Watch Dog Timer 35<br />
2.4.7.2 Sleep 35<br />
2.4.8 Interrupts 36<br />
3 Programmbeispiele 37<br />
3.1 Überblick <strong>und</strong> Erläuterung eines Ablaufdiagramms am Beispiel von BLINK.... 37<br />
3.2 <strong>Sonderfunktionen</strong> 38<br />
3.2.1 Fünffachschalter (PENTA-S) 38<br />
3.2.1.1 Problemstellung <strong>und</strong> Funktionsprinzip 38<br />
3.2.1.2 Das Programm PENTAS.asm 39<br />
Das Hauptprogramm 39<br />
Subroutine SCAN 40<br />
3.2.1.3 Praktische Hinweise 41<br />
3.2.2 Schrittmotorradarantrieb (RADAR) 42<br />
3.2.2.1 Problemstellung <strong>und</strong> Funktionsprinzip 42<br />
Der Schrittmotor 42<br />
3.2.2.2 Steuerelektronik <strong>und</strong> praktischer Aufbau 43<br />
3.2.2.3 Das Programm RADAR.asm 44<br />
3.2.2.4 Praktische Hinweise 45<br />
3.2.3 RC-Streichholz (ZUND) 45<br />
3.2.3.1 Problemstellung <strong>und</strong> Funktionsprinzip 45<br />
3.2.3.2 Elektronische Schaltung <strong>und</strong> praktischer Aufbau 46<br />
3.2.3.3 Das Programm ZUND.asm 46<br />
3.2.3.4 Praktische Hinweise 48<br />
3.2.4 Kombination von RADAR <strong>und</strong> ZUND (RADZUND) 48<br />
3.2.5 Erzeugung eines Typhon- bzw. Zerstörersirenentons (DUOSIG) 49<br />
3.2.5.1 Problemstellung <strong>und</strong> Funktionsprinzip 49<br />
3.2.5.2 Elektronische Schaltung <strong>und</strong> praktischer Aufbau 49<br />
3.2.5.3 Das Programm DUOSIG.asm 50<br />
3.2.5.4 Praktische Hinweise für die Programmierung 52<br />
3.2.6 Schalter zu Servosignalkonverter (S2PWM) 52<br />
3.2.6.1 Problemstellung <strong>und</strong> Funktionsprinzip 52
3.2.6.2 Das Programm S2PWM.asm 54<br />
Das Hauptprogramm 54<br />
SubroutineMETHOD 55<br />
Subroutine SERVSET 55<br />
3.2.6.3 Praktische Hinweise zur Programmierung 55<br />
3.3 Überwachungseinheit für Modellparameter (NAVIGUARD) 56<br />
3.3.1 Problemstellung <strong>und</strong> Funktionsprinzip 56<br />
3.3.1.1 Elektronische Schaltung <strong>und</strong> praktischer Aufbau 57<br />
3.3.1.2 Das Programm NAVIGUARD.asm 57<br />
Das Hauptprogramm 57<br />
Programmierung der Tabellen in der Routine MELDG 59<br />
3.3.2.3 Praktische Hinweise für die Programmierung 60<br />
3.4 Drehzahlsteller 60<br />
3.4.1 Einwellen-2-kHz-Drehzahlsteller für Kleinmodelle (MONONAUT) 61<br />
3.4.1.1 Eigenschaften 61<br />
3.4.1.2 Problemstellung <strong>und</strong> Funktionsprinzip 62<br />
3.4.1.3 Das Programm MONONAUT.asm 63<br />
Das Hauptprogramm 63<br />
Modul SCAN 65<br />
Subroutine CLCTIM 66<br />
3.4.1.4 Praktische Hinweise 68<br />
3.4.2 Standardmehrwellen-2-kHz-Drehzahlsteller(MULTINAUT) 68<br />
3.4.2.1 Eigenschaften 68<br />
3.4.2.2 Praktischer Aufbau 69<br />
3.4.2.3 Das Programm MULTINAUT.asm 70<br />
Das Hauptprogramm 70<br />
Modul SCAND 71<br />
Modul CLCTIM 71<br />
3.4.2.4 Praktische Hinweise für die Programmierung 72<br />
3.4.3 Mehrwellen-Gleichstromdrehzahlsteller (DCNAUT) 73<br />
3.4.3.1 Problemstellung <strong>und</strong> Funktionsprinzip 73<br />
3.4.3.2 Das Programm DCNAUT.asm 74<br />
Das Hauptprogramm 74<br />
Subroutine SCAN 75<br />
Subroutine FAHRT 75<br />
3.4.3.3 Praktische Hinweise für die Programmierung 76<br />
3.4.4 Automatische Fahrstufenregelung (AUTONAUT) 76<br />
3.4.4.1 Problemstellung <strong>und</strong> Funktionsprinzip 77<br />
3.4.4.2 Das Programm AUTON.asm 78<br />
Das Hauptprogramm 78<br />
Subroutine PID 78<br />
3.4.4.3 Praktische Hinweise für die Programmierung 79<br />
3.4.5 Modell-Controller (MODCON-S, -P <strong>und</strong> -D) 80<br />
3.4.5.1 MODCON-S 80<br />
3.4.5.2 MODCON-P 82<br />
3.4.5.3 MODCON-D 82
3.5 Enkoder <strong>und</strong> Dekoder für eine RC-Anlage 84<br />
3.5.1 Problemstellung 84<br />
3.5.2 Enkoder für RC-Sender (NVENKO) 86<br />
3.5.2.1 Schaltung 86<br />
3.5.2.2 Das Programm NVENKO.asm 87<br />
3.5.2.3 Praktische Hinweise 88<br />
3.5.3 Signaldekoder für RC-Empfänger (NVDEKO) 88<br />
3.5.3.1 Schaltung 89<br />
3.5.3.2 Das Programm NVDEKO.asm 90<br />
3.5.3.3 Praktische Hinweise 91<br />
4 Anhang 92<br />
4.1 Literatur 92<br />
4.1.1 Zeitschriften 92<br />
4.1.1 Handbücher (Manuals) 92<br />
4.2 Platinenlayouts <strong>und</strong> Liste der Programme auf der CD-ROM 93<br />
4.2.1 Platinenlayouts <strong>und</strong> Bestückungspläne 93<br />
4.2.1.1 Platinenlayout <strong>und</strong> Bestückungsplan für PENTA-S 93<br />
4.2.1.2 Platinenlayout <strong>und</strong> Bestückungsplan für RADAR 93<br />
4.2.1.3 Platinenlayout <strong>und</strong> Bestückungsplan für ZUND 93<br />
4.2.1.4 Platinenlayout <strong>und</strong> Bestückungsplan für DUOSIG 93<br />
4.2.1.5 Platinenlayout <strong>und</strong> Bestückungsplan für S2PWM 94<br />
4.2.1.6 Platinenlayout <strong>und</strong> Bestückungsplan für MONONAUT 94<br />
4.2.1.7 Platinenlayout <strong>und</strong> Bestückungsplan für MODCON 94<br />
4.2.2 Liste der Programme auf der CD-ROM 95<br />
4.2.2.1 <strong>PIC</strong>-Sourceprogramme (.asm) 95<br />
4.2.2.2 FORTRAN-Unterstützungsprogramme (.for) 96
Über den Autor<br />
Dirk Lübbesmeyer (Jahrgang 1942) beschäftigt<br />
sich seit r<strong>und</strong> 50 Jahren mit Schiffsmodellbau,<br />
wobei seine Vorliebe bei den zeitgenössischen<br />
Einheiten der US-Navy liegt, die in Holz<br />
nach selbst gezeichneten oder kommerziellen<br />
Plänen im einheitlichen Maßstab von 1:200<br />
gebaut <strong>und</strong> in den einschlägigen Fachzeitschriften<br />
regelmäßig vorgestellt werden. Um die<br />
Modelle mit interessanten <strong>Sonderfunktionen</strong><br />
ausrüsten zu können, kamen nach <strong>und</strong> nach<br />
auch die Entwicklung <strong>und</strong> der Bau von Fernsteuerungskomponenten<br />
hinzu. Was zunächst<br />
noch mit viel Löterei verb<strong>und</strong>en war, hat<br />
inzwischen weitgehend den Mikroprozessoren<br />
Platz gemacht.<br />
Beruflich ist der Autor in der Reaktorsicherheitsforschung<br />
tätig <strong>und</strong> arbeitet als Kerntechnikingenieur<br />
in einem Forschungsinstitut<br />
mehr mit Großrechnern als mit Mikroprozessoren.<br />
Er wohnt im etwa 20 km westlich von<br />
Zürich gelegenen Baden.
Vorwort<br />
Elektronik gehört wohl zu den wenigen Dingen,<br />
die mit der Zeit immer billiger geworden<br />
ist, weswegen auch ihr Einzug in den Modellbau<br />
in den letzten Jahrzehnten stetig zugenommen<br />
hat. War man in den 1960ern noch mit<br />
einem abwechselnden Rudervollausschlag zufrieden<br />
<strong>und</strong> sah es schon als einen ungeheueren<br />
Luxus an, wenn auch die Fahrmotoren anbzw.<br />
ausgeschaltet oder gar umgepolt werden<br />
konnten (es gab damals eine Rudermaschine<br />
namens Kinematic, die diese „Sonderfunktion"<br />
über kurze Ruderruckler realisierte), so<br />
sind heute neben der proportionalen Lenkung<br />
<strong>und</strong> stufenlosen Steuerung der Motordrehzahl<br />
die mannigfaltigsten Zusatzfunktionen selbst<br />
mit nicht allzu großem finanziellem Aufwand<br />
zu realisieren. Auch findet man in den einschlägigen<br />
Fachzeitschriften regelmäßig Bauvorschläge<br />
für die unterschiedlichsten Anlagenteile,<br />
die es selbst dem elektronisch weniger<br />
versierten Modellbauer erlauben, die Möglichkeiten<br />
seiner Fernsteuerung bezüglich <strong>Sonderfunktionen</strong><br />
zu erweitern. Einige dieser Bauvorschläge<br />
sind schon recht umfangreich <strong>und</strong><br />
benötigen nicht nur eine Menge Lötarbeit, sondern<br />
sind im Modell auch von beträchtlichem<br />
Volumen bzw. Gewicht.<br />
Hier kommt uns nun eine technische Entwicklung<br />
zugute, die in der Elektronikindustrie<br />
schon seit Beginn der 80er-Jahre vermehrt<br />
eingesetzt wird, sich bei Hobbyelektronikern<br />
dank inzwischen <strong>einfach</strong> zu bedienender <strong>und</strong><br />
preiswerterer Heimcomputer (PC) aber erst seit<br />
10<br />
wenigen Jahren durchzusetzen beginnt, der<br />
Mikroprozessor auch Mikrocontroller oder hier<br />
oft <strong>einfach</strong> <strong>und</strong> kurz uP genannt. Er erlaubt die<br />
Synthese einer komplizierten, diskret aufgebauten<br />
elektronischen Schaltung durch einen<br />
entsprechend programmierten Mikroprozessor,<br />
an dessen Ausgängen (IC-Pins) dann die der<br />
diskreten Schaltung äquivalenten Signale erzeugt<br />
werden.<br />
Auch die Modellbauindustrie hat den uP<br />
schon vor einigen Jahren entdeckt. Blättert man<br />
regelmäßig in Katalogen für elektronisches<br />
Modellbaugerät, so kann man die rasche Zunahme<br />
mikroprozessorgesteuerter Elektronik<br />
kaum übersehen. Zuerst kamen die „Computerfernsteuerungen",<br />
bei denen die zu übertragenden<br />
Steuerinformationen, d.h. die Poti-Stellungen<br />
der Steuerknüppel <strong>und</strong> eventuelle Schalterstellungen,<br />
digitalisiert, durch mannigfaltige<br />
menügesteuerte Manipulationen im uP verarbeitet<br />
<strong>und</strong> schließlich als Binärzahlen (d.h.<br />
Ein-/Aus-Stellungen des Senders) an den Empfänger<br />
gesendet werden. Dort dröselt ein weiterer<br />
uP diese Information wieder auf. Andere<br />
seit längerer Zeit verwendete uP-Einsatzorte<br />
sind Drehzahlsteller <strong>und</strong> Ladegeräte. All dies<br />
umweht mit dem Begriff „mikroprozessorgesteuert"<br />
immer noch das Odium des Exquisiten.<br />
Im Modellbau haben wir es aber meist mit<br />
elektronisch eher <strong>einfach</strong> gelagerten Problemen<br />
zu tun, weshalb uP-Lösungen in der Regel<br />
billig sind. Im Endeffekt ist ein uP nämlich<br />
eigentlich nichts anderes als ein sehr kosten-
günstiger Spezial-IC, der all das intern erledigt,<br />
für das man sonst einen Haufen Bauteile<br />
zusammenlöten müsste. Die Spezialisierung<br />
eines im Kaufzustand oder nach Löschung leeren<br />
IC erfolgt durch Programmierung mit einem<br />
geeigneten Programm. Dass der IC intern<br />
dann wie ein Rechner mit Zahlen arbeitet, spielt<br />
im Einsatz praktisch keine Rolle, ja man stellt<br />
kaum einen Unterschied zur analogen Schaltung<br />
fest, es sei denn den meist höheren Komfort<br />
der uP-Lösung.<br />
Bei so vielen Vorteilen fragt man sich natürlich,<br />
warum im Amateurbereich immer noch<br />
so viel Modellelektronik diskret aufgebaut wird.<br />
Neben traditionellen Aspekten - man macht<br />
eben das weiter, was man schon immer so<br />
gemacht hat - ist eine Hauptbarriere bestimmt<br />
auch der Einstiegspreis, denn ohne einen PC<br />
mit der notwendigen Software <strong>und</strong> dem an<br />
einen PC-Port angeschlossenen uP-Programmiergerät<br />
geht es nun mal nicht. PC, Programmiergerät<br />
<strong>und</strong> PC-Software braucht man, um<br />
die beim Kauf leeren Mikroprozessoren mit<br />
einem Programm zu laden <strong>und</strong> damit auf die<br />
gewünschten Eigenschaften zu programmieren.<br />
Ansonsten ist nur noch Know-how nötig,<br />
dessen Vertiefung ein Ziel dieses Buches ist.<br />
Im Weiteren möchte ich den Lesern den<br />
Einsatz von Mikroprozessoren schmackhaft<br />
machen. Dazu wird zunächst das Funktionsprinzip<br />
eines uP allgemein umrissen, dann stelle<br />
ich die verschiedenen, in diesem Buch verwendeten<br />
uP-Typen der Firma Microchip kurz<br />
vor <strong>und</strong> gehe auf die zur Programmierung nötige<br />
Hard- <strong>und</strong> Software ein.<br />
Im zweiten Teil werden wir uns dann mit<br />
der Erstellung von uP-Programrnen beschäftigen,<br />
<strong>und</strong> zwar mit Assembler-Programmen, da<br />
diese Programmierung die für Mikroprozessoren<br />
effektivste Art darstellt. Dieser Teil dient<br />
vor allem auch dem Verständnis der nachfolgenden<br />
Programme.<br />
Im dritten Teil schließlich werden verschiedene<br />
Anwendungsbeispiele vorgestellt<br />
<strong>und</strong> diskutiert. Das reicht vom Fünffachschalter<br />
zur Gewinnung von fünf Schaltstellungen<br />
aus einem Funktionskanal (Servosignal) über<br />
ein <strong>einfach</strong>es Programm zur Schrittmotorsteuerung<br />
für einen Modellradarantrieb durch<br />
Miniaturschrittmotore, die Zündeinrichtung<br />
für Feuerwerk mit Sicherheitsschaltung <strong>und</strong><br />
Spannungsverdreifachung zur optimalen Ansteuerung<br />
der Leistungs-FETs bei niedrigen<br />
Bordspannungen, ferner Servosignalgeneratoren<br />
aus <strong>einfach</strong>en Schaltersignalen (Schalter<br />
zu Servosignalkonverter) bis zu einem Typhon-<br />
<strong>und</strong> Sirenensignalgenerator. Zur Überwachung<br />
verschiedener Modellkenngrößen<br />
wie Akkuspannungen oder RC-Signalgüte<br />
wird eine Überwachungsschaltung vorgestellt,<br />
die den Alarmfall mit einem Signalscheinwerfer<br />
per Morsetelegramm sendet.<br />
Einen großen Teil nehmen die Drehzahlsteller<br />
ein, vom <strong>einfach</strong>en MONONAUT mit<br />
Transistorbrücke für Kleinmodelle über den<br />
MULTINAUT für Mehrwellenmodelle mit individueller<br />
Umpolung der Fahrmotoren einer<br />
Schiffsmodellseite bei Hartrudermanövern bis<br />
zum MODCON-D, wo die beiden Fahrmotoren<br />
in Abhängigkeit der Richtungsvorgabe gesteuert<br />
werden können.<br />
Schließlich werden Enkoder (Sender) <strong>und</strong><br />
Dekoder (Empfänger) vorgestellt, die es erlauben,<br />
mit einer Fernsteuerung gleichzeitig zwei<br />
Modelle zu steuern, <strong>und</strong> zwar analog für Richtung<br />
<strong>und</strong> Fahrstufe <strong>und</strong> mit 15 Schalterstellungen<br />
pro Modell. Dazu lassen sich zwei weitere<br />
Modelle betriebsbereit halten, auf die man von<br />
den gerade fahrenden Modellen jederzeit um<strong>schalten</strong><br />
kann.<br />
11
1 Der Mikroprozessor<br />
1.1 Uberblick<br />
Wir beschränken uns in diesem Buch auf Mikroprozessoren<br />
des Herstellers Microchip, die<br />
das Präfix „<strong>PIC</strong>" tragen, was für Programmable<br />
Integrated Circuit, also programmierbarer<br />
integrierter Schaltkreis (IC), steht <strong>und</strong> damit<br />
schon andeutet, um was es sich bei einem Mikroprozessor<br />
handelt, nämlich um einen mehr<br />
oder weniger großen Spezial-IC. Im Rahmen<br />
dieses Buches werden Typen mit minimal 8<br />
(DIP-8) <strong>und</strong> maximal 28 Pins im DIP-28-Gehäuse<br />
verwendet. Jede dieser ICs ist ein kompletter<br />
8-Bit-Computer mit Prozessor (ALU =<br />
Arithmetical Logical Unit), Programm- <strong>und</strong> Datenspeicher<br />
(RAM = Random Access Memo-<br />
Verschiedene in diesem Buch verwendete<br />
<strong>PIC</strong>-Mikroprozessoren. In der oberen Reihe<br />
zwei OTP-Typen (12C672 <strong>und</strong> 16C505), in der<br />
unteren vier löschbare <strong>PIC</strong>s, drei JW-Typen<br />
mit Quarzfenster (12C509A. 16C505 <strong>und</strong><br />
16C71) <strong>und</strong> ein elektrisch löschbarer <strong>PIC</strong>.<br />
12<br />
ry) sowie Ein- <strong>und</strong> Ausgabeleitungen in Form<br />
der IC-Pins. Einige Typen verfügen darüber<br />
hinaus über Spezialfunktionen wie Analog-digital-Wandler<br />
(ADW), vom Programmablauf<br />
unabhängig im Hintergr<strong>und</strong> laufende Zähler<br />
(Timer) <strong>und</strong> PWM-Signalgeneratoren, die bei<br />
der Motorsignalerzeugung in der Anwendung<br />
Drehzahlsteller die Programmierung sehr erleichtern.<br />
Was macht einen uP für den Einsatz im<br />
Modell denn nun so interessant? Eigentlich,<br />
sollte man meinen, braucht es ja zum Fernsteuern,<br />
wenn überhaupt, nur wenig Rechnerei.<br />
Zwar summt je nach Ausbaugrad der <strong>Sonderfunktionen</strong><br />
oft einige Elektronik im Modell<br />
vor sich hin, doch die besteht meist aus Transistoren<br />
nebst externer Beschattung <strong>und</strong><br />
vielleicht ein paar Digital- oder Spezial-ICs für<br />
die Verarbeitung von RC-Signalen; also weit<br />
<strong>und</strong> breit kein Bedarf für einen Computer.<br />
Doch betrachten wir einmal ein relativ<br />
<strong>einfach</strong>es Problem, nämlich die Ein-Aus-<br />
Schaltung eines Relais mittels eines Steuerknüppels<br />
(Kanalschalter). Mit diskreter Elektronik<br />
aufgebaut braucht man dazu einen<br />
Mono-Flop zur Erzeugung eines Referenzimpulses,<br />
Gatter zum Vergleich von Kanal- <strong>und</strong><br />
Referenzimpulslängen <strong>und</strong> schließlich einen<br />
Impulsdehner, der die resultierenden kurzen<br />
Differenzimpulse so dehnt, dass das angeschlossene<br />
Relais auch im geschalteten Zustand<br />
nicht flattert. Wie das Wort Differenzimpuls<br />
andeutet, wird auch in der diskreten
Schaltung „gerechnet", nämlich etwa 50 Subtraktionen<br />
pro Sek<strong>und</strong>e.<br />
Wie geht nun ein Mikroprozessor das Problem<br />
an? Hier wird während der aktiven Phase<br />
des Kanalimpulses (H-Phase bei positiver<br />
Logik) eine Variable hochgezählt, was wegen<br />
des Rechnertaktes einer Zeitmessung bzw. Impulslängenmessung<br />
gleichkommt. Vom Zählergebnis<br />
wird dann der Referenzwert abgezogen<br />
<strong>und</strong> der Ausgangspin des uP -1- (= H)<br />
gesetzt, wenn das Ergebnis negativ, <strong>und</strong> -0- (=<br />
L), wenn es positiv ist. Die Rechnerarbeit besteht<br />
hier also aus Zählen, Subtraktion <strong>und</strong><br />
Auswertung des Vorzeichens bezüglich Schalterstellung.<br />
Bei dieser Einschalterversion springt der<br />
Vorteil eines uP, obwohl in etwa kostenneutral,<br />
noch nicht gerade ins Auge. Durch simple<br />
Aufteilung des Zählergebnisses in mehrere Bereiche<br />
ist es mit dem gleichen uP aber problemlos<br />
möglich, mehrere Schalterstellungen<br />
anzusteuern, z.B. für die ersten 17% Steuerknüppelauslenkung<br />
ist der Stufenschalter aus,<br />
für 17% bis 34% steht er auf Schalterstellung -<br />
1- usw. So kann man jetzt mit einem Funktionskanal<br />
bereits fünf verschiedene <strong>Funktionen</strong><br />
ansteuern, was diskret aufgebaut schon einige<br />
elektronische Bauteile mehr verlangt. Aber damit<br />
noch nicht genug. Die einzelnen Schalterstellungen<br />
weiter zu bearbeiten <strong>und</strong> sie z.B.<br />
mit Triggerfunktionen (nur kurze Haltezeit)<br />
oder Memoryfunktion (ihr Zustand bleibt<br />
jeweils so lange erhalten, bis sie erneut angesprochen<br />
werden) stellt für den uP kein Problem<br />
dar, würde eine diskrete elektronische<br />
Schaltung aber schon recht komplizieren; auf<br />
das Beispiel werden wir im Abschnitt 3.2.1<br />
(PENTA-S) zurückkommen.<br />
Auch für unser Modellbaubudget sind die<br />
Vorteile von Mikroprozessoren augenfällig. So<br />
lässt sich z.B. die Steuerelektronik (also abzüglich<br />
des Leistungstreibers <strong>und</strong> der Umpolrelais)<br />
meines seit Jahren in Mehrwellenschiffen eingesetzten<br />
Drehzahlstellers DUONAUT mit einem<br />
einzigen 14-Pin-IC für um die 2 Euro realisieren,<br />
der extern nur noch mit einem Kera-<br />
Diskret aufgebaute Schaltungen für NAVI-<br />
GUARD <strong>und</strong> DUONAUT (unten) im Vergleich<br />
zur Mikroprozessorlösung mit zwei uPS<br />
(oben)<br />
mikkondensator zu Störunterdrückung beschaltet<br />
werden sollte (siehe Abschnitt 3.4.2). Dagegen<br />
verschlingt die gleiche Elektronik diskret<br />
aufgebaut einige Bauteile <strong>und</strong> einige Euro mehr.<br />
Ein anderes Beispiel ist meine Modellüberwachung<br />
NAVIGUARD, deren diskrete Schaltung<br />
in der Zeitschrift Modell Werft, Heft 12/<br />
99, vorgestellt wurde. Das Gerät ist eine eng<br />
bestückte Platine mit den Abmessungen 1 (X)x70<br />
mm <strong>und</strong> insgesamt sieben ICs inklusive eines<br />
EPROMS. Die dieser diskreten Schaltung funktionell<br />
noch überlegene uP-Version besteht nur<br />
aus einer einzigen 8-Pin-IC mit einer äußeren<br />
Beschaltung von drei Widerständen, einer Z-<br />
Diode <strong>und</strong> einem Kondensator zur Störungsunterdrückung<br />
(siehe Abschnitt 3.3).<br />
Einen entscheidenden Vorteil der uP-Lösung<br />
sehe ich schließlich in ihrer hohen Modifikationsfre<strong>und</strong>lichkeit,<br />
ist es doch wesentlich<br />
<strong>einfach</strong>er, in einem Programm ein paar h<strong>und</strong>ert<br />
Zeilen zu ändern, einen uP neu zu programmieren<br />
<strong>und</strong> ihn schließlich in den entsprechenden<br />
IC-Sockel zu stecken, als eine<br />
ganze Schaltung umzulöten, wozu u.U. sogar<br />
eine neue Platine entworfen <strong>und</strong> angefertigt<br />
werden muss. Gerade dieser letzte Punkt hat<br />
mich daher vor allem bewogen, meine Modellflotte<br />
zu „digitalisieren", d.h., wo immer es<br />
geht, diskret aufgebaute Schaltungen durch<br />
Mikroprozessoren zu ersetzen.<br />
13
1.2 Gr<strong>und</strong>sätzliche Wirkungsweise<br />
<strong>und</strong> Takterzeugung<br />
1.2.1 Gr<strong>und</strong>sätzliche<br />
Wirkungsweise<br />
Ein Mikroprozessor ist, wie jeder Computer,<br />
eine elektronische Maschine, die eine Liste von<br />
Maschinenbefehlen, Programm genannt,<br />
nacheinander abarbeiten kann. Dazu wird ein<br />
Zeilenzähler hochgezählt <strong>und</strong> dann der in der<br />
jeweiligen Zeile des Programms stehende Befehl<br />
ausgeführt. Der etwa 35 verschiedene Instruktionen<br />
umfassende Befehlssatz für <strong>PIC</strong>-<br />
Prozessoren beinhaltet Sprunganweisungen,<br />
Wertzuweisungen, Addition <strong>und</strong> Subtraktion<br />
positiver ganzer Zahlen (8 Bit, d.h. 0 bis 255),<br />
logische Verknüpfungen (AND, OR <strong>und</strong><br />
EXOR) <strong>und</strong> verschiedene Manipulationen einzelner<br />
Bits in einer 8-Bit-Variablen, die der<br />
uP-Hersteller Microchip als Register-Files bezeichnet,<br />
im Weiteren <strong>einfach</strong> „Register" genannt.<br />
Je nach uP-Typ sind ein oder mehrere<br />
Register bitweise mit den Pins des ICs (PORT)<br />
verb<strong>und</strong>en <strong>und</strong> können individuell sowohl gelesen<br />
(input) als auch gesetzt werden (output),<br />
was die Kommunikation mit der Außenwelt<br />
14<br />
EXTRC<br />
<strong>einfach</strong>er R-C-Oszillator<br />
ermöglicht <strong>und</strong> damit den uP-Einsatz in elektronischen<br />
Schaltungen überhaupt erst interessant<br />
macht. Im Gegensatz zu herkömmlichen<br />
Computerprogrammen laufen uP-Programme<br />
endlos. Deshalb enthält jedes sinnvolle Programm<br />
am Ende einen Sprungbefehl in den<br />
Anfangsbereich des Hauptprogramms, was einem<br />
Zurücksetzen des Zeilenzähler gleichkommt.<br />
1.2.2 Takterzeugung<br />
Zum Hochzählen des Zeilenzähler brauchen<br />
Computer einen Takt. Während man bei PCs<br />
<strong>und</strong> Großcomputern bezüglich Taktfrequenz<br />
heute schon von GHz spricht, verkraften preiswerte<br />
Mikroprozessoren in der Regel kaum<br />
mehr als 20 MHz; bei den Anwendungen in<br />
diesem Buch beschränken wir uns durchwegs<br />
auf für unsere Zwecke ausreichende 4 MHz.<br />
<strong>PIC</strong>-Mikroprozessoren benötigen für die Abarbeitung<br />
eines Maschinenbefehl vier Takte,<br />
was bei 4 MHz Taktfrequenz der Ausführung<br />
eines Befehls pro Mikrosek<strong>und</strong>e entspricht.<br />
Der Computertakt muss bei Mikroprozessoren<br />
bis auf die Ausnahmen, wo ein interner,<br />
Drei verschiedene Arten der Takterzeugung<br />
für <strong>PIC</strong>-Mikroprozessoren<br />
LP, XT, HS<br />
Quarz Oszillator<br />
externer<br />
Taktgenerator<br />
Inverter<br />
externer Takt<br />
a . ) b . ) c . )
vom Hersteller kalibrierter Taktgenerator implementiert<br />
ist, extern erzeugt werden. Da bei<br />
den <strong>PIC</strong>s der Halbleiterteil der Oszillatorschaltung<br />
schon im uP integriert ist, sind die Externa<br />
nur passive Bauteile, d.h. Widerstände, Kondensatoren<br />
<strong>und</strong>/oder ein Quarz (Fälle a <strong>und</strong> b).<br />
Bezüglich des Quarzoszillators werden bei <strong>PIC</strong>-<br />
Mikroprozessoren drei Typen unterschieden:<br />
,,LP" für den unteren Frequenzbereich bis maximal<br />
200 kHz, wo der Stromverbrauch eines<br />
<strong>PIC</strong>s besonders niedrig ist, „XT" als Standardquarz<br />
für Frequenzen bis 4 MHz <strong>und</strong> „HS" für<br />
alles Höherfrequente. Schließlich kann man<br />
aber auch den Takt eines externen Taktgebers<br />
am Pin CLKTN eingeben, was besonders dann<br />
zweckmäßig ist, wenn mehrere Mikroprozessoren<br />
mit dem gleichen Takt betrieben werden<br />
sollen (Fall c), um sie synchron laufen zu lassen<br />
oder <strong>einfach</strong> um Bauteile, insbesondere<br />
Quarze, einzusparen.<br />
Die für die Beschallung in den Fällen a<br />
bzw. b nötigen Werte für „R" <strong>und</strong> „C" sind der<br />
Tabelle zu entnehmen; bei Quarzen hängen sie<br />
auch etwas von dessen Hersteller ab (hier wurden<br />
die flachen Typen HC49U-S verwendet).<br />
Der Widerstand R ist in den Quarzoszillatorschaltungen<br />
oft nicht nötig. Der zu verwendende<br />
Oszillatortyp muss im Konfigurationswort<br />
mit den Bits FOSC,0 bis FOSC,2 definiert<br />
werden. Da ein interner Oszillator<br />
allerdings nur in wenigen <strong>PIC</strong>-Typen vorhanden<br />
ist, besteht das Konfigurationswort<br />
normalerweise nur aus zwei Bits (FOSC,0 <strong>und</strong><br />
FOSC,l) für vier Oszillatortypen.<br />
FOSC,0-1<br />
11 EXTRC C<br />
R<br />
00 LP C<br />
R<br />
01 XT C<br />
R<br />
10 HS C<br />
R<br />
100 kHz<br />
100p<br />
82k<br />
22p<br />
10R<br />
270 kHz<br />
270p<br />
12k<br />
Bei <strong>PIC</strong>-Typen mit internem Oszillator hat<br />
der FOSC-Teil das Konfigurationswort drei Bit.<br />
100 INTRC interner, vom Hersteller<br />
kalibrierter Oszillator (4 MHz)<br />
ohne Ausgabe an Pin OSC2<br />
101 INTRC wie 100, nur mit Ausgabe an<br />
Pin OSC2, der dann nicht als<br />
allgemeiner Port verwendet<br />
werden kann<br />
110 EXTRC externer R-C-Generator<br />
ohne Ausgabe an Pin OSC2<br />
R- <strong>und</strong> C-Werte wie für<br />
Code'11'<br />
111 EXTRC externer R-C-Generator mit<br />
Ausgabe an Pin OSC2, der<br />
dann nicht als allgemeiner<br />
Port verwendet werden kann<br />
R- <strong>und</strong> C-Werte wie für<br />
Code'11'<br />
Wird der Takt von einem externen Generator<br />
am Pin CLKTN eingespeist, müssen FOSC,0<br />
<strong>und</strong> FOSC,l für einen Quarz LP, XT oder HS<br />
definiert werden. Am CLKOUT-Pin wird dann<br />
ein Viertel der Taktfrequenz, d.h. die Frequenz<br />
des Maschinenzyklus, ausgegeben.<br />
1.3 <strong>PIC</strong>-Typen<br />
<strong>und</strong> ihre Eigenschaften<br />
Im Rahmen dieses Buches wird natürlich nur<br />
ein sehr kleiner Teil der im Lieferprogramm des<br />
Herstellers Microchip angebotenen Mikroprozessoren<br />
verwendet, gibt es doch <strong>PIC</strong>-Mikroprozessoren<br />
in den verschiedensten Typen <strong>und</strong><br />
500 kHz<br />
270p<br />
4,7k<br />
1 MHz<br />
100p<br />
4,7k<br />
22p<br />
68R<br />
4 MHz<br />
27p<br />
3,9k<br />
22p<br />
68R<br />
10 MHz 20 MHz<br />
33p<br />
47R<br />
33p<br />
39R<br />
15
Gehäuseformen, was schon in der Kennung der<br />
ICs erkennbar ist. Analysieren wir als Beispiel<br />
die Kennung des <strong>PIC</strong>-16C71/04. Die 16 vor<br />
dem „C" steht darin für die vom Prozessor intern<br />
verwendete Wortlänge, hier eine Gesamtwortlänge<br />
von 14 Bit, wovon die unteren 8 Bit<br />
(0 bis 7) den Wert des angesprochenen Registers,<br />
1 Bit die Destination des Ergebnisses nach<br />
einer Operation <strong>und</strong> die restlichen Bits den Code<br />
des Maschinenbefehls definieren. „C" beschreibt<br />
den Chiptyp, hier ein EPROM, <strong>und</strong> die folgende<br />
Nummer ist die spezielle uP-Kennung.<br />
Schließlich sagt die ,/04" etwas über die maximale<br />
Taktfrequenz in MHz, die von ihm noch<br />
verarbeitet werden kann.<br />
Die billige Standardversion eines „C"-Typs<br />
ist OTP (= One Time Programmable) im Plastikgehäuse.<br />
Sie ist, wie der Name sagt, nur<br />
einmal programmierbar, was bei der Code-Entwicklung<br />
wenig zweckmäßig ist (pro Fehler<br />
ein neuer IC). Es gibt die „C"-<strong>PIC</strong>s daher auch<br />
in einem „JW"-Keramikgehäuse mit integriertem<br />
Quarzglasfensters, das beliebige Löschung<br />
im UV-Löscher erlaubt; das Quarzglasfenster<br />
macht den IC allerdings sehr viel teurer.<br />
Einige wenige Programme verwenden auch<br />
die neueren uP-Typen 16F872 <strong>und</strong> 16F876, wo<br />
das „F" für den Chiptyp „flash" steht. Diese ICs<br />
sind elektrisch löschbar, d.h., der alte Inhalt wird<br />
beim Programmieren <strong>einfach</strong> überschrieben. Da<br />
zum Löschen kein UV-Licht notwendig ist, genügt<br />
immer das billige Plastikgehäuse. Ein weiterer<br />
Vorteil der F-Typen ist, dass sie über einen<br />
nichtflüchtigen Datenraum verfugen, wo der<br />
Registerinhalt auch nach dem Ab<strong>schalten</strong> des<br />
Mikroprozessoren erhalten bleibt; dies ist z.B.<br />
für die Speicherung von Justierungen sehr praktisch<br />
<strong>und</strong> findet in den Drehzahlstellerprogrammen<br />
MODCON Anwendung. Angemerkt sei in<br />
diesem Zusammenhang noch, dass Microchip<br />
zurzeit (2002) für einige der „C"-Typen Pinkompatible<br />
Flashversionen auf den Markt bringt,<br />
die wohl nach nur minimalen Änderungen in<br />
den entsprechenden Programmen anstelle der<br />
vorgesehenen „C"-Typen eingesetzt werden können.<br />
16<br />
Der RAM-Größe kommt für alle hier vorgeschlagenen<br />
Programme keine allzu große<br />
Bedeutung zu, weswegen im Rahmen dieses<br />
Buches die Auswahlkriterien vor allem sind:<br />
• Anzahl der für den Informationsaustausch<br />
benötigten Pins<br />
• für die Aufgabenstellung benötigte Zusatzfunktionen<br />
(Analog zu Digitalwandler oder<br />
programmparallele PWM-Signalerzeugung)<br />
• interner Taktgenerator<br />
• Überschreibbarkeit („C"- oder „F"-Typ)<br />
• Preis<br />
Nun wollen wir uns die im Rahmen diese<br />
Buches verwendeten <strong>PIC</strong>-Typen noch etwas<br />
näher ansehen.<br />
1.3.1 <strong>PIC</strong>-12C509A<br />
Der Mikroprozessor <strong>PIC</strong>-12C509A wird für<br />
die Projekte BLINK, PENTA-S, RADAR,<br />
ZUND, DUOSIG <strong>und</strong> MONONAUT verwendet.<br />
Es ist ein billiger uP mit nur acht Pins <strong>und</strong><br />
damit ideal geeignet für kleine Schaltungen.<br />
Der 1k-Speicher erlaubt die Programmierung<br />
von etwa 1.000 Befehlen <strong>und</strong> auch die Zahl<br />
der frei zur Verfügung stehenden Register ist<br />
mit 25 + 16 (in Bank 1) für die meisten Anwendungen<br />
ausreichend.<br />
Der <strong>PIC</strong>-12C509A hat einen Ein-/Ausgabe-<br />
Port (GPIO) von maximal 6 Bit (bei internem<br />
Taktgenerator). Fünf der sechs Bit sind bidirektional,<br />
d.h., sie können programmseitig sowohl<br />
als Input als auch als Output definiert werden.
Pin4 (GPIO,3) ist immer ein Input, dafür aber<br />
vom Typ Schmitt-Trigger (d.h., es gibt eine<br />
Hysterese zwischen Low <strong>und</strong> High-Level). Anstelle<br />
eines allgemeinen Ein-/Ausgabe-Ports (I/<br />
O-Port) kann GPIO,2 auch als Eingabe für einen<br />
externen Timer-Zeittakt (TOCKI) <strong>und</strong><br />
GPIO,3 als Master-RESET (MCLR, aktiv low)<br />
programmiert werden; während der Chip-Programmierung<br />
dient GPIO,3 als Eingabe für die<br />
Programmierspannung (VPP) von 12 V.<br />
An OSC1 wird gegebenenfalls der R-C-<br />
Oszillator oder der externe Takt, an OSC1<br />
<strong>und</strong> OSC2 der Quarzoszillator angeschlossen;<br />
die entsprechenden Pins stehen dann als<br />
allgemeine I/O-Ports natürlich nicht mehr zur<br />
Verfügung.<br />
Ein in vielen Anwendungen großer Vorteil<br />
des <strong>PIC</strong>-12C509A ist sein interner, vom Hersteller<br />
auf 4 MHz kalibrierter Taktfrequenzoszillator,<br />
der die Schaltung ohne externen Quarz<br />
oder R-C-Netzwerk auskommen lässt <strong>und</strong><br />
darüber hinaus GPIO,4 <strong>und</strong> GPIO,5 als allgemeine<br />
I/O-Ports freigibt.<br />
<strong>PIC</strong>-12C509A sind nicht interruptfähig.<br />
Als „C"-Typ ist er im billigen Plastikgehäuse<br />
nur einmal programmierbar, weswegen<br />
ein löschbarer „JW"-IC eingesetzt werden sollte,<br />
bis das entsprechende Programm zur absoluten<br />
Zufriedenheit läuft. Vor der ersten Löschung<br />
muss man aber die interne Taktkalibrierung<br />
aufschreiben (es gibt einen entsprechenden<br />
Lesebefehl im Windows-Icon des<br />
MPLAB-IDE-Programms), da auch sie bei der<br />
Löschung der IC verloren geht; der festgehaltene<br />
Wert wird dann bei jeder weiteren Programmierung<br />
programmseitig in W <strong>und</strong> anschließend<br />
in das Register OSCCAL geladen.<br />
Die Pin-kompatible Flash-Version zum<br />
12C509A heißt 12F629.<br />
1.3.2 <strong>PIC</strong>-12C672<br />
Der Mikroprozessor <strong>PIC</strong>-12C672 wird für die<br />
Projekte NAVIGUARD <strong>und</strong> AUTONAUT verwendet.<br />
Auch er ist ein uP mit nur acht Pins<br />
<strong>und</strong> gleicht in seinen allgemeinen Eigenschaften<br />
dem oben beschriebenen <strong>PIC</strong>-12C509A,<br />
insbesondere mit seinem vom Hersteller kalibrierten<br />
internen Taktgeber von 4 MHz <strong>und</strong> seinem<br />
I/O-Port (GPIO) von maximal 6 Bit, wobei<br />
GPIO,3 auch hier ein reiner Eingabe-Port<br />
ist. Im Unterschied zu 12C509A kann er aber<br />
mehr <strong>und</strong> ist etwas teurer.<br />
Da sind zunächst der 2k-Programmspeicher<br />
für über 2.000 Programmzeilen <strong>und</strong> die<br />
128 frei zur Verfügung stehenden Register.<br />
Sein für uns wesentlicher Vorzug ist allerdings<br />
der integrierte Analog-Digital-Wandler (ADW)<br />
mit 8 Bit Auflösung, der hintereinander (Multiplexverfahren)<br />
die an bis zu vier Eingangspins<br />
(ANO bis AN3) anliegenden Spannungen<br />
mit der <strong>PIC</strong>-Versorgungsspannung bzw.<br />
einer an Pin6 vorzugebenden Referenzspannung<br />
Vref vergleichen <strong>und</strong> in eine Zahl zwischen<br />
0 <strong>und</strong> 255 umwandeln kann.<br />
Bei allen Problemstellungen also, wo Spannungen<br />
gemessen werden sollen, z.B. in Spannungsüberwachungen<br />
oder beim Abfragen von<br />
Poti-Stellungen, werden im Folgenden uP-Typen<br />
mit ADW zum Einsatz kommen.<br />
Der <strong>PIC</strong>-12C672 ist mit vier verschiedenen<br />
Quellen interruptfähig, u.a. mit einer externen<br />
Quelle an Pin6 (INT).<br />
Die Pin-kompatible Flash-Version zum<br />
12C672 heißt 12F675.<br />
1.3.3 <strong>PIC</strong>-16C505<br />
Der Mikroprozessor <strong>PIC</strong>-16C505 wird für die<br />
Projekte RADZUND, MULTTNAUT, DCNAUT<br />
17
<strong>und</strong> NVDEKO verwendet. Er ist ein preiswerter<br />
uP im DIP-14-Gehäuse, der einen internen, vom<br />
Hersteller auf 4 MHz kalibrierten RC-Oszillator<br />
besitzt <strong>und</strong> daher in unseren Programmen ohne<br />
externe Oszillatorschaltung verwendet wird.<br />
Der lk-Speicher erlaubt die Programmierung<br />
von etwa 1.000 Befehlen, wozu 24 +<br />
3x16 Register (in vier Bänken) zur freien Verfügung<br />
stehen. Der <strong>PIC</strong>-16C505 hat zwei I/O-<br />
Ports (PORTB <strong>und</strong> PORTC) von je 6 Bit. Elf<br />
dieser PORT-Pins sind bidirektional, d.h. als<br />
Ein- oder Ausgabe programmierbar, Pin4<br />
(PORTB,3) ist nur für die Eingabe zu verwenden,<br />
dafür aber vom Typ Schmitt-Trigger, also<br />
mit störungsunempfindlicherer Hysterese.<br />
Der <strong>PIC</strong>-16C505 ist nicht interruptfähig.<br />
Bezüglich „OTP"- bzw. ,JW"-Versionen<br />
sowie Taktkalibrierung gelten auch hier die<br />
schon beim 12C509A bzw. 12C672 gemachten<br />
Anmerkungen.<br />
Die Pin-kompatible Flash-Version zum<br />
16C505 heißt 16F630.<br />
1.3.4 <strong>PIC</strong>-16C71<br />
Der Mikroprozessor <strong>PIC</strong>-16C71 wird nur für<br />
das Projekt S2PWM verwendet. Er ist ein uP<br />
im DIP-18-Gehäuse <strong>und</strong> sein lk-Speicher erlaubt<br />
die Programmierung von etwa 1.000 Befehlen,<br />
wozu 36 Register zur freien Verfügung<br />
stehen.<br />
18<br />
Der <strong>PIC</strong>-16C71 hat zwei I/O-Ports (POR<br />
TA <strong>und</strong> PORTB) mit 5 respektive 8 Bit, die<br />
alle bidirektional, d.h. als Ein- oder Ausgabe<br />
programmierbar sind. Pin3 (PORTA,4) ist dabei<br />
vom Typ Schmitt-Trigger, also mit störungsfester<br />
Hysterese, wenn er als Input programmiert<br />
ist.<br />
Ein Vorteil des <strong>PIC</strong>-16C71 gegenüber z.B.<br />
dem <strong>PIC</strong>-16C505 ist der integrierte ADW mit<br />
8 Bit Auflösung. Dieser kann hintereinander<br />
an bis zu vier Eingangspins (AN0 bis AN3)<br />
anliegende Spannungen mit der <strong>PIC</strong>-Versorgungsspannung<br />
bzw. einer an Pin2 vorzugebenden<br />
Referenzspannung Vref vergleichen<br />
<strong>und</strong> in eine Zahl zwischen 0 <strong>und</strong> 255 umwandeln.<br />
Welche der Pins von PORTA analog <strong>und</strong><br />
welche digital, d.h. gewöhnliche I/O-Pins sind,<br />
entscheidet das Programm-Codewort AD-<br />
CON1, ebenso über die Spannungsreferenz<br />
(VDD oder Vref).<br />
Für unsere Anwendung eher nachteilig ist<br />
das Nichtvorhandensein eines internen Taktgenerators,<br />
der daher mittels externer Beschaltung<br />
(RC-Netzwerk oder Quarzoszillator) erzeugt<br />
werden muss. Der <strong>PIC</strong>-16C71 ist interruptfähig<br />
mit vier Quellen.<br />
1.3.5 <strong>PIC</strong>-16F872<br />
Der Mikroprozessor <strong>PIC</strong>-16F872 wird für die<br />
Projekte MODCON-S, MODCON-P <strong>und</strong>
NVENKO verwendet. Er ist ein uP im DJP-28-<br />
Gehäuse. Sein 2k-Speicher erlaubt die Programmierung<br />
von etwa 2.000 Befehlen, wozu 128<br />
Register in vier Speicherbänken zur Verfügung<br />
stehen. Darüber hinaus ist noch ein EEPROM<br />
für 64 Speicherplätze vorhanden, in dem Daten<br />
gespeichert werden können, die auch nach Ab<strong>schalten</strong><br />
des uP nicht verloren gehen. Der Maschinentakt<br />
muss mittels externer Beschattung,<br />
am besten mit Quarz, erzeugt werden.<br />
Als „F"-Typ ist er elektrisch überschreibbar,<br />
man benötigt also keine teuren JW-Typen.<br />
Der <strong>PIC</strong>-16F872 verfügt über drei bidirektionale<br />
I/O-Ports (PORTA, PORTB <strong>und</strong><br />
PORTC) mit 6 (PORTA) respektive 8 Bits<br />
(PORTB, PORTC). Pin6 (PORTA,4) <strong>und</strong> alle<br />
Pins des PORTC sind dabei vom Typ Schmitt-<br />
Trigger, also mit störungsfester Hysterese, wenn<br />
sie als Input programmiert sind.<br />
<strong>PIC</strong>-16F872 hat eine Reihe von Zusatzfunktionen,<br />
von denen hier nur die in unseren<br />
Anwendungen interessierenden erwähnt werden<br />
sollen:<br />
• drei unabhängige Timer (TMR0,TMR1 <strong>und</strong><br />
TMR2), davon TMR1 mit einer Größe von<br />
16 Bit<br />
• ein PWM-Modul (Pulsweiten-Modulation),<br />
das parallel dem Programmablauf unter Ver<br />
wendung von TMR2 ein PWM-Signal mit<br />
vorgebbarer Frequenz <strong>und</strong> variablen Duty<br />
Cycles erzeugt (Ausgang CCP1, Pin 13)<br />
• einen Analog-digital-Wandler (ADW) mit<br />
10-Bit-Auflösung, mit dem maximal fünf<br />
Analogkanäle des PORTA (ANO bis AN4)<br />
bezogen auf VDD oder Vref digitalisiert werden<br />
können<br />
• einen synchronen seriellen Port (PORTC)<br />
Wegen der vielen Spezialfunktionen können<br />
auch bei diesem uP viele allgemeine I/O-<br />
Port-Pins u.U. spezielle Aufgaben haben, die<br />
mit Kürzeln an den entsprechenden Pins angegeben<br />
sind. Da die meisten dieser Spezialfunktionen<br />
im Rahmen dieses Buches keine Rolle<br />
spielen, wird hier nicht weiter auf diese Kürzel<br />
eingegangen, sondern auf das entsprechende<br />
Datenblatt verwiesen.<br />
Der <strong>PIC</strong>-16F872 ist interruptfähig mit<br />
insgesamt zehn verschiedenen Quellen.<br />
1.3.6 <strong>PIC</strong>-16F876<br />
Der Mikroprozessor <strong>PIC</strong>-16F876 wird nur für<br />
das Projekt MODCON-D verwendet. Wie der<br />
16F872 ist er ein elektrisch überschreibbarer<br />
uP im DIP-28-Gehäuse <strong>und</strong> mit ihm auch in<br />
der Außenbeschaltung identisch. Gewachsen<br />
ist allerdings die Speichergröße auf 8k <strong>und</strong> die<br />
Registerzahl auf 368 Register im RAM <strong>und</strong><br />
256 Speicherplätze im nichtflüchtigen EE<br />
PROM. Ein weiterer Unterschied zum <strong>PIC</strong>-<br />
16F872 ist, dass neben dem 10-Bit-ADW <strong>und</strong><br />
den drei Timern jetzt zwei vom Programmablauf<br />
unabhängige PWM-Generatoren (Pulsweiten-Modulation)<br />
vorhanden sind. Sie laufen<br />
zwar mit der gleichen Pulsfrequenz, ihre Duty<br />
Cycles können aber unabhängig voneinander<br />
programmiert werden. Diese Eigenschaft machte<br />
seine Wahl für den Doppeldrehzahlsteller<br />
MODCON-D notwendig, wo die Back- <strong>und</strong><br />
Steuerbordmotoren eines Modells in Abhängigkeit<br />
von der Lenkung von zwei unabhängigen<br />
PWM-Signalen gesteuert werden können.<br />
19
Auch beim <strong>PIC</strong>- 16F876 muss der Takt mittels<br />
externer Beschaltung, am besten mit Quarz,<br />
erzeugt werden. Er ist interruptfähig mit<br />
insgesamt zehn verschiedenen Quellen.<br />
1.4 Notwendige<br />
Gr<strong>und</strong>ausstattung<br />
Mikroprozessoren arbeiten mit einem Programm,<br />
das in elektronisch lesbarer Form geschrieben,<br />
in eine vom <strong>PIC</strong>-uP verarbeitbare<br />
Liste übersetzt (compiliert) <strong>und</strong> schließlich in<br />
den Chip geladen werden muss. Dazu braucht<br />
man als Gr<strong>und</strong>ausrüstung:<br />
1. Personal Computer (PC)<br />
Auf dem PC muss Windows 95 (oder höher)<br />
laufen mit einem freien Speicherplatz von 32<br />
MB <strong>und</strong> freiem Harddiskbereich von 45 MB.<br />
Er muss über einen CD-Leser <strong>und</strong> eine RS-<br />
232-Schnittstelle (Druckerausgang) verfügen,<br />
an die das uP-Programmiergerät angeschlossen<br />
werden kann, braucht aber ansonsten nicht<br />
allzu leistungsfähig zu sein.<br />
2. Programmiersoftware (MPLAP-IDE)<br />
Das zur Programmerzeugung <strong>und</strong> -Verwaltung<br />
von 8-Bit-<strong>PIC</strong>-uP-Programmen benötige Soft<br />
20<br />
warepaket heißt MPLAB-IDE <strong>und</strong> wird von<br />
Microchip im Internet kostenlos zur Verfügung<br />
gestellt (www.microchip.com). Es beinhaltet<br />
eine Projektverwaltung der verschiedenen<br />
Programme, einen Editor zum Schreiben<br />
oder Ändern einzelner Programme, das eigentliche<br />
Übersetzungsprogramm (MPASM) sowie<br />
eine umfangreiche Simulationssoftware<br />
(MPLAM-SIM), mit der man das richtige Funktionieren<br />
eines <strong>PIC</strong>-Programms auf dem PC<br />
simulieren kann. So kann man mit MPLAB-<br />
SIM den Ablauf des Programms schrittweise<br />
verfolgen <strong>und</strong> sich den jeweiligen Wert der<br />
verschiedenen Register anzeigen lassen. Selbst<br />
der Zustand von Eingabe-Pins kann simuliert<br />
<strong>und</strong> die Antwort des uP darauf beobachtet werden,<br />
was bei der Fehlersuche sehr hilfreich ist.<br />
3. Programmiergerät mit Software<br />
Schließlich benötigt man noch ein Programmiergerät,<br />
mit dem man die übersetzten Programme<br />
physikalisch in einen Mikroprozessor laden kann.<br />
Da man in der Regel Mikroprozessoren unterschiedlicher<br />
Pin-Zahl verwendet, ist ein Programmiergerät<br />
mit variablem Sockel zu bevorzugen.<br />
Programmiergerät, Softwarepaket MPLAB-<br />
IDE, eine reichliche Dokumentation inklusive<br />
Datenblätter der verschiedenen <strong>PIC</strong>-Typen <strong>und</strong><br />
Applikationsbeispiele auf CD-ROMs (im Gr<strong>und</strong>e<br />
die gesamte auf der Homepage von Microchip<br />
zu findende Information) werden von Microchip<br />
zusammen als „<strong>PIC</strong>START PLUS Development<br />
Kif" angeboten. Damit alle in Weiteren<br />
vorgeschlagenen Programme verwendet<br />
werden können, sollte man darauf achten, dass<br />
MPLAB-IDE mindestens die Version V-5.00<br />
<strong>und</strong> das Programmiergeräts mindestens die Version<br />
V-2.30 ist.<br />
4. EPROM-Löschgerät<br />
Für die JW-Typen der C-Serie benötigt man<br />
auch noch ein Löschgerät. Dieses besitzt eine<br />
spezielle UV-Lampe, mit der die ICs in etwa<br />
zehn Minuten gelöscht werden können; mit<br />
normalen Lampen geht es überhaupt nicht, im<br />
prallen Sonnenlicht dauert es Wochen.
2 Die Programmierung<br />
2.1 Überblick<br />
Ein <strong>PIC</strong>-Maschinenprogramm (_.hex in Microchip-Terminologie)<br />
besteht aus Zeilen vierstelliger<br />
Hexadezimalzahlen, wobei jede dieser<br />
Zahlen in codierter Form einen Maschinenbefehl,<br />
die Adresse des Operanden, auf den der<br />
Befehl angewendet werden soll, <strong>und</strong> dessen<br />
aktuellen Wert enthält. Diese Zahlenreihen sind<br />
natürlich sehr unübersichtlich <strong>und</strong> schwierig<br />
zu programmieren, weswegen Microchip eine<br />
<strong>einfach</strong>e Sprache entwickelt hat, die die einzelnen<br />
Befehle nebst den zugehörigen Operanden<br />
mit verständlichen Abkürzungen benennt<br />
(Operator-Mnemonic <strong>und</strong> Operand). Viel mehr<br />
ist die so genannte Assemblersprache eigentlich<br />
nicht. Für die gewöhnlich ungleich längeren<br />
Großrechnerprogramme ist man daher<br />
schon Mitte der 60er-Jahre zu höheren Programmiersprachen<br />
wie BASIC, ALGOL,<br />
FORTRAN, PASCAL oder C übergegangen,<br />
wo eine einzige Instruktionen u.U. für viele<br />
Zeilen Assemblerbefehle stehen kann; z.B.<br />
schreibt man anstelle eines Vielzeilen-Assemblerprogramms<br />
für eine Multiplikation dann<br />
<strong>einfach</strong> nur „*". Höheren Programmiersprachen<br />
wie C sind inzwischen auch für <strong>PIC</strong>-<br />
Mikroprozessoren auf dem Markt <strong>und</strong> auch in<br />
MPLAB-IDE ist ein C-Compiler mit Namen<br />
<strong>PIC</strong>C verfügbar. Sie übersetzen das in der höheren<br />
Sprache geschriebene Programm in den<br />
Maschinencode <strong>und</strong> erleichtern so bei vielen<br />
Anwendungen die Programmierarbeit beträcht<br />
lich. Trotzdem bevorzuge ich die direkte Assemblerprogrammierung,<br />
weil sie die weitaus<br />
effektivsten Codes ergibt. Insbesondere Applikationen,<br />
wo es auf die genaue Zahl der verbrauchten<br />
Maschinenzyklen ankommt (was bei<br />
einigen der weiter unten beschriebenen Programme<br />
der Fall ist), lassen sich ohne Auszählen<br />
der Zykluszeiten (bzw. Assemblerzeilen)<br />
kaum realisieren.<br />
Der besseren Verständlichkeit der im dritten<br />
Teil des Buches angegebenen Programme<br />
wegen wollen wir jetzt auf die Programmierung<br />
in Assembler etwas näher eingehen <strong>und</strong><br />
nach Erläuterung des Befehlssatzes ohne Anspruch<br />
auf Vollständigkeit einige Tricks beschreiben,<br />
die in den Programmen häufiger<br />
verwendet werden, die aber auch das Arbeiten<br />
an eigenen Projekten anregen sollen.<br />
2.2 Allgemeiner<br />
Programmaufbau<br />
Ein für die Übersetzung mit MPASM geeignetes<br />
Programm muss einer festgelegten Form<br />
genügen. Der Schrifttyp (Klein-/Großbuchstaben)<br />
ist ohne Belang, doch habe ich es mir, der<br />
besseren Lesbarkeit der Programme wegen, zur<br />
Gewohnheit gemacht, Marken (Label) <strong>und</strong> Register<br />
mit Großbuchstaben, Operatoren (Instruktionen)<br />
des Befehlssatz <strong>und</strong> Konstanten<br />
(vordefinierte Zahlenwerte) dagegen kleinzuschreiben.<br />
Von MPASM ignorierte Kommen-<br />
21
tare stehen rechts eines Semikolons <strong>und</strong> folgen<br />
den Groß-klein-Rechtschreibregeln.<br />
Es ist gute Programmierpraxis, öfter wiederkehrende<br />
Programmteile zu „Subroutinen"<br />
(Unterprogrammen) zusammenzufassen <strong>und</strong><br />
dann nur an den tatsächlich benötigten Stellen<br />
aufzurufen. Dies spart nicht nur eine Menge<br />
Speicherplatz (der Programmteil wird ja nur<br />
einmal geschrieben, aber u.U. oft verwendet),<br />
sondern erhöht auch die Übersichtlichkeit. Da<br />
bei älteren <strong>PIC</strong>-Typen (z.B. 12C509A <strong>und</strong><br />
16C505) die Adressenspeicherung im Subroutinenstack<br />
u.U. Probleme machen kann (siehe<br />
Abschnitt 2.4.5.1), sind Subroutinen in Programmen<br />
für diese Mikroprozessoren in den<br />
vorderen Programmzeilen anzuordnen. Dies ist<br />
bei neueren Typen wohl nicht mehr nötig, aus<br />
22<br />
; Projekt Blink<br />
; ><br />
; VDD -I I- VSS<br />
; Das Programm dient als Muster für I I<br />
; den gr<strong>und</strong>satzlichen Programmaufbau. -I I- LED<br />
; Es ist funktionsfähig <strong>und</strong> lauft als I I<br />
; Blinksignal-Generator vorgebbarer, -I I-<br />
; beliebiger Sequenz für eine an Pin7 I I<br />
; (GPIO.O) angeschlossene LED -I I-<br />
LIST P=12C509A<br />
__config B'01010' ; MCRL=intern, CP=off, WDT=off,<br />
; interner RC-Oszillator<br />
__MAXRAM H'3F'<br />
IFNDEF __12C509A<br />
MESSG "Processor-header file mismatch. Verify selected processor."<br />
ENDIF<br />
; Konstanten Definition<br />
w EQU H'00' ; Ziel-Bits<br />
f EQU H'01'<br />
c EQU H'00' ; Status-Bit<br />
z EQU H'02'<br />
optval EQU B'11000111' ; Option Register : kein wake up,<br />
; T0CS=0 (intern). TOSE=0. PSA=0 (RTCC),<br />
; PS2,PS1,PS0=1,1,1 (Vorteiler=256)<br />
; > Timer-Schritt=O.256ms bei Takt 4 MHz<br />
trisval EQU B'11101000' ; Pin-Definition : bis auf Pin4 (nicht möglich)<br />
; sind alles Ausgange.<br />
frequ EQU D'04' ; Blinkfrequenz (=1/(frequ * 0.06553) in Hz<br />
; mit frequ=4 also ~4 Hz für eine Einheit<br />
; Register Files<br />
TMRO EQU H'01'<br />
STATUS EQU H'03'<br />
OSCCAL EQU H'05' ; Kalibrierung des internen Takts auf 4 MHz<br />
GPIO EQU H'06' ; Port<br />
FRQ EQU H'07' ; Blinkfrequenz-bestimmende Laufvariable<br />
BLK1 EQU H'08' ; Blinksequenz -1-<br />
BLK2 EQU H'09' ; " -2-<br />
BLK3 EQU H'OA' ; " -3-<br />
BLK4 EQU H'OB' ; " -4-<br />
org 0 ; Start des Programm <strong>und</strong> Initialisierung<br />
0 movlw H'AO' ; nur für JW-Chip (Wert vor 1. Loschung)<br />
1 movwf OSCCAL ; Laden der Oszillator-Calibrierung<br />
2 clrwdt<br />
3 goto START<br />
; subroutine « LEERn » verbraucht "n" Zyklen<br />
4 LEER10 goto LEER8<br />
5 LEER8 goto LEER6<br />
6 LEER6 goto LEER4<br />
7 LEER4 retlw H'00'<br />
; HAUPTPROGRAMM<br />
8 START movlw B'10010101' ; Eingabe der Blinkfrequenz jeweils von<br />
9 movwf BLK1 ; rechts nach links<br />
A movlw B'11100011'<br />
B movwf BLK2<br />
C movlw B'00111000'<br />
D movwf BLK3<br />
E movlw B'00010101'<br />
F movwf BLK4<br />
10 movlw trisval ; Definition des Ports GPIO<br />
11 TRIS GPIO<br />
12 bcf GPIO.O ; LED aus<strong>schalten</strong><br />
13 movlw frequ<br />
14 movwf FRQ ; FRQ - frequ<br />
15 LOOP movlw trisval ; Definition des Ports GPIO<br />
16 TRIS GPIO<br />
17 movlw H'01'<br />
18 movwf TMR0 ; TMR0 = 1<br />
19 movlw optval ; <strong>und</strong> Starten des Timers<br />
1A OPTION<br />
1B WAIT call LEER10 ; (nicht unbedingt notig, nur Demonstration<br />
1C movf TMRO,w ; eines Subroutinenaufrufs)<br />
1D btfss STATUS,z ; Test von TMRO auf Ueberlauf<br />
1F decfsz FRQ.f<br />
20 goto LOOP<br />
21 btfss BLK1.0 ; Laden des untersten Bits von BLK1 in GPIO.O<br />
22 bcf GPIO.O<br />
23 btfsc BLK1.0<br />
24 bsf GPIO.O<br />
25 bcf STATUS.c<br />
26 btfsc BLK1.0<br />
27 bsf STATUS,c<br />
28 rrf BLK4,f ; Rechtsverschiebung der Blinkfrequenz<br />
29 rrf BLK3,f ; wobei nulltes Bit von BLK1 via STATUS,c in<br />
2A rrf BLK2,f ; höchstes Bit von BLK4 geschoben wird<br />
2B rrf BLKl,f<br />
2C movlw frequ<br />
2D movwf FRQ ; FRQ = frequ<br />
2E goto LOOP<br />
END<br />
Gründen der Übersichtlichkeit bin ich aber bei<br />
allen in diesem Buch aufgeführten Programmen<br />
bei dieser Praxis geblieben.<br />
Mit dem Musterprogramm BLINK.asm soll<br />
nun die allgemeine Form eines <strong>PIC</strong>-Programms<br />
erläutert werden inklusive dem Aufruf einer<br />
Subroutine (die hier eigentlich nicht nötig ist),<br />
dem Einsatz eines Timers <strong>und</strong> der Behandlung<br />
des Ports. Der funktionstüchtige BLINK ist<br />
ein Blinkgenerator (<strong>PIC</strong>-12C509) für eine an<br />
Pin7 (GPIO,0) über einen Widerstand von 180<br />
Ohm angeschlossene LED mit beliebig vorgebbarer<br />
Blinksequenz, was mit konventioneller<br />
Elektronik hergestellt einen großen Aufwand<br />
bedeutet würde. Auch die Blinkfrequenz<br />
pro Sequenzeinheit kann mit frequ vorgegeben<br />
werden, im Muster etwa 4 Hz.
Das Programm beginnt mit dem Programmkopf,<br />
der durch das LIST-Statement definiert<br />
ist. Es folgt dann der Definitionsblock für Konstanten<br />
<strong>und</strong> Register. Das Nullsetzen des Zeilenzählers<br />
durch die Direktive org zeigt auf<br />
den Beginn des Instruktionsteils, der mit END<br />
abgeschlossen wird. Im Listing sind den Instruktionszeilen<br />
jeweils die Zeilennummern<br />
(Hexadezimal) vorangestellt.<br />
2.2.1 Der Programmkopf<br />
Der Programmkopf beginnt, wie schon gesagt,<br />
mit der Direktive LIST. Alles davor ist Kommentar,<br />
der in meinen Programmen jeweils<br />
eine kurze Programmbeschreibung nebst einer<br />
Pin-Belegung enthält. Mit dem LIST-Statement<br />
wird der <strong>PIC</strong>-Typ festgelegt (Parameter „P"),<br />
für den das Programm geschrieben wurde. Mit<br />
weiteren Parametern kann, abweichend von der<br />
Norm, die Form des Listing <strong>und</strong> des Maschinenprogramms<br />
beeinflusst werden (siehe<br />
gegebenenfalls das MAPSM-Manual).<br />
Eine wichtige Größe ist das Konfigurationswort<br />
(__config), das für die verschiedenen <strong>PIC</strong>-<br />
Typen unterschiedlich lang ist <strong>und</strong> dem jeweiligen<br />
Datenblatt entnommen werden muss. Es<br />
bestimmt den Oszillatortyp, erlaubt die Aktivierung<br />
des Watch Dog Timers (siehe Abschnitt<br />
2.4.7.1) <strong>und</strong> ermöglicht den Leseschutz des Programms.<br />
Das Konfigurationswort kann auch erst<br />
beim Programmieren des Mikroprozessors mit<br />
dem Programmierprogramm <strong>PIC</strong>START interaktiv<br />
eingegeben werden.<br />
__MAXRAM- (<strong>und</strong> _BADRAM-)Direktiven<br />
schließen nicht implementierte Registerplätze<br />
aus <strong>und</strong> warnen den Programmierer bei<br />
der Übersetzung seines Programms, wenn er<br />
die nicht vorhandenen Registerplätze<br />
versehentlich zu benutzen versucht.<br />
Dasselbe bewirkt die IFNDEF-Direktive<br />
bezüglich des <strong>PIC</strong>-Typs, in den das Programm<br />
geladen werden soll.<br />
Der gesamte Programmkopf ist Teil eines<br />
Files pic.inc (wobei „pic" für den verwendeten<br />
<strong>PIC</strong>-Typ steht), das im MPLAB-DIE-Softwarepaket<br />
zu finden ist <strong>und</strong> von dort kopiert werden<br />
kann.<br />
2.2.2 Der Definitionsblock<br />
2.2.2.1 Konstanten (Literais)<br />
In einem Programm werden gewöhnlich viele<br />
konstante Zahlen („literals" in Microchip-Bezeichnung)<br />
verwendet, die mit Variablen verknüpft<br />
schlussendlich zu den vom Mikroprozessor<br />
erwarteten Ergebnissen führen. Man<br />
kann diese Zahlen jeweils am Ort ihrer Verwendung<br />
als 8-Bit-Zahl ins Programm einführen.<br />
Da viele der Konstanten aber eine konkrete<br />
Bedeutung haben <strong>und</strong> im Programm u.U. an<br />
mehreren Orten vorkommen, bevorzugt man<br />
ihre Beschreibung mit Namen, die dann vor<br />
dem Beginn des Instruktionsteils im Konstantendefinitionsblock<br />
mittels der Direktive EQU<br />
als 8-Bit-Zahl definiert werden müssen. Dort<br />
kann man sie gegebenenfalls auch leichter ändern<br />
als an verschiedenen Orten im Programm.<br />
Für die Zahlen werden in meinen Programmen<br />
in der Regel Hexadezimalzahlen (H'..') verwendet,<br />
wenn es nicht, wie für die Definition<br />
von Ports oder bei Maskierungen, auf die Bit-<br />
Struktur des Wortes ankommt (B'..'). Es sind<br />
aber auch Dezimalzahlen (D'..') möglich, die<br />
sich aus den Hexadezimalzahlen durch Multiplikation<br />
der ersten Ziffer mit 16 plus Addition<br />
der letzten Ziffer ergeben; bei Hexadezimalzahlen<br />
gilt A = 10, B = 11 bis F = 15 (H'FE' ist<br />
damit D'254'= 15 x 16+14).<br />
Erwähnt werden soll hier auch die Festlegung<br />
von Systembits am Beginn des Konstantenblocks.<br />
Da sind zunächst die beiden<br />
Zielbits w <strong>und</strong> f, die bei einigen der weiter<br />
unten beschriebenen Instruktionen auf lesbare<br />
Weise die Destination festlegen, d.h., ob<br />
das Ergebnis der Operation im Arbeitsregister<br />
W oder in einem Register F landen soll.<br />
Weiter werden hier auch die Werte der verschiedenen<br />
Bits des STATUS-Registers so<br />
23
definiert, dass im Programm später nur noch<br />
sinngebende, die Lesbarkeit des Programms<br />
verbessernde Buchstaben wie z, c, rp0 oder<br />
rpl geschrieben werden müssen.<br />
2.2.2.2 Register<br />
Wie schon bei der Beschreibung der einzelnen<br />
<strong>PIC</strong>-Typen erwähnt, verfügen die verschiedenen<br />
<strong>PIC</strong>-Mikroprozessoren im RAM über eine<br />
wechselnde Zahl von Variablen, die vom Hersteller<br />
Microchip mit „Register-Files" (abgekürzt<br />
„F") bezeichnet werden <strong>und</strong> die im RAM<br />
auf maximal vier Datenblöcke („bank") mit<br />
maximal je 127 Register aufgeteilt sind. Jedes<br />
der im Weiteren <strong>einfach</strong> als „Register" bezeichneten<br />
Register-Files hat eine Größe von<br />
8 Bit, d.h. entspricht einer Zahl zwischen 0<br />
<strong>und</strong> 255. uP-intern werden die Register fortlaufend<br />
durchnummeriert, was für die Lesbarkeit<br />
eines Programms kaum zweckmäßig wäre.<br />
Es werden deshalb Buchstabenkombinationen<br />
bevorzugt, denen dann im Registerdefinitionsblock<br />
mittels der EQU-Direktive Speicherplatznummern<br />
zugewiesen werden.<br />
Ein Teil der Speicherplatznummern ist<br />
durch Microchip allerdings bereits für spezielle<br />
Register reserviert. Auf die Bedeutung einiger<br />
besonders wichtiger Register wollen wir<br />
deshalb noch kurz eingehen.<br />
• Das Arbeitsregister W<br />
Das Arbeitsregister W (working register) ist<br />
eines der wichtigsten <strong>PIC</strong>-Register, wird doch<br />
bis auf wenige Ausnahmen fast die gesamte<br />
Rechnerei über dieses Register abgewickelt.<br />
So laufen z.B. selbst Wertzuweisungen wie<br />
F = 2 mit 2 —>W —>F über dieses Register.<br />
• Der aktuelle Wert<br />
des internen Timers TMRO<br />
TMRO registriert das Resultat eines vom Programmablauf<br />
unabhängigen Zählers, der in fast<br />
allen Programmen zur Anwendung kommt<br />
(mehr im Abschnitt 2.4.6).<br />
24<br />
• Der Programmzeiger PCL<br />
Der Programmzeiger PC ist ein 14-Bit-Register,<br />
dessen Wert jeweils der Programmzeile entspricht,<br />
die gerade in Arbeit ist, <strong>und</strong> wird vom<br />
Maschinentakt hochgezählt. Die unteren 8 PC-<br />
Bits, PCL genannt, können wie ein gewöhnliches<br />
Register, Ziel einer arithmetischen Operation<br />
sein, was dann zu einem Programmsprung<br />
in die resultierende Zeile führt (siehe Abschnitt<br />
2.4.2.3). Auf die oberen Bits von PC kann über<br />
das PCLATH-Register zugegriffen werden. Bei<br />
einigen älteren <strong>PIC</strong>-Typen hat PC nur 12 Bits.<br />
• STATUS-Register<br />
STATUS ist ein Flaggenregister, dem in einem<br />
<strong>PIC</strong>-Programm eine dem W-Register vergleichbare<br />
Bedeutung zukommt, werden mit seinen<br />
unteren 5 Bits doch Operationsergebnisse kommentiert<br />
(c, dc, z, pd <strong>und</strong> to Bit) <strong>und</strong> mit den<br />
oberen 3 Bits (rpO, rpl <strong>und</strong> irp) der Zugriff auf<br />
die vier Registerblöcke gesteuert; wir kommen<br />
auf die Bedeutung der wichtigsten Bits in den<br />
Abschnitten 2.3.2,2.4.2 bzw. 2.4.7.1 zurück.<br />
Die Definition der oberen STATUS-Bits ist<br />
bei den einzelnen <strong>PIC</strong>-Typen etwas unterschiedlich.<br />
• FSR-<strong>und</strong> INDF-Register<br />
dienen der indirekten Adressierung (siehe Abschnitt<br />
2.4.4).<br />
• Ein-/Ausgabe-PORT<strong>und</strong><br />
die zugehörigen TRIS-Register<br />
Die IC-Pins (PORT) sind bidirektional <strong>und</strong><br />
können daher bitweise je nach Definition des<br />
entsprechenden Port-Bits sowohl zur Ausgabe<br />
(Bit=0) als auch zur Eingabe (Bit=l) verwendet<br />
werden. Die I/O-Definition selbst erfolgt<br />
durch Laden eines „Definitionswortes" (Konstante,<br />
in meinen Programmen meist trisval<br />
genannt) in das Definitionsregister TRIS_REG<br />
(bei älteren <strong>PIC</strong>-Typen mit dem speziellen Befehl<br />
TRIS). Dazu wird in trisval das dem Port-<br />
Bit äquivalente Bit für einen Output -0- <strong>und</strong><br />
für einen Input -1- gesetzt. Die gelegentliche<br />
Wiederholung der Port-Definition in der Haupt-
schleife eines Programms ist gute Programmierpraxis.<br />
Die mit den IC-Pins verb<strong>und</strong>enen Port-Register<br />
werden programmtechnisch wie gewöhnliche<br />
Register behandelt.<br />
Bei <strong>PIC</strong>-Typen mit integriertem Analog-digital-<br />
Wandler kann am entsprechenden Pin, der dann<br />
als Eingabe definiert sein muss, auch eine analoge<br />
Spannung zwischen null <strong>und</strong> einer Referenzspannung<br />
anliegen (V extern oder VDD). Ob es sich<br />
beim entsprechenden Port-Pin um einen gewöhnlichen<br />
digitalen oder um einen analogen Eingang<br />
handelt, wird mit einem weiteren Code-Wort im<br />
Spezialregister ADCON1 entschieden (Näheres<br />
in den entsprechenden Typendatenblättern).<br />
• OSCCAL-Regjster<br />
Das OSCCAL-Register gibt es nur bei den wenigen<br />
<strong>PIC</strong>-Typen mit internem Oszillator. Es<br />
weist ihm eine Kalibrierung zu, die ihn exakt<br />
auf der Nennfrequenz von 4 MHz arbeiten lässt.<br />
Der von Microchip ermittelte Wert für OSC-<br />
CAL steht bei einem jungfräulichen uP<br />
normalerweise im Arbeitsregister <strong>und</strong> muss dann<br />
in einer der ersten Programmzeilen ins OSC<br />
CAL-Register übertragen werden. Bei JW-Typen<br />
wird W nach der ersten Löschung zuvor mit<br />
der Kalibrierungskonstante geladen.<br />
Es ist noch eine Reihe weiterer, durch Microchip<br />
vordefinierter Register vorhanden, deren<br />
Zahl vom verwendeten <strong>PIC</strong>-Typ <strong>und</strong> dessen Spezialisierung<br />
abhängig ist. Auch alle Spezialregister<br />
sind auf dem schon im Kontex Programmkopf<br />
angesprochenen File pic.inc, aber natürlich<br />
auch in den Datenblättern des jeweiligen Pic-<br />
Typs zu finden. Dort sind auch die einzelnen<br />
Register-Bits definiert, die alle hier zu erwähnen<br />
den Rahmen dieses Abschnitts sprengen würde.<br />
2.2.3 Die Programmzeilen<br />
Der Instruktionsteil eines Programms beginnt,<br />
wie schon erwähnt, mit einer org-Direktive,<br />
die dem Programmzähler (PC) einen Anfangs<br />
wert zuweist, im allgemeinen 0. Dann folgen<br />
die eigentlichen Programmzeilen mit den Maschinenbefehlen,<br />
wobei jede Programmzeile<br />
gr<strong>und</strong>sätzlich aus maximal vier Komponenten,<br />
nämlich einem eventuellen Label, dem Operator<br />
(Mnemonic des Instruktionsbefehls), dem<br />
Operanden <strong>und</strong> einem eventuellen Zeilenkommentar,<br />
besteht.<br />
• LABEL<br />
Er muss in der ersten Spalte beginnen <strong>und</strong> sein<br />
erstes Zeichen muss ein Buchstabe sein. Ein<br />
Label ist nur nötig, wenn die entsprechende<br />
Zeile Ziel einer Sprunganweisung oder die erste<br />
Zeile einer Subroutine ist. In meinen Programmen<br />
werden Label mit Großbuchstaben<br />
geschrieben.<br />
• OPERATOR<br />
steht für einen der 35 Befehle, die im Abschnitt<br />
<strong>PIC</strong>-Befehlssatz näher beschrieben werden.<br />
Er darf frühestens in der zweiten Spalte<br />
einer Zeile beginnen. In meinen Programmen<br />
werden die Operatoren mit Kleinbuchstaben<br />
geschrieben.<br />
• OPERAND<br />
ist die Größe, auf die der mit dem Operator<br />
definierte Befehl angewendet wird. Mehr als<br />
ein Operand (z.B. Ziel d oder Bit b) müssen<br />
durch ein Komma getrennt werden. In meinen<br />
Programmen werden die Operanden je nach<br />
Typ (Register, Label oder Subroutinen-Namen)<br />
groß- <strong>und</strong> Konstanten wie auch Ziele oder Bit-<br />
Indizes kleingeschrieben.<br />
• KOMMENTAR<br />
Kommentare sind Erläuterungen zu den Programmzeilen<br />
<strong>und</strong> beginnen immer mit einem<br />
Semikolon. Alles rechts eines Semikolons gilt<br />
als Kommentar <strong>und</strong> wird vom Übersetzerprogramm<br />
ignoriert. Das gilt auch für eigentliche<br />
Programmzeilen, die man während der Codeentwicklung<br />
oder als Alternative durch ein<br />
Semikolon in der ersten Spalte inaktiv gemacht<br />
hat.<br />
25
Unabhängig davon, ob der Watch Dog Timer<br />
(WDT) im Konfigurationswort eingeschaltet<br />
ist, sollte einer der nächsten Befehle in jedem<br />
Fall ein Nullsetzen des WDT mit der<br />
Direktive clrwdt sein.<br />
Dann wird zum eigentlichen Programmstart<br />
am Label START (er kann auch anders heißen)<br />
gesprungen, da im ersten Programmabschnitt<br />
die Subroutinen gespeichert werden, hier als<br />
Beispiel die Subroutine LEER 10, die zehn Maschinenzyklen<br />
mit Sprüngen verbraucht.<br />
2.3 Der <strong>PIC</strong>-Befehlssatz<br />
2.3.1 Überblick<br />
Der im Weiteren beschriebene zwischen 33<br />
<strong>und</strong> 35 Instruktionen umfassende Befehlssatz<br />
der <strong>PIC</strong>-Mikroprozessor-Familie von Microchip<br />
beinhaltet Sprunganweisungen, Wertzuweisungen,<br />
Addition <strong>und</strong> Subtraktion positiver<br />
ganzer Zahlen, Register-Bit-Verschiebung<br />
nach rechts bzw. links, logische Verknüpfungen<br />
(AND, OR <strong>und</strong> EXOR) <strong>und</strong> das Abfragen,<br />
Setzen oder Löschen einzelner Bits in einem 8-<br />
Bit-Register. Dieser Befehlssatz ist auch Inhalt<br />
der englischsprachigen Datenblätter für die verschiedenen<br />
<strong>PIC</strong>-Typen.<br />
Fast jeder der weiter unten aufgeführten<br />
Maschinenbefehle benötigt zur Ausführung<br />
genau vier Taktschritte, was als ein Maschinenzyklus<br />
bezeichnet wird. Ein Maschinenzyklus<br />
entspricht damit<br />
oder mit den für meine Programme üblichen<br />
4 MHz Taktfrequenz 1 us. Durch Abzählen<br />
der Programmzeilen kann man so auf <strong>einfach</strong>e<br />
Weise die Zeit bestimmen, die der uP für<br />
einen Programmabschnitt braucht, wobei<br />
allerdings zu beachten ist, dass alle Maschinenbefehle,<br />
die einen Zugriff auf den Zeilenzähler<br />
bewirken, also alle direkten <strong>und</strong> indirekten<br />
Sprungbefehle, zwei Maschinenzyklen<br />
26<br />
benötigen. Die Kenntnis, wie viel Zeit der uP<br />
in einen bestimmten Programmabschnitt verbraucht,<br />
ist bei allen Zeit- bzw. Impulslängenmessungen<br />
wichtig. Wenn z.B. eine Impulslänge<br />
ausgemessen werden soll (ein im Rahmen<br />
dieses Buches häufiger vorkommendes<br />
Problem), so kann man in einer Schleife ein<br />
Register so lange hochzählen, bis sich der Pegel<br />
am Eingangspin ändert. Die Impulslänge<br />
ist dann gleich der Zeilenzahl mal dem Zählstand<br />
des Registers mal der Maschinenzykluszeit<br />
(Sprunganweisungen zählen doppelt!).<br />
2.3.2 Der Befehlssatz<br />
in alphabetischer Reihenfolge<br />
Die nachfolgende Liste gibt den ganzen <strong>PIC</strong>-<br />
Befehlssatz in alphabetischer Reihenfolge der<br />
Operator-Mnemonics. Der daneben stehende<br />
Operand bezieht sich auf die Größe, auf die der<br />
Operator angewendet werden kann, also ein<br />
Register F oder eine Konstante k.<br />
In der Spalte Funktion wird die Funktion<br />
beschrieben, die der Operator durchführt. Ist der<br />
erste Buchstabe ein „D", so ist die Destination<br />
entweder das Arbeitsregister W oder das Operandregister,<br />
was durch das Zielbit d (0 oder 1<br />
bzw. w oder f) im Operanden festgelegt wird.<br />
In arithmetischen Operationen wird immer<br />
mit positiven, ganzen 8-Bit-Zahlen gerechnet,<br />
also mit einem Wert zwischen 0 <strong>und</strong> 255. Wird<br />
dieser Wertbereich durch die Operation unteroder<br />
überschritten, so wird <strong>einfach</strong> wieder von<br />
null begonnen oder wie es heißt „über null<br />
gerollt". So ergeben 255 + 4 = 3 <strong>und</strong> 3 - 4 =<br />
255. In beiden Fällen wird allerdings das c-Bit<br />
(Carry-Bit) im STATUS-Register beeinflusst,<br />
sodass man durch dessen Abfrage das „Überrollen"<br />
feststellen kann (in den obigen Beispielen<br />
wird es bei einer Addition gesetzt (= 1) <strong>und</strong><br />
bei einer Subtraktion gestrichen (= 0). Ein anderes<br />
abfragbares STATUS-Bit ist das z-Bit<br />
(Zero-Bit), das jeweils gesetzt wird, wenn das<br />
Ergebnis einer Operation null wird, andernfalls<br />
wird es gestrichen. Das dc-Bit ist ähnlich zum
c-Bit, nur dass die „Überrollgrenze" hier das 4.<br />
Bit ist. Es wird in keinem meiner Programme<br />
verwendet, weshalb im Rahmen dieses Buches<br />
nicht weiter darauf eingegangen werden soll.<br />
Welche der Operationen aus dem Befehls<br />
satz welche Bits von STATUS beeinflussen,<br />
Operator Operand Funktion Status-Bits Bemerkungen<br />
wird in der folgenden Liste ebenfalls angege<br />
ben. Wichtig ist in diesem Zusammenhang,<br />
dass das angegebene Bit durch die entspre<br />
chende Operation immer beeinflusst, also je<br />
nach Gegebenheit <strong>und</strong> Operator entweder ge<br />
setzt oder gestrichen wird.<br />
addlw k W = W + k c,dc,z Addiert 8-Bit-Konstante k zu W. c = 1 wenn W >255<br />
(Überlauf) dc = 1 wenn W >15 z = 1 wenn W = 0<br />
addwf F,d D = W + F c,dc,z Addiert W zu Register F<br />
Einfluss auf c, de <strong>und</strong> z wie in addlw<br />
andlw k W = W .and. k z Bitweise AND-Verknüpfung zwischen W <strong>und</strong><br />
Konstante k. Das Ergebnis für jedes Bit ist nur 1,<br />
wenn sowohl das entsprechende Bit in W als auch<br />
in k 1 ist, sonst null.z = 1 wenn W = 0. Dient vor<br />
allen dem Nullen einzelner Bits in W mittels einer<br />
„Maske" k, wo das zu nullende Bit „0" ist.<br />
andwf F,d D = W .and. F z Bitweise AND-Verknüpfung zwischen W <strong>und</strong><br />
Register F mit zu andlw identischer Logik. Die<br />
„Maske" steht in W.<br />
bcf<br />
bsf<br />
btfsc<br />
F,b<br />
F.b<br />
F,b<br />
F,b = 0 ---<br />
F,b = 1 —<br />
skip bei F,b = 0 —<br />
Setzt b-tes Bit in Register F null(Bit-Zählung von 0<br />
bis 7)<br />
Setzt b-tes Bit in Register F eins<br />
Uberspringt die dem Befehl folgende Zeile, wenn<br />
das b-te Bit in F null ist.<br />
btfss F,b skip bei F,b = 1 — Uberspringt die dem Befehl folgende Zeile, wenn<br />
das b-te Bit in F eins ist.<br />
call name PC+1 ->TOS Aufruf einer Subroutine. Dabei wird der Wert des<br />
Programmzählers (PC) plus 1 (= nächste<br />
Programmzeile) in den Programm-Stack (TOS)<br />
geladen (siehe auch Abschnitt 2.4.5).Dieser Befehl<br />
benötigt zwei Maschinenzyklen.<br />
clrt F F = 0 z = 1 Setzt Reqister F null<br />
clrw W = 0 z = 1 Setzt Arbeitsreqister W null<br />
clrwdt WDT = 0 to,pd Setzt Watch Dog Timer zurück (siehe Abschnitt<br />
2.4.7.1)<br />
comf F,d D = 255 - F z Bildet Complement des Registers F, d.h., jedes<br />
Null-Bit in F wird zu eins <strong>und</strong> umgekehrt, was bei<br />
einem 8-Bit-Register äquivalent zu 255 - F ist.<br />
(z = 1) wenn D = 0<br />
decf F,d D = F-1 z Register F um eins zurücksetzen, z = 1 wenn D = 0<br />
decfsz F,d skip wenn<br />
Register F um eins zurücksetzen <strong>und</strong> folgende<br />
D = F-1 = 0<br />
Zeile überspringen, wenn das Ergebnis D null ist<br />
goto label ->LABEL — Sprung zur Marke LABEL. Dieser Befehl benötigt<br />
zwei Maschinenzyklen.<br />
incf F,d D = F + 1 z Register F um eins erhöhen. z = 1 wenn D = 0<br />
incfsz F,d skip wenn<br />
Register F um eins erhöhen <strong>und</strong> folgende Zeile<br />
D = F+1=0<br />
überspringen, wenn das Ergebnis D null ist<br />
(Überlauf)<br />
iorlw k W = W.OR. k z Bitweise OR-Verknüpfung zwischen W <strong>und</strong><br />
Konstante k. Das Ergebnis für jedes Bit ist 1, wenn<br />
entweder das entsprechende Bit in W oder das in k<br />
= 1 ist, sonst null.z = 1 wenn W = 0<br />
iorwf F,d D = W .OR. F z Bitweise OR-Verknüpfung zwischen W <strong>und</strong><br />
Register F mit zu iorlw identischer Logik<br />
27
movf F,d D = F z z = 1 wenn D = 0. Da D je nach Ziel-Bit sowohl F<br />
(= 1) oder W (= 0) sein kann, dient der Befehl<br />
einerseits als Nulltest eines Registers (z-Bit von<br />
Status) oder ist der erste Schritt einer Registerkopie<br />
(F1 ->W ->F2).<br />
movlw k W = k — Laden einer Konstanten ins Arbeitsregister W<br />
movwf F F = W — Laden des Arbeitsregisters W in die Register F (ist<br />
auch der zweite Schritt einer Kopie von F1 ->F2)<br />
nop ---- —- Verbrauch von einem Maschinenzyklus mit<br />
Nichtstun<br />
(OPTION) Spezieller Befehl zur Initialisierung des Timers (nur<br />
bei älteren <strong>PIC</strong>-Versionen). Das benötigte Wort<br />
muss zuvor in W geladen werden.<br />
retfie TOS ->PC Rücksprung aus einer Interrupt-Routine. Dabei wird<br />
der Inhalt des obersten Programmstacks (TOS) in<br />
den Programmzähler (PC) zurückgeladen. Dieser<br />
retlw k TOS ->PC<br />
W = k<br />
Befehl benötigt zwei Maschinenzyklen.<br />
Rücksprung aus einer Subroutine. Dabei wird der<br />
Inhalt des mit call geladenen Programmstacks<br />
(TOS) in den Programmzähler (PC) zurückgeladen.<br />
Darüber hinaus wird die Konstante k in W geladen<br />
(wichtig für tabellarische <strong>Funktionen</strong>). Dieser Befehl<br />
benötigt zwei Maschinenzyklen.<br />
return TOS ->PC Rücksprung aus einer Subroutine. Wie retlw, aber<br />
ohne Einfluss auf W.Befehl bei älteren <strong>PIC</strong>-Typen<br />
nicht vorhanden<br />
rlf F,d D = 2 * F c Verschiebung der Bits des Registers F nach links.<br />
Dabei wird zuerst das STATUS,c-Bit in das tiefste<br />
F-Bit geladen <strong>und</strong> abschließend das oberste Bit von<br />
F in c verschoben. Der Vorgang entspricht einer<br />
Multiplikation mit 2, wenn das c-Bit null gesetzt<br />
wurde.<br />
rrf F,d D = F/2 c Verschiebung der Bits des Registers F nach rechts.<br />
Dabei wird zuerst das STATUS,c-Bit in das oberste<br />
F-Bit geladen <strong>und</strong> abschließend das tiefste F-Bit in<br />
c verschoben. Der Vorgang entspricht einer<br />
Division durch 2, wenn das c-Bit vorher null gesetzt<br />
sleep WDT = 0 to,pd<br />
wurde.<br />
Abschaltung des Mikroprozessors(siehe<br />
Abschaltung<br />
Abschnitt 2.4.7.2)<br />
sublw k W = W-k c,dc,z Subtraktion einer Konstanten von W. c = 0 wenn<br />
Ergebnis negativ, sonst c = 1. dc = 1 wenn 15-k<br />
nicht negativ, sonst dc = 0. z = 1 wenn W = 0<br />
subwf F,d D = F-W c,dc,z Subtraktion des Arbeitsregisters W von einem<br />
Register F. Einfluss auf c, dc <strong>und</strong> z wie in sublw<br />
swapf F,d D[7:4] = F[0:3]<br />
D[0:3] = F[7:4] — Vertauscht die unteren vier Bits des Registers F<br />
mit dessen oberen vier.<br />
(TRIS) port Spezieller Befehl zur Initialisierung von Ports (nur<br />
bei älteren <strong>PIC</strong>-Versionen). Das benötigte Wort<br />
muss zuvor in W geladen werden.<br />
xorlw k W =W .EXOR. k z Bitweise Exclusive-OR-Verknüpfung zwischen W<br />
<strong>und</strong> Konstante k. Das Ergebnis für jedes Bit ist „1",<br />
wenn eins <strong>und</strong> nur eins der beiden entsprechenden<br />
Bits „1" ist, sonst „0".z = 1 wenn W = 0. Dient oft der<br />
Umschaltung von einzelnen Bits von W, wobei k als<br />
„Maske" dient, in der die umzu<strong>schalten</strong>den Bits „1"<br />
sind.<br />
xorwf F,d D =F .EXOR. W z Bitweise Exclusive-OR-Verknüpfung zwischen<br />
Register F <strong>und</strong> Arbeitsregister W mit zu xorlw<br />
identischer Logik. Die „Maske" steht in W.<br />
28
2.4 Anwendung des Befehlssatzes<br />
<strong>und</strong> spezielle Programmierungstricks<br />
Wegen der besseren Verständlichkeit der nachfolgenden<br />
Programme wollen wir noch auf einige<br />
häufiger auftretende Programmschritte etwas<br />
näher eingehen. Dazu zählen die Bankumschaltung,<br />
konditionelle Verzweigungen, das<br />
Rechnen mit negativen oder großen Zahlen,<br />
die indirekte Adressierung von Registern, die<br />
Verwendung von dem Programmablauf parallel<br />
laufenden Zählern, aber auch der Einsatz<br />
von Tabellen als Ersatz für <strong>Funktionen</strong>, Interrupts<br />
oder der Watch Dog Timer.<br />
2.4.1 Registerbank<strong>und</strong><br />
Seitenumschaltung<br />
2.4.1.1<br />
Registerbankumschaltung<br />
Wie wir schon sahen, ist der Registerbereich<br />
eines <strong>PIC</strong>-uP in verschiedene Bänke aufgeteilt;<br />
auch einige der Spezialregister stehen in<br />
höheren Bänken.<br />
Für die Umschaltung von einer Datenbank<br />
in eine andere werden die Bits rpO <strong>und</strong> rpl des<br />
STATUS-Registers verwendet, die damit praktisch<br />
zwei höhere Bits zur 7-Bit-Registeradressierung<br />
beisteuern. Die angesprochene Bank<br />
bleibt dann jeweils so lange erhalten, d.h., jedes<br />
durch eine Operation angesprochene Register<br />
kommt aus diesem Datenraum, bis die<br />
BANK bsf STATUS,rp0 ; Umschaltung auf<br />
Bank-1- Register<br />
; Bank -1- [0l]<br />
bsf STATUS,rpl ; Umschaltung auf<br />
Bank-3- Register<br />
; Bank -3- [11]<br />
bcf STATUS,rpl ; Umschaltung auf<br />
bcf STATUS.rp0 ; Bank -0- [00]<br />
Bank-0- Register<br />
entsprechenden STATUS-Bits anders definiert<br />
werden. Beim Start des uP sind rpO <strong>und</strong> rpl<br />
null, weswegen normalerweise Register aus<br />
der Bank -0- verwendet werden.<br />
Bei älteren <strong>PIC</strong>-Typen (12C509A oder<br />
16C505) werden zur Umschaltung anstelle des<br />
STATUS-Registers höhere Bits des Registers<br />
FSR verwendet.<br />
Übrigens setzt der Compiler MAPSM bei der<br />
Übersetzung eine Warnung, wenn Register aus<br />
einer Bank größer null angesprochen werden.<br />
Man kann dann verifizieren, ob die notwendigen<br />
Bankumschaltungen programmiert wurden.<br />
2.4.1.2<br />
Programmseitenwechsel<br />
Bei älteren <strong>PIC</strong>-Typen (z.B. 12C509A oder<br />
16C505) bezieht der Programmzeilenzähler<br />
(PC) nur die unteren 9 Bit aus direkten Instruktionen<br />
(z.B. call oder goto). 9 Bit lange<br />
Programmabschnitte (512 Zeilen) werden daher<br />
als eine Programmseite definiert. Bei einem<br />
Seitenwechsel, d.h.. wenn z.B. die Zeile<br />
512 in welche Richtung auch immer überschritten<br />
wird, muss dann zur Seitenumschaltung<br />
das fehlende 10. Bit via STATUS,pa0 beigesteuert<br />
werden. Bei den meisten anderen <strong>PIC</strong>-<br />
Typen hat der Zeilenzähler eine höhere Bit-<br />
Tiefe, weshalb die Seitenumschaltung bei direkten<br />
Anweisungen keine Probleme macht.<br />
Ein Beispiel für direkte Sprunganweisungen<br />
mit Seitenumschaltung sind im Programm<br />
MULTINAUT.asm zu finden. Dort wird<br />
STATUS, pa0 = 0 gesetzt, wenn ein Wechsel<br />
von Seite eins auf Seite null stattfindet, <strong>und</strong><br />
STATUS, pa0 = 1, wenn er in umgekehrte Richtung<br />
erfolgt.<br />
Dagegen müssen bei indirekten Sprüngen,<br />
d.h. Zugriffen über das 8-Bit-PCL-Register,<br />
bei allen <strong>PIC</strong>s die höheren Bits mit den PC-<br />
LATH-Bits ergänzt werden, was die<br />
Umschaltung zwischen maximal vier Programmseiten,<br />
nämlich den Seiten 0 bis 3, erlaubt.<br />
Die entsprechenden Bits in PCLATH<br />
29
(bzw. STATUS,pa0) sind dazu jeweils der Zielseite<br />
anzupassen (siehe auch Abschnitt 2.4.2.3).<br />
2.4.2 Die konditioneile Verzweigung<br />
Die <strong>einfach</strong>sten konditionellen Verzweigungen<br />
sind die beiden Operatoren btfss <strong>und</strong> btfsc aus<br />
dem Befehlssatz, auf die sich fast alle weiteren<br />
Fälle abstützen. Im ersteren Fall wird die nachfolgende<br />
Zeile übersprungen (oft ein Sprungbefehl),<br />
wenn ein vorgegebenes Bit im Operanden<br />
gesetzt ist (= 1), im letzteren Fall, wenn es<br />
gestrichen ist (= 0). Daneben gibt es noch zwei<br />
weitere Verzweigungen im Befehlssatz, nämlich<br />
incfsz <strong>und</strong> decfsz, bei denen die nächste<br />
Zeile übersprungen wird, wenn das Ergebnis<br />
einer Erhöhung bzw. Erniedrigung null wird.<br />
Sie werden vor allem in Schleifen eingesetzt,<br />
wo Laufvariablen hochgezählt werden, in höheren<br />
Programmiersprachen „DO-Loops" genannt.<br />
2.4.2.1 Arithmetische<br />
konditionale Verzweigung<br />
Nicht mehr ganz so <strong>einfach</strong> wird es, wenn die<br />
Verzweigungsbedingung kein Operanden-Bit,<br />
sondern das Vergleichsergebnis von zwei Registern,<br />
V2 >= VI oder V2 < VI, ist.<br />
Die Verzweigungsbedingung führt dann über<br />
eine Subtraktion der beiden Register, wobei das<br />
Zielregister in den meisten Fällen das Arbeitsregister<br />
W ist, um den Wert beider Register zu<br />
erhalten. Die Abfrage von STATUS,c mit btfss<br />
bzw. btfsc führt dann zur gewünschten Verzwei<br />
30<br />
VERZW movf Vl.w<br />
subwf V2,v ; W = V2-V1<br />
btfss STATUS,c ; wenn :<br />
goto A2<br />
A1 ; groesser/gleich<br />
; (c=1)<br />
goto CONT<br />
A2 ; kleiner (c=0)<br />
CONT<br />
gung. Würde man statt des c-Bits das z-Bit abfragen,<br />
so entspräche das der Bedingung V2 = V1.<br />
2.4.2.2 Wertbegrenzung<br />
Oft ist die Begrenzung von Registern auf vorgegebene<br />
Minimal- bzw. Maximalwerte gefragt,<br />
insbesondere wenn eine Wertbegrenzung<br />
wie beim Rechnen mit negativen Zahlen oder<br />
mit Tabellen wichtig ist.<br />
MINIM movlw minimum<br />
subvf VAR,v ; W = VAR-minimum<br />
movlw minimum ; W = minimum<br />
btfss STATUS,c ; VAR < minimum (c=0)<br />
movwf VAR ; --—> VAR=W<br />
MAXIM movlw maximum<br />
subvf VAR.w ; W = VAR-maximum<br />
movlw maximum ; W = maximum<br />
btfsc STATUS, c ; VAR > maximum (c=l)<br />
movwf VAR ; - > VAR=W<br />
Der entsprechende Programmabschnitt ist<br />
weitgehend identisch zur arithmetischen Verzweigung.<br />
Der Trick besteht nur darin, dass das Arbeitsregister<br />
W nach der Subtraktion mit subwf<br />
erneut mit dem Minimal- bzw. Maximalwert geladen<br />
wird, was keinen Effekt auf das STATUS-<br />
Register hat. Bei Abfrage von STATUS.c wird<br />
W dann nur in VAR geladen, wenn die Bedingung<br />
erfüllt ist, sonst bleibt VAR unverändert.<br />
Auf diese Weise werden jeweils zwei Maschinenzyklen<br />
verbrauchende Sprunganweisungen<br />
eingespart <strong>und</strong> die Begrenzung verbraucht bedingungsunabhängig<br />
fünf Maschinenzyklen.<br />
2.4.2.3 Arithmetische<br />
Sprunganweisung<br />
Bei <strong>PIC</strong>-Mikroprozessoren kann das Register<br />
„PCL" als Low-Byte des Programmzeilenzählers<br />
Ziel einer arithmetischen Operation sein.<br />
Addiert (oder subtrahiert) man daher zu<br />
PCL ein Register SKIP, so springt das Programm<br />
SKIP-1 Zeilen weiter bzw. zurück
CGOTO movlw zblock ; zblock=Zeile/256<br />
movwf PCLATH ; fuer Zeilen > 255<br />
movf SKIP,w<br />
addwf PCL,f ; Zeilenzaehler<br />
; + SKIP<br />
SKIP-2 Zeilen<br />
CONTI ; SKIP-1 te Zeile<br />
(SKIP = 0 ist die der addwf/subwf-Operation<br />
folgende Zeile). Da SKIP gewöhnlich das Ergebnis<br />
vorheriger Rechnungen ist, wird dieser<br />
Programmsprung in höheren Programmiersprachen<br />
als „Computed Goto" bezeichnet.<br />
PCL ist ebenso wie SKIP in der addwf-<br />
Operation als 8-Bit-Register behandelt, was den<br />
Programmsprung auf 255 Zeilen beschränkt.<br />
In der Praxis können <strong>PIC</strong>-Programme je<br />
nach Programmspeicherplatz aber einige tausend<br />
Zeilen umfassen, weswegen die oberen<br />
Bits des Zeilenzählers (zblock) in das Register<br />
„PCLATH" geladen werden müssen (nach unserer<br />
Nomenklatur im nächsten Abschnitts ist<br />
PCLATH quasi das _hi-Byte des Registers PC),<br />
zblock erhält man durch Division der Zeile, in<br />
der der addwf-Operator steht, durch 256 (für<br />
z.B. Zeile 617 also zblock = 2). Eine Bit-Erweiterung<br />
von SKIP ist sehr umständlich, weswegen<br />
arithmetische Sprunganweisungen praktisch<br />
auf weniger als 255 Zeilen begrenzt sind.<br />
2.4.3 Rechnen mit großen<br />
<strong>und</strong> mit negativen Zahlen<br />
Wie schon eingangs dieses Kapitels angedeutet,<br />
beziehen sich alle arithmetischen Operationen<br />
des Befehlssatzes auf positive ganze Zahlen im<br />
Wertebereich zwischen 0 <strong>und</strong> 255. Nun gibt es<br />
ja durchaus Probleme, wo mit größeren Zahlenwerten<br />
als 255 zu rechnen ist, insbesondere nach<br />
einer Multiplikation von zwei Registern. Für<br />
diese Multiplikationen bzw. Divisionen sind<br />
übrigens spezielle Unterprogramme nötig (Microchip-Dokumentation<br />
„Fixed Point Routines"<br />
(AN617)), von denen in meinen Programmen<br />
verschiedentlich Gebrauch gemacht wird.<br />
2.4.3.1 Große Zahlen<br />
Den Bit-Bereich eines Registers kann man<br />
leicht erweitern, indem man für die große Zahl<br />
zwei Teilregister verwendet, nämlich NAMElo<br />
<strong>und</strong> NAMEhi. Die mit den kleingeschriebenen<br />
Ergänzungen „lo" bzw. „hi" bezeichneten<br />
Teilregister stehen darin für das untere <strong>und</strong><br />
obere Byte des 16-Bit-Registers NAME (Wertebereich<br />
0 bis 65535).<br />
Zwei 16-Bit-Register werden dann addiert,<br />
<strong>und</strong> zwar zuerst die beiden oberen Bytes <strong>und</strong><br />
dann die beiden unteren. Ergibt sich bei letzterer<br />
Addition ein Überlauf, d.h. STATUS, c = 1,<br />
so wird das _hi-Register noch um eins erhöht.<br />
Ist Z1 nur ein 8-Bit-Register, so startet die<br />
Addition erst bei ADD8 (für Zllo kann man<br />
dann auch <strong>einfach</strong> Z1 schreiben). Analog ist<br />
bei Subtraktionen vorzugehen.<br />
ADD16 movf Zlhi,w ; obere Bits<br />
addwf Z2hi,f<br />
ADD8 movf Zllo.w ; untere Bits<br />
addwf Z21o,f ; wenn Z21o>255<br />
btfsc STATUS,c ; d.h. _c=l<br />
incf Z2hi,f ; Z2hi=Z2hi+l<br />
Ein interessanter Aspekt der „großen Zahl"<br />
ist es übrigens, dass ihr hi-Byte gerade dem<br />
Ergebnis einer Teilung durch 256 entspricht.<br />
In allen meinen Programmen, bei denen ein<br />
Referenzwert (z.B. Fahrstufen-Null oder Rudermitte)<br />
durch Mittelung von Registern über<br />
einen gewissen Zeitraum zu bestimmen war,<br />
wird von dieser Tatsache Gebrauch gemacht.<br />
2.4.3.2 Negative Zahlen<br />
Ein <strong>PIC</strong>-uP rechnet mit positiven ganzen Zahlen.<br />
Bei vielen Problemstellungen kommen aber<br />
auch negative Werte vor, man denke nur an die<br />
„negativen Fahrstufen" bei Rückwärtsfahrten,<br />
die sich aus der negativen Differenz zwischen<br />
aktueller <strong>und</strong> Referenzimpulslänge ergeben <strong>und</strong><br />
31
die eine Umpolung der Fahrmotoren bewirken<br />
sollen. Es ist also zweckmäßig, eine Methode<br />
zu haben, wie elegant auch mit negativen Zahlen<br />
gerechnet werden kann.<br />
Kleine Zahlen<br />
Kann man die Ergebnisse von arithmetischen<br />
Operationen auf 7 Bits, d.h. Werte zwischen 0<br />
<strong>und</strong> 127, beschränken (z.B. mit den oben angegebenen<br />
MAXIM-Zeilen, Abschnitt 2.4.2.2),<br />
so kann im freien achten Bit eine Vorzeicheninformation<br />
mitgezogen werden.<br />
Nehmen wir zwei 7-Bit-Zahlen Z1 <strong>und</strong> Z2<br />
mit Z2 > Z1. Subtrahiert man jetzt Z2 von Z1,<br />
so läuft das Resultat über null <strong>und</strong> Z1 hat damit<br />
einen Wert zwischen 255 <strong>und</strong> 128 (z.B. 3-5<br />
—> 254) oder anders ausgedrückt, ein gesetztes<br />
höchstes Bit ist ein negatives Vorzeichen. Solange<br />
man den Absolutwert von Z1 nicht benötigt,<br />
kann mit Z1 normal weitergerechnet,<br />
d.h. positive <strong>und</strong> negative Zahlen addiert bzw.<br />
subtrahiert werden, wobei natürlich die 7-Bit-<br />
Wertbedingung für alle Register inklusive Resultat<br />
erfüllt bleiben muss.<br />
Irgendwann braucht man aber auch den<br />
realen Zahlenwert (Absolutwert). Ist das höchste<br />
Bit null, so ist nichts weiter zu tun.<br />
Andernfalls wird das Register mit dem Zweireiher<br />
NEG8 negiert (gleichbedeutend mit 256<br />
minus Register), wobei das negative Vorzeichen,<br />
wenn nötig, an anderer Stelle (z.B. einem<br />
Flaggenregister) gespeichert werden muss.<br />
32<br />
CONEG movf Z2,v ; NEGATIVE ZAHLEN<br />
subvf Zl.f ; Z1 = Z1 - Z2<br />
movf Z3,v ; 7 Bit Zahl Z3<br />
addwf Zl,f ; Z1 = Z1 + Z3<br />
ABS btfss Z1,7 ; Test des 8. Bits<br />
goto CONTI ; positiv —> Rest<br />
NEG8 comf Zl,f ; Z1 = 255 - Z1<br />
incf Zl.f ; Z1 - Z1 + 1<br />
CONTI<br />
(Für obiges Zahlenbeispiel gilt: 3 - 5 —> 254;<br />
256 - 254 (negieren) —> 2, negatives Vorzeichen<br />
anderswo.)<br />
Große Zahlen<br />
Große Zahlen werden wieder durch _hi- <strong>und</strong><br />
_lo-Teilregister dargestellt, wobei das 16. Bit<br />
(d.h. höchste Bit von_hi) das Vorzeichen birgt.<br />
Solange kein Absolutwert benötigt wird, gelten<br />
die gleichen Regeln wie in Abschnitt 2.4.3.1.<br />
Ansonsten ist das 16-Bit-Register zu negieren<br />
(invertieren), wenn VAR_hi,7 = 1 (höchstes<br />
Bit) ist.<br />
NEG16 comf VAR.lo.f ; Negation von<br />
incf VAR.lo.f ; 16-Bit Register<br />
btfsc STATUS,z<br />
decf VAR_hi,f<br />
comf VAR_hi,f<br />
Zur Negation von VAR benötigen wir den<br />
Fünfzeiler NEG16, ein Microchip-Applikationsprogramm.<br />
Das Modul funktioniert natürlich<br />
auch umgekehrt <strong>und</strong> macht aus einem 15-<br />
Bit-Register mit einem andernorts gespeicherten<br />
negativen Vorzeichen ein negatives von 16<br />
Bit (das höchste Bit von VAR_hi ist 1).<br />
In einigen meiner Programme kommt es<br />
vor, dass die Summation von zwei 7-Bit-Zahlen<br />
mit Vorzeichen (NG1 <strong>und</strong> NG2) zu einer<br />
Summe führen kann, die größer als 7 Bit ist,<br />
die Darstellung aller Register durch 16-Bit-<br />
Größen aber zu aufwändig wäre.<br />
Hier helfen die Zeilen SUM9, deren Ergebnis<br />
in SUM als 8-Bit-Absolutwert vorliegt,<br />
während das Vorzeichen im nullten Bit<br />
des Haggenregisters FLAG gespeichert ist (das<br />
Bit FLAG,1 darf nicht belegt werden, da es<br />
von SUM9 u.U. benötigt wird). In SUM9<br />
werden zunächst die Vorzeichen der beiden<br />
Summanden abgefragt <strong>und</strong> gegebenenfalls<br />
FLAG um eins erhöht. FLAG wird ein weiteres<br />
Mal erhöht, wenn es bei der folgenden
SUH9 btfsc NG1,7<br />
incf FLAG,f ; wenn NG1 negativ<br />
btfsc NG2,7<br />
incf FLAG,f ; wenn NG2 negativ<br />
movf NG2,W<br />
addwf NGl,w ; SUM = NG1 + NG2<br />
movlw SUM<br />
btfsc STATUS,c<br />
incf FLAG, f ; wenn > 255<br />
btfss FLAG,0 ; Vorzeichenflagge = 1<br />
comf SUM,f ; Negierung von SUM<br />
incf SUM,f<br />
Addition beider Summanden zum Überlauf<br />
kommt. Der Zustand des nullten FLAG-Bits<br />
ist dann das Vorzeichen von SUM (1 —> negativ),<br />
das für den Absolutwert gegebenenfalls<br />
negiert werden muss. NG1 <strong>und</strong> NG2 bleiben<br />
für weitere Rechnungen 7-Bit-Zahlen mit Vorzeichen.<br />
2.4.4 Indirekte Adressierung<br />
Wie schon erwähnt, sind Register prozessorintern<br />
nur als Speicherplatzadresse (Zahl) bekannt<br />
<strong>und</strong> erhalten einen Namen erst im Definitionsblock.<br />
Nun kann es aber programmtechnisch<br />
von Vorteil sein, wenn man ein Register auch<br />
über seinen Speicherplatz ansprechen kann, wobei<br />
man dessen Adresse vorher in einer arithmetischen<br />
Operation ermittelt hat (z. B. wenn I=1<br />
nehme Register A, wenn I = 2 nehme Register B<br />
usw.). Das nennt man dann indirekte Adressierung,<br />
weil das Register nicht mit seinem im<br />
Definitionsblock festgelegten Namen, sondern<br />
indirekt über seine Speicherplatznummer (Adresse)<br />
angesprochen wird. Dazu gibt man dem Ope<br />
INDIA movlw strw<br />
movwf FSR ; FSR-Startwert<br />
LOOP movlw wert<br />
CONTI<br />
movwf INDF ; Register = Wert<br />
incf FSR,f ; FSR = FSR + 1<br />
movlw endw<br />
subwf FSR,w ; wenn FSR < endw<br />
btfsc STATUS,c<br />
goto LOOP ; > weiter<br />
randen in einer Operation den Namen, „INDF",<br />
wobei dessen Speicherplatzadresse durch den<br />
Wert des FSR-Registers definiert ist, der<br />
wiederum das Ergebnis einer arithmetischen<br />
Operation mit FSR ist. Sowohl FSR als auch<br />
INDF haben als Spezialregister feste Speicherplätze<br />
im RAM <strong>und</strong> müssen im Definitionsblock<br />
definiert werden (INDF hat den Speicherplatz<br />
„0").<br />
Als Beispiel für indirekte Adressierung nehmen<br />
wir die Zuordnung eines bestimmten Anfangswertes<br />
wert für die Register im RAM-<br />
Bereich von strw bis endw. FSR wird zunächst<br />
mit der Speicherplatznummer des ersten Registers<br />
geladen <strong>und</strong> dann die Wertzuweisung<br />
mit movlw wert <strong>und</strong> movwf INDF ausgeführt.<br />
Es folgt die Erhöhung der Speicherplatznummer<br />
um 1. Die Schleife LOOP mit der Wertzuweisung<br />
wird dann so lange durchlaufen, bis<br />
FSR gleich endw ist <strong>und</strong> somit alle Register<br />
mit Speicherplatznummern zwischen strw <strong>und</strong><br />
endw mit wert geladen sind.<br />
2.4.5 Unterprogramme<br />
<strong>und</strong> Tabellen<br />
Gr<strong>und</strong>sätzlich sind Programme für Mikroprozessoren<br />
rechenzeit- oder speicherplatzkritisch,<br />
d.h., es kommt bei der Programmierung entweder<br />
auf einen zumindest in einigen Abschnitten<br />
möglichst schnellen Code an, was bei <strong>PIC</strong>-<br />
Mikroprozessoren vor allem die Vermeidung<br />
von Sprunganweisungen bedeutet, oder der<br />
Code kann hinsichtlich des Speicherplatzes an<br />
die Grenzen des entsprechenden Mikroprozessors<br />
stoßen, weswegen man mehrfach vorkommende<br />
Programmabschnitte tunlichst in Unterprogrammen<br />
(Subroutinen) zusammenfasst,<br />
um sie dann an den benötigten Stellen nur<br />
aufzurufen. Da Subroutinen darüber hinaus die<br />
Programmübersichtlichkeit bedeutend verbessern,<br />
ist ihr Einsatz gute Programmierpraxis;<br />
in den verschiedenen Programmen dieses Buches<br />
stehen sie immer in der ersten Hälfte des<br />
Listings.<br />
33
2.4.5.1 Einfache<br />
Unterprogramme<br />
Subroutinen unterscheiden sich bis auf zwei<br />
Ausnahmen nicht von gewöhnlichen Programmabschnitten.<br />
Die Ausnahmen sind:<br />
• Die erste Zeile der Subroutine hat einen Label,<br />
der dem Namen der Subroutine entspricht.<br />
• Subroutinenausgänge sind return- bzw. retlw-<br />
Befehle; es darf keine Sprunganweisungen<br />
aus der Subroutine geben, die diese Befehle<br />
umgehen.<br />
Mikroprozessorintern läuft ein Subroutinenaufruf<br />
wie folgt ab. Mit dem Befehl call wird<br />
die aktuelle Zeilennummer, um eins erhöht,<br />
auf die oberste Zeile eines Stapels (STACK)<br />
geschrieben (TOS = top of Stack) <strong>und</strong> dann zu<br />
der Zeile gesprungen, wo der Namens-Label<br />
der Subroutine steht. Dort setzt das Programm<br />
die Arbeit fort, bis es auf ein return bzw. retlw<br />
stößt, welches ein Rückladen der Zeilennummer<br />
aus TOS in den Zeilenzähler veranlasst<br />
<strong>und</strong> damit den Rücksprung ins Hauptprogramm.<br />
Wird innerhalb der Subroutine eine<br />
zweite aufgerufen, so wird deren Zeilennummer<br />
TOS, um bei Rücksprung auch als erste<br />
wieder geladen zu werden.<br />
Bei älteren <strong>PIC</strong>-Typen (12C509A, 16C505)<br />
ist der STACK nur zwei Schritte tief, d.h., es<br />
können nur zwei Subroutinen verschachtelt<br />
werden. Hier wird außerdem das 9. Bit von<br />
TOS immer null gesetzt, sodass Subroutinen<br />
jeweils in den ersten 256 Zeilen einer Programmseite<br />
(a 512 Zeilen) stehen müssen.<br />
Der Aufruf von Subroutinen kostet vier<br />
zusätzliche Maschinenzyklen (zwei call <strong>und</strong><br />
zwei return), weswegen in zeitkritischen Programmabschnitten<br />
auf sie verzichtet werden<br />
sollte, es sei denn, sie werden, wie mein<br />
LEERn, zur Zeitvergeudung bewusst eingesetzt.<br />
Rechenzeitkritisch sind im Rahmen dieses<br />
Buches vor allem einige Drehzahlstellerprogramme.<br />
34<br />
2.4.5.2 Tabellen<br />
Eine spezielle Form des Unterprogramms ist<br />
die Funktion, W = f (VAR) geschrieben, wo in<br />
Abhängigkeit des Registers VAR ein Wert ins<br />
Arbeitsregister geschrieben wird.<br />
TABEL movf VAR,w<br />
addwf PCL,f ; Zeilezaehler + VAR<br />
retlw f(0) ; Ergebnis fuer VAR=0<br />
retlw f(l) ; " " VAR=1<br />
retlw f(n) ; " " VAR=n<br />
Eine solche Funktion programmiert man<br />
als Tabelle, da so ohne viel Aufhebens selbst<br />
die kompliziertesten funktionalen Zusammenhänge<br />
problemlos angegangen werden können.<br />
Die Tabelle besteht im Prinzip aus der schon<br />
im Abschnitt 2.4.2.3 dargestellten arithmetischen<br />
Verzweigung <strong>und</strong> dem speziellen Rücksprungoperator<br />
retlw, der vor dem Rücksprung<br />
noch den Operanden ins Arbeitsregister lädt.<br />
Da diese Operanden die Funktionswerte<br />
darstellen, erhält man bei jedem Tabellenaufruf<br />
den zu VAR gehörenden Funktionswert.<br />
Bezüglich arithmetische Verzweigung gelten<br />
die schon im Abschnitt 2.4.2.3 erörterten<br />
Limitierungen. Zusätzlich ist bei Tabellen darauf<br />
zu achten, dass VAR innerhalb der in der<br />
Tabelle aufgelisteten Zeilen bleibt, da der Subroutine<br />
andernfalls ihr Rücksprungbefehl retlw<br />
fehlt <strong>und</strong> sich der uP aufhängen kann.<br />
2.4.6 Timer<br />
Timer sind Zähler, die mittels eines Taktes (gewöhnlich<br />
des Maschinenzyklus) ein Register<br />
hochzählen, prinzipiell also die ständigen Wiederholung<br />
der Operation incf TIMER,f, wobei<br />
der uP so für nichts anderes verwendet werden<br />
könnte. Der Vorteil eines Timers ist es daher,<br />
dass er die Zählung im Hintergr<strong>und</strong>, also unabhängig<br />
vom Programmablauf, durchfuhren kann.
TIMER movlw t0 ;<br />
movwf TMR0 ; TMR0-t0<br />
movlw optval ; Initialisierung<br />
movwf OPTION_REG<br />
(OPTION)<br />
movf TMR0,w ; Wert-Abfrage<br />
Für die Benutzung des Timers 0 muss dem<br />
Register TMRO zunächst ein Anfangswert zugewiesen<br />
werden, worauf die Timereinheit<br />
selbst initialisiert <strong>und</strong> gestartet wird, indem ein<br />
Initialisierungswort optval in das Register<br />
OPTION_REG geladen wird (bei älteren <strong>PIC</strong>s<br />
gilt der Operator OPTION). Im Initialisierungswort<br />
sind die unteren 3 Bits (PS0 bis PS2) für<br />
die Definition des Vorteilers reserviert, mit dem<br />
man die Zählfrequenz stark herabsetzen kann;<br />
der Wert des Vorteilers ergibt sich aus der 3-<br />
Bit-Zahl ps zu VORTEILER = 2 (ps+1)<br />
.<br />
Neben dem Vorteiler sind in optval noch<br />
das vierte Bit (PSA) <strong>und</strong> das sechste Bit T0CS<br />
von Interesse. Ersteres regelt, ob der Vorteiler<br />
für TMR0 (= 0) oder für den Watch Dog Timer,<br />
WDT, (= 1) verwendet werden soll, letzteres<br />
bestimmt den Takt des Timers als internen<br />
Maschinenzyklus (= 0) oder extern eingespeist<br />
am Pin TOCKI (= 1).<br />
Die Zählstand des Timers 0 (Register TMRO)<br />
kann jederzeit abgefragt <strong>und</strong> zu weiteren Entscheidungen<br />
verwendet werden. Die Destination<br />
in der Abfrage muss dabei allerdings w sein, da<br />
ein Schreiben auf TMRO (Destination f) die Nullsetzung<br />
des Registers OPTION_REG <strong>und</strong> damit<br />
auch des Vorteilers zur Folge hat <strong>und</strong> deshalb<br />
von einer Initialisierung gefolgt sein muss.<br />
2.4.7 Watch Dog Timer<br />
<strong>und</strong> Sleep<br />
2.4.7.1 Watch Dog Timer<br />
Der Watch Dog Timer WDT („Wachh<strong>und</strong>")<br />
ist ein spezieller Zeitmesser, der den Betreiber<br />
eines uP vor den u.U. fatalen Folgen eines<br />
Programmabsturzes bewahren soll, wie er vor<br />
allem bei Einbrüchen der Betriebsspannung<br />
leicht einmal vorkommen kann.<br />
Der WDT läuft mit einem internen, vom<br />
Maschinentakt unabhängigen Taktgenerator<br />
von r<strong>und</strong> 14 kHz <strong>und</strong> braucht damit, im Konfigurationswort<br />
eingeschaltet, r<strong>und</strong> 18 ms, bis er<br />
von 0 auf 255 hochgezählt hat <strong>und</strong> es danach<br />
zu einem Zählerüberlauf kommt. Ein WDT-<br />
Überlauf bewirkt einen RESET des Mikroprozessors,<br />
d.h. einen Sprung zu Zeile 0 des Programms,<br />
was dem Ab<strong>schalten</strong> <strong>und</strong> Neustart<br />
des Mikroprozessors vergleichbar ist. Neben<br />
dem RESET setzt der WDT-Überlauf auch<br />
noch das to-Bit von STATUS, damit der Prozessor<br />
die Fälle Ein<strong>schalten</strong> des uP <strong>und</strong> WDT-<br />
Reset unterscheiden kann.<br />
Nun ist man natürlich nicht daran interessiert,<br />
dass jede 18 ms ein WDT-Reset ausgelöst<br />
wird, weswegen er mit clrwdt, d.h. durch<br />
Nullen des WDT-Registers, verhindert wird.<br />
clrwdt muss dazu in Schleifen eingebaut werden,<br />
die kürzer als 18 ms sind. Läuft das Programm<br />
normal, so bleibt der WDT-Reset aus.<br />
Der im Zusammenhang mit dem Timer<br />
TMRO beschriebene Vorteiler kann wahlweise<br />
auch für den WDT eingesetzt werden (PSA =<br />
1 in optval), wobei die drei PS-Bits den Vorteiler<br />
hier mit VORTEILER = 2 ps<br />
definieren.<br />
Da er aber nur entweder für TMRO oder WDT<br />
eingesetzt werden kann, läuft der WDT in allen<br />
meinen Programmen ohne Vorteiler.<br />
2.4.7.2 Sleep<br />
Mit dem Befehl sleep kann man einen <strong>PIC</strong>-uP<br />
schlafen schicken, was bei ihm ein Ab<strong>schalten</strong><br />
des internen Oszillators <strong>und</strong> damit jeder Computeraktivität<br />
bedeutet <strong>und</strong> in einer Reduzierung<br />
seines Energieverbrauchs resultiert.<br />
Vor dem Schlafenschicken sollte man<br />
zunächst die Weckbedingungen festlegen, im<br />
vorliegenden Beispiel aus dem Programm<br />
S2PWM die Änderung an den Schaltereingängen.<br />
Diese Eingänge werden unmittelbar vor<br />
35
dem Schlafengehen noch einmal abgefragt, um<br />
klare Bedingungen zu schaffen.<br />
Ist eine Weckbedingung erfüllt, gönnt man<br />
dem uP noch zwei Mikrosek<strong>und</strong>en zum Augenreiben<br />
(nop), setzt die Weckbedingung zurück<br />
(keine Interrupts) <strong>und</strong> fährt im Programm<br />
fort.<br />
2.4.8 Interrupts<br />
Ein Interrupt ist eine spezielle Form von Unterprogramm,<br />
das nicht im gewöhnlichen Programmablauf<br />
durch den call-Operator, sondern<br />
durch ein vom Programmablauf unabhängiges<br />
Ereignis, die „Interrupt-Quelle", ausgelöst wird.<br />
Solche Quellen können je nach <strong>PIC</strong>-Typ ein<br />
Timer-Überlauf, ein Pegelwechsel an einem<br />
der Eingangspins, ein Signal am externen Interrupt-Pin<br />
(INT) selbst oder ein sonst vom<br />
uP-Hersteller definiertes Ereignis sein.<br />
Bleiben wir als Beispiel beim Timer-Überlauf,<br />
bei dessen Eintreten im gedachten Programm<br />
vom uP bestimmte Aktionen erwartet<br />
werden. Ohne Interrupt müsste man den Timer<br />
im fraglichen Zeitbereich mit movf TMR0,w<br />
36<br />
SLP movlw B'00001000'; erlaubt Waie-up bei<br />
movwf INTCON AenderunganPins<br />
movwf INTCON AenderunganPins sleep ; Prozessor AUS<br />
nop ; AUFWACHEN<br />
nop<br />
TST clrf INTCON ; keine Interrupts<br />
btfsc INTCON,7 ; mit Pruefung<br />
goto TST<br />
; Programmfortsetzung<br />
<strong>und</strong> Kontrolle von STATUS,z dauernd überwachen<br />
<strong>und</strong> kann während dieser Zeit nichts<br />
anderes tun. Mit einem Interrupt auf Timer-<br />
Überlauf dagegen wird der uP mit sinnvoller<br />
Arbeit beschäftigt. Tritt das Interrupt-Ereignis,<br />
d.h. der Timer-Überlauf, ein, wird die aktuelle<br />
Befehlszeile noch abgearbeitet. Dann verzweigt<br />
das Programm an die Zeilenadresse „004", dem<br />
einheitlichen Label aller Interrupt-Unterprogramme.<br />
Hier stehen dann die Programmanweisungen,<br />
die der uP im Falle des Interrupt-<br />
Ereignisses durchführen soll. Ähnlich wie bei<br />
Subroutinen werden sie von einer Rücksprunganweisung<br />
retfie abgeschlossen, worauf im<br />
Hauptprogramm an der der letzten Anweisung<br />
folgenden Zeile fortgesetzt wird.<br />
Da das Interrupt-Unterprogramm immer auf<br />
Zeile „004" beginnt, muss bei verschiedenen<br />
Interrupt-Quellen, die unterschiedliche Aktionen<br />
des uP zur Folge haben sollen, zwischen<br />
den einzelnen Quellen unterschieden <strong>und</strong> dann<br />
entsprechend verzweigt werden. Das ist möglich,<br />
weil jede Interrupt-Quelle auch Erkennungsflaggen<br />
setzt, die eine notwendige Verzweigung<br />
erlauben, doch wird das u.U. schon<br />
bald einmal recht kompliziert <strong>und</strong> unübersichtlich.<br />
Deshalb kann man Interrupts natürlich<br />
auch ab<strong>schalten</strong> <strong>und</strong> einige billigere Mikroprozessoren<br />
haben überhaupt keine Interrupt-Möglichkeit.<br />
Auch in meinen Programmen wurde<br />
bisher auf Interrupts verzichtet, weswegen im<br />
Rahmen dieses Buches auf weitere Details der<br />
Interrupt-Technik verzichtet werden kann; es<br />
sei auf die einschlägigen Manuals verwiesen,<br />
insbesondere DS33023A.
3 Programmbeispiele<br />
3.1 Überblick <strong>und</strong> Erläuterung<br />
eines Ablaufdiagramms am<br />
Beispiel von BLINK<br />
Die in diesem Kapitel vorgestellten PlC-Programme<br />
sind in einzelne Anwendungsgruppen<br />
gegliedert, nämlich <strong>Sonderfunktionen</strong>, Modellüberwachung,<br />
Drehzahlsteller sowie RC-Anlage.<br />
Alle Programme sind auf meinen Schiffsmodellen<br />
im Einsatz.<br />
Im Folgenden wird die gr<strong>und</strong>legende Funktion<br />
jedes Programms anhand von Ablaufdiagrammen<br />
erläutert, während seine lesbare <strong>und</strong><br />
für eine Übersetzung mit MAPSM geeignete<br />
Form, das .asm File von der Homepage des<br />
vth- Verlags (www.modellwerft.de/downloads)<br />
kostenlos bezogen werden kann.<br />
Zur Erklärung der Ablaufdiagrammsymbolik<br />
nehmen wir uns aber zuerst noch einmal<br />
das Demonstrationsprogramm BLINK vor, dessen<br />
Listing weiter vorne ausgedruckt ist.<br />
Das Programm beginnt mit der Zuweisung<br />
von W an das Kalibrierungsregister OSCCAL<br />
(Zuweisungsrechteck), dem immer angezeigten<br />
ersten Clearen des WDT <strong>und</strong> einem Sprung<br />
zum Label START (kleiner Kreis). Nach der<br />
Zuweisung der Blinkzeit einer Sequenzeinheit<br />
(FRQ=frequ) <strong>und</strong> der Definition der Blinksequenz<br />
in den vier Registern BLK1 bis BLKn<br />
kommen wir zur Endlosschleife beginnend mit<br />
dem Label LOOP. Hier wird zunächst der Timer<br />
TMRO zurückgesetzt <strong>und</strong> dann ebenso wie<br />
der Port GPIO neu definiert. Die Zeitschleife<br />
Ablaufdiagramm des Programms BLINK<br />
37
eginnend mit dem Label WAIT dient dem<br />
Zeitverbrauch, um eine genügend niedrige<br />
Blinkfrequenz zu erzeugen. Dazu verbraucht<br />
das Unterprogramm LEER 10 (abgeschrägtes<br />
Rechteck, in anderen Ablaufdiagrammen auch<br />
für Programmabschnitte (Module) verwendet),<br />
zunächst zehn Maschinenzyklen, bevor in der<br />
arithmetischen Sprunganweisung (Rombus,<br />
innen die Bedingung, außen das Konditionsergebnis)<br />
auf Timer-Überlauf getestet wird; bei<br />
NEIN geht es jeweils direkt zurück nach WAIT.<br />
Die zweite arithmetische Sprunganweisung<br />
erniedrigt FRQ um eins <strong>und</strong> testet das Ergebnis<br />
auf null (decfsz-Operator), bei NEIN geht<br />
es hier zurück nach LOOP. Nur wenn FRQ-1<br />
= 0 ist, wird BLK1,0 zuerst in den LED-Anschluss-Pin<br />
(GPIO,0) <strong>und</strong> in STATUS,c geladen.<br />
Dann werden die Bits in allen Blinksequenzregistern<br />
(BLK1 bis BLKn) beginnend<br />
mit BLKn nach rechts geschoben, wodurch die<br />
Bitsequenz umläuft <strong>und</strong> jedes Bit der Blinksequenzregister<br />
am Punkt BLK1,0 ankommt <strong>und</strong><br />
dann den Zustand der LED bestimmt.<br />
Im Musterprogramm definieren die Register<br />
BLK1 bis BLK4, jeweils von rechts nach links<br />
gelesen, die Sequenz eines SOS Morsesignals.<br />
Es können aber auch noch mehr Register mit<br />
jeder beliebigen Sequenz programmiert werden.<br />
3.2 <strong>Sonderfunktionen</strong><br />
Beginnen wir jetzt mit den eher <strong>einfach</strong>en Programmen<br />
für verschiedene <strong>Sonderfunktionen</strong>.<br />
Da ist zunächst ein Mehrfachschalter mit fünf<br />
Schalterstellungen. Es folgt eine Strangstromerzeugung<br />
für Miniaturschrittmotore zum<br />
Antrieb von Modellradarschirmen, ein Pyrozünder<br />
sowie ein Tongenerator für zwei verschiedene<br />
Signaltypen (Nebelhorn <strong>und</strong> Zerstörersirene).<br />
Den Abschluss bildet schließlich ein<br />
Programm, das es erlaubt, ein <strong>einfach</strong>es Schaltersignal<br />
in ein Servosignal umzuwandeln, um<br />
mit <strong>einfach</strong>en EIN-Stellungen von Schalterbausteinen<br />
Servoauslenkungen beliebiger Art<br />
auslösen zu können.<br />
38<br />
3.2.1 Fünffachschalter<br />
(PENTA-S)<br />
3.2.1.1 Problemstellung<br />
<strong>und</strong> Funktionsprinzip<br />
Die Zahl der auf einem Modell möglichen <strong>Sonderfunktionen</strong><br />
wird in der Regel durch die Zahl<br />
der mit der Fernsteuerung verfügbaren Schaltfunktionen<br />
limitiert. Im Handel erhältliche Ausbausätze<br />
zur Erhöhung der Schalterzahl gehen<br />
schnell ins Geld. Eine Alternative ist der Selbstbau<br />
einer „Magnetorgel", wo ein auf den Ruderarm<br />
eines Servos geklebter kleiner Magnet<br />
verschiedene in seinem Drehkreis angeordnete<br />
Reed-Relais ansprechen kann <strong>und</strong> so bei entsprechender<br />
Vorgabe am Steuerorgan des Senders<br />
mehrere <strong>Funktionen</strong> schaltbar macht.<br />
PENTA-S (Fuenffach-Schalter)<br />
Schaltbild des Fünffachschalters PENTA-S<br />
Die uP-Variante der Magnetorgel ist der<br />
von einem <strong>PIC</strong>-12C509A gesteuerte Fünffachschalter<br />
PENTA-Switch. Seine fünf vom Fahrnetz<br />
versorgten Transistorendstufen vertragen<br />
kurzzeitig auch ohne Kühlung schon mal ein<br />
paar Ampere. Empfängerseitig wird er an einen<br />
freien Servokanal angeschlossen (positiver<br />
Impuls), von wo auch der Betriebsstrom<br />
(5 V) für den uP kommt; die negativen Pole<br />
von Fahr- <strong>und</strong> RC-Akku müssen dazu verb<strong>und</strong>en<br />
sein. Die Schaltung lässt sich auf einer<br />
einseitig beschichteten Platine von 4x5 cm mit
Ein fertig bestückter PENTA-S. Links der<br />
uP in einer Fassung, rechts die Reihe der<br />
Schalttransistoren <strong>und</strong> die Freilaufdioden<br />
Standardbauteilen aufbauen, für die Layout <strong>und</strong><br />
Bestückungsplan im Anhang zu finden sind.<br />
Senderseitig ist der Stellweg des Gebers in<br />
sechs Abschnitte zu unterteilen (null <strong>und</strong> die<br />
fünf Schalter), weswegen hierfür mit Vorteil<br />
ein Schieber eingesetzt wird.<br />
Bekanntlich liefern die Kanalausgänge eines<br />
RC-Empfangers Impulse mit einer variablen<br />
Länge zwischen 1 <strong>und</strong> 2 ms (siehe Abschnitt<br />
3.4.1). In der variablen Millisek<strong>und</strong>e<br />
dieses Aktivsignals steckt die Information, die<br />
z.B. ein Servo über den gesamten Schwenkbereich<br />
bewegt. Dem aktiven Signal folgt eine<br />
der Empfängersynchronisation dienende, aber<br />
bezüglich der Servoinformation irrelevante längere<br />
Pause (Passivsignal), die je nach Senderhersteller<br />
zwischen 20 <strong>und</strong> 40 ms betragen<br />
kann. Misst man nun die Länge des Aktivsignals,<br />
subtrahiert davon die r<strong>und</strong> 1 ms des konstanten<br />
Teils <strong>und</strong> teilt den Rest in z.B. sechs<br />
Abschnitte, so kann man ähnlich einer Magnetorgel<br />
jedem dieser Abschnitte eine Schalterstellung<br />
zuordnen, in unserem Beispiel von<br />
null bis fünf. Dabei ist es sinnvoll, die Auslösung<br />
der Schalterstellung jeweils für kurze Zeit<br />
zu verzögern (Konsistenzkontrolle), damit<br />
erstens kurzeitige Signalstörungen unterdrückt<br />
werden <strong>und</strong> zweitens das beim senderseitigen<br />
Einstellen unvermeidliche Überlaufen anderer<br />
Schalter nicht zu wenn auch nur kurzen, unge<br />
wollten Schalterstellungen führt. Da der uP<br />
mit dieser Aufgabe aber noch keineswegs ausgelastet<br />
ist, können die einzelnen Schalterstellungen<br />
noch etwas nachbearbeitet werden, z.B.<br />
mit Memoryfunktion (die eingestellte Schalterstellung<br />
bleibt so lange erhalten, bis der<br />
Schalter nach einer anderen Schalterstellung<br />
ein nächstes Mal angesprochen wird) oder mit<br />
Trigger (die Schalterstellung bleibt unabhängig<br />
von der Sendervorgabe nur für kurze Zeit<br />
aktiv).<br />
3.2.1.2 Das Programm<br />
PENTAS.asm<br />
Definieren wir zunächst die Aufgabenstellung<br />
für den Mikroprozessor:<br />
• Bestimmung des konstanten Signalanteils<br />
beim Ein<strong>schalten</strong> des Geräts (senderseitig<br />
muss dazu die kürzeste Kanalimpulslänge<br />
vorgegeben werden)<br />
• Messung der aktuellen Impulslänge, Abzug<br />
des konstanten Signalteils, Division <strong>und</strong><br />
daraus schließlich Bestimmung der Schalterstellung<br />
• Konsistenzkontrolle der Schalterstellung für<br />
einige Sek<strong>und</strong>en<br />
• Weiterbehandlung ausgewählter Schalterstellungen<br />
(Memory bzw. Trigger)<br />
Das Hauptprogramm<br />
Wie das Ablaufdiagramm des Programms PEN<br />
TA-S zeigt, wird nach dem Ein<strong>schalten</strong><br />
zunächst der konstante Signalanteil K0 bestimmt<br />
(linker oberer Ast), indem die Subroutine<br />
SCAN 256-mal durchlaufen, die gemessene<br />
Impulslänge im 16-Bit-Register K0 aufsummiert<br />
<strong>und</strong> mittels alleiniger Verwendung<br />
des hi-Bytes automatisch durch 256 geteilt wird.<br />
Die Summation findet nur bei gültigem RC-<br />
Signal statt (FLAG,0=0), andernfalls wird so<br />
lange neu begonnen, bis 256 Mittelungen am
Generelles Ablaufdiagramm des Programms<br />
PENTA-S<br />
Stück einwandfrei sind. Abschließend sorgt der<br />
Modul MIMAX noch dafür, dass K0 innerhalb<br />
vorgegebener Grenzen bleibt.<br />
Die Endlosschleife des Programms beginnt<br />
am Label LOOP, wo mit SCAN zunächst die<br />
Kanalimpulslänge bestimmt wird. Bei fehlerfreiem<br />
Signal wird dann die konstante Impulslänge<br />
K0 vom Messergebnis KNEW abgezogen<br />
<strong>und</strong> wenn größer null mit dem Divisionsmodul<br />
DV08L durch kdiv dividiert, sodass sich<br />
aus dem Wertebereich der variablen Kanalimpulslänge<br />
von 1 ms (hier 1.000 : 12 us = 84,<br />
mit 12 us Messeinheit in SCAN) ein Resultat<br />
zwischen null <strong>und</strong> fünf ergibt. Sicherheitshalber<br />
wird KNEW noch auf fünf begrenzt.<br />
KNEW wird zur Konsistenzprüfung dann<br />
safety Mal mit dem alten Schalterwert KOLD<br />
verglichen, bis es als gültig gilt <strong>und</strong> zum Label<br />
AUSWRT gesprungen werden kann.<br />
Hier wird dann die eventuelle Bearbeitung<br />
der verschiedenen Schalterstellungen in einer<br />
Schleife mit indirekter Adressierung der Register<br />
S1 bis S5 durchgeführt. Entspricht der<br />
40<br />
Wert von KNEW nicht der Laufvariablen I,<br />
die von 1 bis nswtch (= 5) durchlaufen wird, so<br />
ist die entsprechende Schalterstellung null,<br />
wenn es sich nicht um einen Memoryschalter<br />
handelt, was die entsprechende Flagge in<br />
MFLG anzeigt. Ist dagegen KNEW = I <strong>und</strong><br />
handelt es sich um eine neue Schalterstellung,<br />
d.h., die First-Flagge FLAG,1 ist gesetzt, so<br />
wird die FLAG,1 gestrichen, die entsprechende<br />
Schalterstellung null gesetzt, falls die Memoryflagge<br />
nicht gesetzt ist, <strong>und</strong> dann das unterste<br />
Bit der Schalterstellung invertiert. Im<br />
Normalfall bedeutet das immer Ein-, im Falle<br />
eines Memoryschalters ein Um<strong>schalten</strong>.<br />
Schließlich wird der aktuellen Schalterstellung<br />
mit der Tabelle TRIGER noch eine Triggerzeit<br />
TRGT zugewiesen. Die Triggerfunktion tritt<br />
allerdings nur in Kraft, wenn TRGT größer<br />
null ist, <strong>und</strong> wird dann in jedem AUSWRT-<br />
Durchlauf für KNEW=I um eins vermindert,<br />
bis es null ist. In diesem Fall wird die entsprechende<br />
Schalterstellung wieder abgeschaltet<br />
unabhängig davon, ob der entsprechende Senderbefehl<br />
noch ansteht. Abgeschlossen wird<br />
die I-Schleife (Schalterstellungen) mit einer<br />
Linksverschiebung der Bits in MFLG, damit<br />
beim Durchlaufen der I-Schleife jeweils das<br />
zur Schalterstellung gehörende Bit in MFLG,4<br />
abgefragt wird, <strong>und</strong> mit der Änderung der indirekten<br />
Adresse (FSR) für die Schalterstellungen<br />
Sl bis S5.<br />
Aus den Schalterstellungen wird schließlich<br />
für alle fünf Schalter S. der entsprechende Pegel<br />
für die uP-Pins bestimmt (SOUT) <strong>und</strong> auf<br />
GPIO kopiert, bevor wieder an den Beginn des<br />
Endlosschleife gesprungen wird.<br />
Subroutine SCAN<br />
Das Ablaufdiagramm der Subroutine SCAN<br />
zeigt zwei Äste, nämlich für den passiven <strong>und</strong><br />
den aktiven Signalteil. Zunächst werden KLEN<br />
(Impulslänge) <strong>und</strong> FLAG,0 (Fehlerflagge) null<br />
gesetzt. Da beim SCAN-Aufruf davon ausgegangen<br />
wird, dass kein Signalimpuls vorliegt
Ablaufdiagramm des PENTA-S-Unterpro-<br />
gramms SCAN<br />
(passiv), wird ein vorhandener Impuls (aktiv)<br />
als Fehler betrachtet <strong>und</strong> zum Label SC_ERR<br />
gesprungen, wo die Fehlerflagge gesetzt wird.<br />
Ab Label SC_PAS wird der Beginn des Aktivsignals<br />
abgewartet, wobei mit TMRO die Pausenlänge<br />
zwischen den Impulsen überwacht<br />
wird. Hält sich diese nicht in den vorgegebenen<br />
Grenzen<br />
passmn < TMR0 < passmx<br />
so liegt ebenfalls ein Fehler vor <strong>und</strong> es<br />
wird nach SC_ERR gesprungen. Sonst beginnt<br />
die Impulslängenmessung am Label SC_AKT.<br />
Die Schleife um SC_AKT dauert dank der<br />
Leerroutine LEER7 genau zwölf Zyklen d.h.<br />
12 us (mit 4 MHz internem Takt). Maximal<br />
2 ms Impulslänge ergeben damit einen Wert<br />
von 167 im Register KLEN. Bei längerem Impuls<br />
kann es zu einem Überlauf von KLEN<br />
kommen, was ebenfalls zu einem Sprung nach<br />
SC_ERR führt. Läuft dagegen alles ordnungs<br />
gemäß, wird TMRO zurückgesetzt <strong>und</strong> sowohl<br />
Timer als auch der Port GPIO neu initialisiert;<br />
diese Initialisierung kann auch durch Aufruf<br />
von FRAMIN herbeigeführt werden.<br />
Während der Initialisierungsphase des Programms<br />
PENTA-S wird neben der konstanten<br />
Impulslänge K0 auch noch die Länge des RC-<br />
Frames RCFRAM (Länge zwischen den ersten<br />
positiven Flanken von zwei aufeinander folgenden<br />
Impulspaketen) gemessen <strong>und</strong> im Folgenden<br />
als Zeitbasis verwendet. Die mit TMRO<br />
gemessene Länge des RC-Frame wird in<br />
TMR00 registriert <strong>und</strong> dann im Hauptprogramm<br />
zu RCFRAM addiert <strong>und</strong> mittels Verwendung<br />
des High-Bytes durch 256 geteilt.<br />
3.2.1.3 Praktische Hinweise<br />
Einige unter der Überschrift „— Benutzerspezifische<br />
Konstanten —" im Programmkopf zusammengefassten<br />
Parameter müssen vom Benutzer<br />
seiner Anlage angepasst werden. Das gilt<br />
vor allem für die Grenzwerte des RC-Signals<br />
(passmn <strong>und</strong> passmx), die für die Signalüberwachung<br />
wichtig sind <strong>und</strong> die falsch vorgegeben<br />
die ordendiche Funktion des PENTA-S verunmöglichen<br />
(Daueralarm). Zwar kann man sehr<br />
niedrige bzw. sehr hohe Werte vorgeben, doch<br />
wird die Signalkontrolle dann sehr unscharf.<br />
Deshalb ist es von Vorteil, die RC-Zykluszeit<br />
des verwendeten Senders mittels eines Oszilloskops<br />
zu messen, d.h. die Zeit zwischen zwei<br />
positiven Ranken an einem beliebigen Kanalausgang.<br />
Man sollte dabei auch die Länge des<br />
variablen Impulsteils überprüfen <strong>und</strong><br />
gegebenenfalls den Teiler kdiv anpassen:<br />
kdiv = (KLEN (max) - KLEN (min) ):5<br />
mit KLEN = Impulslänge in ms: 0,012<br />
Die meisten anderen Parameter beziehen<br />
sich auf die persönlichen Bedürfnisse des Anwenders.<br />
Insbesondere sind die Auswahl von<br />
Memoryschaltern (eine „1" der entsprechenden<br />
Flagge, von rechts nach links gelesen) in<br />
41
der Konstanten memory <strong>und</strong> eventuelle Triggerzeiten<br />
vor der Programmierung des uP festzulegen.<br />
Man kann das Programm natürlich auch auf<br />
mehr Schalterstellungen erweitern, wenn man<br />
z.B. mit dem <strong>PIC</strong>-16C505 mehr Pins zur Verfügung<br />
hat. Allerdings wird dann die senderseitige<br />
Betätigung u.U. etwas problematisch. Eine<br />
andere Variante auf der Basis des <strong>PIC</strong>-16C505<br />
wäre das Einlesen von MFLG von einem Port,<br />
womit man dann die Auswahl Normal- oder<br />
MemorySchalter mittels eines DIL-Mehrfachschalters<br />
(Mäuseklavier) bzw. von Jumpern<br />
jederzeit ändern kann, ohne einen IC neu programmieren<br />
zu müssen. Bei Verwendung eines<br />
<strong>PIC</strong>-16C505 anstelle des hier vorgesehenen <strong>PIC</strong>-<br />
12C509A muss das Programm PENTAS.asm<br />
allerdings, wenn auch nur geringfügig, modifiziert<br />
werden (z.B. GPIO wird PORTB).<br />
3.2.2 Schrittmotorradarantrieb<br />
(RADAR)<br />
3.2.2.1 Problemstellung<br />
<strong>und</strong> Funktionsprinzip<br />
Als Antriebsmotoren für Modellradars verwendet<br />
man meist Kleinstgetriebemotoren, die in<br />
direkter Falllinie in den Autbauten versteckt<br />
<strong>und</strong> über einen Federstahldraht mit dem Schirm<br />
verb<strong>und</strong>en sind. Eine dazu elegante <strong>und</strong> kostengünstige<br />
Alternative sind Miniaturschrittmotoren,<br />
wie sie z.B. im elektronischen Uhrenbau<br />
Verwendung finden. Diese naturgemäß kleinen,<br />
leichten <strong>und</strong> wegen des fehlenden Getriebes ruhigen<br />
Antriebe können, ohne die Optik groß zu<br />
stören, als modelltechnische Darstellung des originalen<br />
Antriebs auch direkt am Antennenschirm<br />
eingebaut werden. Ein Nachteil des Schrittmotors<br />
ist allerdings, dass er eine spezielle Steuerelektronik<br />
benötig, die samt Schrittmotor im<br />
Selbstbau jedoch kaum mehr kostet als der altbewährte<br />
Getriebemotor.<br />
Eine solche Steuerelektronik mit dem <strong>PIC</strong>-<br />
12C509A stellen wir hier vor. Zum besseren<br />
42<br />
Zwei Miniaturschrittmotorradarantriebe auf<br />
der Insel meines Trägermodells „Shangri-<br />
La". Beide Radarschirme sind auf Ausle<br />
gern montiert <strong>und</strong> ließen sich konventio<br />
nell nur mit großem Aufwand antreiben<br />
Verständnis des entsprechenden Programms<br />
wird zunächst aber noch ein kurzer Blick in die<br />
Welt der Schrittmotoren geworfen.<br />
Der Schrittmotor<br />
Schrittmotoren gibt es erst seit Anfang der 60er-<br />
Jahre. Mit ihnen kann eine Drehbewegung von<br />
wenigen Grad Auflösung ohne spezielle Rückmeldung<br />
erreicht werden, weswegen sie vor<br />
allem in Druckern, Plottern <strong>und</strong> Robotern verwendet<br />
werden, wo ein definierter Stellweg<br />
verlangt ist. In elektronischen Uhren kommt es<br />
bei minimalen Abmessungen auf langsame<br />
Umdrehungen an, was ebenfalls mit einem<br />
Schrittmotor, wenngleich oft auch leicht ruckelnd,<br />
realisiert werden kann.
Prinzip eines Schrittmotors<br />
Während in den vertrauten Gleichstrommotoren<br />
mit Permanentmagnet eine oder mehrere<br />
stromdurchflossene Spulen in Form eines<br />
Ankers im magnetischen Feld eines Permanentmagneten<br />
(Stator) drehen <strong>und</strong> damit die<br />
Sache läuft, der Ankerstrom über die Bürsten<br />
nicht nur zugeführt, sondern durch den Kollektor<br />
bei jeder Umdrehung auch mehrfach<br />
umgepolt (kommutiert) werden muss, besteht<br />
ein Schrittmotor aus einem drehenden Permanentmagnetanker<br />
mit den stromdurchflossenen<br />
Spulen (Phasen oder Stränge) als Stator (siehe<br />
Skizze, wo jede Spule jeweils aus zwei gegenüberliegenden<br />
Teilen besteht). Fließt nun in<br />
der Spule I ein Strom (Schritt 1), so dreht sich<br />
der Anker so weit, bis seine beiden Pole den<br />
entsprechenden Polen der Spule am nächsten<br />
sind, <strong>und</strong> bleibt dann stehen bzw. „rastet" (die<br />
eingeschaltete Spule ist in der Abbildung durch<br />
eine Tönung markiert). Legt man den Strom<br />
nun an Spule II (Schritt 2), so dreht der Anker<br />
dorthin <strong>und</strong> rastet erneut. Im Schritt 3 dreht<br />
man den Strom in Spule I um (Umkehrung der<br />
Spulenpolung), sodass der andere Pol des Ankers<br />
von der Spule angezogen wird. Im Schritt 4<br />
macht man schließlich dasselbe mit Spule II.<br />
Im <strong>einfach</strong>sten Fall eines zweipoligen Ankers<br />
hat man durch Be<strong>schalten</strong> der beiden Spulen<br />
also vier Schritte von je 90° bzw. eine Volldrehung<br />
in vier Rucklern durchgeführt. Glücklicherweiser<br />
haben Schrittmotore immer mehrere<br />
Ankerpole, weswegen ein Schritt in der Praxis<br />
nicht 90°, sondern nur wenige Grad beträgt.<br />
Um einen solchen Schrittmotor langsam<br />
zu drehen, muss man die Spulenumschaltungen<br />
also nur kontinuierlich bei niedrigem Takt<br />
durchführen.<br />
Betriebsart Wavedrive Normal Halbschritt<br />
Takt Spule 1 Sp. 2 Spule 1 Sp. 2 Spule 1 Sp. 2<br />
1 -1 0 -1 -1 -1 0<br />
1.5 -1 -1<br />
2 0 -1 + 1 -1 0 -1<br />
2,5 +1 -1<br />
3 + 1 0 +1 +1 +1 0<br />
3,5 +1 +1<br />
4 0 +1 -1 +1 0 +1<br />
4.5 -1 +1<br />
Dafür gibt es drei gängige Möglichkeiten,<br />
nämlich den Wavedrive-, den Normal- <strong>und</strong> den<br />
Halbschrittbetrieb, eine Kombination aus den<br />
beiden ersten. Sie sind für eine Drehrichtung in<br />
der Tabelle angegeben, wobei „—1" <strong>und</strong> „+1"<br />
für die beiden Stromrichtungen <strong>und</strong> „0" für abgeschalteten<br />
Strom steht.<br />
3.2.2.2 Steuerelektronik<br />
<strong>und</strong> praktischer Aufbau<br />
Wie dem Schaltbild für den Radarantrieb zu<br />
entnehmen ist, besteht die Steuerelektronik aus<br />
zwei ICs, nämlich dem Mikroprozessor <strong>PIC</strong>-<br />
12C509A mit internem Oszillator, der für die<br />
Steuerung der Spulenbestromung zuständig ist,<br />
<strong>und</strong> einem Treiber (TX-4469), der die geringen<br />
Ausgangsströme des uP in Handfestes für den<br />
Schrittmotor umsetzt, hier ein Miniaturtyp (SEI-<br />
KE-6507) mit den Abmessungen O10x11mm<br />
<strong>und</strong> einer Schrittweite von 18°, was zum nicht<br />
ganz ruckelfreien Antrieb eines direkt auf seiner<br />
Achse befestigten Radarschirms ausreicht.<br />
Schrittmotor Radarantrieb<br />
Schaltbild der Radarschirmantriebselektronik<br />
43
Die Steuerelektronik für einen Radaran<br />
trieb. Auf der linken Seite der Treiber mit<br />
der Anschlussbuchse für den Schrittmotor<br />
(IC-Sockelleiste), rechts der uP; die rechte<br />
zweipolige Buchse dient der Methodenaus<br />
wahl (offen bedeutet Halbschrittverfahren)<br />
Die Schaltung ist auf einer einseitig beschichteten<br />
Platine aufgebaut, wobei der Motor<br />
über eine vierpolige IC-Sockelleiste angeschlossen<br />
wird (Layout <strong>und</strong> Bestückungsplan<br />
im Anhang).<br />
Es liegt nahe, mit dieser Methode auch<br />
mehrere Schirme gleichzeitig anzutreiben. In<br />
diesem Falle ist allerdings für jeden Motor ein<br />
eigener Treiber vorzusehen, denn zumindest<br />
bei mir schlug sowohl die Reihen- als auch die<br />
Parallelschaltung mehrerer Motoren fehl.<br />
3.2.2.3 Das Programm<br />
RADAR.asm<br />
Die Aufgabenstellung für den Mikroprozessor<br />
kann man wie folgt umreißen:<br />
• Erzeugung der geeigneten Schrittfrequenz zur<br />
Erreichung der gewünschten Motordrehzahl<br />
• Definition der Spulenstromrichtung für jeden<br />
Motorschritt durch geeignete Pegel an<br />
den vier Output-Pins<br />
Wie diese Aufgabenstellung erwarten lässt,<br />
besteht das <strong>einfach</strong>e Programm für die Strang<br />
44<br />
stromerzeugung aus einem Taktgeber sowie<br />
dem Schrittgenerator, der die Bestromung der<br />
beiden Motorspulen nach einer der drei oben<br />
beschriebenen Betriebsarten steuert.<br />
Im Ablaufdiagramm von RADAR.asm besteht<br />
der Schrittgenerator nur aus der Verzweigung<br />
um „GPIO,mode", wo in Abängigkeit des<br />
Pegels am Pin4 des uP entweder das Halbschrittverfahren<br />
(=H) oder der Wavedrive (=L) verwendet<br />
werden kann; anstelle von WAVEDRV<br />
kann man im Code am entsprechenden call auch<br />
NORMDRV einsetzen. Programmiert sind alle<br />
drei Betriebsarten als Tabellenfunktionen<br />
Pinpegel=f(STEP), wobei die Bits des Operanden<br />
von retlw GPIO angepasst sind, d.h., das<br />
nicht als Output programmierbare 4. Bit<br />
Ablaufdiagramm des Programms RADAR
(GPIO,3) ist immer null <strong>und</strong> die entsprechende<br />
Information steht im 5. Bit (GPIO,4). Die Tabellen<br />
von WAVEDRV <strong>und</strong> NORMDRV bestehen<br />
aus zwei Vollschritten, um mit den acht<br />
Halbschritten von HALFDRV kompatibel zu<br />
sein. Für das Halbschrittverfahren muss der Zeitfaktor<br />
FAK halbiert werden.<br />
Das Tabellenergebnis wird dann in GPIO<br />
kopiert, indem zunächst in OUT zwischengespeichert,<br />
der GPIO-Inhalt dann nach W kopiert,<br />
wo alle bis auf Bit,3 genullt <strong>und</strong><br />
schließlich zu OUT <strong>und</strong> GPIO addiert werden.<br />
Dieses etwas umständliche Vorgehen ist notwendig,<br />
da GPIO,3, wie gesagt, kein Output<br />
ist <strong>und</strong> deshalb nicht überschrieben werden<br />
sollte. Schließlich wird der Schrittzähler<br />
„STEP" um eins erhöht <strong>und</strong> bei Erreichen von<br />
acht gegebenenfalls auf null zurückgesetzt.<br />
Der Rest des Programms dient dem die<br />
Drehzahl des Motors bestimmenden Taktgeber,<br />
der mit einer Doppelschleife aus TMRO<br />
<strong>und</strong> Multiplikator FAK realisiert wurde. Die<br />
längste Zeit verbringt der uP daher in der mit<br />
dem Label TAKT beginnenden Warteschleife<br />
aus TMRO <strong>und</strong> FAK. Bei 4 MHz uP-Takt dauert<br />
ein Motorschritt<br />
woraus sich eine Schirmdrehzahl von<br />
ergibt.<br />
Beim Abschluss eines Schritts werden<br />
schließlich für eine kurze Umschaltzeit von 17<br />
x laus Millisek<strong>und</strong>en alle Stränge abgeschaltet,<br />
bevor es mit einem Rücksprung zum Label<br />
SCHRITT zum Beginn der Endlosschleife zurückgeht.<br />
3.2.2.4 Praktische Hinweise<br />
Die vom Anwender wählbaren Parameter beschränken<br />
sich auf die beiden Konstanten rtcc<br />
<strong>und</strong> nfak, mit denen die Motordrehzahl definiert<br />
werden kann, im Musterprogramm etwa<br />
30 U/min. Wenn man den internen Taktgenerator<br />
durch einen externen R-C-Generator mit<br />
einem Potenziometer ersetzt, kann man die<br />
Drehzahl des Motors durch Verstellung der<br />
uP-Taktfrequenz auch manuell einstellen, wozu<br />
allerdings eine Änderung der drei fosc-Bits im<br />
Konfigurationswort notwendig ist.<br />
3.2.3 RC-Streichholz (ZUND)<br />
3.2.3.1 Problemstellung<br />
<strong>und</strong> Funktionsprinzip<br />
Für pyrotechnische <strong>Sonderfunktionen</strong> auf Modellen<br />
braucht man ein „fernsteuerbares Streichholz",<br />
am <strong>einfach</strong>sten ein Stück dünnen Widerstanddraht<br />
(00,15 mm Kanthai), der für<br />
wenige Sek<strong>und</strong>en mit einem hohen Strom belastet<br />
wird, dabei hellrot aufleuchtet <strong>und</strong> so die<br />
Zündschnur des Feuerwerks entflammt.<br />
Allerdings halten Ausgänge von Schalterbausteinen<br />
die hierfür benötigten hohen Ströme<br />
meist nicht durch, weswegen entweder hoch<br />
belastbare, aber großvolumige Relais oder Leistungstransistoren<br />
die Lösung sind.<br />
Auf meinen inzwischen alle mit einem startbaren<br />
Hubschrauber (siehe ModellWerft, Heft<br />
4/1998) ausgerüsteten Kleinmodellen mit 5-V-<br />
Bordnetz macht ein Leistungstransistor aber<br />
Probleme, da sein Spannungsabfall selbst im<br />
voll durchgesteuerten Zustand schon zu groß<br />
ist. Abhilfe schaffen würde hier ein FET (BUZ-<br />
11) mit seinem sehr niedrigen Durchlasswiderstand<br />
(0,04 Ohm), doch braucht dieser zur<br />
vollen Durchsteuerung leider eine Gate-Spannung<br />
von mehr als 5 V. Glücklicherweise gibt<br />
es nun aber <strong>einfach</strong>e so genannte Spannungsverdreifacherschaltungen,<br />
die die Erzeugung<br />
einer höheren Gate-Spannung mittels hochfrequenter<br />
Wechselspannung erlauben. Neben dieser<br />
ist zur Schonung von Akku <strong>und</strong> Glühdraht<br />
auch eine Begrenzung der Schaltzeit auf<br />
ungefähr zwei Sek<strong>und</strong>en angezeigt. Schließlich<br />
45
sollte man aus Sicherheitsgründen eine Auslöseverzögerung<br />
von einigen Sek<strong>und</strong>en vorsehen,<br />
während der ein Auslösebefehl ungestört<br />
anstehen muss.<br />
3.2.3.2 Elektronische<br />
Schaltung <strong>und</strong> praktischer<br />
Aufbau<br />
Wie dem Schaltbild zu entnehmen ist, bleibt<br />
die externe Beschaltung des uP sehr bescheiden.<br />
Sein Pin7 (GPIO,0) geht für eine Schaltphase<br />
von r<strong>und</strong> zwei Sek<strong>und</strong>en auf positiv,<br />
während der Pin6 (GPIO, 1) <strong>und</strong> Pin5 (GPIO,2)<br />
mit einer Frequenz von um die 15 kHz ihre<br />
Pegel wechseln <strong>und</strong> so mit ihrer äußeren Beschaltung<br />
eine ungefähre Spannungsverdreifachung<br />
am Gate des FET ermöglichen. Der steuert<br />
voll durch <strong>und</strong> lässt den angeschlossenen<br />
Schaltbild des RC-Streichholzes (Pyrozünder)<br />
Der fertige Pyrozünder. Der größte Teil der<br />
Elektronik ist unter dem FET montiert, der<br />
für die Aufnahme etwas angehoben wurde<br />
46<br />
FET PYROZUENDER<br />
Widerstandsdraht hell aufleuchten. Beim 5-V-<br />
Einfachbordnetz sind beide Plusschienen<br />
miteinander verb<strong>und</strong>en. Es sind auch getrennte<br />
Netze möglich, doch muss eine gemeinsame<br />
Minusmasse existieren. Als Eingangssignal<br />
(Zündbefehl, aktiv LOW) genügt der Ausgang<br />
eines TTL- oder CMOS-Gatters (5 V).<br />
Der Aufbau der Schaltung kann auch „fliegend"<br />
erfolgen, doch verwende ich in meinen<br />
Modellen eine Platine, deren Layout <strong>und</strong> Bestückungsplan<br />
im Anhang abgedruckt sind. Aus<br />
Platzgründen wird der FET liegend über der<br />
übrigen Elektronik platziert, wobei sich wegen<br />
der kurzen Schaltzeiten eine Kühlung erübrigt.<br />
3.2.3.3 Das Programm<br />
ZUND.asm<br />
Definieren wir nun die von ZUND zu erfüllenden<br />
Aufgaben:<br />
• Feststellung der Störungsfreiheit des Auslösebefehls<br />
über eine definierte Zeit (hier etwa<br />
zehn Sek<strong>und</strong>en)<br />
• Ein<strong>schalten</strong> des Glühstroms für kurze Zeit<br />
(etwa zwei Sek<strong>und</strong>en)<br />
• Während der Schaltphase Bereitstellung einer<br />
Wechselspannung hoher Frequenz<br />
(mindestens 10 kHz) an Pin6 <strong>und</strong> Pin5 (5 ist<br />
dabei immer das Invers von 6) zur Ansteuerung<br />
des Spannungsverdreifachers<br />
• Niedriger Stromverbrauch während der u.U.<br />
langen Wartezeit auf einen Zündbefehl<br />
Wie im Ablaufdiagramm des Programms<br />
ZUND.asm unschwer zu erkennen ist, gliedert<br />
sich das Programm im Wesentlichen in zwei<br />
Schleifenblöcke von jeweils drei Individualschleifen<br />
mit den Laufregistern I, J <strong>und</strong> K in<br />
beiden Ästen des Bildes. Es beginnt am Label<br />
WART mit der Initialisierung des Ports GPIO<br />
<strong>und</strong> des Timers, der zwar in dieser Anwendung<br />
selbst nicht benötigt wird, wegen des „wake<br />
up"-Bits für SLEEP aber initialisiert werden<br />
muss. Danach werden alle Ausgänge auf AUS
Ablaufdiagramm des Programms ZUND<br />
gesetzt <strong>und</strong> ein erstes Mal der Eingang auf seinen<br />
Zustand befragt. Ist dieser passiv, so wird<br />
der uP auf minimalen Stromverbrauch gesetzt<br />
(SLEEP). Natürlich wacht er bei einem Zündbefehl<br />
(Pegelwechsel) am Pin GPIO,3 sofort<br />
wieder auf <strong>und</strong> beginnt mit der Abarbeitung der<br />
SLEEP folgenden Instruktion. Das ist hier der<br />
Beginn der Signaluntersuchung, die er im Falle<br />
eines aktiven Signals an GPIO,3 schon sofort<br />
begonnen hätte. Im vorliegenden Programm ist<br />
negative Logik programmiert (aktiv = LOW),<br />
eine Logikumkehrung ist im Programm durch<br />
Ersatz mit der durch Semikolon inaktiv gesetzten<br />
Folgezeile möglich.<br />
Die Signalprüfung dient dazu, das unbeabsichtigte<br />
Zünden von Feuerwerk als Folge von<br />
RC-Signalstörungen zu verhindern. Sie besteht<br />
im Wesentlichen aus dem ersten Schleifen<br />
block (Label STR_ im mittleren <strong>und</strong> unteren<br />
Teil des linken Astes im Ablaufdiagramm).<br />
Hier wird für die Zeit von<br />
die Störungsfreiheit des Zündbefehls untersucht,<br />
d.h., es darf während keines Schleifenschritts<br />
von jeweils 1,28 ms Länge ein<br />
Wechsel des Signals auftreten, da andernfalls<br />
sofort zum Anfang des Programms (WART)<br />
zurückgesprungen wird. Von dort wird gegebenenfalls<br />
der gesamte Schleifenblock erneut<br />
durchlaufen (als Auslöser am Sender sollte<br />
ein Druckknopf verwendet werden, um ein<br />
Stehenlassen des Zündbefehls auszuschließen).<br />
Erst wenn das Signal t(pruef) Millisek<strong>und</strong>en<br />
ungestört angestanden hat, springt das Programm<br />
in den „Zündblock" (Label ZND_, rechter<br />
Ast im Ablaufdiagramm), der erneut aus<br />
drei Individualschleifen I, J <strong>und</strong> K besteht <strong>und</strong><br />
dessen Gesamtlänge<br />
beträgt. Zunächst werden die Ausgänge<br />
für die Zündphase eingeschaltet, was GPIO,0<br />
= 1, GPIO,l = 1 <strong>und</strong> GPIO,2 = 0 (invers von<br />
GPIO,1) bedeutet. Bei jedem frqu-ten Durchlauf<br />
der am häufigsten durchlaufenen K-<br />
Schleife (dafür trägt Loop-Register L Sorge)<br />
werden GPIO,l <strong>und</strong> GPIO,2 durch eine<br />
EXOR-Verknüpfung des Ports GPIO mit der<br />
Maske W umgepolt (in W sind nur die Bits 1<br />
<strong>und</strong> 2 eins). Die Frequenz der Wechselspannung<br />
ist damit<br />
oder im Musterfall mit frqu = 5 zu 500/43 =<br />
11,6 kHz; sie kann durch Änderung von frqu<br />
nach oben <strong>und</strong> unten variiert werden. Eine Rücknahme<br />
des Zündbefehls (GPIO,3 = 1) führt auch<br />
hier zu einem sofortigen Abbruch der Zündung.<br />
47
Mit Abarbeitung der drei Schleifen nach<br />
ungefähr t(zuend) Millisek<strong>und</strong>en werden zunächst<br />
die Ausgänge abgeschaltet. Dann fragt das Programm<br />
ein letztes Mal den Zündbefehl ab. Steht<br />
dieser immer noch auf aktiv, so wird der Kontroller<br />
schlafen geschickt, bis der Kommandant<br />
am Sender den Zündbefehl zurückgenommen<br />
hat. Danach geht es zum Label WART<br />
<strong>und</strong> anschließend erneut in schlafende Wartestellung<br />
bis zum nächsten Zündbefehl.<br />
3.2.3.4 Praktische Hinweise<br />
Die Zeitdauer der Signaluntersuchung, die<br />
Zündzeit <strong>und</strong> die Frequenz der zur Spannungserhöhung<br />
benötigten Wechselspannung können<br />
vom Benutzer durch die Konstanten storlop,<br />
z<strong>und</strong>lop <strong>und</strong> frqu bei der Programmierung<br />
definiert werden; sie stehen im Programmkopf<br />
unter „—- Benutzerspezifische Konstanten —".<br />
Die bei meinen Anwendungen negative Logik<br />
des Zündbefehls kann im Programm an den<br />
entsprechenden vier Positionen geändert werden;<br />
die entsprechenden Änderungen sind in<br />
den Folgezeilen durch Semikolon inaktiv gemacht,<br />
das Semikolon muss also lediglich eine<br />
Zeile nach oben gesetzt werden.<br />
3.2.4 Kombination von RADAR<br />
<strong>und</strong> ZUND (RADZUND)<br />
Das Programm RADZUND.asm ist eine<br />
Kombination der vorherigen Programme<br />
RADAR.asm <strong>und</strong> ZUND.asm, um bei Kleinmodellen<br />
die Größe der Elektronik <strong>und</strong> den Bauteilaufwand<br />
zu reduzieren. Das Programm nutzt<br />
im Prinzip die langen Wartezeiten in RADAR,<br />
um zwischendurch schnell noch die Aufgaben<br />
von ZUND zu erledigen. Da eine größere Zahl<br />
von Pins benötigt wird, kommt anstelle des <strong>PIC</strong>-<br />
12C509A ein <strong>PIC</strong>-16C505 zum Einsatz, der<br />
ebenfalls mit internem Takt betrieben wird <strong>und</strong><br />
der, wie das Schaltbild zeigt, gleich beschaltet ist<br />
wie die entsprechenden Einzelgeräte.<br />
48<br />
RADZND<br />
(Radarantriab & Pyrozuender)<br />
Schaltbild des Radarschirmantriebs <strong>und</strong><br />
Pyrozünders für Kleinmodelle RADZUND<br />
RADARANTRIEB<br />
& PYROZUENDUNG<br />
Ablaufdiagramm des Programms RADZUND<br />
Das Ablaufdiagramm von RADZUND ist<br />
zu Beginn (Schrittgenerator) weitgehend identisch<br />
mit RADAR, wenn man einmal davon<br />
absieht, dass wegen ZUND ein paar Register<br />
mehr definiert werden müssen.<br />
Während der langen TMRO-gesteuerten<br />
Wartezeit des Radartaktes ist genügend Zeit, die<br />
Zündlogik abzuarbeiten, was wegen deren Dau-
er im Sek<strong>und</strong>enbereich allerdings nur abschnittsweise<br />
erfolgen kann; die Flaggen ZFLG,0 <strong>und</strong><br />
ZFLG,1 steuern deshalb den jeweiligen Zustand<br />
des Zündteils. Ist kein Zündbefehl vorhanden<br />
(Label Z-OFF), sind beide Flaggen gestrichen<br />
<strong>und</strong> der Zündkreis (PORTC,l bis 3) abgeschaltet.<br />
Bei anliegendem Zündbefehl dagegen wird<br />
mit der Laufvariablen,J" zunächst die Störungsfreiheit<br />
untersucht, d.h., der Zündbefehl muss<br />
für storlop Radartakte ungestört anliegen, bevor<br />
mit Setzen von ZFLG,0 die Zündung freigegeben<br />
wird. Bei gesetztem ZFLG,0 wird in den<br />
folgenden Radartakten die Zünddauer „J" bis<br />
z<strong>und</strong>tim hochgezählt, wonach mit ZFLG,1 gesetzt<br />
<strong>und</strong> die Zündung nebst Zündflagge wieder<br />
abgeschaltet wird.<br />
In der weiteren Wartezeit des Radartaktes<br />
sowie während der kurzen Abschaltphase der<br />
Radarschrittumschaltung erfolgt bei eingeschalteter<br />
Zündung (ZFLG,0=H) die Erzeugung des<br />
höherfrequenten Wechselstroms für den Spannungsverdreifacher<br />
mit der Subroutine VTRI-<br />
PL, bevor in die Endlosschleife der Radarschrittsteuerung<br />
zurückgesprungen wird.<br />
3.2.5 Erzeugung eines Typhonbzw.<br />
Zerstörersirenentons<br />
(DUOSIG)<br />
Es gibt heute schon eine Menge So<strong>und</strong>module<br />
auf dem Markt, die in der Luxusklasse sogar<br />
auf den Geräuschen der Originale fußen. Digitalisiert,<br />
in EPROMs geladen <strong>und</strong> im Modell<br />
in Analogsignale umgewandelt, schließlich verstärkt<br />
<strong>und</strong> über Lautsprecher abgestrahlt, geben<br />
solche Tonerzeuger einen wirklich sehr<br />
realistischen So<strong>und</strong> ab. Wie gesagt, das ist die<br />
Luxusklasse, die natürlich auch ihren Preis hat.<br />
3.2.5.1 Problemstellung<br />
<strong>und</strong> Funktionsprinzip<br />
Mit dem DUOSIG bleiben wir zwar der digitalen<br />
Schallquelle treu, doch stellen wir sie mittels<br />
eines uP <strong>PIC</strong>-12C509A synthetisch her. Das<br />
Ergebnis ist zugegebenermaßen nicht ganz so<br />
perfekt wie die oben angesprochene Methode<br />
mit Originaltönen, doch viel kostengünstiger.<br />
DUOSIG erzeugt den Ton eines Nebelhorns<br />
(Typhon) <strong>und</strong> den einer Zerstörersirene,<br />
wobei die Auswahl durch Ansteuerung des betreffenden<br />
EIN-Pins typh bzw. zsig erfolgt.<br />
Ein Typhonsignal beginnt immer mit Zischen,<br />
da der entsprechende Tonerzeuger bei<br />
den Originalen mit Pressluft oder Dampf angeblasen<br />
wird <strong>und</strong> es zunächst einige Sek<strong>und</strong>en<br />
dauert, bis das Rohr in Resonanz fällt <strong>und</strong><br />
damit den typischen tiefen Hornton erzeugt.<br />
Ein Typhonton besteht deshalb aus den Komponenten<br />
„Zischen" <strong>und</strong> Resonanzton (
DUO-SIGNALGEBER<br />
Schaltbild des digitalen Signalgenerators<br />
DUOSIG<br />
kereingang hilft ein <strong>einfach</strong>es RC-Netzwerk,<br />
die vom uP kommenden Rechtecksignale zur<br />
Verbesserung der Tonqualität noch etwas abzur<strong>und</strong>en.<br />
Naturgemäß ist die Auslegung dieses<br />
Netzwerks stark von der Tonfrequenz abhängig<br />
<strong>und</strong> wurde hier für die Zerstörersirene<br />
optimiert, wie das entsprechende Oszilloskopbild<br />
verdeutlicht.<br />
Als Lautsprecher kommen Breitbandlautsprecher<br />
mit 4 bis 8 Ohm Impedanz infrage,<br />
die aus modelltechnischen Gründen nicht allzu<br />
groß sein können, aber im unteren Frequenzbereich<br />
trotzdem eine ausreichende Tonqualität<br />
liefern sollten.<br />
Der DUOSIG vor dem Zusammenbau. Links<br />
die Platine, die mit der Bestückung nach<br />
unten auf den Magneten der Lautsprecher<br />
rückseite aufgesetzt wird<br />
50<br />
Die ganze DUOSIG-Einheit ist auf einer<br />
Platine montiert, die auf der Rückseite des Lautsprechers<br />
Platz hat. Ein entsprechendes Platinenlayout<br />
samt Bestückungsplan ist im Anhang<br />
zu finden. Für das Funktionieren der<br />
Schaltung muss eine positive Massenverbindung<br />
(Pluspol RC-Batterie zu Pluspols Fahrbatterie)<br />
bestehen.<br />
3.2.5.3 Das Programm<br />
DUOSIG.asm<br />
Das Programm DUOSIG.asm gliedert sich,<br />
wie das Ablaufdiagramm zeigt, in drei charakteristische<br />
Abschnitte. In der Mitte ist die<br />
Befehlskette für das abgeschaltete System zu<br />
sehen mit einer Warteschleife (TAUS), die<br />
über den Label S-OFF durchlaufen wird, bevor<br />
der uP den Verstärker abschaltet<br />
(GPIO,vst=H) <strong>und</strong> in Warteposition geht, bis<br />
Ablaufdiagramm des Programms DUOSIG
Vier Perioden des Typhonsignals vor dem<br />
Verstärkereingang. Gut zu erkennen ist<br />
der reine Ton (durch RC-Netzwerk abge<br />
r<strong>und</strong>ete Rechtecke), der jeweils den hinte<br />
ren Teil jeder Halbperiode einnimmt.<br />
Davor der chaotische Signalverlauf des<br />
Zischens<br />
an einem der beiden Befehlseingänge ein<br />
HIGH-Signal anliegt.<br />
Im linken Ast der Diagramms ist der Befehlsablauf<br />
für das Typhon dargestellt. Beim<br />
ersten Aufruf wird es nur initialisiert. In den<br />
folgenden Durchläufen werden dann der Resonanzton<br />
<strong>und</strong> Zischton hintereinander erzeugt,<br />
Ersterer durch <strong>einfach</strong>e Bitumschaltung<br />
im durch das frequenzbestimmende Register<br />
FRQ festgelegten Takt <strong>und</strong> Letzterer<br />
mittels Bit-Linksverschiebung im 16-Bit-Register<br />
SR (Schieberegister) <strong>und</strong> geeigneter<br />
Verknüpfungen der Bits 15,4 <strong>und</strong> 9. Dadurch<br />
entstehen die Zufallszahlen eines quasiweißen<br />
Rauschsignals, das sich akustisch wie Zischen<br />
anhört.<br />
Während der Mischzeit mix0 werden der<br />
niederfrequente Resonanzton <strong>und</strong> das Rauschen<br />
gemischt, indem für die Zeit FRQ null <strong>und</strong> MIX von mix0 —> null)<br />
die LOW- <strong>und</strong> HIGH-Halbphasen des Tonsignals<br />
mit den hochfrequenten Rauschsignalen<br />
aufgefüllt werden, wie im entsprechenden Oszillogramm<br />
deutlich wird. Abschließend wird<br />
MIX dann um eins vermindert, bis es null<br />
wird.<br />
Die Typhon-Tonfrequenz wird mit der Timer-Schleife<br />
(Label T_WAIT) synchronisiert<br />
<strong>und</strong> kann mit<br />
<strong>und</strong><br />
berechnet werden. tmrf_t kann maximal<br />
205 gesetzt werden, da Typhon maximal 46<br />
Zyklen verbraucht. Die Mischzeit nach dem<br />
Ein<strong>schalten</strong> des Typhons ist schließlich<br />
Auf der rechten Diagrammseite ist der Befehlsablauf<br />
für die Zerstörersirene zu sehen,<br />
die einen hohen Pfeifton erzeugt, dessen Frequenz<br />
gegen Ende noch stark ansteigt, um dann<br />
abrupt abzubrechen.<br />
Im linken Ast des Sirenenteils (Label ZS-<br />
N) bleibt die Sirene während der Phase zwischen<br />
den Sirenensignalen für die Zeit T2<br />
abgeschaltet, im rechten (Label ZS-I) wird<br />
die Initialisierung durchgeführt <strong>und</strong> im mittleren<br />
erfolgt die Umpolung von GPIO,out<br />
Zerstörersirenensignal vor (unten) <strong>und</strong><br />
nach dem RC-Netzwerk. Dank des dem uP<br />
nachgeschalteten RC-Netzwerks ist das<br />
ursprüngliche Rechtecksignal fast ein<br />
Sinus<br />
51
ei jedem Durchlauf, was mit der Taktsynchronisation<br />
mittels Timer TMRO am Ende<br />
der Schleife zu einer konstanten Tonfrequenz<br />
führt. Diese konstante Tonhöhe wird für eine<br />
Zeit T0xT1 gehalten. Danach wird der Startwert<br />
TMRF des Timers TMRO kontinuierlich<br />
bis zum Abbruchwert tmin_k erhöht,<br />
was zu einer Verkürzung der Schleife <strong>und</strong><br />
damit zum gewünschten Anstieg der Tonfrequenz<br />
führt. Mit Erreichen von tmin_k wird<br />
die Tonerzeugung T2 Schritte abgeschaltet<br />
<strong>und</strong> beginnt dann von neuem.<br />
Dank des dem uP nachgeschalteten RC-<br />
Netzwerks ist das erzeugte Signal weitgehend<br />
sinusförmig.<br />
3.2.5.4 Praktische Hinweise<br />
für die Programmierung<br />
Die die Tonhöhen der beiden Signalgeber bestimmenden<br />
Konstanten sind im Programmkopf<br />
wieder unter „— Benutzerspezifische<br />
Konstanten —" zu finden. Ihre Definition richtet<br />
sich naturgemäß etwas nach dem persönlichen<br />
Geschmack <strong>und</strong> Probieren geht hier wohl<br />
über Studieren. Bezüglich Typhon sollte man<br />
die Konstante tmrf_t nahe ihrem Maximalwert<br />
belassen, da sie für ein hochfrequentes Zischsignal<br />
wichtig ist; die Resonanzfrequenz des<br />
Typhons wird mit tfrq eingestellt.<br />
3.2.6 Schalter zu<br />
Servosignalkonverter<br />
(S2PWM)<br />
3.2.6.1 Problemstellung<br />
<strong>und</strong> Funktionsprinzip<br />
Im Funktionsmodellbau ist hin <strong>und</strong> wieder<br />
ein definierter Stellweg gefordert, z.B. für<br />
das Öffnen <strong>und</strong> Schließen von Klappen bzw.<br />
das Anheben <strong>und</strong> Absenken von Kranauslegern<br />
oder, bei nur kurzen Stellwegen, das<br />
Auslösen von Schlepphaken oder Katapulten.<br />
52<br />
Als Problemlösung bietet sich entweder ein<br />
Getriebemotor oder ein Servo (Rudermaschine)<br />
an, wobei Letzteres bei den heutigen Preisen<br />
von Standardservos die kostengünstigere<br />
Lösung darstellt. Der Servoeinsatz hat<br />
allerdings den Nachteil, dass zur Ansteuerung<br />
ein Kanalsignal (Analogkanal) benötigt<br />
wird, deren Zahl bei Fernsteuerungen meist<br />
begrenzter ist als die dank Ausbausätzen (oder<br />
PENTA-S) zahlreicheren Schaltfunktionen<br />
(Digitalkanäle). Kann man also die Ein-Aus-<br />
Schalterinformation in ein von der Rudermaschine<br />
lesbares Steuersignal übersetzen, so<br />
liefert ein am Übersetzer angeschlossenes Servo<br />
bei Schalter EIN auch ohne die Belegung<br />
wertvoller Analogkanäle einen einstellbaren<br />
Ausschlag. Die Mikroprozessorschaltung<br />
S2PWM ist ein solcher Übersetzer für maximal<br />
zwei Schaltereingänge. Mit ihr kann ein<br />
Servo in Abhängigkeit eines mit einem DIL-<br />
Mehrfachschalter (Mäuseklavier) vorgebbaren<br />
Methodencodes auf verschiedene Arten<br />
auslenkt werden, nämlich:<br />
Code [000] -> abwechselnder beidseitiger<br />
Triggerausschlag mit nur<br />
einem Schalter<br />
[001] -> beidseitiger Triggerausschlag<br />
mit beiden Schaltern<br />
[010] -> abwechselnder beidseitiger<br />
Ausschlag mit nur einem<br />
Schalter<br />
[011] -> beidseitiger Ausschlag mit<br />
beiden Schaltern<br />
[100] -> abwechselnder Vollausschlag<br />
mit nur einem Schalter<br />
[101] -> Vollausschlag mit beiden<br />
Schaltern<br />
[110] -> abwechselnder, langsamer<br />
Vollausschlag mit nur einem<br />
Schalter<br />
[111] -> langsamer Vollausschlag mit<br />
beiden Schaltern<br />
Codes [000] bis [101] übersetzen ein oder<br />
zwei Schalterinformationen in einen kurzen<br />
Trigger, z.B. zum Auslösen eines Schlepphakens<br />
oder Katapults, oder in einen anhaltenden<br />
Rechts- bzw. Linksausschlag eines Servos.
Beim Zweischalterbetrieb steuert jeder der beiden<br />
Schalter in eine definierte Richtung, während<br />
das Servo im Einschalterbetrieb (nur Sl)<br />
abwechselnd nach beiden Seiten ausschlägt,<br />
wobei die Ausschlaggeschwindigkeit nur vom<br />
verwendeten Servo abhängt. Bei AUS-Stellung<br />
beider Schalter steht das Servo entweder<br />
in Mittelstellung (Codes [000] bis [011]) oder<br />
bei Codes [100] bzw. [101] in der jeweiligen<br />
Endstellung (z.B. zum Öffnen bzw. Schließen<br />
von Klappen).<br />
Mit den Codes [110] <strong>und</strong> [111] kann man<br />
das Servo auch langsam bewegen, wodurch<br />
das Öffnen bzw. Schließen von Klappen (z.B.<br />
Heckklappe eines Rettungskreuzers) den optischen<br />
Gegebenheiten angepasst werden kann.<br />
Die Auslenkzeit (bzw. die Triggerzeit für Codes<br />
[000] <strong>und</strong> [001]) kann ebenso wie die Servoneutralstellung<br />
<strong>und</strong> der minimale bzw. maximale<br />
Ausschlag mit insgesamt drei Trimmern<br />
eingestellt werden.<br />
Liegen keine Schaltbefehle vor, so geht<br />
S2PWM nach wenigen Sek<strong>und</strong>en schlafen<br />
(sleep), womit der uP <strong>und</strong> die Signalerzeugung<br />
abgeschaltet werden. Man kann sich natürlich<br />
fragen, ob es auf den im Vergleich zur<br />
verbleibenden Stromrechnung kleinen Minderverbrauch<br />
eines schlafenden Mikroprozessors<br />
nun wirklich ankommt. Eigentlich nein.<br />
Was sleep hier aber interessant macht, ist die<br />
Tatsache, dass auch das Servosignal abgestellt<br />
<strong>und</strong> damit das Servo stillgelegt wird.<br />
Letzteres ist vor allen dann praktisch, wenn<br />
das Servo am Endausschlag unter Belastung<br />
steht <strong>und</strong> dann ein mürrisches Brummen hören<br />
lässt.<br />
Wegen der Zahl der benötigten Pins<br />
einerseits <strong>und</strong> der externen Justiermöglichkeiten<br />
von Servomitte, Ausschlagsspanne <strong>und</strong><br />
Auslenkgeschwindigkeit bzw. Triggerhaltezeit<br />
andererseits, die einen uP-internen Analog-digital-Wandler<br />
nötig machen, wird ein <strong>PIC</strong>-<br />
16C71 eingesetzt, der mit einem externen R-<br />
C-Taktgenerator betrieben wird. Wie das entsprechende<br />
Schaltbild zeigt, ist seine äußere<br />
Beschaltung <strong>einfach</strong> <strong>und</strong> besteht aus dem Mäu-<br />
Schaltbild für den Schalter zu Servosignal-<br />
konverter S2PWM-1<br />
S2PWM-1<br />
(justierbar)<br />
Der fertige Schalter zu Servosignalkonver-<br />
ter auf der linken Seite der Platine, wo die<br />
drei Trimmer <strong>und</strong> das Mäuseklavier zu se<br />
hen sind. Der Anschluss des Servos er<br />
folgt hier über eine Sockelleiste mit als<br />
Verpolungsschutz zugelöteter Buchse.<br />
(Das CMOS-IC, die Transistoren <strong>und</strong> die<br />
beiden Relais gehören zur Flut-/Lenz-Mo-<br />
torsteuerung eines flutbaren Docks <strong>und</strong><br />
haben mit dem S2PWM nichts zu tun, der<br />
für das Docktor zuständig ist.)<br />
seklavier mit Pull-down-Widerständen, den drei<br />
Trimmern für die Justierung, dem RC-Oszillator,<br />
den beiden Schaltereingängen (Sl <strong>und</strong> S2<br />
werden als TTL- bzw. CMOS-Signale angenommen<br />
andernfalls müssen Pull-down-Widerstände<br />
vorgesehen werden) <strong>und</strong> dem Servoausgang.<br />
53
Der S2PWM kann auf einer kleinen Platine<br />
aufgebaut werden, deren Layout <strong>und</strong> Bestückungsplan<br />
im Anhang zu finden sind.<br />
3.2.6.2 Das Programm<br />
S2PWM.asm<br />
Für den Mikroprozessor ergeben sich so die<br />
folgenden Aufgaben:<br />
• Lesen der beiden Schalter <strong>und</strong> des Codes am<br />
Mäuseklavier<br />
• Aus<strong>schalten</strong> des Prozessors, wenn für mehrere<br />
Sek<strong>und</strong>en kein Schaltbefehl vorliegt<br />
• Generierung eines PWM-Servosignals anhand<br />
des Methodencodes<br />
Das Hauptprogramm<br />
In der am Label PWM beginnende Endlosschleife<br />
wird das Servosignal generiert, das<br />
analog einem Empfängerkanalsignal einen<br />
LOW-Anteil von 30 ms <strong>und</strong> einen HIGH-Anteil<br />
von 1 bis 2 ms hat. Die Endlosschleife<br />
besteht, wie der generelle Ablaufplan von<br />
S2PWM.asm zeigt, aus zwei Hauptblöcken,<br />
dem Lese- <strong>und</strong> Testteil sowie dem kurzen Ausführungsteil<br />
beginnend am Label SIGNAL.<br />
Der Lese- <strong>und</strong> Testteil fällt in den langen<br />
LOW-Abschnitt des Servosignals. Hier werden<br />
in der Subroutine SERVSET zunächst die Ausschlaggrenzen<br />
sowie Triggerzeit bzw. Auslenkgeschwindigkeit<br />
durch Analog-digital-Wandlung<br />
(ADW) der Pegel an den entsprechenden<br />
Pins ermittelt. Zurück im Hauptprogramm folgen<br />
dann die Abfrage der Schalterstellungen<br />
<strong>und</strong> des Mäuseklaviers sowie einige Plausibilitätstests;<br />
so dürfen nicht beide Schalter gleichzeitig<br />
EIN sein <strong>und</strong> die Information von S2 ist<br />
nicht zugelassen, wenn MTH gerade, d.h. das<br />
unterste Bit null ist. Wenn eine langsame Servobewegung<br />
noch läuft (FLAG,2) oder das<br />
AUS-Signal erst sehr kurz ansteht (TAU>0),<br />
springt das Programm zum Label SIGNAL.<br />
54<br />
Generelles Ablaufdiagramm des Programms<br />
S2PWM-1.asm<br />
S2PWM<br />
Generalplan<br />
Bleiben die Schalter weiter aus, so wird der uP<br />
nach kurzer Wartezeit (WTSLP) abgeschaltet<br />
(sleep); er erwacht erst wieder, wenn an einem<br />
der Schaltern ein Signal anliegt.<br />
Bei gültigem Schalter (Label S-ON) wird<br />
zunächst eine Störungsunterdrückung durchgeführt,<br />
d.h., das Signal muss während einer<br />
bestimmten Zeit (SHALT) anstehen, bevor es<br />
gültig erklärt wird. Ist die Schalterstellung neu<br />
(FLAG,0=L), so werden dann je nach Methode<br />
verschiedene Parameter neu definiert <strong>und</strong><br />
im Monoschalterbetrieb (gerader MTH-Code)<br />
die Richtung umgeschaltet (alternierender Ausschlag)<br />
sowie bei Triggeranwendung Triggerzeit<br />
<strong>und</strong> -endflagge zurückgesetzt.<br />
Der Ausführungsteil beginnt mit dem Modul<br />
METHOD, wo anhand der vorgegebenen Methode<br />
die für das Servo notwendige Länge des<br />
Aktivsignals (1 bis 2 ms) bestimmt wird, wäh-
end der wesentlich längere LOW-Abschnitt (30<br />
ms) mit dem Test von TMRO in der S-LOW-<br />
Schleife abgeschlossen wird. Der Timer wird für<br />
den nächsten Frame sofort wieder gestartet <strong>und</strong><br />
das aktive Servosignal dann mittels eines 16-Bit-<br />
Registers (ILH) in einer Doppel schleife erzeugt.<br />
Damit die Doppelschleife mit decfsz funktioniert,<br />
muss rLHhi jeweils um eins erhöht werden.<br />
Schließlich folgt die Endlosschleife mit dem<br />
Rücksprung zum Label PWM.<br />
Modul METHOD<br />
Im Modul METHOD wird die Länge des Aktivimpulses<br />
ILH generiert, die aus einem konstanten<br />
Teil <strong>und</strong> dem variablen Teil ILHB besteht,<br />
die am Schluss der Routine zu einem 16-<br />
Bit-Register addiert werden; ILHhi ist dabei<br />
aus den oben erwähnten Gründen um eins zu<br />
erhöhen.<br />
S2PWM<br />
Modul Method<br />
Ablaufdiagramm des S2PWM-Unterpro-<br />
gramms METHOD<br />
Im linken Ast des Ablaufplans ist die ILH-<br />
Generierung mit unverzögertem Servoauschlag<br />
dargestellt. Ist einer der Schalter gesetzt (SS>0),<br />
so gilt mit ILMI bzw. ILMX, indirekt adressiert<br />
über SSS, der Maximalausschlag. Bei gesetzter<br />
Triggerflagge (FLAG,1) wird der Maximalausschlag<br />
nur für eine Zeit TRTIM gehalten, dann<br />
wird FLAG,1 <strong>und</strong> SSS auf null zurückgesetzt.<br />
Da SSS=0 bei indirekter Adressierung Mittelstellung<br />
ILMD bedeutet (FSR=SSS+H10), läuft<br />
das Servo nach Ablauf der Triggerzeit wieder in<br />
die Mittelstellung zurück. Das Gleiche gilt bei<br />
Schalterstellung null <strong>und</strong> MTHS
die Richtung umgeschaltet wird) <strong>und</strong> waitslp<br />
(= Schalterauszeit vor sleep) im Konstantendefinitionsblock<br />
definiert werden.<br />
Kann man bei bestimmten Anwendungen<br />
auf die Justiermöglichkeit verzichten <strong>und</strong> genügt<br />
es, die Werte für ILMD, ILMI, ILMX,<br />
DIHL <strong>und</strong> TGRHLT im Programm selbst vorzugeben,<br />
so reicht auch der kostengünstigere<br />
<strong>PIC</strong>-12C509A mit internem Taktgeber. Das<br />
dafür modifizierte Programm heißt S2PWM-<br />
O.asm. Es ist bis auf die PORT-Definitionen<br />
<strong>und</strong> die Subroutine SERVSET mit S2PWMl.asm<br />
identisch.<br />
3.3 Überwachungseinheit<br />
für Modellparameter<br />
(NAVIGUARD)<br />
3.3.1 Problemstellung <strong>und</strong><br />
Funktionsprinzip<br />
Durch laufende Überwachung von RC- <strong>und</strong><br />
Fahrakkuspannung, der Störungsfreiheit des<br />
RC-Signals <strong>und</strong> der Leckfreiheit im fahrenden<br />
Schiffsmodell kann der Besitzer rechtzeitig<br />
bei drohendem Unheil gewarnt werden.<br />
NAVIGUARD-Signalscheinwerfer auf dem<br />
Brückennock des Versorgermodells USS<br />
„Yukon". Die Lampe sollte eine Glühbirne<br />
sein, damit man ihr Blinken auch an einem<br />
sonnigen Teich nicht übersehen kann<br />
56<br />
Meine dazu geeignete uP-Schaltung heißt NA<br />
VIGUARD <strong>und</strong> untersucht vier Parameter auf<br />
vorzugebende Grenzwerte. Werden einer oder<br />
gar mehrere unterschritten, so gibt es Alarm,<br />
der von meinen Modellen als Morsetelegramm<br />
(Blinksequenz) mittels Signalscheinwerfer geblinkt<br />
wird, aber natürlich auch akustisch angezeigt<br />
werden könnte. Dazu kann bei Aufforderung<br />
eine beliebige fünfte Meldung gesendet<br />
werden. Bei mehreren Alarmen wählt<br />
NAVIGUARD die wichtigste für die Sendung<br />
aus.<br />
Das Morsetelegramm für jede der fünf<br />
Alarmmeldungen steckt direkt im Programm,<br />
bitweise von links nach rechts <strong>und</strong> zeilenweise<br />
als Tabelle gespeichert, wobei für jede Meldung<br />
(M1 bis M5) eine eigene Tabelle vorhanden<br />
ist. Im Alarmfall wird eine Zeile der entsprechenden<br />
Meldung ausgelesen <strong>und</strong> steuert<br />
dann anhand des Bitwertes Bit für Bit den<br />
Signalscheinwerfer.<br />
Zur Überwachung der Akkus wird die uP-<br />
Versorgungsspannung (RC-Akkuspannung) im<br />
Verhältnis zu einer stabilisierten Spannung bestimmt,<br />
während der Fahrspannungswert im<br />
Vergleich zur Versorgungsspannung des uP<br />
ermittelt <strong>und</strong> dann beide mit vorgegebenen<br />
Grenzwerten verglichen werden. Die Suche<br />
nach einem RC-Signalfehler erfolgt durch Ausmessen<br />
eines Kanalimpulses mit zugehöriger<br />
Synchronisationspause, die in definierten Grenzen<br />
bleiben müssen. Ein Servosignal muss daher<br />
am entsprechenden IC-Pin anliegen (es kann<br />
natürlich gleichzeitig auch für ein Servo benutzt<br />
werden). Der Lecksensor schließlich ist<br />
ein hochohmiger Eingang des uP, der bei Wasser<br />
zwischen den Sensorspitzen (Abstand 1 bis<br />
2 mm) auf Masse gezogen wird; das Teichwasser<br />
ist dazu in der Regel leitfähig (= schmutzig)<br />
genug. Als fünfte, freie Meldung wird in<br />
meinen Modellen die Modellstilllegung angezeigt<br />
(siehe Fahrtregler).<br />
Da zur Messung der Akkuspannungen ein<br />
Analog-Digital-Wandler notwendig ist, wird<br />
ein <strong>PIC</strong>-12C672 eingesetzt, der über einen integrierten<br />
ADW verfügt.
<strong>PIC</strong>-NAVIGUARD<br />
Schaltbild der Modellüberwachung<br />
NAVIGUARD<br />
3.3.1.1 Elektronische<br />
Schaltung <strong>und</strong> praktischer<br />
Aufbau<br />
Wie das Schaltbild zeigt, besteht NAVI<br />
GUARD aus zwei Baugruppen, nämlich der<br />
Elektronik um den uP, die von der RC-Batterie<br />
versorgt wird, <strong>und</strong> dem Treiber für den Signalscheinwerfer,<br />
der seinen Saft aus der größeren<br />
Fahrbatterie bezieht (im praktischen Betrieb<br />
ist der NAVIGUARD-Treiber eine Stufe in<br />
meinen Schaltertreibern, siehe Abschnitt<br />
3.5.3.1). Anzumerken ist hier, dass die gemeinsame<br />
Masseschiene positiv ist, d.h. die Pluspole<br />
von RC- <strong>und</strong> Fahrakku miteinander verb<strong>und</strong>en<br />
sind.<br />
Für die RC-Signalüberwachung muss ein<br />
Servosignal angeschlossen werden. Die RC-<br />
Akkuspannung liegt mit einer Zehnerdiode stabilisiert<br />
am RC-Akkueingang, während die Fahrspannung<br />
über einen Spannungsteiler zugeführt<br />
wird, der je nach Fahrnetzspannung unterschiedlich<br />
dimensioniert werden muss. Der Lecksensor<br />
ist ein hochohmiger uP-Eingang, der mit<br />
390 kOhm auf hohem Potenzial gehalten wird.<br />
3.3.1.2 Das Programm<br />
NAVIGUARD.asm<br />
Definieren wir damit die vom uP im NAVI<br />
GUARD zu erfüllenden Aufgaben:<br />
Test auf Alarmbedingung der vier Parameter<br />
RC-Signalstörung, Akkuspannung von<br />
RC- bzw. Fahrakku <strong>und</strong> Leckdetektion<br />
Prioritätsbildung bei Vorhandensein mehrerer<br />
Alarmmeldungen<br />
Gegebenenfalls Senden der entsprechenden<br />
Warnung in Form eines Morsetelegramms,<br />
dessen Zeichen im uP gespeichert sind<br />
Das Hauptprogramm<br />
Das Ablaufdiagramm des Programms NAVI<br />
GUARD beginnt in der linken unteren Hälfte<br />
mit der Initialisierungsschleife zur Messung<br />
von RCFRAM mit der Subroutine SCAN, die<br />
schon im Zusammenhang mit PENTAS.asm<br />
beschrieben wurde. RCFRAM (Zeit zwischen<br />
NAVIGUARD<br />
Ablaufdiagramm des Programms<br />
NAVIGUARD<br />
57
dem Beginn von zwei Impulspaketen) dient im<br />
weiteren Programmablauf als Taktbasis für die<br />
Blinkfrequenz.<br />
Die Endlosschleife des Hauptprogramms<br />
startet am Label LOOP <strong>und</strong> verzweigt meist<br />
direkt nach EVAL. In jedem btime-ten Durchlauf<br />
(btime ist der Multiplikator von RCFRAM<br />
für eine sichtbare Signalscheinwerferblinkfrequenz)<br />
jedoch wird zunächst die jeweilige Bit-<br />
Position (ZPOS) in der aktuellen Morsezeile<br />
MORSE der Meldung WARN bestimmt. Das<br />
höchste Bit von MORSE bestimmt dann den<br />
Zustand des Signalscheinwerfers, worauf die<br />
Bits in MORSE um eins nach links verschoben<br />
werden. Am Zeilenende (ZPOS=0) wird sowohl<br />
ZPOS auf 8 gesetzt als auch mit der<br />
Subroutine MELDG durch Tabellenaufruf die<br />
nächste Zeile MORSE der Meldung WARN<br />
bestimmt; wird dort eine Endmarke H'FF',<br />
d.h. alle Zeilen-Bits „1", gef<strong>und</strong>en, wird der<br />
Zeilenzeiger (ZEILE) auf eins zurückgesetzt<br />
<strong>und</strong> die Warnungsmeldung neu begonnen.<br />
Am Label EVAL beginnt die Signalauswertung.<br />
Sie besteht aus den fünf Abschnitten<br />
RC-Signalüberwachung (Subroutine SCAN mit<br />
Auswertung der Fehlerflagge), den beiden<br />
ADW-Teilen zur Messung der Spannungen von<br />
RC-Akku <strong>und</strong> Fahrbatterie <strong>und</strong> den zwei <strong>einfach</strong>en<br />
Signalüberwachungen Leckdetektor<br />
(durch Pegeländerung an einem hochohmigen<br />
Eingang infolge der Leitfähigkeit des eingedrungenen<br />
Teichwassers) sowie dem Befehl<br />
für eine Sondermeldung.<br />
In der Subroutine ADW für die Spannungsmessungen<br />
(Analog-Digital-Wandler) wird<br />
zunächst jeweils der uP-interne ADW für den<br />
entsprechenden Eingang (hier GPIO,0 oder<br />
GPIO,l) initialisiert. Da dies ein bisschen dauert,<br />
wird eine „Zeitvergeudungsschleife" durchlaufen<br />
<strong>und</strong> danach in der Schleife AD1 bzw.<br />
AD2 die eigentliche Spannungsmessung am entsprechenden<br />
Pin durchgeführt, wobei<br />
ADCON0, go bestimmt, wann die ADW beendet<br />
ist. Ihr Ergebnis, ein Wert zwischen null <strong>und</strong><br />
255 (255 entspricht der Versorgungsspannung),<br />
ist dann im Register ADRES gespeichert.<br />
58<br />
Im Falle der RC-Spannungsmessung<br />
(GPIO,0) wird das Messergebnis nach Abzug<br />
von 100 auch in VKORR gespeichert <strong>und</strong> null<br />
gesetzt, wenn das Ergebnis dieser Differenz<br />
negativ ausfallt (VKORR wird zur Korrektur<br />
der Fahrspannungsmessung benötigt). ADRES<br />
wird dann mit dem Grenzwert für die RC-<br />
Akkuspannung rcmax verglichen. Hier gilt es<br />
zu bedenken, das ADRES eine mit einer Zehnerdiode<br />
stabilisierte, konstante Spannung bezogen<br />
auf die variable Versorgungsspannung<br />
des uP ist, wobei Letztere die interessierende<br />
Größe darstellt. Der Messwert ADRES wird<br />
also mit fallender RC-Akkuspannung größer<br />
<strong>und</strong> der Alarm daher ausgelöst, wenn<br />
ADRES > rcmax<br />
wird.<br />
Die Fahrspannung wird über einen Spannungsteiler<br />
GPIO,1 zugeführt <strong>und</strong> ebenfalls<br />
mit ADW digitalisiert. Der in ADRES erscheinende<br />
Wert ist dann ein Maß für die<br />
Spannung am Spannungsteilerknoten bezogen<br />
auf die Versorgungsspannung des uP (RC-<br />
Spannung). Bei gleichzeitig fallender RC-<br />
Spannung wird dieses Messergebnis also verfälscht,<br />
weshalb eine Korrektur, d.h. die Addition<br />
von VKORR (siehe oben), nötig ist;<br />
das Additionsergebnis soll 255 nicht übersteigen.<br />
Alarm wird ausgelöst, wenn<br />
(ADRES+VKORR) > fhrmx<br />
wird.<br />
Jede Alarmquelle schreibt gegebenenfalls<br />
ihre Meldungsnummer ins Alarmregister<br />
(MLDP) <strong>und</strong> überschreibt dort dann eventuelle<br />
andere Nummern. Die Anordnung der einzelnen<br />
Parametertests hinter dem Label EVAL<br />
entscheidet daher nach dem Motto „Wer zuletzt<br />
lacht..." über die Priorität der einzelnen Warnungen.<br />
Im Musterprogramm hat der RC-Signalfehler<br />
die höchste Priorität.<br />
Im alarmfreien Zustand ist MLDP=0. Das<br />
Warnungstextauswahlregister WARN <strong>und</strong> das
Referenzregister MLDO werden null gesetzt<br />
<strong>und</strong> der uP springt über den Label WNEW<br />
(neue Warnung) nach Initialisierung von Zeilennummer<br />
<strong>und</strong> Zeilenzeiger sowie nach Aus<strong>schalten</strong><br />
des Signalscheinwerfers direkt zu Beginn<br />
der Endlosschleife zurück. Ist dagegen<br />
eine Meldung vorhanden <strong>und</strong> ist sie seit avgO<br />
Schleifendurchläufen gleich der Referenzmeldung<br />
MLDO, so wird das Abarbeiten des laufenden<br />
Warnungsmeldung fortgesetzt.<br />
Im Falle einer neuen Warnung also bei<br />
MLDP = MLDO <strong>und</strong> AVG > avgO<br />
(d.h., ein Alarm muss für längere Zeit<br />
vorliegen), wird WARN=MLDP gesetzt <strong>und</strong><br />
mit dem Rücksprung über WNEW direkt mit<br />
dem Senden der neuen Meldung begonnen,<br />
wenn vorher keine Meldung vorlag<br />
(WARN=0), andernfalls wird durch Erhöhung<br />
des Taktteilers MTIM noch eine kurze Pause<br />
eingelegt.<br />
Programmierung der Tabellen<br />
in der Routine MELDG<br />
Die Subroutine MELDG ist als Tabellenaufruf<br />
programmiert, wobei zunächst mit der Meldungsnummer<br />
WARN die aktuelle Tabelle<br />
ausgesucht wird (computed goto). Bei<br />
WARN=0 wird nur eine MORSE-Zeilen mit<br />
Nullen produziert <strong>und</strong> der Zeilenzähler zurückgesetzt.<br />
Die Morsetelegramme der einzelnen Meldungen<br />
stecken, von links nach rechts gelesen,<br />
in den Tabellen M1 bis M5, wo die Ein- <strong>und</strong><br />
Aus-Zustände des Signalscheinwerfers in Zeilen<br />
zu je acht Zeichen so geschrieben sind,<br />
dass sich ein dem vorgegebenen Text entsprechendes<br />
Morsesignal ergibt. Der Parameter<br />
ZEILE sucht dann, wiederum mit computed<br />
goto, die jeweilige Zeile aus <strong>und</strong> lädt deren<br />
Inhalt beim Routinenrücksprung in das Arbeitsregister<br />
W, von wo es dann in das Register<br />
MORSE kopiert wird.<br />
Bekanntlich besteht ein Morsezeichen aus<br />
einer Reihe von kurzen (Punkt) <strong>und</strong> langen<br />
Impulsen (Strich), in unserem Fall kurzen <strong>und</strong><br />
langen Lichtblitzen, die von Aus-Perioden<br />
(Pausen) unterschiedlicher Länge unterbrochen<br />
sind. Die Längen von Punkt, Strich <strong>und</strong><br />
Pausen stehen in einem festen Verhältnis<br />
zueinander, wobei die zeitliche Länge einer<br />
„Einheit" (Punkt) in der Praxis von der Geübtheit<br />
des Gebers oder in unserem Fall von<br />
der unterscheidbaren Blinkgeschwindigkeit<br />
der verwendeten Glühbirne abhängt (beim<br />
NAVIGUARD in der Größenordnung von<br />
r<strong>und</strong> 0,25 s):<br />
kurzer Impuls (Punkt): eine Einheit [1]<br />
langer Impuls (Strich): drei Einheiten [111]<br />
Pause zwischen<br />
Impulsen: drei Einheiten [000]<br />
Abschluss Buchstabe: plus zwei Einheiten [+00] (total 5)<br />
Abschluss Wort/<br />
Leerzeichen: plus zwei Einheiten [+00] (total 7)<br />
Eine „1" steht hier jeweils für Lampe EIN<br />
<strong>und</strong> eine „0" für Lampe AUS.<br />
Bezüglich Einzelheiten der Umsetzung von<br />
Buchstaben in Morsezeichen sei auf die Tabelle<br />
verwiesen, wo für alle Buchstaben <strong>und</strong> Zahlen<br />
das entsprechenden Morsezeichen (Punkt/<br />
Strich) <strong>und</strong> der jeweilige binäre Datensatz aufgelistet<br />
sind. Als „stop"-Zeichen werden acht<br />
„1" in einer Zeile verwendet.<br />
Für das vorliegende <strong>PIC</strong>-Programm muss<br />
der Benutzer seine verschiedenen Warnungsmeldungen<br />
anhand der Liste in den Morsecode<br />
übersetzen <strong>und</strong> dann in Form von Zeilen ä acht<br />
Zeichen (Bits) hinter den retlw-Befehlen der<br />
Tabellen M1 bis M5 einsetzen (im Programm<br />
ist ein allgemein gehaltener Text als Beispiel<br />
programmiert). Dabei sollte man eine Gesamtsumme<br />
von 128 Zeilen nicht überschreiten.<br />
Das Programm NAVIGUARD.asm ist dabei<br />
schon so groß, dass der Programmzeilenzähler<br />
PC größer neun Bits wird, weswegen für das<br />
„computed goto" der Tabellen (siehe Abschnitt<br />
2.4.2.3) das 10. Bit mittels PCLATH-Direktive<br />
ergänzt werden muss.<br />
59
Tabelle Morsezeichen<br />
<strong>und</strong> ihre binäre Repräsentation<br />
a . - 100011100000<br />
ä 1000111000100011100000<br />
b 11100010001000100000<br />
c -.-. 1110001000111000100000<br />
ch - 11100011100011100011100000<br />
d -.. 1110001000100000<br />
e . 100000<br />
f ..-. 10001000111000100000<br />
g --. 111000111000100000<br />
h .... 100010001000100000<br />
i .. 1000100000<br />
j .--- 100011100011100011100000<br />
k -.- 111000100011100000<br />
I 10001110001000100000<br />
m -- 11100011100000<br />
n -. 111000100000<br />
0 - 11100011100011100000<br />
ö -. 111000111000111000100000<br />
p 1000111000111000100000<br />
q --.- 111000111000100011100000<br />
r .-. 1000111000100000<br />
s ... 10001000100000<br />
t - 11100000<br />
u ..- 1000100011100000<br />
ii ..-- 1000100011100011100000<br />
v 10001000100011100000<br />
w .-- 100011100011100000<br />
x 1110001000100011100000<br />
y -.-- 111000100011100011100000<br />
z --.. 1110001110001000100000<br />
1 .---- 100011100011100011100011100000<br />
2 ..- 1000100011100011100011100000<br />
3 ..-- 10001000100011100011100000<br />
4 100010001000100011100000<br />
5 1000100010001000100000<br />
6 -.... 111000100010001000100000<br />
7 11100011100010001000100000<br />
8 - .. 1110001110001110001000100000<br />
9 - . 111000111000111000111000100000<br />
0 - 11100011100011100011100011100000<br />
10001110001000111000100011100000<br />
. --.-- 1110001110001000100011100011100000<br />
? ..--.. 100010001110001110001000100000<br />
Leerzeichen 0000000<br />
stop 11111111<br />
@K Blinken kurz 10101010101010<br />
®L Blinken lang 11111110000000<br />
@F Lichtblitze 10000001000000<br />
@L Lichtunterbrüche 11111101111110<br />
3.3.2.3 Praktische Hinweise<br />
für die Programmierung<br />
Die einzelnen Grenzwerte, insbesondere für das<br />
RC-Signal <strong>und</strong> die Akkuspannungen, müssen<br />
vom Anwender seinen Gegebenheiten angepasst<br />
werden. Hinsichtlich des RC-Signals sei auf die<br />
diesbezüglichen Hinweise für den PENTA-S<br />
60<br />
verwiesen. Die entsprechenden Werte für die<br />
Akkuspannungen ermittelt man am <strong>einfach</strong>sten<br />
durch Versuch, wobei die im Programm angegebenen<br />
Größen durchaus als gute Richtlinien<br />
dienen können; wegen der Streuung der verwendeten<br />
Bauteile (Z-Diode <strong>und</strong> Widerstände)<br />
ist eine Überprüfung aber ratsam.<br />
Wer über einen FORTRAN-Compiler verfügt,<br />
kann sich die Übersetzung der gewünschten<br />
Meldungen in den entsprechenden Morsetext<br />
sparen, wenn er das auf der ModellWerft-<br />
Homepage (www.modellwerft.de/downloads)<br />
im ,,.for"-Directory vorhandene FORTRAN-<br />
Programm MORSE.for benutzt. Es benötigt als<br />
Input ein File namens „messg.in", für das ein<br />
Muster ebenfalls dort zu finden ist. In dessen<br />
erster Zeile steht die Zahl der gewünschten Meldungen,<br />
gefolgt vom Klartext der Meldungen<br />
(erlaubt sind nur die in der Tabelle angegebenen<br />
Zeichen), die jeweils 79 Zeichen lang sein dürfen.<br />
Bei Ausführung generiert MORSE ein File<br />
„morse.asm", das an entsprechender Stelle nur<br />
noch in NAVIGUARD.asm kopiert werden<br />
muss <strong>und</strong> auch die nötigen PCLATH- <strong>und</strong> ORG-<br />
Anweisungen enthält. Teil des Ergebnisses sind<br />
auch die im Kopf jeder Warnung als Kommentar<br />
aufgelisteten Morsecodes der Meldung.<br />
Eine Besonderheit von MORSE.for sind<br />
fünf Sonderzeichen, die alle mit einem „@"<br />
beginnen <strong>und</strong> mit „@K" (hohe Blinkfrequenz),<br />
„@L" (niedrige Blinkfrequenz), „@F" (Blitze),<br />
„@I" (inverse Blitze) <strong>und</strong> „@S" (lange<br />
Pausen) bezeichnet sind (in der Morsetabelle<br />
angegeben). Diese Sonderzeichen wurden von<br />
mir für diejenigen Modellbesitzer eingeführt,<br />
die - wie ich selbst - des Morsens nicht so<br />
ganz mächtig sind <strong>und</strong> daher die verschiedenen<br />
vom Modell geblinkten Warnungen nur<br />
eingeschränkt lesen können.<br />
3.4 Drehzahlsteller<br />
In diesem Abschnitt werden sieben Drehzahlsteller<br />
vorgestellt, die mit Ausnahme des<br />
DCNAUT alle vom Impulstyp sind <strong>und</strong> mit
einer Taktfrequenz des Motorsignals von etwas<br />
über 2 kHz arbeiten. Ansonsten reicht die<br />
Palette vom Minidrehzahlsteller MONONAUT<br />
mit Brückentreiber für Kleinmotoren <strong>und</strong> Kleinmodelle<br />
über meinen Standarddrehzahlsteller<br />
MLTNAUT für Mehrwellenmodelle, wo sich<br />
bei Hartrudermanövern zwecks Verbesserung<br />
der Manövrierfähigkeit die Motordrehrichtung<br />
auf einer Modellseite einseitig kehren lässt, bis<br />
zum Drehzahlregler AUTONAUT, der eine<br />
automatische Fahrstufenanpassung eines Modells<br />
an eine externe Regelgröße (z.B. eine<br />
anderes Modell bei Parallelfahrt) möglich<br />
macht. Der Drehzahlsteller DCNAUT dagegen<br />
verzichtet auf ein getaktetes Motorsignal<br />
<strong>und</strong> gibt stattdessen eine 4-Bit-Zahl an seinen<br />
Treiber weiter, die dieser in eine die Drehzahl<br />
bestimmende, motorinnenwiderstandkompensierte<br />
Klemmspannung für die Antriebsmotoren<br />
umwandelt. Zwei weitere Drehzahlsteller<br />
MODCON kombinieren die Modellüberwachung<br />
NAVIGUARD mit dem Drehzahlsteller<br />
MLTNAUT in einem uP (MODCON-S) <strong>und</strong><br />
im MODCON-P zusätzlich noch mit dem AU<br />
TONAUT. Schließlich ist MODCON-D ein<br />
echter Doppeldrehzahlsteller plus NAVI<br />
GUARD, wo die beiden Antriebsseiten als<br />
Funktion der Ruderstellung unabhängig<br />
voneinander gedrosselt bzw. beschleunigt werden,<br />
was z.B. auch für Kettenfahrzeuge von<br />
Interesse sein kann.<br />
3.4.1 Einwellen-2-kHz-<br />
Drehzahlsteller für Kleinmodelle<br />
(MONONAUT)<br />
3.4.1.1 Eigenschaften<br />
Der MONONAUT ist ein Drehzahlsteller für<br />
Kleinmotoren <strong>und</strong> mit Drehzahlstellern auf<br />
Basis modifizierter Servoelektroniken vergleichbar.<br />
Mit Standardbauteilen kann er auf<br />
einer Platine von 23x27 mm aufgebaut werden<br />
(Platinenlayout <strong>und</strong> Bestückungsplan im An-<br />
Drehzahlsteller MONONAUT für Kleinmo<br />
delle zusammen mit dem ICPROP-Empfän-<br />
ger auf einer Platine. Der MONONAUT<br />
nimmt dabei das rechte Drittel der Platine<br />
in Anspruch mit dem uP in der unteren<br />
<strong>und</strong> der Transistorbrücke in der oberen<br />
Bildhälfte. Ganz rechts oben die Buchse<br />
für die Alarm-LED<br />
hang); ich verwende ihn in Verbindung mit<br />
meinem Miniempfänger ICPROP für meine<br />
Kleinmodelle.<br />
Zum Einsatz kommt einmal mehr der kleine<br />
<strong>und</strong> billige Mini-uP <strong>PIC</strong>-12C509A mit nur<br />
acht Pins, wobei er dank Verwendung des internen<br />
4-MHz-Taktfrequenzoszillators praktisch<br />
ohne externe Beschaltung auskommt. Die<br />
4 MHz sind ausreichend für einen Motorsignaltakt<br />
von 2,2 kHz <strong>und</strong> eine RC-Signalauflösung<br />
von 14 us; bei den üblichen 1 ms variabler<br />
RC-Signallänge wird das Signal damit in je<br />
31 Schritte vorwärts bzw. rückwärts unterteilt.<br />
Die Eigenschaften des MONONAUT lassen<br />
sich wie folgt zusammenfassen:<br />
• Taktfrequenz von 2,2 kHz<br />
• Fahrtrichtungsumkehr via Transistorbrücke<br />
für Kleinmotoren bis etwa 600 mA. Für größeren<br />
Antriebsleistungen kann nach geringfügigen<br />
Änderungen im Programm (die dort<br />
angegeben sind) auch eine Treiberstufe mit<br />
Umpolrelais angesteuert werden.<br />
• Die Justierung auf die Nullstellung des Fahrmotors<br />
erfolgt jeweils automatisch beim Ein<strong>schalten</strong><br />
des Empfängers <strong>und</strong> nimmt dann<br />
den Wert an, den man am eingeschalteten<br />
Sender als Mittelstellung vorgibt (gewisse<br />
Wertegrenzen können im Programm eingegeben<br />
werden).<br />
61
• Der Motor ist durch ein entsprechendes<br />
LOW-Signal am Enable-Pin des uP unabhängig<br />
von der Impulsvorgabe abschaltbar.<br />
• Anhebung der Motorspannung im unteren<br />
Fahrstufenbereich durch nichtlineare Kennlinie<br />
<strong>und</strong> Motorkick, d.h. Vorgabe einer leicht<br />
höheren Fahrstufe für wenige Sek<strong>und</strong>en nach<br />
längerem Motorstillstand, um ihn erst einmal<br />
anzuwerfen.<br />
• Alarmleuchte (LED)<br />
Kontinuierliches Leuchten bei durch Enable<br />
abgeschaltetem Fahrmotor<br />
Schnelles Blinken bei fehlerhaftem RC-<br />
Empfang<br />
Langsames Blinken bei Wasser am Lecksensor<br />
(Wassereinbruch)<br />
• Watch Dog Timer. Die uP-interne Überwachung<br />
durch den Watch Dog Timer verhindert<br />
einen Ausfall des uP (Programmabsturz)<br />
z.B. nach kurzem Einbruch der Versorgungsspannung.<br />
Schaltbild des Kleindrehzahlstellers<br />
MONONAUT (Version Brücke)<br />
Schaltbild des Kleindrehzahlstellers<br />
MONONAUT (Version Treiber)<br />
62<br />
MONONAUT-T<br />
MONONAUT-B<br />
Wie dem Schaltbild (Version „Brücke") zu<br />
entnehmen ist, genügt für die externe Beschaltung<br />
des uP neben einem Siebkondensator ein<br />
Widerstand für den Lecksensor, die Alarm-<br />
LED nebst obligatem Vorwiderstand sowie die<br />
Transistorbrücke für Motoren bis ca. 600 mA<br />
(Kleinmodelle). Bei größeren Modellen <strong>und</strong><br />
Motorleistungen gilt die Version „Treiber" mit<br />
Leistungstransistor <strong>und</strong> Umpolrelais.<br />
3.4.1.2 Problemstellung<br />
<strong>und</strong> Funktionsprinzip<br />
Die Kanalausgänge eines RC-Empfängers liefern<br />
Impulse von 1 bis 2 ms Länge (Aktivsignal,<br />
t [a,RC] ), gefolgt von einer bezüglich der Information<br />
irrelevanten, r<strong>und</strong> 30 ms dauernden<br />
Pause (Passivsignal, t [RC]). Das den Fahrstrom<br />
liefernde PWM-Rechtecksignal (PWM = Puls-<br />
Weiten-Modulation) ist dagegen während einer<br />
Periode von, beim MONONAUT, 0,43 ms<br />
Dauer (entsprechend 2,2 kHz Taktfrequenz)<br />
für jeweils ILH x 14 us high <strong>und</strong> für ILL (31 -<br />
ILH) x 14 us low. Aus dem Duty Cycle genannten<br />
Verhältnis zwischen High- <strong>und</strong> Low-<br />
Anteilen ergibt sich dann die Drehzahl des<br />
Motors zwischen null (ILH=0) <strong>und</strong> Vollgas<br />
(ILH=maximum, 31 x 14 us = 0,43 ms).<br />
Der uP steuert die Motorstromtransistorbrücke<br />
(hier Pin6 <strong>und</strong> Pin7), die je nach Vorgabe<br />
am Sender abwechselnd für ILH Zeiteinheiten<br />
EIN <strong>und</strong> ILL=(31 - ILH) Zeiteinheiten<br />
AUS geschaltet werden muss, wobei der konkrete<br />
Zustand der beiden Pins während der<br />
EIN-Phase über die Drehrichtung entscheidet.<br />
Die Umschaltung selbst nimmt jeweils nur 2<br />
bis 4us in Anspruch, weswegen die übrige<br />
Zeit zur Ausmessung der Kanalimpulslänge<br />
<strong>und</strong>, folgend der Bestimmung von ILH, der<br />
Motordrehrichtung sowie für andere Aufgaben<br />
zur Verfügung steht.<br />
Wie man im Oszillogramm von Fahr-<br />
(oben) <strong>und</strong> Motorimpuls (unten) gut erkennt,<br />
sind die Umschaltzeitintervalle mit 0,43 ms<br />
wesentlich kürzer als die Länge des auszu-
Drehzahlstellersignale: a.) RC-lmpulspa-<br />
ket, b.) Kanalimpuls, c.) Motorsignal<br />
(PWM-Signal)<br />
Die Oszillogramme des MONONAUT.<br />
Unten das Eingangssignal, oben das<br />
Fahrsignal für den Motortreiber<br />
messenden Kanalimpulses (1-2 ms), weswegen<br />
man die in den oben erwähnten SCAN-<br />
Unterprogrammen schon verschiedentlich angewandte<br />
Methode der durchgehenden Zählung<br />
(siehe PENTAS.asm oder<br />
NAVIGUARD.asm) hier leider nicht verwenden<br />
kann. Vielmehr muss die Kanalimpulslänge<br />
abschnittsweise bestimmt werden, um<br />
dazwischen die Treiberstufe umsteuern zu können.<br />
SCAN ist daher hier so aufgebaut, dass<br />
jeder Durchlauf exakt die oben schon erwähn<br />
ten 14 us, d.h. einen SCAN-Zyklus, dauert,<br />
womit die Kanalimpulslänge als sein Vielfaches<br />
definiert ist. In der langen Pause von 20<br />
bis 30 ms Dauer zwischen den Kanalimpulsen<br />
kann dann das Messergebnis verarbeitet <strong>und</strong> in<br />
die richtigen Motorstromimpulslängen umgerechnet<br />
werden (Unterprogramm CLCTIM).<br />
MONONAT.asm <strong>und</strong> auch das weiter unten<br />
beschriebene MULTINAUT.asm sind extrem<br />
zeitkritische Programme, d.h., es kommt darauf<br />
an, dass in bestimmten Programmabschnitten<br />
genaue Vielfache des SCAN-Zyklus verbraucht<br />
werden. Da Verzweigungen zu einem unterschiedlichen<br />
Verbrauch von Maschinenzyklen<br />
führen, wird sowohl in MONONAUT.asm als<br />
auch in MLTNAUT.asm zur Zyklusangleichung<br />
viel Gebrauch von auf den ersten Blick sinnlos<br />
erscheinenden Anweisungen wie dem „Nullbefehl"<br />
nop, goto zur darauf folgenden Zeile<br />
(= Verbrauch von zwei Maschinenzyklen) oder<br />
der Subroutine LEERn gemacht.<br />
3.4.1.3 Das Programm<br />
MONONAUT.asm<br />
Das Hauptprogramm<br />
Wie das generelle MONONAUT-Ablaufdiagramm<br />
zeigt, gliedert sich das Programm in<br />
drei Abschnitte, nämlich die Initialisierung<br />
(links oben), wo zunächst die Mittelstellung<br />
des Kanalimpulses (I0F=Fahrnull) festgelegt<br />
wird, <strong>und</strong> die beiden die Endlosschleife bildenden<br />
Schleifen LOW- <strong>und</strong> HIGH, die die<br />
Low- <strong>und</strong> High-Anteile des PWM-Motorsignals<br />
generieren.<br />
Während der Initialisierung wird SCAN<br />
256-mal durchlaufen, um den Mittelwert der<br />
Kanalimpulslänge bei Sendermittelstellung<br />
(I0F) <strong>und</strong> die Länge des RC-Frames (RCF<br />
RAM) zu bestimmen (jeweils als hi-Bytes von<br />
16-Bit-Variablen), wozu der Sender eingeschaltet<br />
sein <strong>und</strong> auf der gewünschten Mittelstellung<br />
stehen muss. Bei fehlendem oder gestörtem<br />
Signal springt MONONAUT jeweils zum<br />
63
Generelles Ablaufdiagramm des Programms<br />
MONONAUT<br />
Label INIT zurück <strong>und</strong> wartet mit der Initialisierung,<br />
wobei die Alarm-LED blinkt. IOF wird<br />
abschließend mit im Programm vorgegebenen<br />
Grenzwerten verglichen <strong>und</strong> gegebenenfalls<br />
innerhalb dieser Grenzen gehalten.<br />
Damit beginnt die aus Low- <strong>und</strong> High-<br />
Schleife bestehende Endlosschleife, deren<br />
Durchlauf jeweils einem Zyklus des Motorstrom-PWM-Signals<br />
von 0,43 ms Dauer entspricht.<br />
Beide Schleifen „PLOW" (Low-Teil)<br />
<strong>und</strong> „PHIGH" (High-Teil) sind dabei bis auf<br />
die Motorschaltung identisch. Wir können uns<br />
daher bei der weiteren Betrachtung auf eine<br />
Schleife, z.B. PLOW, beschränken.<br />
Zunächst wird der Watch Dog Timer<br />
(WDT) zurückgesetzt <strong>und</strong> die RC-Signalfehlerflagge<br />
(RFLG,7) abgefragt, um gegebenenfalls<br />
in den Fehlerteil PLOWE zu springen.<br />
Dann wird die Laufvariable „I" gleich ILL<br />
(bzw. ILH in PHIGH) gesetzt <strong>und</strong> auf null<br />
geprüft, was einen Sprung in die jeweils an<br />
64<br />
MONONAUT<br />
Generalplan<br />
dere Schleife zur Folge hätte (Stopp bzw.<br />
Vollgas), ansonsten wird die Transistorbrücke<br />
AUS (beide Pins 0) geschaltet. Eine Prüfung<br />
der Flagge SFLG,2 (RC-Signalpassivflagge)<br />
entscheidet dann den weiteren Verlauf.<br />
Ist das RC-Signal aktiv (SFLG,2=0), d.h.,<br />
befinden wir uns in der Phase der Kanalimpulslängenmessung,<br />
so wird das Fahrimpulslängenregister<br />
FLEN um eins erhöht, wil<br />
bisher ungefähr 14 Maschinenzyklen, d.h. ein<br />
SCAN-Zyklus, verbraucht wurden. Dann wird<br />
in die SCAN-Schleife gesprungen (Label<br />
PLOWL) <strong>und</strong> die dann noch ILL-1 Mal durchlaufen;<br />
bei ILL-1=0 geht's natürlich gleich in<br />
den HIGH-Block.<br />
Befinden wir uns dagegen im passiven Teil<br />
des RC-Signals (SFLG,2=1), braucht sich der<br />
uP für einige Zeit nicht um die Ausmessung<br />
des Fahrimpulses zu kümmern <strong>und</strong> kann sich<br />
der Auswertung zuwenden, d.h. der Berechnung<br />
von ILL, ILH <strong>und</strong> den Pin-Zuständen<br />
nach Vorgabe von FLEN, was in der Routine<br />
CLCTIM geschieht. Für den Aufruf von<br />
CLCTIM müssen allerdings verschiedene Kriterien<br />
erfüllt sein, nämlich:<br />
• SFLG,0=1, d.h., die Flagge für das Kanalimpulsende<br />
muss gesetzt sein, da sonst die FLEN-<br />
Bestimmung noch nicht abgeschlossen ist.<br />
• TMRO < lowmin, d.h., der passive Signalteil<br />
muss noch eine Weile andauern.<br />
• I > ilc_min, da CLCTIM diese Anzahl an<br />
SCAN-Zyklen verbrauchen könnte<br />
Die Zahl der von CLCTIM verbrauchten<br />
SCAN-Zyklen wird im Arbeitsregister übergeben<br />
(retlw) <strong>und</strong> von I abgezogen. Dann wird<br />
in die SCAN-Schleife (PLOWL bzw.<br />
PHIGHL) gesprungen.<br />
Nach ILL SCAN-Zyklen verzweigt das Programm<br />
in die High-Schleife mit Label PHIGH,<br />
die bis auf die Zuweisung von ILH zur Schleifenvariablen<br />
I <strong>und</strong> das Schalten des Fahrsignals<br />
auf EIN (high-Schaltung einer der beiden<br />
Pins je nach Motordrehrichtung) gleich aufgebaut<br />
ist wie die Low-Schleife.
Wie schon in den anderen gleichnamigen<br />
SCAN-Modulen wird auch hier bei der Entdeckung<br />
von Fahrimpulsstörungen eine Fehlerflagge<br />
(RFLG,7) gesetzt, die zu Beginn der<br />
Low- bzw. High-Schleifen eine Verzweigung<br />
in die Fehlerteile (Label PLOWE bzw. PHIG-<br />
HE) veranlasst. Eine Abfrage des Timers TMRO<br />
mit Warteschleife sorgt dort zunächst für die<br />
Einhaltung der RC-Framelänge auch bei Signalfehlern<br />
(z.B. bei TMRO < passm). Dann<br />
wird ignore-mal der Fehler ignoriert <strong>und</strong> mit<br />
den alten Fahrstufenwerten ILL <strong>und</strong> ILH weitergearbeitet,<br />
bevor der Fahrmotor gestoppt,<br />
ILH=0 <strong>und</strong> ILL=31 gesetzt (Routine M_AUS),<br />
ein schnelles Blinken der Alarm-LED veranlasst<br />
<strong>und</strong> zurück in die Endlosschleife gesprungen<br />
wird. Jede Unregelmäßigkeit im RC-Signal<br />
führt so schon nach kurzer Zeit zum Maschinenstopp,<br />
ohne dass allerdings schon die<br />
kleinste Unterbrechung ein Maschinenstottern<br />
bewirkt.<br />
Am Beginn jeder Hauptschleife von maximal<br />
0,43 ms Länge wird wie schon gesagt der<br />
Watch Dog Timer (WDT) zurückgesetzt, was<br />
bei normalem Programmablauf den WDT-Reset<br />
verhindert (siehe Abschnitt 2.4.8.1). Sollte<br />
sich das Programm jedoch einmal aufhängen,<br />
z.B. wegen eines kurzzeitigen Einbruchs in der<br />
Versorgungsspannung, so kommt es schon bald<br />
zum WDT-Reset <strong>und</strong> damit zum Rücksprung<br />
zur Programmzeile null. Die gesetzte STA-<br />
TUS-Flagge to hilft dann, den Programmteil<br />
Vorlauf zu überspringen (Label WDTEX) <strong>und</strong><br />
sich sofort wieder der Drehzahlkontrolle des<br />
Fahrmotors zuzuwenden; man kann davon ausgehen,<br />
dass die Werte von I0 <strong>und</strong> RCFRAM<br />
erhalten bleiben.<br />
Modul SCAN<br />
SCAN dient der Bestimmung der Fahrimpulslänge.<br />
Da dieser, wie gesehen, erheblich länger<br />
als die Periode des PWM-Signals ist, kann<br />
die Messung nur schrittweise zwischen den<br />
PWM-Umschaltungen erfolgen. SCAN besteht<br />
Ablaufdiagramm des MONONAUT-Unter-<br />
programms SCAN<br />
MONONAUT<br />
MODUL SCAN<br />
daher aus zwei Sektionen (passiv <strong>und</strong> aktiv)<br />
mit je zwei Untergruppen „in Arbeit" <strong>und</strong><br />
„Start", die durch Flaggen selektioniert werden.<br />
SCAN bestimmt zunächst immer die Sektion,<br />
in der es gerade tätig ist, indem der Level<br />
des Kanalimpulses an GPIO,4 (Pin3 des uP)<br />
bestimmt wird. Bei GPIO,4=0 wird im Passivteil<br />
des Moduls weitergearbeitet, wo es als<br />
Nächstes zu entscheiden gilt, ob das Passivsignalmodul<br />
vom vorherigen SCAN-Aufruf<br />
bereits in Arbeit ist oder neu begonnen werden<br />
muss. Dazu dient die Abfrage der SCAN-<br />
Flagge SFLG,2. Ist sie 0, d.h. neu, so werden<br />
SFLG,2 <strong>und</strong> SFLG,0 = 1 sowie SFLG,3 = 0<br />
gesetzt <strong>und</strong> der Timer TMRO mit Vorteiler<br />
256 zur Passivsignallängenmessung initialisiert.<br />
Das Setzen der Flagge SFLG,0 bedeutet<br />
dabei, dass ein RC-Impulspaket abgearbeitet,<br />
d.h. die Länge des Fahrimpulses während der<br />
vergangenen SCAN-Aufrufe gemessen wurde,<br />
was, wie oben gesehen, ein Kriterium für<br />
den CLCTIM-Aufruf ist.<br />
Im laufenden Passivzyklus (SFLG,2=1)<br />
wird nur der Zähl stand des Timers (TMRO)<br />
geprüft. Ist sein Wert größer als der zulässige<br />
65
Maximalwert passmx, so ist das RC-Signal<br />
fehlerhaft <strong>und</strong> die Fehlerflagge RFLG,7 wird<br />
gesetzt.<br />
Bei neuem, aktivem Fahrimpuls<br />
(GPIO,4=l, SFLG,3=0) wird in Start (aktiv)<br />
verzweigt <strong>und</strong> SFGL,3=1, SFLG,2=0 <strong>und</strong> der<br />
„Messwert" FLEN=0 gesetzt, um in den folgenden<br />
Durchläufen („in Arbeit") bei jedem<br />
SCAN-Aufruf um eins erhöht zu werden. Tritt<br />
dabei ein Überlauf auf (FLEN > 255, entsprechend<br />
3,5 ms), wird ebenso wie bei TMRO <<br />
passmn, d.h. zu kleiner Pause zwischen den<br />
Kanalimpulsen, die Fehlerflagge (RFLG,7) gesetzt.<br />
Sie wird damit immer gesetzt, wenn eine<br />
der Bedingungen nicht erfüllt ist:<br />
oder<br />
FLEN < 255<br />
(passmn <strong>und</strong> passmx müssen an die verwendete<br />
RC-Anlage angepasst werden).<br />
SCAN ist mit Leerbefehlen nop oder zusätzlichen<br />
goto (zwei Maschinenzyklen) so ausgelegt,<br />
dass jeder der vier möglichen Durchläufe<br />
genau 14 Maschinenzyklen, d.h. 14 us,<br />
dauert (ein SCAN-Zyklus), womit die Messung<br />
der Fahrimpulslänge nichts anderes ist als<br />
das Zählen der SCAN-Durchläufe; bei aktivem<br />
RC-Signal wird FLEN in jedem SCAN-<br />
Durchlauf daher gerade um eins, entsprechend<br />
14 us, erhöht.<br />
SCAN ist zwar wie eine Subroutine aufgebaut,<br />
wird aber im Programm dreimal explizit<br />
verwendet (Labels SCL_, SCH_ <strong>und</strong> SI_), da<br />
der Aufruf einer Subroutine allein schon vier<br />
Maschinenzyklen erfordert, die Länge eines<br />
SCAN-Zyklus also von 14 us auf 18 us steigen<br />
würde. Dies hätte sowohl eine schlechtere Auflösung<br />
bei der Impulslängenmessung als auch<br />
eine niedrigere PWM-Signalfrequenz zur Folge.<br />
In der Initialisierungsschleife ist SCAN<br />
geringfügig modifiziert.<br />
66<br />
Subroutine CLCTIM<br />
Ist die Länge des Fahrimpulses ausgemessen<br />
(d.h. SFLG,0 =1), können daraus während der<br />
langen Impulspause die Register ILL <strong>und</strong> ILH<br />
des PWM-Signals <strong>und</strong> der Zustand der beiden<br />
Ausgangspins im EIN-Zustand (Drehrichtung)<br />
bestimmt werden, was in der Subroutine<br />
CLCTIM geschieht.<br />
Ablaufdiagramm des MONONAUT-Unter-<br />
programms CLCTIM<br />
MONONAUT<br />
Modul CLCTIM<br />
Von der mit SCAN bestimmten Fahrimpulslänge<br />
(FLEN) wird zunächst die Mittelstellung<br />
IOF abgezogen. Nach dieser Subtraktion<br />
ist FLEN eine 7-Bit-Zahl mit Vorzeichen<br />
(siehe Abschnitt 2.4.3.2), die auf max_F (bzw.<br />
max_iF bei negativem Wert) limitiert wird.<br />
FLEN durchläuft dann die Glättung, wo der<br />
Mittelwert aus aktuellem <strong>und</strong> drei FLEN-Werten<br />
zu früheren Zeitpunkten gebildet wird:
ILH = (FLEN + GSUM)/4<br />
mit GSUM = G2 + Gl + GO<br />
(GSUM <strong>und</strong> FLEN sind hierin 7-Bit-Zahlen<br />
mit Vorzeichen, die Addition eine 9-Bit-<br />
Addition nach Abschnitt 2.4.3.2).<br />
Nach jedem isksten CLCTIM-Aufruf wird<br />
GSUM neu berechnet <strong>und</strong> die vier G-Werte<br />
verschoben:<br />
GSUM = GSUM -GO,<br />
GO
Je nach Verzweigung verbraucht CLCTIM<br />
unterschiedlich viele Maschinenzyklen. Durch<br />
Leerbefehle (nop), Sprungbefehle zur folgenden<br />
Zeile (zwei Zyklen) oder den Aufruf der<br />
Subroutine LEERn wurde aber dafür gesorgt,<br />
dass sich jeweils Vielfache von 14 (ein SCAN-<br />
Zyklus) ergeben. Die Zahl der verbrauchten<br />
SCAN-Zyklen wird dann beim Rücksprung<br />
mit retlw an das Arbeitsregister übergeben <strong>und</strong><br />
anschließend vom Laufregister „I" (Maß der<br />
PWM Duty Cycles) abgezogen, wodurch das<br />
PWM-Signal durch den CLCTIM-Aufruf unbeeinflusst<br />
bleibt; es gibt <strong>einfach</strong> weniger<br />
SCAN-Aufrufe in der PLOW- bzw. PHIGH-<br />
Schleife. Falls innerhalb von CLCTIM eine<br />
Verzweigung gerade 14 Zyklen verbraucht,<br />
wird das Register I u.U. schon in CLCTIM<br />
angepasst.<br />
3.4.1.4 Praktische Hinweise<br />
Einige unter der Überschrift „— Benutzerspezifische<br />
Konstanten —" im Programmkopf<br />
zusammengefasste Parameter müssen vom Benutzer<br />
u.U. seiner Anlage angepasst werden.<br />
Das gilt vor allem für die Grenzwerte des RC-<br />
Signals (passmn <strong>und</strong> passmx), die für die Signalüberwachung<br />
wichtig sind <strong>und</strong> die, falsch<br />
vorgegeben, die ordentliche Funktion des MO-<br />
NONAUT verunmöglichen (Daueralarm).<br />
Zwar kann man sehr niedrige bzw. sehr hohe<br />
Werte vorgeben, doch wird die Signalkontrolle<br />
dann sehr unscharf. Es ist daher von<br />
Vorteil, die RC-Zykluszeit (t RC) des verwendeten<br />
Senders mittels eines Oszilloskops zu<br />
messen, d.h. Zeit zwischen zwei positiven<br />
Flanken an einem beliebigen Kanalausgang.<br />
Man sollte dabei auch prüfen, ob der aktive<br />
Signalanteil t a,RC mittels Steuerknüppel zwischen<br />
1 ms <strong>und</strong> 2 ms variiert werden kann<br />
mit einer Mittelstellung bei ungefähr 1,5 ms<br />
(Standard der meisten RC-Anlagen). Die hier<br />
ermittelten Werte haben eventuell Einfluss<br />
auf die Parameter iO_min, iO_max, <strong>und</strong> max_F<br />
bzw. max_iF.<br />
68<br />
Die meisten anderen Parameter sind Sache<br />
des persönlichen Geschmacks des Anwenders,<br />
ihre jeweilige Bedeutung ist im Kommentar<br />
angegeben.<br />
Bezüglich der Tabelle FKNLI können Anwender,<br />
die über einen FORTRAN-Compiler<br />
verfugen, mein Programm knn.for vom ".for"-<br />
Directory der ModellWerft-Homepage (www.<br />
modellwerft.de/downloads) einsetzen, das eine<br />
in mono.asm kopierbare Tabelle als Funktion<br />
von fünf Eingabeparametern imax (maximales<br />
ILH, Ausgabe), imax_S (maximales LLH, Eingabe),<br />
xoffs (Totbereich), yoffs (erster ILH-<br />
Wert größer null) <strong>und</strong> a (Koeffizient für Exponentialfunktion)<br />
erzeugt. Die Form der Kennlinie<br />
wird dabei durch a bestimmt, wobei positive<br />
Werte das Resultat lange tief halten <strong>und</strong><br />
gegen Ende schnell ansteigen lassen, negative<br />
Werte dagegen zu Beginn stark erhöhen.<br />
3.4.2 Standardmehrwellen-<br />
2-kHz-Drehzahlsteller<br />
(MULTINAUT)<br />
3.4.2.1 Eigenschaften<br />
MULTLNAUT ist ein Drehzahlsteller für Mehrwellenmodelle<br />
mit einer Taktfrequenz von 2,2<br />
KHz, wobei seine Besonderheit die Einbeziehung<br />
der Ruderinformation ist. Das erlaubt<br />
einerseits, bei Hartrudermanövern (Rudervollausschlag)<br />
die Drehrichtung der dem Ruderausschlag<br />
zugewandten Antriebsmotoren automatisch<br />
umzukehren, was bei Schiffsmodellen<br />
ein, "Drehen auf dem Teller" möglich macht,<br />
andererseits eine automatische Reduzierung der<br />
Fahrstufe bei stärkerer Kurvenfahrt, was die<br />
Krängung eines Schiffsmodells herabzusetzen<br />
hilft („Antikräng"). Diese automatischen Ruderunterstützungen<br />
sind natürlich durch LOW-<br />
Pegel an den entsprechenden Enable-Pins abschaltbar,<br />
entweder durch Jumper oder durch<br />
eine Schaltfunktionen der Fernsteuerung. Auch<br />
kann der Drehzahlsteller selbst inaktiviert werden,<br />
was beim gleichzeitigen Einsatz mehrerer
Modelle mit nur einem Sender gestattet, einzelne<br />
Modelle außer Betrieb zu setzen. Ein<br />
HIGH-Pegel an einem weiteren uP-Eingang<br />
erlaubt die Abschaltung der äußeren Wellen<br />
bei Vierwellenanlagen.<br />
Die automatische Ruderunterstützung macht<br />
die Auswertung sowohl des Ruder- als auch des<br />
Fahrsignals nötig. Für das Funktionieren des<br />
MULTINAUT ist es dazu nötig, dass der Fahrsignalimpuls<br />
unmittelbar auf den Ruderimpuls folgt.<br />
Die generellen Eigenschaften des MULTI<br />
NAUT sind mit denen des MONONAUT identisch,<br />
darüber Hinausgehendes lässt sich wie<br />
folgt zusammenfassen:<br />
• Bei Hartrudermanövern entweder individuelle<br />
Umpolung der Fahrmotoren einer Modellseite<br />
oder leichte Reduzierung der Fahrstufe<br />
(Antikräng)<br />
• Durch ein entsprechendes HIGH-Signal am<br />
QUAD-Disable-Eingang des uP können die<br />
äußeren Wellen bei Vierschraubenmodellen<br />
abgeschaltet werden. Dazu ist der Treiber<br />
entsprechend auszulegen.<br />
• High-Signal am Alarmpin bei RC-Signalfehlern<br />
• MULTINAUT setzt voraus, dass das Fahrsignal<br />
unmittelbar auf das Rudersignal folgt.<br />
3.4.2.2 Praktischer Aufbau<br />
Wie dem Gesamtschaltbild zu entnehmen ist,<br />
braucht man für den Einsatz des MULTINAUT<br />
auch noch einen Treiber (rechter Schaltbildteil),<br />
der einerseits den für den Betrieb der<br />
Fahrmotoren hohen Strom liefert <strong>und</strong><br />
andererseits die beiden Umpolrelais enthält,<br />
die bei Rückwärtsfahrt beide <strong>und</strong> bei Hartrudermanövern<br />
jeweils eine Motorseite zusätzlich<br />
umpolen (bei Fahrt zurück würde ein angezogenes<br />
Relais also wieder abfallen).<br />
Der Treiber ist bei mir ein eigenes Bauteil,<br />
das in der Nähe der Fahrmotoren untergebracht<br />
<strong>und</strong> über eine fünfadrige Verbindungsleitung<br />
mit der Elektronik verb<strong>und</strong>en ist, die sich im<br />
<strong>PIC</strong> DUONAUT<br />
mit Temperaturueberwachung<br />
Schaltbild des Mehrwellendrehzahlstellers<br />
MULTINAUT für den Zweiwellenbetrieb<br />
(DUONAUT)<br />
Empfängergehäuse befindet. Damit alles funktioniert,<br />
müssen die Pluspole von RC- <strong>und</strong><br />
Fahrakku als gemeinsame Masseleitung<br />
miteinander verb<strong>und</strong>en sein (nur an einer Stelle<br />
direkt von Akku zu Akku <strong>und</strong> nicht im<br />
Treiber!).<br />
Der Eingangsspannungsteiler dient der<br />
Übersetzung der 5-V-Pegel des uP auf die<br />
Fahrnetzspannung, indem das Fahrsignal um<br />
Die Elektronikplatine des MULTINAUT<br />
(rechts) zusammen mit der NAVIGUARD-<br />
Modellüberwachung (links). Die Platine ist<br />
Teil meiner RC-Empfänger<br />
69
Mein Standarddrehzahlstellertreiber für<br />
Ströme bis zu 6 Ampere. Links der Treiber<br />
stecker <strong>und</strong> der CMOS für die Pegelumset<br />
zung, in der Mitte zwei FETs mit ihren<br />
Kühlkörpern <strong>und</strong> angeschraubtem NTC<br />
<strong>und</strong> rechts die beiden Umpolrelais mit den<br />
Sicherungen dazwischen<br />
den Umschaltpunkt des CMOS-Gatters<br />
schwankt; die Dimensionierung des Spannungsteilers<br />
ist deshalb von der Fahrspannung<br />
abhängig (12-V-Werte in Klammern)<br />
<strong>und</strong> funktioniert nicht bei Fahrnetzspannungen<br />
wesentlich über 12 V; man muss dann<br />
Transistorinverter einsetzen.<br />
Nach einem FET-Hitzetod in Teichmitte<br />
wurden meine Treiber mit einer Temperaturüberwachung<br />
des FET-Kühlkörpers nachgerüstet.<br />
Sie nutzt den bei Temperaturerhöhung<br />
auf über 100°C um mehr als eine Zehnerpotenz<br />
fallenden Widerstand eines NTC, um den<br />
Spannungspegel am entsprechenden CMOS-<br />
Gatter auf LOW gehen zu lassen <strong>und</strong> damit<br />
den Treiber abzustellen. Ist die Kühlkörpertemperatur<br />
wieder abgefallen, kippt das CMOS-<br />
Gatter wieder zurück <strong>und</strong> die Fahrt kann fortgesetzt<br />
werden.<br />
Für die Ströme meiner Modellantriebe genügen<br />
meist ein bis zwei FETs (BUZ-11 o.Ä.).<br />
Bei größerem Bedarf können aber auch noch<br />
mehr FETs parallel geschaltet werden; man<br />
sollte dann allerdings darauf achten, dass auch<br />
die Umpolrelais die entsprechenden Ströme<br />
verkraften können.<br />
70<br />
3.4.2.3 Das Programm<br />
MLTNAUT.asm<br />
Das Hauptprogramm<br />
Wie im Ablaufdiagramm des MULTINAUT zu<br />
sehen ist, ist seine Logik der des MONONAUT<br />
sehr ähnlich. Allfälligen Abweichungen sind im<br />
Wesentlichen auf die gleichzeitige Auswertung<br />
des Rudersignals zurückzuführen.<br />
Im Initialisierungsteil muss daher neben<br />
RCFRAM <strong>und</strong> IOF auch der Rudermittelwert<br />
von I0R bestimmt werden, weswegen ein von<br />
MONONAUT-SCAN geringfügig abweichender<br />
Modul SCAND eingesetzt wird.<br />
Die Endlosschleife des Hauptprogramms<br />
besteht auch hier aus den beiden höherfrequenten<br />
Motorsignalhalbzyklen PLOW <strong>und</strong> PHIGH.<br />
Gegenüber MONONAUT geändert hat sich<br />
eigentlich nur die Pin-Steuerung für die beiden<br />
Fahrsignale (innere <strong>und</strong> äußere Wellen) <strong>und</strong><br />
für die beiden Umpolrelais. In der Aktivphase<br />
Generelles Ablaufdiagramm des Programms<br />
MULTINAUT<br />
MULTINAUT<br />
Generalplan
des RC-Signals (Flagge SFLG,2=0) wird die<br />
gerade gemessene Variable, RLEN oder FLEN,<br />
mittels indirekter Adressierung um eins erhöht;<br />
der Wert von FSR wird dazu im Modul SCAND<br />
definiert. Im passiven Teil des RC-Signals<br />
(SFLG,2= 1) erfolgt die Auswertung in der Routine<br />
CLCTIM, wo die wesentlichen Unterschiede<br />
zu MONONAUT zu finden sind.<br />
Modul SCAND<br />
Im Gegensatz zum MONONAUT-SCAN muss<br />
im Modul SCAND sowohl die Länge des Ruder-<br />
als auch des Fahrimpulses bestimmt werden.<br />
Mit Ausnahme der zweiten Impulslängenmessung,<br />
die zwei Verzweigungen mehr not-<br />
MULTINAUT<br />
Modul SCAND<br />
Ablaufdiagramm des MULTINAUT-Unter-<br />
programms SCAND<br />
wendig macht, läuft allerdings alles gleich wie in<br />
SCAN. Die Fehlerflagge (RFLG,7) wird gesetzt,<br />
wenn eine der Bedingungen nicht erfüllt ist:<br />
passmn < T RC, Pause < passmx<br />
oder<br />
RLEN < 255<br />
oder<br />
FLEN < 255<br />
Jeder der sechs verschiedenen SCAND-<br />
Durchläufe erfordert wieder genau 14 Maschinenbefehle,<br />
entsprechend einer Zeitdauer von<br />
14 us.<br />
Modul CLCTIM<br />
CLCTIM berechnet aus den Signallängen<br />
FLEN <strong>und</strong> RLEN die Fahrstufe <strong>und</strong> die Stellung<br />
der Motorumpolrelais für beide Wellenseiten.<br />
Es wird in der PWM-Low- bzw. -High-<br />
Schleife des Hauptprogramms zu den gleichen<br />
Bedingungen wie im Programm MONONAUT<br />
aufgerufen. Auch sind die ersten Abschnitte<br />
von CLCTIM bis zum Label CRUD nahezu<br />
identisch zur gleichnamigen MONONAUT-<br />
Subroutine, weshalb hier nicht mehr darauf<br />
eingegangen werden muss.<br />
MULTINAUT Modul CLCTIM<br />
Ablaufdiagramm des MULTINAUT-Unter-<br />
programms CLCTIM<br />
71
Erst ab CRUD weicht der Programmablauf<br />
von dem in MONONAUT signifikant ab,<br />
kommt doch hier der Einfluss der Ruderstellung<br />
ins Spiel, die in den auf CRUD folgenden<br />
Befehlen zunächst ermittelt wird. Der Pegel<br />
am PORTB,renab entscheidet dann darüber,<br />
ob ein Rudereinfluss gegebenenfalls via Motorumpolung<br />
(linker Pfad im Ablaufdiagramm)<br />
oder via Fahrstufenreduzierung (rechter Pfad)<br />
erfolgt.<br />
Im Falle Motorumpolung, d.h. einem HIGH<br />
am Pin PORTB,renab, wird geprüft, ob ein<br />
Hartrudermanöver vorliegt, d.h. der Ruderausschlag<br />
zur Einschaltung größer rdein bzw. zur<br />
Abschaltung kleiner rdaus ist; diese Hysterese<br />
verhindert ein Flattern der Relais in der Nähe<br />
des Umschaltpunktes. Liegt kein Hartruderausschlag<br />
vor (RFL,5=0), gilt die generelle<br />
Relaisstellung nach Maßgabe der Fahrtrichtungsflagge<br />
für beide Relais, d.h., sie ziehen<br />
bei RFLG,0=1 (= Rückwärtsfahrt) an. Bei einem<br />
Hartrudermanöver (RFLG,5=1) wird<br />
zuerst die zur entsprechenden Ruderseite gehörende<br />
Maske erstellt, die dann mittels EXOR-<br />
Verknüpfung der Relaisstellung (IOL0) zur einseitigen<br />
Umpolung der betreffenden Seite führt.<br />
Bei PORTB,renab=L verzweigt das Programm<br />
zum Label C_KNRG (Antikräng), wo<br />
dann geprüft wird, ob PORTB,akre=H ist (bei<br />
mir ein Jumper) <strong>und</strong> ob sowohl die Fahrstufe<br />
(> ilhmin) als auch der Ruderausschlag genügend<br />
groß sind, um eine Fahrstufenreduktion<br />
zu rechtfertigen. Gegebenenfalls wird dann mit<br />
der Tabelle RKNLI aus dem Ruderwert ein<br />
Abzug für die Fahrstufe bestimmt; auch diese<br />
Differenz darf nicht unter die Eingriffsfahrstufe<br />
ilhmin fallen. RKNLI ist eine Exponentialfunktion,<br />
die erst bei vollem Ruderausschlag<br />
nennenswerte Fahrstufenabzüge erzeugt.<br />
Um Motoren <strong>und</strong> Relais bei Umschaltungen<br />
zu schonen (bei Hartrudermanövern passiert<br />
das öfter auch in hohen Fahrstufen), erfolgt<br />
die Umpolung jeweils nur bei Motorstillstand.<br />
Dies gewährleistet der dem Label<br />
C_OUT folgende Programmabschnitt, wo<br />
zunächst die alte Relaisstellung (IOL1) mit der<br />
72<br />
aktuellen (IOL0) verglichen wird. Sind sie<br />
gleich, d.h., ist keine Umpolung nötig, werden<br />
aus IOL0 die Pin-Pegel im Low- (IOL) <strong>und</strong> im<br />
High-Teil (IOH) des PWM-Zyklus bestimmt.<br />
Beim Vierwellenmodell können mit einem<br />
HIGH am Pin PORTB,qdisa <strong>und</strong> entsprechendem<br />
Treiber noch die Außenwellen abgeschaltet<br />
werden.<br />
Bei einer Motorumpolung sind IOL0 <strong>und</strong><br />
IOL1 ungleich. Die Fahrstufe wird dann null<br />
gesetzt <strong>und</strong> nach nmpl0 Durchläufen das Relais<br />
umgeschaltet, d.h., IOL wird mit dem aktuellen<br />
IOL0 <strong>und</strong> nicht dem alten IOL1 geladen.<br />
Schließlich wird nach nmpl Durchläufen<br />
IOL1 gleich IOL0 gesetzt, wodurch die Gleichheitsbedingung<br />
beim nächsten Durchlauf<br />
wieder erfüllt ist <strong>und</strong> die Motoren damit normal<br />
arbeiten.<br />
Der verzweigungsabhängige Verbrauch von<br />
Maschinenzyklen wurde erneut mit nop, goto<br />
oder der Subroutine LEERn auf ein Vielfaches<br />
eines SCAND-Zyklus eingestellt <strong>und</strong> wird<br />
schließlich via retlw an das Hauptprogramm<br />
übergeben.<br />
3.4.2.4 Praktische Hinweise<br />
für die Programmierung<br />
Im Programmkopf sind unter der Zeile „—<br />
Benutzerspezifische Konstanten —" wieder die<br />
Parameter zusammengefasst, die vom Benutzer<br />
u.U. definiert werden sollten. Das sind neben<br />
den schon beim MONONAUT benötigen<br />
Größen (z.B. die RC-Signalkenngrößen passmn<br />
<strong>und</strong> passmx) hier vor allem die Parameter,<br />
die sich auf den Rudereinfluss beziehen, zum<br />
einen also der Hartruderausschlag rdenein bzw.<br />
rdenaus, zum anderen die Fahrstufe ilhmin, ab<br />
der Antikräng angewendet werden soll. Außerdem<br />
muss der Rudereinfluss in der Subroutine<br />
„RKNLI" programmiert werden, wofür<br />
das Fortranprogramm rnn.for auf der Modell-<br />
Werft-Homepage (Directory „for") verwendet<br />
werden kann. Es funktioniert ähnlich wie<br />
knn.for für die Tabelle FKNLI.
Die in MLTN.asm angegebenen Werte sind<br />
für meine Anlage <strong>und</strong> für meine Modelle optimiert.<br />
3.4.3 Mehrwellen-<br />
Gleichstromdrehzahlsteller<br />
(DCNAUT)<br />
3.4.3.1 Problemstellung<br />
<strong>und</strong> Funktionsprinzip<br />
Die bisher beschriebenen Impulsdrehzahlsteller<br />
steuern Gleichstrommotoren durch unterschiedlich<br />
lange Impulse von nahezu Nennspannung.<br />
Die resultierende Motordrehzahl<br />
ist daher, besonders im unteren Drehzahlbereich,<br />
stark vom verwendeten Motor (Trägheit<br />
des Ankers, genereller Aufbau), aber auch<br />
von seiner augenblicklichen Belastung abhängig.<br />
Die im unteren Drehzahlbereich oft<br />
nicht befriedigenden Laufeigenschaften wurden<br />
im MONONAUT bzw. MULTINAUT<br />
daher mittels der Funktion „FKNLI" künstlich<br />
verbessert.<br />
Beim Gleichstrommotor mit Permanentmagnet,<br />
dem im Modellbau gängigen Antriebsmotor,<br />
setzt sich die Klemmspannung aus der<br />
so genannten Gegen-EMK (Elektro-Motorische-Kraft),<br />
die mit zunehmender Drehzahl<br />
ansteigt, <strong>und</strong> aus der Spannung zusammen, die<br />
am Innen widerstand der Motorwicklungen ab<br />
Schaltbild des Gleichstromdrehzahlstellers<br />
DCNAUT<br />
<strong>PIC</strong> DCNAUT<br />
fällt. Letzterer Spannungsabfall ist proportional<br />
dem durch die Wicklungen fließenden<br />
Strom <strong>und</strong> damit zur Motorbelastung. Bei gleicher<br />
vorgegebener Klemmspannung dreht der<br />
Motor unter Belastung also langsamer, ein für<br />
einen Drehzahlsteller wenig erwünschter Effekt.<br />
Kann dagegen der Spannungsabfall in<br />
den Motorwicklungen kompensiert werden, so<br />
wird die Motordrehzahl direkt proportional zur<br />
vorgegeben Klemmspannung. Man erhält so<br />
einen Drehzahlsteller, der die Motordrehzahl<br />
weitgehend unabhängig von dessen Belastung<br />
steuert <strong>und</strong> sich durch ein weitgehend lineares,<br />
besonders in unteren Drehzahlbereichen positiv<br />
auswirkendes Stellverhalten auszeichnet.<br />
Ein solcher Drehzahlsteller ist DCNAUT,<br />
der mit seinem Treiber eine belastungskompensierte<br />
Klemmspannung in 15 diskreten<br />
Fahrstufen erzeugt. Seine übrigen Eigenschaften<br />
sind die gleichen wie beim MULTINAUT<br />
für Zweiwellenmodelle, d.h., es gibt einen<br />
Ruderstellungseinfluss auf die Fahrstufe (Antikräng)<br />
bzw. die individuelle Motordrehrichtungsumkehr<br />
bei Hartrudermanövern.<br />
Auch beim DCNAUT ist es nötig, dass<br />
der Fahrsignalimpuls unmittelbar auf den Ruderimpuls<br />
folgt.<br />
Wie das DCNAUT-Schaltbild zeigt, besteht<br />
er wieder aus zwei Baugruppen, nämlich<br />
der Elektronik um den <strong>PIC</strong>-16C505, die Ruder-<br />
<strong>und</strong> Fahrimpuls so aufbereitet, dass an<br />
ihren Ausgangspins die Fahrstufe als 4-Bit-<br />
Zahl sowie die Steuersignale für die beiden<br />
Umpolrelais anliegen. Im Treiber wird die 4-<br />
Bit-Fahrstufeninformation dann in eine Gleichspannung<br />
zwischen null <strong>und</strong> Fahrspannung<br />
umgewandelt (Digital-Analog-Wandlung mit<br />
R-2R-Leiter (DAW)) <strong>und</strong> steht dann nach Leistungsverstärkung<br />
als Klemmspannung für die<br />
Motoren zur Verfügung. Mit dem Leistungswiderstand<br />
in der Motorleitung wird dabei auch<br />
der Motorstrom gemessen, der dann der Kompensation<br />
der Wicklungsverluste dient, wobei<br />
die Wirksamkeit dieser Kompensation mit dem<br />
Potibeeinflusst werden kann; sie ist etwas vom<br />
Motortyp abhängig.<br />
73
Für die Leistungstransistoren wurden Germanium-Typen<br />
mit geringer Sättigungsspannung<br />
ausgewählt, um die Spannungsverluste<br />
klein zu halten, was besonders bei einem<br />
6-V-Bordnetz wichtig ist. Die Widerstände<br />
in den Eingangsleitungen dienen der Spannungstransformation<br />
von 5 V (<strong>PIC</strong>, RC) auf<br />
12V (Fahr), beim 6-V-Netz sind sie nicht<br />
nötig. Zudem ist auch ein NTC vorhanden,<br />
der die Kühlkörpertemperatur der Leistungstransistoren<br />
überwacht, gegebenenfalls den<br />
DAW auf null setzt <strong>und</strong> damit den Drehzahlsteller<br />
bis zur Abkühlung ausschaltet. Der<br />
Kühlkörper muss übrigens wesentlich größer<br />
sein als bei den Impulstreibern gleicher Leistung,<br />
da die Endstufe als variabler Widerstand<br />
arbeitet <strong>und</strong> deshalb u.U eine Menge<br />
Wärme produziert. Dies ist neben dem größeren<br />
Bauteileaufwand ein weiterer Nachteil<br />
des DCNAUT gegenüber den Impulsdrehzahlstellern.<br />
Die allgemeinen Eigenschaften des<br />
DCNAUT sind weitgehend identisch mit denen<br />
des MULTINAUT. Die Abweichungen<br />
lassen sich wie folgt umreißen:<br />
• Vorgabe eine belastungskompensierten<br />
Gleichstromklemmspannung in 15 diskreten<br />
Fahrstufen <strong>und</strong> damit weitgehend lineares<br />
Stellverhalten<br />
• Signalverzögerung durch zeitbestimmte Glättung<br />
von Ruder- <strong>und</strong> Fahrimpuls<br />
3.4.3.2 Das Programm<br />
DCNAUT.asm<br />
Das Hauptprogramm<br />
Wie dem allgemeinen Ablaufdiagramm zu entnehmen<br />
ist, unterscheidet sich das Programm<br />
DCNAUT signifikant vom zuvor diskutierten<br />
MLTNAUT. Wegen Wegfalls des hochfrequenten<br />
Motorimpulses kann die gesamte Impulslängenbestimmung<br />
während der kurzen<br />
Aktivphase des RC-Signals, die Rechenarbeit<br />
74<br />
Generelles Ablaufdiagramm des Programms<br />
DCNAUT<br />
DCNAUT<br />
Generalplan<br />
nachher in der relativ lange Impulspause<br />
durchgeführt werden.<br />
Auch hier werden zunächst die Mittenwerte,<br />
in vorliegenden Fall des Ruder- <strong>und</strong><br />
des Fahrsignals (IOR <strong>und</strong> IOF), mit der Subroutine<br />
SCAN bestimmt <strong>und</strong> auf vernünftige<br />
Werte limitiert; ist das RC-Signal gestört (Fehlerflagge<br />
FLAG,7), so beginnt DCNAUT erneut<br />
mit der Mittenfestlegung (jeweiliger<br />
Rücksprung zum Label INIT). Die Subroutine<br />
FRAMIN, ein Teil von SCAN, initialisiert<br />
zu Beginn Ports, Timer <strong>und</strong> ein paar Register.<br />
Die Endlosschleife startet am Label LOOP,<br />
wo mit der Subroutine SCAN die Längenbestimmungen<br />
von Ruder- (RLEN) <strong>und</strong> Fahrimpuls<br />
(FLEN) durchgeführt werden. Bei einem<br />
Signalfehler (Label RC_ERR), der u.U.<br />
nicht die gesamte Länge eines RC-Frames<br />
ausschöpft, wird jeweils auf RCFRAM synchronisiert<br />
<strong>und</strong> dann ignore-mal mit den bestehenden<br />
Werten weitergefahren, bevor die
Motoren <strong>und</strong> Relais im Unterprogramm AUS<br />
abgeschaltet werden; kurze Signalunterbrechungen<br />
werden so ignoriert.<br />
Bei fehlerfreiem Signal <strong>und</strong> eingeschaltetem<br />
Drehzahlsteller (PORTB,fena=H) erfolgt<br />
die Auswertung während der langen passiven<br />
Phase zwischen den Kanalimpulsen. Dazu<br />
werden nach Abzug der Signalmittenwerte<br />
(IOR bzw. IOF) im Gegensatz zum MLTNAUT<br />
hier beide Signale geglättet bzw. je nach Wahl<br />
von isks_R <strong>und</strong> isks_F verzögert (Modul<br />
GLATT). Da IOR <strong>und</strong> IOF in Bank -1- des<br />
Datenspeichers stehen, ist eine Bankumschaltung<br />
erforderlich, die beim 16C505<br />
ausnahmsweise mit dem 5. Bit des FSR- Registers<br />
durchgeführt wird.<br />
Ist die resultierende Fahrstufe größer f_on,<br />
so erfolgt die weitere Fahrstufen- <strong>und</strong> Relaisstellungsberechnung<br />
in Modul FAHRT, ist<br />
sie kleiner als f_off, so wird der Fahrstrom<br />
abgeschaltet. Dazwischen ist die Fahrstufe<br />
fmin, wenn ihr vorheriger Wert größer, <strong>und</strong><br />
null, wenn auch der vorherige Wert null war<br />
(Hysterese); im Gegensatz zum Ablaufdiagramm<br />
des MULTINAUT ist die Logik der<br />
Hystereserechnung übrigens hier explizit dargestellt.<br />
Subroutine SCAN<br />
Die Subroutine SCAN ist ähnlich aufgebaut<br />
wie die gleichnamigen Unterprogramme in<br />
PENTAS.asm oder NAVIGUARD.asm, nur<br />
dass hier sowohl RLEN als auch FLEN bestimmt<br />
werden müssen. Die RLEN- bzw,<br />
FLEN-Auflösung beträgt einheitlich 12 p (mit<br />
LEERn beeinflussbar), um wegen der Rechnung<br />
mit negativen Zahlen während der Glättung<br />
den Maximalwert, gerechnet von einer<br />
Mittelstellung von 1,5 ms, nicht über 42 ansteigen<br />
zu lassen.<br />
Am Ende von SCAN erfolgt jeweils eine<br />
Initialisierung der Ports <strong>und</strong> des Timers<br />
TMRO. Diese Initialisierung kann auch durch<br />
ein call von FRAMIN veranlasst werden.<br />
D C N A U T<br />
Subroutine SCAN<br />
Ablaufdiagramm des DCNAUT-Unterpro-<br />
gramms SCAN<br />
Subroutine FAHRT<br />
Die Subroutine FAHRT entspricht weitgehend<br />
dem Auswertungsteil des MULTINAUT-<br />
CLCTTM-Unterprogramms (beginnend am Label<br />
C_RUD). Da das Anlaufverhalten von<br />
Gleichstrommotoren beim DCNAUT besser<br />
ist als bei Impulsdrehzahlstellern, wurde auf<br />
einen Motorkick verzichtet. Anstelle der Funktion<br />
FKNLI wird die Divisionsroutine DV08L<br />
(aus Microchip-Unterlagen) eingesetzt, die die<br />
Vierersumme aus der Glättung durch eine Konstante<br />
fdiv so teilt, dass das Ergebnis immer im<br />
Wertebereich zwischen 0 <strong>und</strong> 15 (4 Bit) bleibt;<br />
die Relation Kanalimpulslänge zu Klemmspannung<br />
ist damit beim DCNAUT linear.<br />
Die Relaissteuerung inklusive der individuellen<br />
Motorumpolung bei Hartrudermanövern<br />
sowie Antikräng <strong>und</strong> kurzfristige Motorabschaltung<br />
bei Relaisschaltungen gleichen den entsprechenden<br />
Programmabschnitten in MULTI<br />
NAUT- CLCTIM.<br />
75
Ablaufdiagramm des DCNAUT-Unterpro-<br />
gramms FAHRT<br />
Da die genaue Verarbeitungsdauer beim<br />
DCNAUT keine Rolle spielt, solange sie in der<br />
passiven RC-Signalphase erledigt werden kann,<br />
ist eine Zyklusanpassung unnötig, was das Programm<br />
übersichtlicher macht.<br />
3.4.3.3 Praktische Hinweise<br />
für die Programmierung<br />
Im Programmkopf sind unter der Zeile<br />
„— Benutzerspezifische Konstanten —" wieder<br />
die Parameter zusammengefasst, die vom Benutzer<br />
u.U. neu definiert werden sollten. Das<br />
sind neben den zur RC-Signalfehlererkennung<br />
benötigen Größen passmn <strong>und</strong> passmx hier<br />
vor allem der Parameter fdiv, der der Impulslänge<br />
der RC-Anlage so angepasst werden<br />
muss, dass maximal die Zahl 15 an den Treiber<br />
übergeben werden kann.<br />
76<br />
DCNAUT<br />
Modul Fahrt<br />
Die den Rudereinfluss bestimmenden Parameter<br />
sind identisch zu denen im MULTI<br />
NAUT. Allerdings ist das Maximum in Tabelle<br />
RKNLI sowie ilhmin deutlich kleiner zu<br />
wählen, da die Reduktion hier von einem Maximum<br />
von 15 ausgeht (im Gegensatz von 31<br />
im MULTINAUT).<br />
3.4.4 Automatische<br />
Fahrstufenregelung<br />
(AUTONAUT)<br />
Alle oben beschriebenen Drehzahlsteller dienen<br />
dazu, eine vom Modellkapitän gewünschte<br />
<strong>und</strong> am RC-Sender eingestellte Fahrstufe im<br />
Modell in eine Motordrehzahl umzusetzen <strong>und</strong><br />
damit die verlangte Modellgeschwindigkeit zu<br />
erzeugen. Nun sind aber Fälle denkbar, wo die<br />
Modellgeschwindigkeit nicht von außen vorgegeben<br />
ist, sondern sich an bestimmte Gegebenheiten<br />
automatisch anpassen soll. Ein solcher<br />
Fall ist z.B. bei meinem Modell der USS<br />
„Yukon" die Parallelversorgung, wo der parallel<br />
zum Klienten fahrende Versorger sich<br />
jeweils automatisch an die Geschwindigkeit<br />
seines neben ihm fahrenden Klienten anpassen<br />
<strong>und</strong> immer auf gleicher Höhe mit ihm bleiben<br />
soll; der zu regelende Parameter ist hier also<br />
„gleiche Höhe". Im Beispielfall wird der Para-<br />
Transferleine zwischen zwei meiner Model<br />
le bei der Darstellung der Treibstoffüberga<br />
be. Der Trimmer sitzt im Bauteil am Kopf<br />
der Übergabestation 1. Am Klienten ist die<br />
Transferleine unter dem Flugdeck fixiert
meter mit einem als Spannungsteiler geschalteten<br />
Trimmer ermittelt, der an die modelltechnische<br />
Darstellung der die Treibstoffschläuche<br />
für die Kerosinübergabe tragenden Transferleine<br />
(Federstahldraht) gekoppelt ist. Verändert<br />
sich nun die Stellung des Versorgers gegenüber<br />
dem Klienten, so wird der Trimmer<br />
mit der Folge einer Spannungsänderung verstellt.<br />
Bei abfallendem Versorger wird dann<br />
seine Geschwindigkeit so lange erhöht, bis er<br />
wieder gleichauf ist, <strong>und</strong> wird andernfalls gesenkt<br />
bzw. konstant gehalten. Ein anderes Beispiel<br />
wäre die automatische Tiefensteuerung<br />
eines dynamisch tauchenden U-Boot-Modells,<br />
wo der Regler die Fahrstufe zurücknimmt, wenn<br />
der Tiefensensor (Druckmesser) zu große<br />
Tauchtiefe anzeigt, <strong>und</strong> sie erhöht, wenn das<br />
Modell zu hoch ist; der zu regelnde Parameter<br />
ist in diesem Fall der hydrostatische Druck in<br />
einer bestimmten Tauchtiefe.<br />
3.4.4.1 Problemstellung<br />
<strong>und</strong> Funktionsprinzip<br />
Aufgabe des im folgenden beschriebenen Fahrstufenreglers<br />
AUTONAUT ist es, den Antrieb<br />
eines Modells in Bezug auf einen in Form<br />
einer Spannung am entsprechenden Pin des<br />
Mikroprozessors anliegenden Parameters so zu<br />
steuern, dass die Regelabweichung, d.h. die<br />
Differenz zwischen Ist- <strong>und</strong> vorgegebenem<br />
Sollwert, null bleibt. Dabei ist es für die Funktion<br />
des Reglers im Prinzip egal, welcher Parameter<br />
konkret geregelt wird, solange er als<br />
Spannung am Eingangs-Pin dargestellt werden<br />
kann.<br />
Nach Messung der jeweilige Regelabweichung<br />
(ERR) bestimmt AUTONAUT den Duty<br />
Cycle (PIDRES) eines PWM-Signals, der leistungsverstärkt<br />
die Fahrmotoren bestromt <strong>und</strong><br />
so die nötige Fahrstufe erzeugt, damit ERR<br />
wieder null werden kann. Als Rechengr<strong>und</strong>lage<br />
kommt dabei ein so genannter PID-Regler<br />
(Proportional-Integral-Differenzial-Regler)<br />
zum Einsatz, bei dem sich, wie schon der Name<br />
andeutet, die resultierende Fahrstufe aus drei<br />
Gleichungstermen zusammensetzt:<br />
PIDRES = Fx[Px ERR<br />
+I x | ERR dt + D x dERR/dt]<br />
worin<br />
F ein allgemeiner Umrechnungsfaktor,<br />
ERR = POSR - POSA die Regelabweichung<br />
(POSA = aktuelle <strong>und</strong> POSR = Referenzposition)<br />
<strong>und</strong><br />
P, I, D die Koeffizienten des Proportional-,<br />
Integral- <strong>und</strong> Differenzialterms sind.<br />
Der Proportionalterm sorgt für eine der Regelabweichung<br />
proportionale Korrektur der<br />
Fahrstufe, während der I-Term (Integralanteil)<br />
die Regelabweichung akkumuliert, um so kleine,<br />
dauerhafte Regelabweichungen zu erfassen<br />
(ändert sich in unserem Beispiel die Fahrstufe<br />
des Klienten, so muss diese Änderung dauerhaft<br />
berücksichtigt werden). Schließlich erfasst<br />
der D-Term (Differenzialanteil) die Änderungsgeschwindigkeit<br />
der Regelabweichungen <strong>und</strong><br />
verhindert so ein Überschießen des Reglers,<br />
weil schnellen Änderungen der Regelgröße<br />
schon frühzeitig gegengesteuert wird.<br />
Während die Berechnung des Proportionalterms<br />
eine <strong>einfach</strong>e Multiplikation ist, werden<br />
für Integral- <strong>und</strong> Differenzialbildung von<br />
ERR bezüglich der Zeit <strong>einfach</strong>ste numerische<br />
Verfahren eingesetzt, nämlich Summation für<br />
den Integral- <strong>und</strong> Differenzbildung für den Differenzialterm.<br />
Mit PIDRES wird zuletzt ein PWM-Signal<br />
mit einer Taktfrequenz von r<strong>und</strong> 1 kHz sowie<br />
ein Richtungssignal für die Umpolrelais erzeugt,<br />
das über den zum normalen Drehzahlsteller<br />
gehörenden Leistungstreiber die Fahrmotoren<br />
steuert (AUTONAUT läuft bei mir<br />
parallel zum MULTINAUT, der abgeschaltet<br />
wird, wenn ersterer in Betrieb geht).<br />
Da die Regelgröße als variable Spannung<br />
anliegt, muss der zu verwendende uP-Typ über<br />
einen integrierten Analog-Digital-Wandler verfügen.<br />
Bezüglich Pin-Zahl genügt allerdings<br />
ein Minimum, weswegen sich für den AU-<br />
77
TONAUT der 8-Pin-uP <strong>PIC</strong>-12C672 anbietet,<br />
der dank seines internen Taktoszillators ohne<br />
externe Beschaltung auskommt.<br />
3.4.4.2 Das Programm<br />
AUTON.asm<br />
Das Hauptprogramm<br />
Im Ablaufdiagramm des AUTONAUT lassen<br />
sich zwei Programmbereiche unterscheiden.<br />
Auf der linken Seite beginnt das Programm<br />
mit der Festlegung des Reglersollwertes, wozu<br />
der Spannungswert am entsprechenden Eingang<br />
mittels der schon aus obigen Anwendungen<br />
bekannten Subroutine ADW digitalisiert<br />
<strong>und</strong> dann 256-mal zu POSR gemittelt wird.<br />
Die J-Schleife wird dabei durch den Timer<br />
Generelles Ablaufdiagramm des Programms<br />
AUTONAUT<br />
78<br />
AUTONAUT<br />
Generalplan<br />
synchronisiert, der jeweils mit einem Startwert<br />
von 102 beginnt, um im Zusammenhang mit<br />
dem Vorteiler in optvl0 eine Gesamtmittelungszeit<br />
von 10 s zu realisieren. POSR wird abschließend<br />
auf im Programm vorgebbare Grenzen<br />
limitiert.<br />
Nach der Initialisierung verschiedener Register<br />
beginnt die Endlosschleife am Label<br />
PWM, wo nach Initialisierung von Port <strong>und</strong><br />
Timer GPIO,rgler abgefragt wird, mit dem<br />
AUTONAUT ein- bzw. abgeschaltet werden<br />
kann. Im abgeschalteten Zustand wird der uP<br />
schlafen geschickt, wacht bei einer Änderung<br />
an GPIO,rgler aber sofort wieder auf.<br />
Aus dem Duty Cycle PIDRES werden im<br />
eingeschalteten Zustand zunächst die Lowbzw.<br />
High-Anteile des PWM-Signals festgelegt<br />
<strong>und</strong> aus dem PIDRES-Vorzeichen<br />
(FLAG,sdi) die Ansteuerung des Umpolrelais<br />
bestimmt.<br />
Damit kommen wir zur rechten Seite des<br />
Ablaufdiagramms, wo das PWM-Motorsignal<br />
mit den beiden Signalanteilen LOW- (Label<br />
PWM_L0) <strong>und</strong> HIGH- Phase (Label<br />
PWM_H0) erzeugt wird, wobei zur Synchronisierung<br />
der Timer TMRO dient. Um der Subroutine<br />
PID genügend Zeit zur Berechnung<br />
von PIDRES zu geben, wird sie im jeweils<br />
längeren PWM-Signalteil aufgerufen. Mit dem<br />
Rücksprung zum Label PWM ist dann ein<br />
PWM-Impuls abgeschlossen.<br />
Subroutine PID<br />
Das Unterprogramm PID berechnet den Duty<br />
Cycle des PWM-Signals (Fahrstufe) sowie dessen<br />
Vorzeichen (Fahrrichtung). Es beginnt mit<br />
der Bestimmung der Regelabweichung ERR,<br />
hier ERRN (= ERR neu) genannt, also der Differenz<br />
zwischen der Referenz (POSR) <strong>und</strong> der<br />
aktuellen Regelgröße (POSA). POSA, die<br />
Spannung am Pin7 des uP, wird bei jedem<br />
PID-Durchlauf mit der Subroutine ADW digitalisiert,<br />
während POSR der Wert von POSA<br />
kurze Zeit nach Inbetriebsetzung des AU-
Ablaufdiagramm des AUTONAUT-Unterpro-<br />
gramms PID<br />
TONAUT (Initialisierung) ist. Der Absolutwert<br />
von ERRN wird dann auf errlim limitiert<br />
<strong>und</strong> ist null für Werte kleiner errofs.<br />
Im P-Term (Proportionalterm) wird ERRN<br />
mit dem Wichtungsfaktor P multipliziert <strong>und</strong><br />
auf plim begrenzt, wobei das Resultat, Ppo,<br />
eine 7-Bit- Variable mit Vorzeichen ist.<br />
Um auf <strong>einfach</strong>e Weise für den Faktor P<br />
auch Dezimalzahlen realisieren zu können, ist<br />
er in der Form<br />
P = potp<br />
AUTONAUT<br />
P I D<br />
programmiert, da eine Multiplikation mit<br />
anschließender mehrfacher Division durch zwei<br />
(= Rechtsschiebung der Bits) mit einer geringen<br />
Zahl von Maschinenzyklen durchzuführen<br />
ist. Diese Multiplikation mit kp, die Division<br />
p o t p durch 2 <strong>und</strong> die Begrenzung auf plimit werden<br />
in der Subroutine GAIN durchgeführt.<br />
Die Integration der Regelabweichung wird<br />
durch Aufsummierung von dPit erreicht, wobei<br />
nur jeder kadiv-te PID-Durchlauf für die<br />
Addition verwendet wird. kadiv ist eine 8+4-<br />
Bit-Variable, deren untere Bits (KIDVO) einen<br />
festen Startwert von 16 haben. dPit selbst ist<br />
von der Regelabweichung ERRN abhängig:<br />
Der Integralterm Pit ist eine 7-Bit-Variable<br />
mit Vorzeichen, weshalb er einen Wert von<br />
127 nicht übersteigen <strong>und</strong> auf aclim bzw.<br />
aclim_n limitiert werden muss.<br />
Das Differenzial des D-Terms wird durch<br />
Differenzenbildung aus altem (ERRO) <strong>und</strong> neuem<br />
ERRN über einem Zeitschritt durchgeführt<br />
(9-Bit-Addition mit negativem ERRO), der ein<br />
Vielfaches der PWM-Zykluszeit ist, weswegen<br />
die Differenz wiederum nur jedes kddiv-te<br />
Mal berechnet wird; wie kadiv ist auch kddiv<br />
eine 8+4-Bit-Variable mit KDDV0=16. Die<br />
Differenz wird dann mittels GAIN mit dem<br />
Wichtungsfaktor<br />
multipliziert <strong>und</strong> auf dlim limitiert; auch<br />
das resultierende Pdf ist eine 7-Bit-Variable<br />
mit Vorzeichen.<br />
Schließlich werden alle drei Terme addiert<br />
(9-Bit-Addition) <strong>und</strong> das Ergebnis in Absolutwert<br />
<strong>und</strong> Vorzeichen aufgespalten. Das Vorzeichen<br />
(FLAG,sdi) dient dabei der Steuerung der<br />
Umpolrelais. Der Absolutwert (PIDRES) erhält<br />
einen Totbereich (PIDRES=0) <strong>und</strong> einen Startwert<br />
pdstrt (minimaler Wert im EIN-Zustand).<br />
Schließlich wird er auf pwdcyc begrenzt.<br />
3.4.4.3 Praktische Hinweise<br />
für die Programmierung<br />
Wie schon aus der Programmbeschreibung hervorgeht,<br />
gibt es eine Reihe offener Parameter,<br />
die der Benutzer der Antriebsanlage seines<br />
Modells anpassen muss; im Programmkopf sind<br />
sie wieder unter der Zeile „— Benutzerspezifische<br />
Konstanten —" aufgelistet.<br />
Jeder der drei PID-Terme hat eigene Wichtungfaktoren<br />
<strong>und</strong> Konstanten, die das Gesamtregelverhalten<br />
des AUTONAUT im konkreten<br />
Fall bestimmen. Generell gilt wohl, dass hier<br />
Probieren über Studieren geht, weswegen für<br />
den AUTONAUT während längerer Zeit ein<br />
löschbarer uP eingesetzt werden sollte. Einige<br />
gr<strong>und</strong>sätzliche Dimensionierungsregeln kann<br />
man aber angeben:<br />
79
• Proportionalterm P<br />
Je einflussreicher er mit kp <strong>und</strong> plimit gemacht<br />
wird, desto schneller folgt das System, macht<br />
es andererseits aber auch instabiler.<br />
• Intergralterm I<br />
Ein durch zu kleines potk <strong>und</strong> kadiv sowie zu<br />
großes aclim großzügig dimensionierter Einfluss<br />
des I-Terms führt zu Instabilität, wogegen<br />
ein zu geringer Einfluss es dem Regler<br />
verunmöglicht, dauerhafte Regelabweichungen<br />
nachzuführen.<br />
• Differenzialterm D<br />
Der D-Term hilft Instabilitäten zu dämpfen.<br />
Die Konstante D ist daher zu erhöhen, wenn<br />
der Regler durch großen Einfluss von P- <strong>und</strong>/<br />
oder I-Term zum „Überschießen" neigt.<br />
3.4.5 Modell-Controller<br />
(MODCON-S, -P <strong>und</strong> -D)<br />
Die drei MODCON-Drehzahlsteller -S, -P <strong>und</strong><br />
-D sollen den Abschnitt Drehzahlsteller abschließen.<br />
Allen drei Typen ist gemeinsam,<br />
Die im Empfängergehäuse untergebrachte<br />
MODCON-Platine. Gut sichtbar die Dreier<br />
buchse des Jumpers für die EEPROM-Initi-<br />
alisierung; der Jumper für die Antikräng<br />
option ist unter dem Kabelbaum erkenn<br />
bar. Der Transistor dient der Sensitivitäts-<br />
verbesserung des Leckdetektors<br />
80<br />
dass jeweils mehrere der oben schon beschriebenen<br />
Programme im MODCON-Programm<br />
zusammengefasst sind, das dann auf einem <strong>PIC</strong>-<br />
16F672 bzw. -16F676 läuft. Diese beiden <strong>PIC</strong>-<br />
Typen im DIP-28-Gehäuse sind schon etwas<br />
großvolumiger als die bisher verwendeten Mikroprozessoren.<br />
Ihr für unsere Anwendung<br />
wesentlicher Vorteil ist es aber, dass sie über<br />
ein bzw. zwei vom Programmablauf unabhängige<br />
PWM-Generatoren verfügen, die die Erzeugung<br />
eines hochfrequenten PWM-Motorsignals<br />
sehr <strong>einfach</strong> gestalten <strong>und</strong> uns daher alle<br />
komplizierten Verschachtelungen, wie z.B. des<br />
SCAND-Moduls in MULTINAUT, ersparen.<br />
Darüber hinaus sind beide Mikroprozessoren<br />
vom entwicklerfre<strong>und</strong>lichen „F"-Typ, d.h., sie<br />
sind jederzeit mit einer neueren Programmversion<br />
überschreibbar. Auch ist ein nichtflüchtiger<br />
Datenraum vorhanden, der das dauerhafte<br />
Speichern der Ruder- <strong>und</strong> FahrimpulsnuUwerte<br />
(IOR <strong>und</strong> IOF) sowie des RC-Frames (RCF-<br />
RAM) erlaubt, weshalb eine Justierung bei folgenden<br />
Modelleinsätzen entfallen kann. Ein<br />
Nachteil der beiden Mikroprozessoren ist es<br />
allerdings, dass sie über keinen internen Takt<br />
verfügen, dieser vielmehr extern, am besten<br />
mit einem 4-MHz-Quarz erzeugt werden muss.<br />
Alle drei MODCON-Versionen können auf<br />
der gleichen Platine aufgebaut werden, deren<br />
Layout <strong>und</strong> Bestückungsplan im Anhang wiedergegeben<br />
ist.<br />
3.4.5.1 MODCON-S<br />
Der Modell-Controller MODCON-S kombiniert<br />
die Modellüberwachung NAVIGUARD<br />
mit den Eigenschaften eines dem MLTNAUT<br />
vergleichbaren Drehzahlstellers.<br />
Der Treiber ist identisch mit dem des<br />
MULTINAUT <strong>und</strong> seine Schaltung deshalb<br />
im entsprechenden Schaltbild nicht wiedergegeben.<br />
Bezüglich des im Empfänger untergebrachten<br />
Elektronikteils sind die zwei Schalter<br />
zu erwähnen (in der praktischen Ausführung<br />
Jumper), mit denen die Initialisierung bzw. der
Schaltbild der Elektronik der Modell-Cont<br />
rollers MODCON-S bzw. MODCON-P. Im<br />
Falle MOOCON-S ist das Reglerpoti nicht<br />
angeschlossen<br />
<strong>PIC</strong> MODCON<br />
Antikräng abgestellt werden können; bei der<br />
ersten Inbetriebnahme des MODCON-S muss<br />
die Initialisierung natürlich möglich sein, damit<br />
die entsprechenden Werte in den nichtflüchtigen<br />
Datenbereich des Mikroprozessoren<br />
geschrieben werden können.<br />
Die Beschaltung des NAVIGUARD-Teils<br />
mit Spannungsstabilisierung mittels Z-Diode<br />
(RC-Spannung) <strong>und</strong> Spannungsteiler (Fahrspannung)<br />
entspricht der beim Originalgerät,<br />
doch wurde der Lecksensor durch die Transistorstufe<br />
empfindlicher gemacht.<br />
Wie das generelle Ablaufdiagramm des<br />
MODCON-S verdeutlicht, beginnt das Programm<br />
mit einer umfangreicheren Funktionsfehlersuche,<br />
wird doch einerseits auf WDT-<br />
Überlauf, andererseits aber auch auf „brown<br />
out", d.h. nur kurzer Abfall der Versorgungsspannung<br />
unter einen im uP vorgegebenen<br />
Grenzwert, untersucht (PCON). Liegt einer dieser<br />
Fälle vor, so wird die Bestimmung von<br />
Mittenwerten <strong>und</strong> RC-Framelänge ebenso übersprungen<br />
wie bei mittels Jumper abgeschalteter<br />
Initialisierung (PORTA,eeprm).<br />
Die Endlosschleife beginnt am Label LOOP<br />
mit dem Aufruf der Subroutine SCAN, die im<br />
Aufbau gleich der im Programm DCNAUT ist.<br />
Wird dort kein Fehler gef<strong>und</strong>en, geht es in die<br />
Auswertung (Label AUSWERT), andernfalls<br />
nach RC-ERR, wo die laufende Fabrstufe noch<br />
für ignore Durchlaufe gehalten wird, bevor die<br />
Fahrmotoren abgeschaltet werden.<br />
Für die Auswertung wird zunächst eine<br />
Glättung sowohl des Ruder- als auch des Fahrsignals<br />
durchgeführt, wobei unterschiedliche<br />
Verzögerungswerte (isks_R <strong>und</strong> isks_F) vorgegeben<br />
werden können. Der Fahrnull-Bereich<br />
wird auch hier mit einer Hysterese zwischen<br />
f_on <strong>und</strong> f_off festgelegt. Nach nstops Nullstellungen<br />
werden die Umpolrelais abgeschaltet<br />
(falls sie von einer Rückwärtsfahrt angezogen<br />
sind) <strong>und</strong> die Motorkickflagge gesetzt<br />
(KISTRT).<br />
Im Fahrfall wird der Modul FAHRT<br />
durchlaufen, der den Motorkick, die ruderstellungsabhängige<br />
Relaisumpolung sowie den<br />
„Antikräng" enthält, wie wir sie schon von<br />
den obigen Drehzahlstellerprogrammen her<br />
kennen, wobei eine Zyklusanpassung entfal-<br />
Generelles Ablaufdiagramm des Programms<br />
MODCON-S<br />
MODCON-S<br />
Generalplan<br />
81
len konnte, da der Programmteil nicht zeitkritisch<br />
ist. Durch Laden der Fahrstufe in das<br />
Registers CCPR1L wird der Duty Cycle des<br />
PWM-Generators festgelegt, der dann im Hintergr<strong>und</strong><br />
des Programmablaufs die entsprechenden<br />
an Pin 13 des Mikroprozessors ausgegebenen<br />
Motorimpulse erzeugt. Die Festlegung<br />
der PWM-Frequenz <strong>und</strong> das Starten des<br />
Generators erfolgt bei jedem Durchlauf von<br />
AUS durch Laden der Konstante ccpcon in<br />
das Register CCP1CON. Weil die gemeinsame<br />
Masse für RC- <strong>und</strong> Fahrakku in meinen<br />
Anlagen der Pluspol ist (negative Logik), gilt<br />
für den Duty Cycle (DC).<br />
DC = knlimx - Fahrstufe<br />
DC = 0 bedeutet somit Vollgas,<br />
<strong>und</strong> DC >= knlimx heißt stopp.<br />
Der die Endlosschleife beschließende Programmteil<br />
GUARD ist weitgehend identisch<br />
mit dem Programm NAVIGUARD.<br />
3.4.5.2 MODCON-P<br />
Der Modell-Controller MODCON-P ist ein<br />
MODCON-S mit integriertem AUTONAUT<br />
(Modul AUTON). Im entsprechenden Ablaufdiagramm<br />
ist daher nur der kurze, zu MOD<br />
CON-S unterschiedliche Abschnitt dargestellt.<br />
Der Befehl für die automatische Regelung ist<br />
mit einer Memorylogik ausgestattet, FLAG,5<br />
bleibt also so lange im jeweiligen Zustand, wie<br />
nicht ein neuer H-Pegel an PORTB,prgl anliegt.<br />
Bei FLAG,5=H wird dann anstelle der<br />
Glättung des FLEN-Wertes das Modul AU<br />
TON aufgerufen <strong>und</strong> im GUARD-Modul eine<br />
6. Meldung gesendet, dass das Modell jetzt im<br />
Automatikmode arbeitet.<br />
AUTON ist praktisch identisch mit der Subroutine<br />
PID im Programm AUTONAUT <strong>und</strong><br />
liefert als Ergebnis ein alternatives FLEN, mit<br />
dem dann im Rest des Programms wie im<br />
MODCON-S weitergerechnet wird.<br />
82<br />
Ablaufdiagramm-Modifikationen des MOD<br />
CON-P bezüglich des Programms MODCON-S<br />
3.4.5.3 MODCON-D<br />
MODCON-P<br />
Modifikation<br />
Wie das Schaltbild des MODCON-D-Treibers<br />
verdeutlicht, sind hier im Unterschied zum Standardtreiber<br />
zwei individuelle Impulsverstärker<br />
vorhanden, mit dem zwei unterschiedliche Motorimpulse<br />
verarbeitet <strong>und</strong> den jeweiligen Relaissätzen<br />
der beiden Motorseiten zugeführt werden<br />
können. Die dazu notwendigen, unabhängig<br />
laufenden PWM-Generatoren sind im für<br />
den MODCON-D verwendeten <strong>PIC</strong>-16C876<br />
vorhanden, der ansonsten gleich beschaltet ist<br />
wie der <strong>PIC</strong>-16C872 des MODCON-S.<br />
Auch für MODCON-D werden im entsprechenden<br />
Ablaufdiagramm nur die Abweichungen<br />
zu MODCON-S dargestellt. Nur wenn der<br />
Rudereinfluss aktiviert ist (PORTA,renab=H)<br />
<strong>und</strong> der Ruderausschlag größer rdwirk ist, werden<br />
im Programmteil DOPPEL nicht nur die<br />
entsprechenden Umpolrelais angesteuert, son-
<strong>PIC</strong> MODCONT/D<br />
Treiber<br />
Schaltbild des MODCON-D-Treibers. Der<br />
Elektronikteil ist bis auf den weiteren An-<br />
schluss an Pin12 des 16F876 mit dem von<br />
MODCON-S bzw. MODCON-P identisch<br />
MODCON-D<br />
Modifikation<br />
Ablaufdiagramm-Modifikationen des MOD<br />
CON-D bezüglich des Programms MODCON-S<br />
dern auch die Fahrstufe auf beiden Modellseiten<br />
in Abhängigkeit der Ruderstellung individuell<br />
beeinflusst. Dabei haben die beiden unabhängig<br />
laufende PWM-Generatoren des <strong>PIC</strong>-<br />
16C876 zwar die gleiche Impulsfrequenz, aber<br />
u.U. unterschiedliche Duty Cycles.<br />
Die Bestimmung der beiden individuellen<br />
Fahrstufen FAHR bb <strong>und</strong> FAHR sb folgt der Beziehung:<br />
FAHR bb = FAHR + dFAHR<br />
(Backbordmotoren)<br />
<strong>und</strong><br />
FAHR[sb] = FAHR - dFAHR<br />
(Steuerbordmotoren)<br />
wobei dFAHR der ruderstellungsabhängige<br />
Fahrstufenunterschied zwischen den beiden<br />
Modellseiten ist:<br />
FAHR hat einen Wertebereich von -124<br />
bis +124 <strong>und</strong> RUDER einen entsprechenden<br />
von -168 bis +168 (wegen der Glättung jeweils<br />
4 x SCAN-Resultat).<br />
Das Ablaufdiagramm des Programmteils<br />
DOPPEL zeigt hierzu die programmtechni-<br />
Ablaufdiagramm des MODCON-D-Unterpro-<br />
gramms DOPPEL<br />
83
Generelles Ablaufdiagramm des MODCON-<br />
D-Unterprogramms DTYCYC<br />
schen Einzelheiten. Zur Berechnung von<br />
dFAHR nach obiger Beziehung ist zunächst<br />
eine 8x8-Bit-Multiplikation mit 16-Bit-Resultat<br />
<strong>und</strong> dann eine 16:8-Bit-Division mit 8-Bit-<br />
Resultat notwendig, wozu die Microchip-Routinen<br />
UMUL0808L bzw. UDIV1608L verwendet<br />
werden; das Zwischenergebnis steht dabei<br />
in einem 16-Bit-Register (FBB), während<br />
dFAHR ein 8-Bit-Register ist.<br />
Je nach Ruderstellung wird dFAHR dann<br />
zu FBB <strong>und</strong> FSB addiert bzw. subtrahiert. FBB<br />
<strong>und</strong> FSB sind 15-Bit-Register mit Vorzeichen<br />
<strong>und</strong> werden in der Routine DTYCYC<br />
hintereinander in PWM-Duty-Cycles <strong>und</strong> Relaisstellungen<br />
übersetzt. Die jeweilige Fahrstufe<br />
wird dazu mit der Kennlinientabelle FKN-<br />
LI dem Motorverhalten angepasst <strong>und</strong><br />
schließlich in die Register CCPR1L bzw.<br />
CCPR2L geladen, wo sie den Duty Cycle des<br />
entsprechenden PWM-Generators bestimmt.<br />
Gegebenenfalls wird ein Fahrmotor aber auch<br />
für nmpl x RC_frame Sek<strong>und</strong>en gestoppt, wenn<br />
für den entsprechenden Motor gerade eine<br />
84<br />
MODCON<br />
DTYCYC<br />
Umkehr der Motordrehrichtung eingetreten ist,<br />
d.h. das Vorzeichen von FBB bzw. FSB gewechselt<br />
hat.<br />
Die Adressierung verschiedener Register<br />
in DTYCYC erfolgt indirekt.<br />
Ist PORTA_renab = L, d.h. der Rudereinfluss<br />
abgeschaltet, so wird der Modul EIN<br />
FACH durchlaufen, der dem MODCON-S-<br />
Modul FAHRT äquivalent ist; den Registern<br />
CCPR1L <strong>und</strong> CCPR2L wird dann der gleiche<br />
Wert zugeteilt.<br />
3.5 Enkoder <strong>und</strong> Dekoder<br />
für eine RC-Anlage<br />
3.5.1 Problemstellung<br />
Prinzipiell kann man eine Fernsteuerungsanlage<br />
in sechs Funktionsblöcke unterteilen. Im Sender<br />
befinden sich die ersten drei, nämlich die Geber<br />
in Form von Steuerknüppeln bzw. Schieber <strong>und</strong><br />
Drehknöpfen, der Informationsgenerator, neudeutsch<br />
Enkoder genannt, <strong>und</strong> der HF-Sender,<br />
der die Information mittels Funk zu senden erlaubt.<br />
Im Empfänger sind dann die drei restlichen<br />
Funktionsblöcke HF-Empfänger zum Empfang<br />
der Information, Informationsauswertung<br />
(Dekoder) <strong>und</strong> schließlich die Empfängerperipherie<br />
in Form von Servos, Drehzahlstellern<br />
<strong>und</strong> Schaltstufen zu finden.<br />
Die Information wird in preisgünstigen<br />
Anlagen durch Impulsabstände, d.h. die Abstände<br />
zwischen zwei, im AM-Fall, kurzen HF-<br />
Signalabschaltungen (pulse position mode<br />
(PPM), übertragen. Die einzelnen Befehlsinformationen<br />
(Kanäle) werden dann <strong>einfach</strong><br />
hintereinander gehängt <strong>und</strong> bilden das Impulspaket,<br />
das von einer längeren, der Synchronisation<br />
des Empfängers dienenden Pause abgeschlossen<br />
wird. Impulspaket <strong>und</strong> Synchronisationspause<br />
zusammen bilden den RC-Frame,<br />
der eine konstante Dauer von um die 30 ms<br />
hat. Bei Computeranlagen hingegen werden<br />
die Geberstellungen mittels Binärcode (PCM)<br />
übermittelt, also Ein-/Aus-Tastungen des HF-
Trägers je nach Wert einzelner Bits, wozu die<br />
Geberinformation erst einmal digitalisiert werden<br />
muss. Da mit den die Geberstellungen repräsentierenden<br />
Zahlen auch eine Checksumme<br />
gesendet wird, die im Empfänger überprüft<br />
<strong>und</strong> gegebenenfalls als fehlerhaft identifiziert<br />
werden kann, ist diese Sendeart weniger störungsanfällig<br />
als die analoge Übermittlung<br />
durch Impulspausen variabler Länge.<br />
Im Dekoder des Empfängers wird die Gesamtinformation<br />
dann wieder auf die einzelnen<br />
Kanäle verteilt. wobei bei PPM-Modulation<br />
die Synchronisationspause den jeweiligen<br />
Beginn festlegt. Hier können dann auch die<br />
einzelnen Kanalsignale von einem Servo bzw.<br />
Drehzahlsteller direkt genutzt werden, während<br />
bei PCM-Modulation die übertragenden<br />
Zahlen erst wieder in von Servos lesbare Impulslängen<br />
übersetzt werden müssen.<br />
Von den sechs Funktionsblöcken einer RC-<br />
Anlage eignen sich Enkoder <strong>und</strong> Dekoder gut<br />
für den Einsatz eines Mikroprozessors. Zum<br />
Schluss dieses Buches wenden wir uns daher<br />
noch einem Senderenkoder (NVENKO) <strong>und</strong><br />
dem zugehörigem Empfängerdekoder (NVDE-<br />
KO) zu, mit denen das simultane Steuern von<br />
zwei Modellen möglich ist, wobei zwei weitere<br />
Modelle noch in Bereitschaft liegen <strong>und</strong><br />
wahlweise aktiviert werden können. Jedes Modell<br />
verfügt dabei über zwei Analogfunktionen<br />
für Lenkung <strong>und</strong> Fahrstufe <strong>und</strong> je 15 Schaltfunktionen<br />
(bei meinen Modellen sind es wegen<br />
der <strong>einfach</strong>eren Beschaffbarkeit von Zwölfstufenschaltern<br />
nur zwölf).<br />
Auf die HF-Module in Sender <strong>und</strong> Empfänger<br />
soll hier nicht eingegangen werden. Ich verwende<br />
in meinem Muster einen alten 27-MHz-<br />
AM-Sender <strong>und</strong> AM-Empfänger auf Basis des<br />
IC TCA-440, die ich schon seit mehr als 25<br />
Jahren benutze. Man kann im Schiffs- <strong>und</strong> Automodellbau<br />
aber auch fertig aufgebaute 433,92<br />
MHz-Module einsetzen, die weder HF-Justierungsarbeiten<br />
noch eventuelle postalische Genehmigungen<br />
benötigen. So habe ich z. B. in<br />
einem zweiten Muster die Module TX2 (Sender)<br />
<strong>und</strong> RX2 (Empfänger) von Radiometrix<br />
Frontseite des Sen<br />
ders. Oben der<br />
Hauptschalter <strong>und</strong><br />
die Alarm-LED. Auf<br />
jeder Senderseite<br />
ein Drehknopf<br />
(Lenkung)<strong>und</strong><br />
Schieber (Fahrstu<br />
fe), ein Zwölfstufen<br />
mit Auslöseschal<br />
ter <strong>und</strong> darüber der<br />
Modellsektor für je<br />
ein Modell<br />
eingesetzt, die im Text <strong>und</strong> auch nach Herstellerangabe<br />
im Freien eine in der Praxis ausreichende<br />
Reichweite von etwa 300 m haben.<br />
Wie das entsprechende Bild verdeutlicht, ist<br />
bei meinem Sender die Frontplatte vertikal in<br />
zwei Hälften geteilt. Auf jeder Seite befindet<br />
sich ein Drehknopf für die Lenkung, ein Schiebepotenziometer<br />
für die Fahrmotoren <strong>und</strong> ein<br />
Zwölfstufenschalter nebst Ein-Aus-Schalter für<br />
die Aktivierung von <strong>Sonderfunktionen</strong>. Ein kleiner<br />
Schiebeschalter auf jeder der beiden Hälften<br />
oberhalb der Stufenschalter erlaubt darüber hinaus<br />
die Umschaltung zwischen zwei Modellen;<br />
ein Modell ist dann jeweils in Bereitschaft, während<br />
das andere gefahren werden kann.<br />
So viele Modelle lassen sich mit dem NAVI-<br />
CONT-Sender gleichzeitig kontrollieren,<br />
wobei zwei jeweils fahren können <strong>und</strong> die<br />
beiden anderen in Bereitschaft liegen (das<br />
U-Boot ist im Schlepp eine Fahrmodells)<br />
85
Jedes der beiden aktiven Modelle hat zwei<br />
analoge <strong>Funktionen</strong> (Lenkung <strong>und</strong> Fahrstufe)<br />
sowie einen 4-Bit-Schalter (=15 Schaltfunktionen)<br />
zur Verfügung. Zur Umschaltung zwischen<br />
aktivem <strong>und</strong> in Bereitschaft liegendem<br />
Modell wird noch eine weitere 2-Bit-Schaltfunktion<br />
benötigt. Insgesamt besteht die zu<br />
übertragende Information damit aus zwei mal<br />
zwei Analogkanälen, zwei 4-Bit-Schaltkanälen<br />
<strong>und</strong> zwei 2-Bit-Modellselektoren.<br />
NVENKO/NVDEKO benutzt eine Mischung<br />
aus den beiden oben angesprochenen<br />
Modulationsarten PPM <strong>und</strong> PCM. Die Analoginformationen<br />
(zwei Ruderstellungen <strong>und</strong><br />
zwei Fahrstufen) werden als PPM-Signal codiert,<br />
während die zwei Schalterstellungen (2<br />
mal 4 Bit), die beiden Modellselektoren (2 mal<br />
2 Bit) <strong>und</strong> das Paritäts-Bit für die Übertragungssicherheit<br />
in PCM übertragen werden.<br />
3.5.2 Enkoder für RC-Sender<br />
(NVENKO)<br />
3.5.2.1 Schaltung<br />
Ein uP vom Typ <strong>PIC</strong>-16F872 generiert das Impulspaket<br />
im RC-Sender. Er wird mit einem Takt<br />
von 10 MHz betrieben <strong>und</strong> erlaubt so, falls er<br />
Schaltbild des Enkoders NVENKO für mei<br />
nen AM-Sender nebst äußerer Beschat<br />
tung. Bei Einsatz eines TX2-Sendermoduls<br />
entfällt der Spannungsregler (5V Betriebs<br />
spannung) <strong>und</strong> der Trapezformer. Stattdes<br />
sen wird der TX2 (Pin5) direkt an PIN 18<br />
des uP angeschlossen.<br />
86<br />
Sender Enkoder<br />
Der geöffnete<br />
Sender, zu se<br />
hen sind die<br />
Senderplatine<br />
mit Radiometrix-<br />
TX2-Sendermo-<br />
dul (rechts) <strong>und</strong><br />
der uP (links)mit<br />
seinen verschie<br />
denenAn schlüssen<br />
wünscht, eine Menge zusätzliche Rechenarbeit<br />
in den Impulspaketpausen wie z.B. exponentielle<br />
Steuerkennlinien, Mischung von Steuersignalen<br />
usw.; diese zusätzlichen Programmteile sind<br />
im Musterprogramm allerdings nicht vorhanden,<br />
da ich sie für meine Anwendungen nicht benötige.<br />
Eine Spannungsüberwachung des Senderakkus<br />
löst bei sich leerendem Akku Alarm aus, der<br />
durch eine blinkende LED angezeigt wird.<br />
Das Schaltbild zeigt den Impulsteils des Senders.<br />
Der uP erhält seine Versorgungsspannung<br />
von einem Spannungsregler, der in meinem Fall<br />
die 9-V-Versorgungsspannung des HF-Teils auf<br />
den 5-V-uP-Betrieb herunterregelt <strong>und</strong> seinen<br />
Arbeitstakt von einem Quarzoszillator.<br />
Die Potenziometer der Analogsignalgeber,<br />
zwei Drehpotis für die Lenkung <strong>und</strong> zwei Schiebepotis<br />
für die Fahrstufen, sind zusammen mit<br />
alle Dioden 1N4148<br />
Schaltbild einer Diodenmatrix für die Hex-<br />
zu Binärcodierung
Oszillogramm eines mit NVENKO modulier<br />
ten AM-Sendersignals<br />
ihren zugehörigen Trimmern als Spannungsteiler<br />
geschaltet. Die beiden 4-Bit-Digitalschalter<br />
sind mit ihren Pull-down-Widerständen direkt<br />
an die entsprechenden Pins des Mikroprozessoren<br />
angeschlossen. Gewöhnliche Stufenschalter<br />
wie die leicht erhältlichen Zwölfstufer müssen<br />
mit einer Diodenmatrix an ihren Ausgängen<br />
allerdings noch zu Codierschaltern umgebaut<br />
werden. Auch die Ausgänge der beiden Schiebeschalter<br />
für die Modeliselektoren sind über<br />
pull-downs direkt an den entsprechenden Pins<br />
angeschlossen; sie haben die Codes „0l" für das<br />
eine <strong>und</strong> „10" für das andere Modell.<br />
Die Akkuspannung wird dem uP über einen<br />
Spannungsteiler zugeführt, dessen Knotenspannung<br />
mit fallender Akkuspannung gegenüber<br />
der geregelten <strong>und</strong> damit konstanten uP-Versorgungsspannung<br />
abfällt, was dann uP-intern ausgewertet<br />
werden kann <strong>und</strong> gegebenenfalls zum<br />
Blinken einer Alarm-LED führt.<br />
Am Signalausgang des uP sorgt dann noch<br />
eine Transistorentkopplungsstufe für eine leichte<br />
Abr<strong>und</strong>ung der Rechtecksignale (Trapezformer),<br />
bevor es zum Modulatoreingang der HF-<br />
Stufe geht.<br />
3.5.2.2 Das Programm<br />
NVENKO.asm<br />
Das Ablaufdiagramm zeigt die Funktion des<br />
Programms NVENKO.asm. Die Endlosschleife<br />
beginnt hier am Label NEWPAK, umfasst<br />
so fast das gesamte Programm <strong>und</strong> startet, wie<br />
gewohnt, mit der Initialisierung der Ports. Auch<br />
der Timer muss initialisiert werden, weil TMRO<br />
zwischendurch um framdi reduziert werden<br />
muss, um mit der gegebenen Taktfrequenz einen<br />
genügend langen RC-Frame zu erreichen<br />
(> 256). Eine erste Analog-Digital-Wandlung<br />
von RA4 dient der Überwachung der Akkuspannung<br />
<strong>und</strong> führt bei einer Unterschreitung<br />
zum Alarm, d.h. einer niederfrequenten Wechselspannung<br />
am Alarm-Pin, die eine angeschlossene<br />
LED blinken lässt.<br />
Der Rest der linken Kolonne im Ablaufdiagramm<br />
beschreibt das Einlesen der Analog- <strong>und</strong><br />
Digitalinformation, d.h. die Analog-digital-Wandlung<br />
der vier Poti-Spannungen in einer Schleife<br />
mit indirekter Adressierung <strong>und</strong> die direkte Abfrage<br />
der mit den Schaltern (Stufenschalter <strong>und</strong><br />
Modeilselektoren) verb<strong>und</strong>enen Pins.<br />
In der Mitte des Ablaufdiagramms beginnend<br />
mit dem Label SYNCHR wird der RC-<br />
Frame erzeugt, indem so lange gewartet wird,<br />
bis der Timer nach Überlauf wieder null wird.<br />
NVENKO<br />
Ablaufdiagramm des Programms NVENKO<br />
S7
Mit dem Label FRAME startet die Erzeugung<br />
des Impulspakets, wozu für die Analogsignale<br />
einmal mehr die indirekte Adressierung<br />
zum Einsatz kommt. Für jeden der vier<br />
Analogkanäle beginnt das Signal mit der Erzeugung<br />
des 0,4 ms dauernden Impulses durch<br />
High-Schaltung des Senders (SNDOFF, bei<br />
Amplitudenmodulation entspricht das der im<br />
entsprechenden Oszillogramm erkennbaren<br />
HF-Abschaltung). Danach wird der Sender für<br />
konstante 0,6 ms <strong>und</strong> dann für eine weitere,<br />
vom jeweiligen Analog wert (INDF) abhängige<br />
Zeit LOW geschaltet (HF ein bei Amplitudenmodulation).<br />
Das Viererpaket der Analogkanäle<br />
wird mit einem weiteren 0,4 ms dauernden<br />
Impuls abgeschlossen.<br />
Es folgt in der DIGBIT-Schleife die Übertragung<br />
der 12 Bits des 2x2-Modellselektors<br />
MDSEL <strong>und</strong> des 2x4-SWITCH (Schalter 1<br />
untere, Schalter 2 obere 4 Bits), indem der Sender<br />
je nach Wert des Bits MDSEL,3 für 0,5 ms<br />
High bzw. Low geschaltet wird (Subroutinen<br />
SNDOFF bzw. SNDON) <strong>und</strong> danach alle Bits<br />
in MDSEL <strong>und</strong> SWITCH jeweils um eine Stelle<br />
nach links verschoben werden.<br />
Das gleiche Verfahren wird dann auch noch<br />
für das Parity-Bit angewendet, das vor dem<br />
Abschlussimpuls von ebenfalls 0,4 ms gesendet<br />
wird. Das Parity-Bit ist das nullte Bit der<br />
Summe aller -1 - Bits in MDSEL <strong>und</strong> SWITCH<br />
<strong>und</strong> dient dem Test der Übertragungsgüte.<br />
3.5.2.3 Praktische Hinweise<br />
Unter der Überschrift „— Benutzerspezifische<br />
Konstanten —" sind im Programmkopf wieder<br />
einige Parameter aufgelistet, die vom Benutzer<br />
den eigenen Wünschen angepasst werden können.<br />
Da ist zunächst der Unterspannungsalarm<br />
für den Senderakku, der mit vakku justiert <strong>und</strong><br />
dessen Blinkfrequenz mit blink definiert werden<br />
kann. Aber auch die Signalcharakteristika<br />
können hier modifiziert werden, was dann<br />
allerdings auch Einfluss auf die entsprechenden<br />
Größen in NVDEKO.asm hat.<br />
SS<br />
Programmteile für eine eventuelle weitere<br />
Bearbeitung der Eingabewerte, z.B. Mixer oder<br />
exponentielle Ruderkennlinien, müssten vor<br />
dem Label SYNCHR ins Programm<br />
NVENKO.asm eingefügt werden. Hierfür steht<br />
noch einige Rechenzeit zur Verfügung, die im<br />
Muster noch in der Synchronisationswarteschleife<br />
vergeudet wird.<br />
3.5.3 Signaldekoder<br />
für RC-Empfänger (NVDEKO)<br />
Die vom Demodulator des Fernsteuerempfängers<br />
kommenden Information wird mit einem<br />
<strong>PIC</strong>-16C505 mit internem Taktoszillator dekodiert.<br />
Das benötigte Programm heißt NV<br />
DEKO <strong>und</strong> spaltet das mit NVENKO codierte<br />
Impulspaket wieder in die vier Analog-<br />
(zweimal Lenkung <strong>und</strong> zweimal Fahrstufe) <strong>und</strong><br />
drei Digitalinformationen (Modeilselektor <strong>und</strong><br />
zwei 4-Bit-Schalter) auf. Durch zwei am Empfängergehäuse<br />
angebrachte Schiebeschalter<br />
wird jeweils entschieden, welches Analogsignalpaar<br />
sowie welcher der beiden 4-Bit-Schalter<br />
vom Empfänger verwendet wird (Schalter<br />
AS) bzw. welches der beiden Modelle einer<br />
Senderseite mit einem MDSEL-Befehl stillgelegt<br />
bzw. aktiviert wird (Schalter MS). Zwei<br />
Modelle mit gleichem AS müssen dann also<br />
verschiedene MS-Stellungen haben, um abwechselnd<br />
betrieben werden zu können. Auf<br />
Oszillogramm des Signals am Demodula-<br />
torausgang eines meiner AM-Empfänger<br />
(zum Sendersignal kompatibel)
Ein 433-MHz-Empfänger mit dem Radiome-<br />
trix-RX2-Empfängermodul auf der oberen<br />
Empfängerhälfte. Darunter der NVENKO-uP<br />
<strong>und</strong> außen am Gehäuserand die beiden<br />
Umschalter. Die Buchsenleiste neben dem<br />
uP dient der Verbindung mit einer MOD-<br />
CON- bzw. MULTINAUT/NAVIGUARD-Plati<br />
ne, die kopfüber im Empfängergehäuse an<br />
geordnet wird<br />
einem stillgelegten Modell werden Ruder- <strong>und</strong><br />
Schalterinformationen unterdrückt, wobei im<br />
Falle der Schalterinformation allerdings Ausnahmen<br />
möglich sind, die im Programm (Subroutine<br />
DISABLE) definiert werden können<br />
(die Fahrstufeninformation wird in meinen<br />
Anlagen nicht unterdrückt, da das in den angeschlossenen<br />
Geräten eine RC-Fehlermeldung<br />
auslösen würde). Alle Schalterstellungen können<br />
nach Maßgabe einer programminternen<br />
Tabelle (TRGPOS) auch als Trigger, d.h. mit<br />
begrenzter EIN-Zeit, ausgegeben werden.<br />
Die beiden Analogausgänge des uP werden<br />
direkt zur Ansteuerung von Servo <strong>und</strong><br />
Drehzahlsteller verwendet. Wegen der begrenzten<br />
Anzahl von I/O-Pins gehen die Schalterstellungen<br />
als 4-Bit-Zahl über ein mehradriges<br />
Flachbandkabel an den Treiber, ein separates<br />
Bauteil, das in meinen Modellen auch räumlich<br />
vom Empfänger getrennt ist. Daneben individuell<br />
ausgegeben werden die Schalterstellungen<br />
-1- (R_enable) <strong>und</strong> -2- (Memoryschalter),<br />
die auf meinen Vierwellenmodellen zur<br />
zeitweisen Abschaltung der äußeren Wellen<br />
verwendet werden. Auch MDSEL wird als Pin<br />
F_enable separat geführt, da es ebenfalls in<br />
meinen Drehzahlstellern benötigt wird.<br />
3.5.3.1 Schaltung<br />
Das Schaltbild zeigt den Dekoderteil des Empfängers<br />
<strong>und</strong> den Digitaltreiber, also den Teil<br />
der Schaltung, der die jeweiligen im Dekoder<br />
festgestellten Schalterstellungen dann in handfeste<br />
Ströme für die Schaltung der <strong>Sonderfunktionen</strong><br />
umsetzt.<br />
Das vom Demodulator des Empfängers<br />
kommende RC-Signal wird am Schmitt-Trigger-Eingang<br />
des uP eingespeist, alle anderen<br />
Pins sind Ausgänge, wobei die beiden Analogsignale<br />
direkt genutzt werden können.<br />
Der Treiber wandelt die vom Dekoder<br />
kommende 4-Bit-Zahl in Einzelsignale um,<br />
die so verstärkt werden, dass sie zum Schalten<br />
größerer Lasten (einige Ampere) verwendet<br />
werden können. Die 4-Bit-Zahl wird dazu<br />
zunächst in 15 Einzelsignale umgewandelt,<br />
wozu zwei CMOS-ICs <strong>und</strong> ein Gatter benötigt<br />
werden. Die Stromverstärkung besorgt<br />
dann für jede Schalterstellung eine eigene<br />
Transistorstufe, der wegen der in meinen Anlagen<br />
positiven Massenschiene ein Inverter<br />
vorgeschaltet werden muss; im Schaltbild sind<br />
der Einfachheit halber nur zwei Endstufen<br />
dargestellt.<br />
Wie schon erwähnt, erlaubte die begrenzte<br />
Anzahl von IC-Pins nur einen Memoryschalter,<br />
was bei vielen Anwendungen zu wenig ist,<br />
will man <strong>Sonderfunktionen</strong> oft doch für längere<br />
Zeit ein- bzw. aus<strong>schalten</strong>. Im Treiber wurden<br />
daher weitere „Memorys" auf konventionelle<br />
Art mit Flipflops realisiert (zwei Flip-<br />
DEKODER-Treiber<br />
Schaltbild des Dekoders NVDEKO <strong>und</strong> der<br />
notwendigen Schaltertreiber<br />
89
flops in einem CMOS-4027), wofür ein Beispiel<br />
in der rechten unteren Schaltbildhälfte<br />
eingezeichnet ist.<br />
3.5.3.2 Das Programm<br />
NVDEKO.asm<br />
Wie das Ablaufdiagramm des Programms<br />
NVDEKO.asm zeigt, besteht es aus drei charakteristischen<br />
Abschnitten, nämlich dem Lesen<br />
der RC-Information (linke Bildseite), der<br />
Auswertung <strong>und</strong> Ausgabe der Schalterinformation<br />
in der Mitte sowie der Ausgabe der Analoginformation<br />
in der unteren rechten Bildseite.<br />
Mit dem Label SYNCHO beginnt die Auswertung<br />
des RC-Signals, wobei zunächst der<br />
Beginn der Information durch Bestimmung der<br />
Pausenlänge mit dem Timer TMRO ermittelt<br />
wird. Ist das LOW-Signal kürzer als smin, liegt<br />
keine Pause vor, ist es länger als smax, ist das<br />
RC-Signal gestört <strong>und</strong> das Programm verzweigt<br />
zum Fehlerabschnitt (Label RCERR).<br />
TMRO zwischen smin <strong>und</strong> smax deutet auf<br />
die richtige Synchronisationspause hin <strong>und</strong> das<br />
Programm kann mit der mittels indirekter Adressierung<br />
durchgeführten Auswertung der Analoginformation<br />
beginnen. Zunächst wird der HIGH-<br />
Impuls ausgemessen (Subroutine EVIPHIGH), der<br />
eine Länge von mindestens 0,29 ms haben sollte,<br />
um nicht als fehlerhaft erkannt zu werden; die<br />
Kanalinformation (INDF) wird der Länge des<br />
HIGH-Impulses entsprechend 40 (= 0,4 ms) gesetzt.<br />
Danach wird INDF bis zum folgenden<br />
HIGH-Impuls in 10-us-Schritten hochgezählt. Bei<br />
einem Überlauf von INDF liegt ein Signalfehler<br />
vor (Kanalsignal zu lang), weswegen das Programm<br />
ebenfalls nach RCERR verzweigt. Nach<br />
ordnungsgemäßer Impulslängemessung wird das<br />
Ergebnis noch auf Plausibilität untersucht<br />
impmn < INDF < impmx<br />
<strong>und</strong> andernfalls die Fehlerflagge gesetzt,<br />
was nach Abarbeitung der vier Analogkanäle<br />
ebenfalls zum Sprung nach RCERR führt.<br />
90<br />
Generelles Ablaufdiagramm des Programms<br />
NVDEKO<br />
NVDEKO<br />
Generalplan<br />
Sonst werden die 12 Bits der Schalterinformation<br />
verarbeitet, indem in der Subroutine<br />
PEGEL der jeweilige Signalpegel über eine<br />
längere Zeitdauer bestimmt <strong>und</strong> W beim Rücksprung<br />
je nach Pegelwert null oder eins gesetzt<br />
wird. W wird dann zu DIGS_c addiert, was<br />
einer W-abängigen Änderung des nullten Bits<br />
von DIGS_c gleichkommt. Gleichzeitig wird<br />
W zum Parity-Bit (PARBIT) addiert. Die<br />
Schleife mit dem Startlabel BITNEXT wird<br />
zwölfmal durchlaufen, wobei die Bits in<br />
DIGS_c <strong>und</strong> MDSL_c jeweils um eins nach<br />
links verschoben werden (das erste eingelesene<br />
Bit ist daher schließlich MDSL_c,3, das<br />
oberste gültige Bit).<br />
Zum Abschluss wird noch das Parity-Bit<br />
gelesen (I), das mit dem beim Einlesen ermittelten<br />
Wert PARBIT identisch sein muss,
andernfalls liegt ein Fehler der Digitalübertragung<br />
(FLAG,1) vor.<br />
Mit der Prüfung des abschließenden, 0,4<br />
ms dauernden HIGH-Impulses ist das Lesen<br />
des Impulspakets beendet (Label RCEND),<br />
wonach der Timer zurückgesetzt wird, um die<br />
Länge der Synchronisationspause ermitteln zu<br />
können. Bei fehlerfreiem Signal (FLAG,0=L)<br />
beginnt am Label SELEC die Auswertung mit<br />
der Wahl der für den jeweiligen Empfänger<br />
gültigen Analoginformation anhand des Auswahlschalters<br />
AS.<br />
Ist auch die Übertragung der Schalterinformationen<br />
fehlerfrei (FLAG,1=L), werden anhand<br />
von AS auch der gültige 4-Bit-Schalter<br />
<strong>und</strong> der Modellselektor MDSL_c festgelegt.<br />
Dessen Wert muss für hld_M RC-Frames stabil<br />
sein (Störungsunterdrückung), bevor er in der<br />
weiteren Modellselektion verwendet wird, wo<br />
in Abhängigkeit des Auswahlschalters MS <strong>und</strong><br />
des Wertes von MDSL_c das Modell entweder<br />
stillgelegt (FLAG,4=L <strong>und</strong> PORTB,fen=L) oder<br />
aktiviert wird.; FLAG,4 sorgt hier uP-intern für<br />
die Abschaltung des Rudersignals <strong>und</strong> die Unterdrückung<br />
von Schalterstellungen, PORTB,fen<br />
ist ein Ausgangssignal des uP, das in meinen<br />
Drehzahlstellern zur Fahrmotorabschaltung verwendet<br />
werden kann.<br />
Analog zu MDSL_c wird, beginnend am Label<br />
PRUEF2, auch für den 4-Bit-Schalter DIGS_c<br />
eine Störungsunterdrückung durchgeführt, die hier<br />
in Abhängigkeit der Schalterstellung allerdings<br />
unterschiedlich lang ausfallen kann (Tabelle<br />
STORU). Ist sie erfolgreich, so wird einmal die<br />
Tabelle TRIGER aufgerufen, wo für die betreffende<br />
Schalterstellung eine Triggerzeit bestimmt<br />
wird; Triggerzeit null bedeutet kein Trigger. Dann<br />
wird die Subroutine SWITCH aufgerufen, in der<br />
ausgewählte Schalterstellungen noch speziell bearbeitet<br />
werden (Trigger, Flipflop).<br />
Im Modul ANALOG werden schließlich<br />
die Servo- bzw. Drehzahlstellersignale erzeugt,<br />
indem der jeweilige uP-Pin für jeweils LRD x<br />
10 us bzw. LFH x 10 us aktiv gemacht wird.<br />
LRD <strong>und</strong> LFH sind dabei die Werte, die bei<br />
der Analogsignalmessung in 10-ps-Schritten<br />
hochgezählt wurden. Bei gesetzter FLAG,4<br />
(Modell abgeschaltet) wird die Ausgabe des<br />
Rudersignals übersprungen.<br />
NVDEKO unterscheidet zwei Signalfehler,<br />
nämlich den Analog- <strong>und</strong> den Digitalsignalfehler<br />
(FLAG,0 bzw. FLAG, 1). Im Falle eines Analogsignalfehlers<br />
geschieht errskp RC-Frames<br />
nichts, d.h., das Programm gibt während dieser<br />
Zeit die alten Analogsignale aus, unterdrückt<br />
aber die Digitalinformation. Danach werden<br />
Ruder- <strong>und</strong> Fahrsignale abgestellt <strong>und</strong> gewartet,<br />
bis das RC-Signal wieder in Ordnung ist.<br />
Ist nur die Digitalinformation gestört<br />
(FLAG,1=H), so wird diese <strong>einfach</strong> nicht bearbeitet.<br />
Das Modell kann während dieser Zeit<br />
normal gesteuert werden, verfügt aber über<br />
keine <strong>Sonderfunktionen</strong>.<br />
3.5.3.3 Praktische Hinweise<br />
Unter der Überschrift „— Benutzerspezifische<br />
Konstanten —" sind im Programmkopf wieder<br />
einige Parameter aufgelistet, die sich vom Benutzer<br />
anpassen lassen. Mit dig_r <strong>und</strong> dig_ff<br />
können die Schalterstellungen definiert werden,<br />
die an einzelnen Pins gesondert ausgegeben werden,<br />
in meinen Empfängern ein Schaltbefehl für<br />
die Aktivierung der Ruderunterstützung meiner<br />
Drehzahlsteller (R_enable) <strong>und</strong> eine Schalterstellung<br />
mit Memoryfunktion. Einzelne Schalterstellungen<br />
lassen sich, wie schon erwähnt, in<br />
der Tabelle TRIGER auch als Trigger definieren;<br />
wird hier eine Null gesetzt, ist die entsprechende<br />
Schalterstellung kein Trigger.<br />
In der Tabelle DISABL können Schalterstellungen<br />
definiert werden, die abweichend von<br />
der Norm auch bei nur in Bereitschaft liegendem,<br />
aber abgeschaltetem Modell aktiv bleiben.<br />
Mit der Tabelle STORU kann schließlich<br />
für jede Schalterstellung eine individuelle<br />
Schaltverzögerung vorgegeben werden, die<br />
auch der Störungsunterdrückung dient; bei sicherheitsrelevanten<br />
Schalterstellungen (z.B.<br />
dem Zünden von Feuerwerk), sollte man diesen<br />
Wert nicht zu klein wählen.<br />
91
4 Anhang<br />
4.1 Literatur<br />
Es ist nicht meine Absicht, die reichliche Literatur<br />
zum Thema Mikroprozessoren oder<br />
Schiffmodell auch nur zum Teil aufzulisten.<br />
Ich will mich vielmehr auf einige wenige Bücher<br />
<strong>und</strong> Zeitschriften beschränken, die ich<br />
selber öfter konsultiere oder mehr oder weniger<br />
regelmäßig durchblättere.<br />
Ob die zitierte Literatur in Deutsch oder<br />
Englisch ist, ersieht man fast immer aus dem<br />
Titel.<br />
4.1.1 Zeitschriften<br />
• Elektor. Elektor-Verlag, Aachen<br />
(erscheint monatlich in Deutsch)<br />
• ModellWerft. Verlag für Technik <strong>und</strong><br />
Handwerk, Baden-Baden<br />
(erscheint monatlich in Deutsch)<br />
• Schiffsmodell. Neckar-Verlag,<br />
Villingen-Schwenningen<br />
(erscheint monatlich in Deutsch)<br />
4.1.1 Handbücher (Manuals)<br />
• Kohtz, Dieter: Messen, Steuern <strong>und</strong> Regeln<br />
mit <strong>PIC</strong>-Mikrokontrollern. Franzis Verlag,<br />
1998, ISBN 3-7723-6154-4<br />
92<br />
• Microchip: MPLAB (IDE, Simulator,<br />
Editor) User's Guide, Report DS51025D,<br />
Microchip Technology Inc., 2000<br />
(download von www.microchip.com)<br />
• Microchip: MP ASM (with MPLINK and<br />
MPLIB) User's Guide, Report DS33014F,<br />
Microchip Technology Inc., 1997<br />
• Microchip: <strong>PIC</strong>micro Mid-Range MCU<br />
Family Reference Manual, Report<br />
DS33023A, Microchip Technology Inc.,<br />
1997 (download von www.microchip.com)<br />
• Microchip: Fixed Point Routines (AN617), Report<br />
DS00617B, Microchip Technology Inc.,<br />
1996 (download von www.microchip.com)<br />
• Microchip: <strong>PIC</strong>12C5XX Datenblatt, Report<br />
DS40139E, Microchip Technology Inc.,<br />
1999 (download von www.microchip.com)<br />
• Microchip: <strong>PIC</strong>12C67X Datenblatt, Report<br />
DS30561 A, Microchip Technology Inc.,<br />
1997 (download von www.microchip.com)<br />
• Microchip: <strong>PIC</strong>16C505 Datenblatt, Report<br />
DS40192C, Microchip Technology Inc.,<br />
1999 (download von www.microchip.com)<br />
• Microchip: <strong>PIC</strong>16C71X Datenblatt, Report<br />
DS30272A, Microchip Technology Inc.,<br />
1997 (download von www.microchip.com)<br />
• Microchip: <strong>PIC</strong>16F872 Datenblatt, Report<br />
DS30221 A, Microchip Technology Inc.,<br />
1999 (download von www.microchip.com)<br />
• Microchip: <strong>PIC</strong>16F87X Datenblatt, Report<br />
DS30292C, Microchip Technology Inc.,<br />
2001 (download von www.microchip.com)
4.2 Platinenlayouts <strong>und</strong> Liste der Programme auf der CD-ROM<br />
4.2.1 Platinenlayouts <strong>und</strong> Bestückungspläne<br />
4.2.1.1 Platinenlayout <strong>und</strong> Bestückungsplan für PENTA-S<br />
4.2.1.2 Platinenlayout <strong>und</strong> Bestückungsplan für RADAR<br />
4.2.1.3 Platinenlayout <strong>und</strong> Bestückungsplan für ZUND<br />
4.2.1.4 Platinenlayout <strong>und</strong> Bestückungsplan für DUOSIG<br />
93
4.2.1.5 Platinenlayout <strong>und</strong> Bestückungsplan für S2PWM<br />
4.2.1.6 Platinenlayout <strong>und</strong> Bestückungsplan für MONONAUT<br />
4.2.1.7 Platinenlayout <strong>und</strong> Bestückungsplan für MODCON<br />
94
4.2.2 Liste der Programme<br />
auf der ModellWerft-Homepage<br />
www.modellwerft.de/downloads<br />
4.2.2.1 <strong>PIC</strong>-Sourceprogramme<br />
(.asm)<br />
autonaut.asm<br />
1 -kHz-PWM-Fahrstufenregler für automatische<br />
Fahrstufenanpassung eines Modells an eine Regelgröße<br />
blink.asm<br />
Demonstration für den Programmaufbau.<br />
BLINK erzeugt ein Blinksignal beliebig wählbarer<br />
Sequenz <strong>und</strong> Frequenz (im Muster ist<br />
eine SOS-Blinkfolge programmiert).<br />
dcnaut.asm<br />
Die Fahrstufe wird als 4-Bit-Zahl ausgegeben<br />
<strong>und</strong> mit einem speziellen Treiber in eine belastungskompensierten<br />
Klemmspannung umgewandelt<br />
(DA-Wandler). Mit Logikpegel abschaltbare<br />
Ruderunterstützung bei Hartrudermanövern<br />
durch individuelle Umpolung der dem<br />
Ruderausschlag zugewandten Welle oder Drehzahlreduzierung<br />
bei Hartrudermanövern (Antikräng)<br />
bei abgeschalteter Ruderunterstützung.<br />
duosig.asm<br />
Synthetische Erzeugung eines Typhonsignals<br />
<strong>und</strong> einer Zerstörersirene<br />
mdc_d.asm<br />
Kombiniert zwei Impulsdrehzahlsteller mit der<br />
Modellüberwachung NAVGUARD. Bei größeren<br />
Ruderausschlägen können so nicht nur<br />
die Umpolrelais, sondern auch die Fahrstufen<br />
der beiden Motorseiten individuell beeinflusst<br />
werden.<br />
mcd_p.asm<br />
Kombiniert einen Impulsdrehzahlsteller mit<br />
Ruderunterstützung (MLTNAUT) mit der Modellüberwachung<br />
NAVGUARD <strong>und</strong> dem Automatikregler<br />
AUTONAUT<br />
mdc_s.asm<br />
Kombiniert einen Impulsdrehzahlsteller mit<br />
Ruderunterstützung (MLTNAUT) mit der Modellüberwachung<br />
NAVGUARD<br />
mltnaut.asm<br />
2-kHz-Drehzahlsteller mit durch Logikpegel<br />
abschaltbarer individueller Umpolung der dem<br />
Ruderausschlag zugewandten Welle (Ruderunterstützung)<br />
bzw. Drehzahlreduzierung bei<br />
Hartrudermanövern (Antikräng) bei abgeschalteter<br />
Ruderunterstützung, Anfahrverbesserung<br />
durch Motorkick, Alarmausgabe von RC-Signalfehler<br />
nebst Abschaltung <strong>und</strong> durch weiteren<br />
Logikpegel abschaltbare äußere Wellen bei<br />
Vierwellenmodellen<br />
mono.asm<br />
Mit Logikpegel abschaltbarer 2-kHz-Drehzahlsteller.<br />
Ansteuerung des Fahrmotors erfolgt<br />
entweder via Transistorbrücke (Motorleistungen<br />
bis etwa 600 mA) oder nach Modifizierung<br />
im Programm via Leistungstreiber<br />
<strong>und</strong> Umpolrelais; mit „Motorkick" zur Anfahrverbesserung,<br />
Leckdetektion <strong>und</strong> Alarmausgabe<br />
bei RC-Signalfehler (Blinken).<br />
navgrd.sm<br />
Überwacht modellrelevante Parameter wie RC<strong>und</strong><br />
Fahrakkuspannungen, Leck <strong>und</strong> RC-Signalstörungen<br />
<strong>und</strong> blinkt im Alarmfall ein entsprechendes<br />
Morsetelegramm über einen Signalscheinwerfer<br />
nvdeko.asm<br />
Empfängersignaldekoder für die mit NVEN-<br />
KO erzeugten Steuersignale<br />
nvenko.asm<br />
Senderenkoder zur gleichzeitigen Steuerung von<br />
zwei aktiven <strong>und</strong> zwei in Bereitschaft liegenden<br />
Modellen, wobei zwischen aktiven <strong>und</strong> in Bereitschaft<br />
liegenden Modellen jederzeit umgeschaltet<br />
werden kann. Jedes Modell verfugt dabei<br />
über zwei analoge (Lenkung <strong>und</strong> Fahrstufe) <strong>und</strong><br />
15 digitale, d.h. Schaltfunktionen.<br />
95
pentas.asm<br />
Fünffachschalter aus einem Servosignal (elektronische<br />
Magnetorgel)<br />
radar.asm<br />
Erzeugung der vier Strangsignale zur Ansteuerung<br />
von Miniaturschrittmotoren zum Antrieb<br />
von Modellradarschirmen<br />
radznd.asm<br />
Eine speziell für den Einsatz im 5-V-Bordnetz<br />
von Kleinmodellen entwickelte Kombination<br />
von RADAR.asm <strong>und</strong> ZUND.asm<br />
s2pwm-0.asm<br />
Wie s2pwm-l, jedoch ohne Justierungsmöglichkeit<br />
des Servoausschlags oder der Servolaufzeit<br />
s2pwm-l.asm<br />
Programm erzeugt aus Ein-Aus-Schaltersignalen<br />
Impulsketten zur Ansteuerung eines Servos,<br />
das dann <strong>Sonderfunktionen</strong> auf Modellen<br />
betätigen kann. Durch Selektion an einem<br />
„Mäuseklavier" können verschiedene Auslenkarten<br />
(Trigger, Ausschlag aus Servomitte sowie<br />
Ausschlag nach beiden Seiten) eingestellt<br />
werden.<br />
z<strong>und</strong>.asm<br />
Erzeugt die Gatespannung für den FET-Leistungstreiber<br />
zur Stromschaltung eines Glühdrahtes.<br />
ZUND beinhaltet eine Störungsunterdrückung,<br />
die Begrenzung des Glühzeit auf<br />
wenige Sek<strong>und</strong>en <strong>und</strong> eine Verdreifachung<br />
96<br />
der Gatespannung bei niedrigen Betriebsspannungen.<br />
4.2.2.2 FORTRAN-<br />
Unterstützungsprogramme<br />
(.for)<br />
knn.for<br />
Programm erzeugt die Motorkennlinientabelle<br />
FKNLI in einer direkt in verschiedene Drehzahlstellerprogramme<br />
kopierbaren Form. Parametereingabe<br />
direkt im Code. Das Ausgabefile<br />
ist „knn.asm".<br />
k-rnn.for<br />
Programm erzeugt die Tabellen FKNLI (Motorkennlinie)<br />
<strong>und</strong> RKNLI (Rudereinfluss) in<br />
einer direkt in die MODCON-Programme kopierbaren<br />
Form. Parametereingabe direkt im<br />
Code. Das Ausgabefile ist „dnn.asm".<br />
morse.for<br />
Programm erzeugt den Morsecode von im File<br />
„messg.in" vorgegebenen Meldungen <strong>und</strong> gibt<br />
ihn in einer direkt in NAVGRD bzw. MOD-<br />
CON kopierbaren Form auf dem File<br />
„morse.asm" aus.<br />
rknn.for<br />
Programm erzeugt die Rudereinflusstabelle<br />
RKNLI in einer direkt in verschiedene Drehzahlsteller-<br />
Programme kopierbaren Form. Parametereingabe<br />
direkt im Code. Das Ausgabefile<br />
ist „rnn.asm".
<strong>Funktionen</strong> <strong>und</strong> <strong>Sonderfunktionen</strong><br />
<strong>einfach</strong> <strong>schalten</strong><br />
<strong>PIC</strong>-Mikroprozessoren im Schiffsmodell<br />
<strong>Sonderfunktionen</strong> im Schiffsmodell - dazu braucht man heute keine<br />
komplizierten Schaltungen zusammenlöten, ein programmierbarer<br />
Mikroprozessor genügt.<br />
Dirk Lübbesmeyer bietet in diesem Buch das ganze Know-how, wie<br />
man moderne Mikroprozessoren für <strong>Sonderfunktionen</strong> einsetzen<br />
kann. Zunächst werden die Gr<strong>und</strong>lagen erklärt <strong>und</strong> die zur<br />
Programmierung notwendige Hard- <strong>und</strong> Software beschrieben, dann<br />
geht es um die Erstellung von eigenen Mikroprozessorprogrammen.<br />
Ein umfangreicher Teil stellt dann viele unterschiedliche<br />
Anwendungen vor, z.B. Fünffachschalter aus einem Funktionssignal,<br />
Schrittmotorsteuerung für einen Radarschirm, Typhon- <strong>und</strong><br />
Sirenensignalgenerator, Überwachung von Akkuspannungen,<br />
diverse Drehzahlsteller, Mehrmodellsteuerung <strong>und</strong> einiges mehr.<br />
Alles wird auch dem elektronisch weniger versierten Modellbauer<br />
ausführlich erklärt, dazu sind die Schaltungen, Platinenlayouts <strong>und</strong><br />
Bestückungspläne abgebildet <strong>und</strong> auf der Homepage<br />
www.modellwerft.de im Bereich Downloads findet man alle<br />
beschriebenen Programme.<br />
VTH-Fachbuch<br />
Best.-Nr. 310.2119-Preis: 13,00 € [D]<br />
ISBN 3-88180-719-5