Aus RN-Wissen.de
Wechseln zu: Navigation, Suche
Laderegler Test Tueftler Seite

(Hello_World oder "I'm alive")
(Software)
Zeile 2.562: Zeile 2.562:
  
 
Damit dürfte dieses kleine Beispiel ziemlich ausgereizt sein. Weiter geht's mit den A/D-Wandlern und Motoren des CCRP5:
 
Damit dürfte dieses kleine Beispiel ziemlich ausgereizt sein. Weiter geht's mit den A/D-Wandlern und Motoren des CCRP5:
 +
 +
====Messen, Steuern und Regeln====
  
 
{{Baustelle|Pischke}}
 
{{Baustelle|Pischke}}

Version vom 21. Februar 2007, 17:57 Uhr

Arexx Roboter

Einleitung

CCRP5 steht für C-CONTROL ROBOTER PROJECT 5 und bezeichnet ein Produkt der Firma Conrad Electronic GmbH in Hirschau, welches seit Ende 2003 auf dem Markt ist. Mechanisch und elektrisch wird das System bereits fertiggestellt geliefert, ist aber dennoch erweiterbar. Zur Inbetriebnahme muss nur der Mikrocontroller (µC) programmiert werden. Dies geschieht mit Hilfe der im Lieferumfang befindlichen Entwicklungsumgebung (IDE), in der aus einem Quelltext in der firmeneigenen Programmiersprache CCBASIC ein entsprechendes Programm für den µC erzeugt wird (Cross-Compiling). Dieses kann aus der IDE heraus über eine serielle Schnittstelle des PC (Host) in den µC (Target) übertragen werden, welcher während dieser Zeit in der Schaltung verbleibt (In-System-Programming, kurz: ISP). Ebenfalls im Lieferumfang befinden sich praktikable Beispielprogramme, sodass sich der Arbeitsaufwand ein experimentierbereites System zu erstellen, auf ein Minimum beschränkt. Um die Möglichkeit der Simulation des µC, welche die Entwicklungsumgebung bietet, nutzen zu können, empfiehlt sich der Einsatz eines Windows-PC.

Mechanik

Beschreibung

Diese Abbildung gibt einen Einblick in das Innere des Gehäuses bei demontierter Hauptplatine. Hierzu sind die vier einzigen Rundkopf-Kreuzschlitz- schrauben auf der Hauptplatine heraus zu drehen.

Das Fahrgestell des CCRP5 (auch einzeln erhältlich) besteht aus einer längs geteilten, symmetrischen Kunststoffwanne, die nach oben hin von der Hauptplatine abgedeckt wird. In jeder Gehäusehälfte befindet sich ein eigenständiger Antrieb, bestehend aus Antriebsmotor mit Getriebe und außenliegendem, heckgetriebenem Raupenband. Ein seitliches Herunterrutschen des Raupenbandes wird im Querschnitt durch Formschluss mit dem Antriebs-, bzw. Umlenkrad verhindert. Die elektrischen Anschlüsse der Antriebsmotoren sind durch leicht entfernbare Abdeckungen an den beiden Längsseiten des Fahrgestells gut zugänglich.

In der linken Hälfte der Abbildung erkennt man den durch einen Stellring gesicherten rechten Vorderachsstummel. Vorder- und Hinterachsstummel sind in Gleitlagerbuchsen gelagert. In der rechten Hälfte sieht man das Getriebe mit dem dahinter befindlichen Antriebsmotor. Es handelt sich hierbei um ein dreistufiges Stirnradgetriebe mit Polyamid-Zahnrädern in der Verzahnungsgröße Modul 0,5.

Übersetzung

In der Konfiguration mit jeweils 12 Zähnen am treibenden und jeweils 50 Zähnen am getriebenen Zahnrad ergibt sich für das Getriebe eine Gesamtübersetzung von


[math]i_{gesamt}=i_{1}\cdot i_{2}\cdot i_{3}=\frac{z_{2}}{z_{1}}\cdot\frac{z_{4}}{z_{3}}\cdot\frac{z_{6}}{z_{5}}=\frac{50}{12}\cdot\frac{50}{12}\cdot\frac{50}{12}=\frac{50^{3}}{12^{3}}=\frac{125000}{1728}=72\frac{73}{216}[/math]


So ändert sich die Drehzahl am Antriebsrad des Raupenbandes (hier Index 2) gegenüber der Drehzahl an der Motorwelle (hier Index 1) wie folgt:


[math]n_{2}=\frac{n_{1}}{i}=\frac{n_{1}}{72}[/math]


Die Drehzahl am Antriebsrad beträgt also nur den 72-ten Teil der Motordrehzahl. Dafür steigt das Drehmoment im Verhältnis


[math]M_{2}=i\cdot {M_{1}}=72\cdot {M_{1}}[/math]


auf das 72-fache des ursprünglich an der Motorwelle verfügbaren Wertes.

Elektromechanik

Beschreibung

Die elektromechanische Ausrüstung des CCRP5 besteht in der Grundausstattung aus den beiden Antriebsmotoren und zwei Gabellichtschranken. Leider sind für die Antriebsmotoren keine Kenndaten bei der Conrad Electronic GmbH erhältlich.

Odometrie

Die Gabellichtschranken sind von der Unterseite her mit der Hauptplatine verlötet und verschraubt. Dabei sind sie so plaziert, daß der Lichtweg zwischen Sender und Empfänger von einem der Zahnräder des Getriebes unterbrochen wird. In dieses Zahnrad wurde in entsprechendem Radius eine Bohrung eingebracht, sodaß nun mit jeder Umdrehung dieses Zahnrades ein Impuls der Lichtschranke erzeugt wird. Auf diese Art wird eine indirekte Messung des Weges möglich, den das Fahrgestell bei seiner Fortbewegung zurückgelegt hat (Odometrie). Dieser Weg errechnet sich wie folgt:


Übersetzung [math]i=\frac{z_{2}}{z_{1}}=\frac{50}{12}=\frac{25}{6}[/math]


Aus der Übersetzung ergibt sich die Drehzahl des angetriebenen Zahnrades, welches mit dem Antriebsrad verbunden ist:


Drehzahl [math]n_{2}=\frac{n_{1}}{i}=\frac{1\cdot 6}{25}[/math] Umdrehungen (oder 86°)


Der Durchmesser des Antriebsrades, gemessen über die Außenflächen des Raupenbandes - denn dort rollt sich das Raupenband ja ab - beträgt ca. 50 mm. So gelangt man über die Beziehung


[math]U=d\cdot \pi[/math]


auf die abgerollte Länge einer Umdrehung des Antriebsrades:


[math]U=50mm \cdot \pi\approx 157 mm[/math]


Eine [math]\frac{6}{25}[/math] Umdrehung entspricht dann [math]157mm\cdot\frac{6}{25}\approx38mm[/math]


Mit dieser Schrittweite läßt sich also die Fortbewegung des Fahrgestells überwachen, doch dies hält sich durch Schlupf zwischen Antriebsrad und unverzahntem Raupenband, sowie Schlupf zwischen Raupenband und Untergrund in (physikalischen) Grenzen.

Elektronik

Beschreibung

Die Hauptplatine ist doppelseitig und durchkontaktiert, mißt 185 x 128 mm und wurde beidseitig mit einer schwarzer Lötstopmaske versehen. Ebenso die frontseitige Sensorplatine, welche 80 x 19 mm mißt. Die meisten Bauteile sind in SMD-Technik ausgeführt. Mit Hilfe von abgewinkelten Stiftleisten ist die Sensorplatine an der Außenkante der Hauptplatine rechtwinklig zur deren Unterseite verlötet. Die Bestückungsseite zeigt dabei nach außen. Die Hauptplatine wird so auf das Fahrgestell montiert, daß diese Seite in Bewegungsrichtung vorne liegt (zur Erinnerung: die Getriebe liegen hinten).

Funktionsschaubild

Hier ein Funktionsschaubild der Elektronik des CCRP5:


Funktionsschaubild der Elektronik des CCRP5


Auch die komplizierteste Schaltung besteht aus einzelnen Funktionselementen, welche einzeln für sich betrachtet und nachvollzogen, das Verständnis der Gesamtschaltung ermöglichen. Nachfolgend werden die Schaltungen der Elemente des obigen Funktionsschaubildes anhand von Schaltungsauszügen beschrieben. Diese wurden aus den Unterlagen der Conrad Electronic GmbH erstellt, werden aber aus Haftungsgründen ohne jegliche Gewähr für die Richtigkeit veröffentlicht. Die Verwendung der darin enthaltenen Informationen erfolgt auf eigenes Risiko.

Hauptprozessor

Schaltungsauszug

Im Zentrum der Schaltung des CCRP5 liegt die C-Control 1. Sie basiert auf einem µC vom Typ MC68HC05B6 der Firma Freescale Semiconductor.


Hauptprozessor


Die C-Control ist mit der gesamten Peripherie verbunden - entweder direkt oder über weitere Bausteine. Deshalb findet sich hier die höchste Dichte an ankommenden und abgehenden Leitungen. Nachfolgend eine alphabetische Auflistung der im Schaltungsauszug verwendeten Leitungskürzel und deren Zuordnungen:

BAT Batteriesensor DAT Datenleitung Subsystem/Schieberegister GND Masse
IRQ Interrupt-Request LAD Ladestromsensor LIV Motordrehrichtungssteuerung, links-
LSL Lichtsensor, links- LSR Lichtsensor, rechts- MIC Mikrofonspannung
MOL Motordrehzahlsteuerung, links- MOR Motordrehzahlsteuerung, rechts- MTS Motorstromsensor
REF Referenzspannung REV Motordrehrichtungssteuerung, rechts- RST Reset
SDA Datenleitung I2C-Bus SDL Taktleitung I2C-Bus SEF Sensorfeldspannung
SRC Taktleitung Schieberegister STR Steuerleitung Schieberegister SUC Taktleitung Subsystem
VCC Versorgungsspannung / / / /

Anm.: C9 und C11, sowie R11 und R29 sind auch in den Original-Unterlagen von Conrad Electronic wie gezeigt geschaltet und auf der Platine bestückt.

Schaltungsbeschreibung

IC7 (MC68HC05B6) liegt über Pin 10 (VDD) an der direkt aus der Batterie gespeisten Versorgungsspannung. Aus den technischen Daten dieses IC geht hervor, daß dessen Versorgungsspannung maximal 7 Volt betragen darf. Vom Einsatz von Primärzellen in der Batterie ist daher abzuraten, da die Versorgungsspannung sonst (6x1,5V=) 9 Volt beträgt. C8, C9 und C11 sind gegen Masse geschaltet und filtern zusammen mit anderen Kondensatoren in der Gesamtschaltung so Störspitzen aus der Versorgungsspannung heraus. C9 oder C11 könnte m.E. entfallen. Über Pin 41 (VSS) liegt IC7 an Masse.

Damit IC7 in Betrieb genommen werden kann, muß die Reset-Leitung auf logisch "1" (HIGH) liegen. Das bedeutet, daß hier mindestens 70% der Versorgungsspannung (Pin 10/VDD) anliegen müssen. Dies wird durch den Pull-Up-Widerstand R10 erreicht, der Pin 18 (RESET) mit der Versorgungsspannung verbindet. Bliebe diese Leitung auf logisch "0" (LOW) - maximal 20% der Versorgungsspannung (Pin 10/VDD) - würde der Controller im (Power-on-)Reset-Status verweilen.

Wird nun S1 (der rote SMD-Taster auf der Platine) betätigt, verhindert R10 einen Kurzschluß, indem er den nun fließenden Strom auf einen minimalen Betrag begrenzt. Die gesamte Versorgungsspannung fällt an ihm ab und an Pin 18 (RESET) liegt LOW an. Dies veranlaßt die Watchdog-Schaltung einen Reset im Controller auszulösen, der ihn neu startet.

Gleiches erzielt der Spannungswächter IC5 (TL7757), wenn die Versorgungsspannung einen Wert von nominal 4,55 Volt unterschreitet. R21 entstammt m.E. der Applikationsschaltung des TL7757, in der davon ausgegangen wird, daß noch kein Pull-up-Widerstand vorhanden ist und dient hier zusätzlich zur Strombegrenzung, wenn IC5 die Reset-Leitung auf Masse schaltet. Mit R10 zusammen bildet dieser Widerstand einen parallel geschalteten Pull-Up-Gesamtwiderstand von 5 kOhm. Einer dieser beiden Widerstände könnte m.E. entfallen.

Mehr braucht der Controller grundsätzlich erstmal nicht, um betriebsbereit zu sein, denn er verfügt über einen internen Oszillator mit 2,1 MHz Taktfrequenz. Möchte man diese auf bis zu 4,2 MHz erhöhen (von 12 MHz ist in den technischen Daten nicht die Rede), so kann man entweder einen externen Taktgeber an Pin 16 (OSC1) oder frequenzbestimmende Bauteile zwischen Pin 16 (OSC1) und Pin 17 (OSC2) anschließen.

Abschnitt 2.5.8.3 der technischen Daten des MC68HC05B6 liefert auf Seite 2-12 die entsprechenden Schaltungen und Bauteilwerte. Möchte man eine über längere Zeit stabile Taktfrequenz erzielen, um den Controller z.B. für Zeitmessungen nutzen zu können, empfiehlt sich die dort in Abb. 2-5(a) gezeigte Quarz-Variante. Diese findet sich mit den in den technischen Daten empfohlenen Bauteilwerten im Original-Schaltplan wieder und somit auch im obigen Schaltungsauszug.

Die beiden letzten, nicht vom Betriebssystem "C-Control" im User-ROM kontrollierten Anschlüsse sind Pin 7 (VRL) und Pin 8 (VRH). Hier liegen Referenzspannungen an, die mit dem oberen (Pin8/VRH) und unteren (Pin7/VRL) Grenzwert den Meßbereich des A/D-Wandlers festlegen. Pin 7 (VRL) liegt an Masse. C10 liegt zwischen Pin 8 (VRH) und Masse und filtert so Störspitzen aus der Referenzspannung heraus.

Nach dem Start arbeitet der Controller die Anweisungen des Programms "Betriebssystem" ab. Der MC68HC05B6 wird so zur C-Control 1. Diese wartet in einer Schleife nun auf ein Signal auf Pin 26 (PA5) oder ein über Pin 50 (RDI) empfangenes Kommando-Byte. Pin 50 (RDI) liegt beim Anschluß des CCRP5 an die serielle Schnittstelle des Host-PC an der Leitung TXD, welche gemäß der RS232-Spezifikation mit Pegeln von +/- 12 Volt arbeitet.

Diese werden von T5 (BC847C) - der in Emitterschaltung als elektronischer Schalter arbeitet - gewandelt und invertiert. Bei einem Pegel von +12 Volt fließt ein von R36 begrenzter Basisstrom, der einen dem Verstärkungsfaktor entsprechenden Kollektorstrom fließen läßt, welcher von R35 begrenzt wird - an Pin 50 (RDI) liegt die Sättigungsspannung UCEsat an. Diese wird vom Controller als logisch "0" (LOW) interpretiert.

Beträgt der Pegel -12 Volt, so sperrt die Basis-Emitter-Diode von T5 (die maximal zulässige Emitter-Basis-Spannung UEB von 6V beim BC847C wird dabei um 6 Volt überschritten) und R35 wirkt nun als Pull-Up-Widerstand für Pin 50 (RDI), an dem jetzt die als logisch "1" (HIGH) interpretierte Versorgungsspannung anliegt.

Am zuvor erwähnten Pin 26 (PA5) liegt über die beiden Pull-Up-Widerstände R11 und R29 die Versorgungsspannung an. Wird nun S2 (der schwarze SMD-Taster auf der Platine) betätigt, begrenzen diese beiden Widerstände als parallel geschalteter Pull-Up-Gesamtwiderstand von 9091 Ohm den Strom und verhindern einen Kurzschluß (R11 könnte dabei entfallen, da er sich nur unwesentlich auf den Gesamtwiderstand auswirkt). Die Versorgungsspannung fällt an ihnen ab und an Pin 26 (PA5) liegt LOW an. Dies wurde im Betriebssystem als Startsignal für die C-Control 1 festgelegt.

Die C-Control 1 setzt nun PA3 und PA2 (in dieser Reihenfolge) auf LOW. Da die hier normalerweise angeschlossenen LED "ACTIVE" (gelb) und "RUN" (rot) beim CCRP5 nicht vorhanden sind, bekommt man von außen davon nichts mit. Anschließend beginnt die C-Control 1 aus IC8 (24C65) das Anwenderprogramm auszulesen. Dazu bedient man sich des I2C-Bus-Protokolls.

Pin 31 (PA0) liegt an der Datenleitung des Busses und ist mit Pin 5 (SDA) von IC8 verbunden. R26 dient als Pull-Up-Widerstand für diese Busleitung. Pin 30 (PA1) liegt an der Taktleitung des Busses und ist mit Pin 6 (SCL) von IC8 verbunden. R25 dient als Pull-Up-Widerstand für diese Busleitung. Über Pin 8 (VCC) wird IC8 ebenso wie IC7 direkt aus der Batterie mit Spannung versorgt. Auch hier gilt das eingangs Erwähnte für die Verwendung von Primärzellen.

Befinden sich keine Daten in IC8, werden PA3 und PA2 (in dieser Reihenfolge) wieder auf HIGH gesetzt und das Betriebssystem springt zurück in die Warteschleife.

Damit ein Anwenderprogramm in IC8 geladen werden kann, muß auf Kommando der IDE von der C-Control 1 eine Zeichenkette zurückgesendet werden. Dies geschieht über Pin 52 (TDO), welcher über T4 (BC847C) - wie T5 in Emitterschaltung als elektronischer Schalter - mit der Leitung RXD der seriellen Schnittstelle am Host-PC verbunden ist. Auch diese Leitung arbeitet gemäß der RS232-Spezifikation mit Pegeln von +/- 12 Volt.

Liegt nun an Pin 52 (TDO) ein HIGH-Pegel an, so fließt ein Basisstrom durch T4, der von R33 begrenzt wird. Dieser Basisstrom läßt - wie bei T5 - einen dem Verstärkungsfaktor entsprechenden Kollektorstrom fließen, der durch R34 begrenzt wird. An der Leitung RXD liegt die Sättigungsspannung UCEsat an, welche im Falle des BC847C bei dieser Belastung nicht einmal 100 mV betragen mag.

Bei einem LOW-Pegel an Pin 52 (TDO) fließt kein Basisstrom durch T4 und somit auch kein Kollektorstrom. R34 dient nun als Pull-Up-Widerstand für die Leitung RXD an der seriellen Schnittstelle des Host-PC und sorgt für einen Pegel entsprechend der Versorgungsspannung, die maximal 7,2 Volt beträgt.

Die Übertragung mag mit diesen Pegeln (0,1V/7,2V statt +/- 12V) funktionieren, ist aber m.E. gegenüber einem Schnittstellen-Pegelwandler wie z.B. dem MAX232 keine saubere Lösung.

Port A des Controllers ist vollständig vom Betriebssystem "C-Control 1" belegt. Ebenso wie PA2 (RUN/rot) und PA3 (ACTIVE/gelb), werden PA4 (DCF OK/grün), PA6 (RTS) und PA7 (CTS) beim CCRP5 nicht verwendet. Die restlichen Resourcen des Controllers teilen sich in vom CCRP5 belegte und noch freie Anschlüsse auf.

Über Pin 35 (PB4) und Pin 34 (PB5) wird die Drehrichtung des linken, bzw. rechten Antriebsmotors gesteuert. Die beiden D/A-Wandler des Controllers sind ebenfalls fest vom CCRP5 belegt und steuern die Drehzahl des linken (Pin20/PLMA), bzw. rechten (Pin21/PLMB) Antriebsmotors. Der Motorstrom kann über den Motorstromsensor gemessen werden, der an Pin 14 (PD0/AN0) angeschlossen ist.

Die Versorgung des Subsystems und des Schieberegisters mit Daten erfolgt über eine gemeinsame Datenleitung, welche an Pin 39 (PB0) angeschlossen ist. Zwei getrennte Taktleitungen - Pin 38 (PB1) für das Subsystem und Pin 37 (PB2) für das Schieberegister - sorgen dabei für eine korrekte Zuordnung der Daten auf der Datenleitung. Über ein unbenutztes NAND-Gatter (IC13) der Motorbrückenschaltung wird das Taktsignal für das Schieberegister invertiert. An Pin 36 (PB3) ist die Steuerleitung des Schieberegisters angeschlossen.

Um direkt auf Signale des IR-/ACS-Empfängers reagieren zu können, ist Pin 19 (IRQ) mit dem Subsystem verbunden. R23 dient hier als Pull-Up-Widerstand. Wenn das Subsystem seinen entsprechenden Ausgang auf LOW setzt, fließt hier ein Strom, der diesen Ausgang natürlich nicht überlasten darf. Die Versorgungsspannung fällt an R23 ab und an Pin 19 (IRQ) liegt ein LOW-Pegel an, der von der Watchdog-Schaltung registriert und als Signal im Controller weitergeleitet wird. Im Anwenderprogramm kann auf dieses Signal dann sofort mit einer Interrupt-Routine reagiert werden.

Wenn die Versorgungsspannung den Betrag von 5,4 Volt unterschreitet, ist die Entladeschlußspannung von 0,9 Volt pro Zelle erreicht und der Betrieb des CCRP5 sollte eingestellt werden. Die Versorgungsspannung kann über Pin 12 (PD2/AN2) überwacht werden. Der beim anschließend erfolgenden Ladevorgang fließende Ladestrom kann über Pin 13 (PD1/AD1) überwacht werden. Dazu muß gesagt werden, daß über den Parameter Ladestrom allein bei NiCd- oder NiMH-Zellen kein Ladeschluß definiert werden kann.

Freie Resourcen

Zur individuellen Nutzung sind folgende Resourcen des Controllers noch frei:

Bezeichner Art Pin verfügbar über
PB6 digitaler Ein- oder Ausgang 33 Y41 und Y81
PB7 digitaler Ein- oder Ausgang 32 Y40 und Y80
PC0 digitaler Ein- oder Ausgang 49 Y9
PC1 digitaler Ein- oder Ausgang 48 Y10
PC2/ECLK digitaler Ein- oder Ausgang 47 Y11
PC3 digitaler Ein- oder Ausgang 46 Y12
PC4 digitaler Ein- oder Ausgang 45 Y13
PC5 digitaler Ein- oder Ausgang 44 Y14
PC6 digitaler Ein- oder Ausgang 43 Y15
PC7 digitaler Ein- oder Ausgang 42 Y16
TCAP1 DCF-77 Zeitsignaleingang 22 Y75
TCAP2 Frequenzmeßeingang 23 Y76
PD3/AN3 A/D-Wandlereingang 11 Y2
PD4/AN4 A/D-Wandlereingang 9 Y3
PD5/AN5 A/D-Wandlereingang 5 Y4
PD6/AN6 A/D-Wandlereingang 4 Y5
PD7/AN7 A/D-Wandlereingang 3 Y6

Wobei Pin 11 (PD3/AN3) durch Überbrückung von Y21/Y22 mit einem Jumper mit dem auf der Platine des CCRP5 angebrachten Mikrofon verbunden werden kann; Pin 9 (PD4/AN4) durch Überbrückung von Y23/Y24 mit dem Sensorfeld; Pin 5 (PD5/AN5) durch Überbrückung von Y25/Y26 mit dem linken Lichtsensor und Pin 4 (PD6/AN6) durch Überbrückung von Y27/Y28 mit dem rechten Lichtsensor.

Schieberegister

Schaltungsauszug

Das Schieberegister dient im CCRP5 als Seriell-Parallel-Wandler, um Resourcen des Controllers einzusparen. Mit drei Leitungen werden acht Funktionen gesteuert.


Schieberegister


Nachfolgend eine alphabetische Auflistung der im Schaltungsauszug verwendeten Leitungskürzel und deren Zuordnungen:

AE1 ACS-Sender, Steuerleitung 1 AE2 ACS-Sender, Steuerleitung 2 DAT Datenleitung vom Hauptprozessor
GND Masse SRC Taktleitung vom Hauptprozessor STR Steuerleitung vom Hauptprozessor
SV1 Spannungsversorgung, Zweig 1 SV2 Spannungsversorgung, Zweig 2 VCC Versorgungsspannung

Schaltungsbeschreibung

IC11 (74HC4094D) wird über Pin 16 direkt aus der Batterie mit Spannung versorgt. Aus den technischen Daten dieses IC geht hervor, daß dessen Versorgungsspannung maximal 7 Volt betragen darf. Vom Einsatz von Primärzellen in der Batterie ist daher abzuraten, da die Versorgungsspannung sonst (6x1,5V=) 9 Volt beträgt. C20 ist gegen Masse geschaltet und filtert so Störspitzen aus der Versorgungsspannung heraus. Über Pin 8 ist IC13 mit Masse verbunden.


Die Leitungen STR auf Pin 1, DAT auf Pin 2 und SRC auf Pin 3 kommen vom Hauptprozessor und steuern das Schieberegister.


Wechselt der Signalzustand auf der Leitung SRC (Pin 3 / "Clock") von LOW nach HIGH, so wird der zu diesem Zeitpunkt auf der Leitung DAT (Pin 2 / "Serial in") herrschende Signalpegel - LOW (logisch "0") oder HIGH (logisch "1") - im ersten Bit des insgesamt 8 Bit breiten Schieberegisters von IC11 gespeichert. Der zuvor dort gespeicherte Wert wird in das nächsthöhere Bit des Registers übertragen. Gleiches geschieht auch mit den anderen Bits im Schieberegister und das letzte Bit - mit der Nummer acht - fällt dabei heraus. Sein Inhalt liegt dann an Pin 9 / "Serial out". Mit einem Impuls an der Leitung STR (Pin 1 / "Strobe") wird der Inhalt des Schieberegisters in das Speicherregister von IC11 übertragen. Da an Pin 15 / "Output enable" durch direkten Anschluß an die Versorgungsspannung immer ein HIGH-Pegel anliegt, ist der Inhalt des Speicherregisters nach dem Übertragen ständig an den Parallel-Ausgängen sichtbar. Diese Ausgänge sind gemäß Datenblatt mit 25 mA belastbar.


Über den Parallel-Ausgang 0, Pin 4, wird die Versorgungsspannung für

  • Subsystem,
  • IR-/ACS-Empfänger und
  • Odometrie-Sensorik

ein-, bzw. ausgeschaltet.


Über den Parallel-Ausgang 1, Pin 5 und den Parallel-Ausgang 2, Pin 6, wird in drei Stufen die Reichweite des ACS-Senders gesteuert.


Über den Parallel-Ausgang 3, Pin 7, werden

  • Motorstromsensor,
  • Referenzspannungserzeugung,
  • Sensorfeld,
  • Mikrofon und
  • Lichtsensor

mit Spannung versorgt, dieser Ausgang kann somit als Ein-/Ausschalter für diese Komponenten betrachtet werden.


Parallel-Ausgang 4, Pin 14, bringt über den Vorwiderstand R40 die LED D13 zum Leuchten;
Parallel-Ausgang 5, Pin 13 über den Vorwiderstand R45 die LED D14;
Parallel-Ausgang 6, Pin 12 über den Vorwiderstand R48 die LED D15 und
Parallel-Ausgang 7, Pin 11 über den Vorwiderstand R51 die LED D16.

Mehr Ausgänge für den CCRP5

Nach folgendem Schema lassen sich weitere Schieberegister an den CCRP5 anschließen. Ohne Änderung der mitgelieferten Software lassen sich diese allerdings nicht betreiben.


Porterweiterung

Subsystem

Schaltungsauszug

Das Zusammenwirken von Subsystem und Hauptprozessor im CCRP5 ist ein Beispiel dafür, wie Aufgaben auf mehrere miteinander vernetzte Controller verteilt werden können.


Subsystem


Nachfolgend eine alphabetische Auflistung der im Schaltungsauszug verwendeten Leitungskürzel und deren Zuordnungen:

AE1 ACS-Sender, Steuerleitung 1 AE2 ACS-Sender, Steuerleitung 2 DAT Datenleitung vom Hauptprozessor
GND Masse IRQ Interrupt request RST Reset
SUC Taktleitung vom Hauptprozessor SV1 Spannungsversorgung, Zweig 1 VCC Versorgungsspannung

Schaltungsbeschreibung

Subsystem, IR-/ACS-Empfänger und Odometrie-Sensorik werden über T3 (BC857C) aus der Batterie mit Spannung versorgt, welcher in Emitterschaltung als elektronischer Schalter arbeitet. Liegt die Leitung SV1 über Pin 4 von IC11 (siehe Schieberegister) auf HIGH, so fällt an der Basis-Emitter-Diode die Sättigungsspannung UBEsat ab und mangels Potentialunterschiedes - da VCC-UBEsat =UPin4(HIGH) - kann kein Basisstrom und somit auch kein Kollektorstrom fließen. In diesem Fall würde ohne D17 (LL4148) - nun in Sperrichtung betrieben - die Reset-Leitung des Hauptprozessors als unfreiwillige Spannungsversorgung für die hier angeschlossenen Komponenten dienen.

Liegt SV1 (Pin4/IC11) dagegen auf LOW, so fließt ein Basisstrom, der durch R15 begrenzt wird. Dieser Basisstrom läßt einen dem Verstärkungsfaktor entsprechenden Kollektorstrom fließen, der bei T3 allein durch die begrenzte Stromaufnahme der angeschlossenen Bauteile limitiert ist. T3 kann im Dauerbetrieb mit 100mA belastet werden, kurzzeitig mit bis zu 200mA.

IC2 (MC68HC705KJ1) liegt über Pin 6 (VDD) am Kollektor von T3 und wird so mit Spannung versorgt. Aus den technischen Daten dieses IC geht hervor, daß dessen Versorgungsspannung maximal 7 Volt betragen darf. Vom Einsatz von Primärzellen in der Batterie ist daher abzuraten, da die Versorgungsspannung sonst (6x1,5V-UBEsat=) 8,3 Volt beträgt. C4 ist gegen Masse geschaltet und filtert so Störspitzen aus der Versorgungsspannung heraus. Über Pin 7 (VSS) ist IC2 mit Masse verbunden.

Die Reset-Leitung des Subsystems liegt über den Pull-Up-Widerstand R52 am Kollektor von T3 und wird so auf einem HIGH entsprechenden Pegel gehalten. Sie ist über D17 mit der Reset-Leitung des Hauptprozessors verbunden. Wird dort die Reset-Leitung über S1 oder den Spannungswächter IC5 auf Masse geschaltet (siehe Hauptprozessor), so begrenzt R52 den in Durchlaßrichtung von D17 fließenden Strom und verhindert einen Kurzschluß über T3. Zusammen mit R10 und R21 (siehe Hauptprozessor) verringert sich der Pull-Up-Gesamtwiderstand auf 3333 Ohm.

Wie IC7 besitzt auch IC2 einen internen Oszillator für die Taktfrequenz, welche hier 2,5 MHz beträgt. Durch Anschluß frequenzbestimmender Bauteile zwischen Pin 2 (OSC1) und Pin 3 (OSC2) kann diese erhöht werden - im vorliegenden Fall auf 4 MHz. Abschnitt 1.4.2 der technischen Daten des MC68HC705KJ1 liefert auf den Seiten 16 bis 18 die entsprechenden Schaltungen und Bauteilwerte.

Zur Anzeige der Aktivität des Subsystems blinkt während der Abarbeitung des Programmes im Controller die an Pin 10 (PA5) angeschlossene LED D1 mit etwa 18 Hz. Der nachgeschaltete R5 begrenzt den dabei über D1 fließenden Strom (Vorwiderstand).

An Pin 16 (IRQ/VPP) von IC2 liegt der Ausgang des IR-/ACS-Empfängers IC6 (TSOP1836). R16 dient IC6 als Vorwiderstand. C15 ist gegen Masse geschaltet und filtert so Störspitzen aus der Versorgungsspannung von IC6. Da diese integrierte Schaltung sehr empfindlich auf Störspannungen reagiert, wurde eine relativ hohe Kapazität gewählt. R17 ist dem internen Pull-Up-Widerstand von IC6 parallel geschaltet und sorgt so für einen verhältnismäßig konstanten Wert des Pull-Up-Gesamtwiderstandes - unabhängig vom internen Wert, der sich typabhängig unterscheiden kann. Empfängt IC6 mit 36 kHz moduliertes Infrarotlicht, schaltet es seinen Ausgang auf Masse und löst dadurch in IC2 einen Interrupt aus.

Der IR-Sender wird direkt aus der Batterie mit Spannung versorgt und über Pin 9 (PA6) und Pin 8 (PA7) gesteuert. Über letzteren wird der Sender eingeschaltet. Liegt hier ein HIGH-Pegel an, so fließt ein mit R1 und R2 eingestellter Basisstrom über T2 (PMBTA2), der in Emitterschaltung als elektronischer Schalter arbeitet. Dieser Basisstrom bedingt einen dem Verstärkungsfaktor entsprechenden Kollektorstrom, der seinerseits durch R12 begrenzt wird. Die beiden LED D6 und D10 (beide CQY99) leuchten nun im nicht sichtbaren IR-Bereich. C6 ist gegen Masse geschaltet und dient als Pufferkondensator.

Moduliert wird das IR-Lichtsignal dann über "PA6" (Pin 9). Liegt hier ein HIGH-Pegel an, fließt ein von R4 begrenzter Basisstrom über T1 (BC847C) - die Basis von T2 wird so auf Masse geschaltet, der Kollektorstrom versiegt und die LED D6 und D10 verlöschen. R1 begrenzt in diesem Fall den Kollektorstrom von T1.

Über die gemeinsame Datenleitung an Pin 15 (PA0) ist IC2 mit Hauptprozessor und Schieberegister verbunden. Letzteres empfängt aber wegen der getrennten Taktleitungen nur vom Hauptprozessor Daten. Die Taktleitung zwischen IC2 und Hauptprozessor liegt an Pin 14 (PA1). Über den Ausgang "PA2" an Pin 13 kann IC2 über Pin 19 an IC7 (siehe Hauptprozessor) direkt einen Interrupt auslösen.

Die von der Odometrie-Sensorik (siehe Elektromechanik) kommenden Impulse werden von einem überlaufenden 16-bit-Zähler im Controller registriert. Damit wären Wegstrecken bis etwa 1235 Meter in 38 mm-Schritten meßbar. Zu diesem Zweck liegen die Ausgänge der beiden Lichtschranken OK1 und OK2 (beide CNY36) an Pin 4 (PB3) (rechte Lichtschranke) und Pin 5 (PB2) (linke Lichtschranke).

Die Spannungsversorgung der Lichtschranken erfolgt über den Kollektor von T3. R14, bzw. R31 sind den internen LED zur Strombegrenzung vorgeschaltet (Vorwiderstand). Während der "Dunkelphase" fällt kein Licht von der internen LED auf den Fototransistor in der Lichtschranke. Somit kann auch kein Kollektorstrom fließen und R13, bzw. R30 dient dem Eingang PB3 (Pin 4), bzw. PB2 (Pin5) als Pull-Up-Widerstand - der betreffende Eingang liegt auf HIGH. Fällt nun durch die Bohrung im Zahnrad Licht von der LED auf den Fototransistor, so fließt ein Kollektorstrom und der betreffende Eingang (PB2/Pin5, bzw. PB3/Pin4) wird auf Masse geschaltet. R13, bzw. R30 begrenzen in diesem Fall den Kollektorstrom des Fototransistors.

Über Pin 12 (PA3) und Pin 11 (PA4) werden die linke (D4/SP=CQY99), bzw. rechte (D3/SP=CQY99) IR-LED des ACS-Senders mit Spannung versorgt. Liegt die Leitung AE1 über Pin 5 von IC11 (siehe Schieberegister) auf LOW, so fließt ein Strom durch die Leuchtdiode(n) auf der Sensorplatine, welcher von R42 begrenzt wird. Dies entspricht der niedrigsten Sendeleistung.

Liegt AE2 über Pin 6 von IC11 auf LOW, begrenzt R46 den Strom. Dies entspricht der mittleren Stufe.

Liegen beide Leitungen - AE1 und AE2 - auf LOW, bilden R42 und R46 gemeinsam einen Reihen-Gesamtwiderstand von etwa 965 Ohm. Dies entspricht der höchsten Sendeleistung.

Referenzspannungserzeugung

Schaltungsauszug

Die integrierte Schaltung LM385M-2,5 regelt die Referenzspannung für den A/D-Wandler im Hauptprozessor auf +/- 0,02 Volt genau.


Referenzspannungserzeugung im CCRP5


Nachfolgend eine alphabetische Auflistung der im Schaltungsauszug verwendeten Leitungskürzel und deren Zuordnungen:

GND Masse
REF Referenzspannung
SV2 Spannungsversorgung, Zweig 2

Schaltungsbeschreibung

Die Referenzspannung wird über die Leitung SV2 vom Parallel-Ausgang 3 (Pin 7) an IC11 (s. Schieberegister) abgeleitet. R38 dient dabei der Strombegrenzung. IC12 (LM385M-2,5) regelt die an Pin 8 anliegende Spannung auf 2,5 Volt. C19 ist gegen Masse geschaltet und filtert so Störspitzen aus der Referenzspannung heraus.

Sensorfeld

Schaltungsauszug

Das Sensorfeld liefert bei Berührung eine dem Hautwiderstand entsprechende Spannung, die über den A/D-Wandler des Hauptprozessors ausgewertet werden kann.


Sensorfeld


Nachfolgend eine alphabetische Auflistung der im Schaltungsauszug verwendeten Leitungskürzel und deren Zuordnungen:

GND Masse
SEF Sensorfeldspannung
SV2 Spannungsversorgung, Zweig 2

Schaltungsbeschreibung

Bei Berührung des Sensorfeldes wird der Spalt zwischen den Leitern überbrückt. Je nach Hautwiderstand fließt dabei ein größerer (feuchte Haut) oder kleinerer (trockene Haut) Strom über Hautoberfläche. Entsprechend diesem Strom fällt eine unterschiedliche Spannung an R32 ab, da U = R x I. Diese Spannung kann über die Leitung SEF an den A/D-Wandler des Hauptprozessors weitergeleitet werden. R39 begrenzt zusammen mit dem Hautwiderstand und R32 die Stromaufnahme der Schaltung.

Mikrofon

Schaltungsauszug

Schallwellen sind - auf einen Standort bezogen - kurzfristige Veränderungen im Umgebungsluftdruck pamb. Die in der Kapsel eines Kondensatormikrofons unter konstantem Druck p eingeschlossene Luftmenge reagiert auf diese Schwankungen mit einer Volumenänderung.


[math]p_{1} \cdot V_{1} = p_{2} \cdot V_{2} = konst[/math]

(Gesetz von Boyle-Mariotte)


Durch die Volumenänderung verschiebt sich die Membran und dadurch bedingt verändert sich der Plattenabstand, was wiederum eine Änderung der Kapazität zur Folge hat.


[math]C = \frac{\epsilon_{r} \cdot \epsilon_{0} \cdot A}{d}[/math]

C=Kapazität; [math]\epsilon_{r}[/math]=Dielektrizitätszahl; [math]\epsilon_{0}[/math]=Feldkonstante; A=Plattenfläche; d=Plattenabstand


Mikrofon


Nachfolgend eine alphabetische Auflistung der im Schaltungsauszug verwendeten Leitungskürzel und deren Zuordnungen:

GND Masse
MIC Mikrofonspannung
SV2 Spannungsversorgung, Zweig 2

Schaltungsbeschreibung

Trifft eine Schallwelle auf die Membran der Kapsel des Elektret-Kondensatormikrofons, so verringert sich die Kapazität des Kondensatormikrofons (s.o.). Dementsprechend wird ein Teil der zuvor (mit höherer Kapazität) gespeicherten Ladung (an Masse) abgegeben.

Wölbt sich die Membran nach dem Durchzug der Schallwelle zurück, so steigt auch die Kapazität des Kondensatormikrofons wieder auf ihren ursprünglichen Wert und über R43 fließt ein Ladestrom, der eine Spannung an ihm abfallen läßt.

Auf diese Weise werden die Luftdruckschwankungen in Spannungsschwankungen umgesetzt, die über die Koppelkondensator C21 - von Gleichspannungsanteilen befreit - an den Verstärker IC14 (TLC27M2CD) geführt werden. R41, R44 und R47 bestimmen hier den Verstärkungsfaktor.

Über die Leitung MIC kann das verstärkte Signal dem A/D-Wandler des Hauptprozessors zugeführt werden.

Lichtsensor

Die beiden Lichtsensoren (links/rechts) liegen auf der frontseitigen Sensorplatine und und sind jeweils um 45° nach außen geschwenkt angebracht, um eine Lichtquelle orten zu können. Um die Überdeckung der beiden Sensoren zu verringern, wurde in der Mitte der Sensorplatine eine Buchsenleiste eingelötet, welche die Fotodioden nach innen hin gegenseitig abzuschattet (s. Abb.).


CCRP5-Sensorplatine.jpg


Schaltungsauszug

Da beide Lichtsensoren identisch sind, wird im folgenden nur der rechte behandelt. Die Seitenbezeichnungen sind identisch mit denen der Conrad Electronic GmbH, beziehen sich aber nicht auf die Fahrtrichtung.


Lichtsensor

Schaltungsbeschreibung

Die auf den ersten Blick schlicht erscheinende Schaltung birgt mit dem Netzwerk aus D8/R8-D10/R10 eine Besonderheit, mit der man sich doch einige Zeit beschäftigen kann. So erscheint es im Grunde unsinnig, Dioden in Durchlaßrichtung gegen Masse zu schalten. Vielmehr macht man sich hier einen Begleiteffekt zunutze, der erst einmal nichts mit der primären Funktion einer Diode - Kontrolle über die Richtung eines Stromflusses - zu tun hat:


Fließt ein Strom über eine Diode, so fällt an ihr - in Abhängigkeit von diesem Strom - die sogenannte "Flußspannung" ab.


Diode LL4148 - Flußstrom über der Flußspannung


Wie man dem obigen Diagramm entnehmen kann, verläuft dieser Vorgang im Bereich kleiner Spannungen/Ströme nicht linear. Deshalb habe ich das komplette Netzwerk gemäß folgender Schaltung auf einem Steckbrett aufgebaut.


Lichtsensor: Versuchsaufbau 1


Unter stufenweiser Erhöhung der Versorgungsspannung des Versuchaufbaus habe ich an den Punkten "A", "B" und "C" die dort herrschende Spannung gegen Masse gemessen. In der folgenden Tabelle sind diese Werte mit UA, UB und UC bezeichnet.


VCC [V] 1,05 2,06 3,04 4,15 5,02 6,04 7,23
UA [V] 0,57 1,45 2,38 3,45 4,32 5,33 6,50
UB [V] 0,10 0,84 1,72 2,77 3,62 4,61 5,78
UC [V] 0,00 0,27 1,09 2,10 2,93 3,91 5,06


Aus diesen Spannungen und den bekannten Widerständen lassen sich die einzelnen Ströme IR7 ... IR10 berechnen. Addiert man diese zu IGes und bringt diese Summe in Zusammenhang mit der jeweils angelegten Versorgungsspannung VCC, so erhält man den Gesamtwiderstand des Netzwerkes RGes.


IR7 [µA] 10,50 20,60 30,40 41,50 50,20 60,40 72,30
IR8 [µA] 5,70 14,50 23,80 34,50 43,20 53,30 65,00
IR9 [µA] 21,28 178,72 365,96 589,36 770,21 980,85 1229,79
IR10 [µA] 0,00 270,00 1090,00 2100,00 2930,00 3910,00 5060,00
IGes [µA] 37,48 483,82 1510,16 2765,36 3793,61 5004,55 6427,09
RGes [] 28017,49 4257,75 2013,04 1500,71 1323,28 1206,90 1124,93


Hier wird der steil abfallende Wert - gerade im Bereich niedriger Spannung - deutlich. Das Netzwerk bildet also einen spannungsabhängigen Widerstand, der umso geringer ist, je höher die anliegende Spannung wird.


Lichtsensor: Versuchsaufbau 1 - Gesamtwiderstand über der Versorgungsspannung


Was bringt das nun für die Schaltung des CCRP5? Die Fotodiode wird in Sperrichtung betrieben und begrenzt den fließenden Strom in Abhängigkeit von der Intensität und Wellenlänge ihrer Beleuchtung. Auch dazu ein Versuchsaufbau:


Lichtsensor: Versuchaufbau 2


In völliger Dunkelheit fließt nur der sogenannte "Dunkelstrom" in der Größenordnung von einigen Milliardstel (nA) Ampere. Mit zunehmender Beleuchtung steigt der Strom - nun "Lichtstrom" genannt - an. Begrenzt wird er in etwa durch den Gesamtwiderstand der Widerstände - die (spannungserzeugende) Diode nimmt hier noch etwas Einfluß. Auch hierzu einige Meßwerte in der folgenden Tabelle:


Beleuchtungsquelle VCC [V] I [µA] UR2 [V] UD2 [V] UR7 [V]
Tageslicht 7,23 7 0,065 6,44 0,66
Deckenfluter 7,23 20,7 0,173 5,22 1,54
Schreibtischlampe 7,23 70,3 0,703 (-0,471) 6,99


Nun ist UR7 jene Spannung, welche an den A/D-Wandler des Hauptprozessors zur Auswertung weitergeleitet wird. Dieser arbeitet im CCRP5 mit einer Referenzspannung von 2,5 Volt, sodaß Spannungen die über diesem Wert liegen, nicht mehr ausgewertet werden können. Hier greift nun das Netzwerk aus D8/R8-D10/R10:

Je intensiver die Beleuchtung auf D2 wird, umso größer wird der durch die Diode fließende Strom. In gleichem Maße steigt auch die Spannung an R7, da U = I x R. Ab ca. 0,6 Volt (lt. Diagramm LL4148 - Flußstrom über der Flußspannung, s.o.) beginnt allmählich ein immer größer werdender Strom über D8 zu fließen und somit auch über R8. Der Gesamtwiderstand der Schaltung wird geringer und der weitere Anstieg von UR7 flacher (U = I x R).

Gleiches geschieht bei weiter steigendem Stromfluß durch D2 auch nacheinander mit D9/R9 und D10/R10. R2 sorgt in Reihenschaltung zum Netzwerk dafür, daß der Gesamtwiderstand einen bestimmten Wert nicht unterschreitet und begrenzt so den maximal über D2 fließenden Strom.

Im Versuchsaufbau wurde der Wert von 2,25 Volt für UR7 nicht überschritten.

Batterie-Sensor

Schaltungsauszug

Batteriespannungssensor


Nachfolgend eine alphabetische Auflistung der im Schaltungsauszug verwendeten Leitungskürzel und deren Zuordnungen:


BAT Batteriesensor
GND Masse
VBA Batteriespannung

Schaltungsbeschreibung

Die beiden Widerstände R6 und R7 bilden einen Spannungsteiler mit einem Gesamtwiderstand von 4kOhm. Dabei fließt ein Strom von IGes = UVBA / RGes = 7,2 V / 4000 Ohm = 1,8 mA. Dementsprechend fallen an R6 (UR6 = R6 x IGes = 3000 Ohm x 1,8 mA =) 5,4 V ab. Die auf der Leitung BAT anliegende und dem A/D-Wandler des Hauptprozessors zugeführte Spannung beträgt demnach (UVBA = UVCC - UR6 = 7,2 V - 5,4 V =) 1,8 V. Diese Spannung entspricht einem Wandlerwert von (255 x UBAT / UREF = 255 x 1,8 V / 2,5 V =) 183,6 - also 183.

C5 und C12 sind gegen Masse geschaltet und filtern so Störspitzen aus.

Da NiMH-Zellen durch Tiefentladung beschädigt werden, empfiehlt sich eine Überwachung der Batteriespannung. Sie sollte einen Wert von 0,9 Volt pro Zelle, hier also 5,4 Volt nicht unterschreiten. Diese Spannung entspricht einem Wandlerwert von 0.

Ladestrom-Sensor

Schaltungsauszug

Die Schaltung des Ladestromsensors (grau hinterlegt) ist identisch mit der Schaltung des Batteriesensors.


Ladestromsensor


Nachfolgend eine alphabetische Auflistung der im Schaltungsauszug verwendeten Leitungskürzel und deren Zuordnungen:

GND Masse
LAD Ladestrom
VBA Batteriespannung
VCC Versorgungsspannung

Schaltungsbeschreibung

Der Ladestromsensor ermöglicht zusammen mit dem Batteriesensor die an R3 abfallende Spannung zu messen und so über die Beziehung I=U (da I=U/R und R=1 [Ohm]) den Ladestrom zu ermitteln.

Damit ein Ladestrom fließen kann, muß (bei geschlossenem Schalter SW1) die an J1 anliegende Spannung höher sein als die Batteriespannung. Hinzu kommen noch die Spannungen, die stromabhängig an D2 und R3 abfallen und ausgeglichen werden müssen.

Der Ladevorgang ist deshalb nicht möglich, ohne die direkt an der Batterie angeschlossenen Bauteile zu gefährden (u.a. den Hauptprozessor - s. o.a. Hinweise), welche bereits bei der Batteriespannung - die zum Laden ja überschritten werden muß - an der oberen Grenze ihres Toleranzbereiches arbeiten.

Es empfiehlt sich deshalb, die Zellen zum Laden mit einem externen Gerät auszubauen.

Antriebsmotoren

Schaltungsauszug

Da beide Antriebe identisch sind, wird im folgenden nur der rechte behandelt. Die Seitenbezeichnungen beziehen sich hier auf die Fahrtrichtung.


Antrieb


Nachfolgend eine alphabetische Auflistung der im Schaltungsauszug verwendeten Leitungskürzel und deren Zuordnungen:

GND Masse
MOR Motordrehzahlsteuerung, rechts-
MTS Motorstromsensor
REV Motordrehrichtungssteuerung, rechts-
VBA Batteriespannung

Schaltungsbeschreibung

Die Motorbrückenschaltung wird direkt aus der Batterie mit Spannung versorgt. An der Leitung MOR liegt das Rechtecksignal des D/A-Wandlers 2 im Hauptprozessor, welches an die NAND-Gatter IC1-4 und IC1-1 geführt wird. Mit dem HIGH-LOW-Verhältnis dieses Rechtecksignals wird die Drehgeschwindigkeit des Motors gesteuert (Pulsweitenmodulation: PWM). Das Signal auf der Leitung REV steuert die Drehrichtung des Motors und wird an die NAND-Gatter IC1-4 und IC1-3 geführt. Der über die Motorbrücke fließende Strom läßt an R20 eine Spannung abfallen, welche über die Leitung MTS dem Motorstromsensor zugeführt wird.

Zur Vorwärtsfahrt wird die Leitung REV auf HIGH gesetzt. Der vorzugebende Wandlerwert des PWM-Rechtecksignals auf der Leitung MOR beträgt 255 für Stillstand und 0 für die volle Drehzahl des Motors. Im Stillstand (DA2=255) liegt ein nahezu ständiger LOW-Pegel auf der Leitung MOR. Beide Signale - MOR und REV - werden gemäß folgender Wahrheitstabelle im NAND-Gatter 4 von IC1 verknüpft.

MOR REV Erg.
0 0 1
0 1 1
1 0 1
1 1 0

Das Ergebnis der Verknüpfung (Zeile 3) beträgt logisch "1" - IC1-4 gibt an seinem Ausgang einen HIGH-Pegel aus. Dadurch ergibt sich eine (gemessene) Spannungsdifferenz von UGS = 6,5V - 7,5V = -1V an IC4-2. Der hier liegende p-Kanal-Power-MOSFET läßt bei dieser Spannungsdifferenz (gerade noch) keinen Strom über seine Source-Drain-Strecke fließen.

Bei voller Drehzahlansteuerung (DA2=0) liegt ein nahezu ständiger HIGH-Pegel auf der Leitung MOR. Das Ergebnis dieser Verknüpfung (Zeile 5) in IC1-4 beträgt entsprechend logisch "0" und am Ausgang wird ein LOW-Pegel ausgegeben. Die Spannungsdifferenz UGS an IC4-2 beträgt in diesem Fall (gemessene) 0V - 7,5V = -7,5V und der p-Kanal-Power-MOSFET läßt nun Strom über seine Source-Drain-Strecke fließen.

Mit dem Setzen der Leitung REV für Vorwärtsfahrt liegen am Gate von IC3-1 (gemessene) 6,5V an, was auch der Spannungsdifferenz UGS entspricht, da der Source-Anschluß des n-Kanal-Power-MOSFET an Masse liegt. Bei dieser Spannungsdifferenz läßt der Transistor Strom über seine Drain-Source-Strecke fließen. Der Motor liegt so über IC4-2 an der Batteriespannung und über IC3-1 an Masse und arbeitet auf Grund des vorhandenen Potentialunterschiedes.

Die beiden anderen Power-MOSFET lassen auf Grund ihrer Gate-Source-Spannungen keinen Stromfluß zu. Bei Rückwärtsfahrt (Leitung REV=LOW) kehren sich die Verhältnisse an den Power-MOSFET um und der Motor wird in umgekehrter Richtung von Strom durchflossen.

Motorstrom-Sensor

Schaltungsauszug

Die an R20 (siehe Antriebe) stromabhängig abfallende Spannung wird über die Leitung IAN dem Operationsverstärker zugeführt.


Motorstromsensor


Nachfolgend eine alphabetische Auflistung der im Schaltungsauszug verwendeten Leitungskürzel und deren Zuordnungen:

GND Masse
IAN Spannungsabfall R20, Antrieb
SV2 Spannungsversorgung, Zweig 2
MTS Motorstromsensor

Schaltungsbeschreibung

Mit R53 und R49/R50 wird der Verstärkungsfaktor des Operationsverstärkers IC14 (TLC27M2CD) festgelegt. C25 ist gegen Masse geschaltet und filtert so Störspitzen aus dem Eingangssignal. C23 puffert kurzfrsitige Schwankungen im Ausgangssignal, welches über die Leitung MTS dem A/D-Wandler im Hauptprozessor zugeführt wird.

Software

Beschreibung

Im Lieferumfang des CCRP5 befinden sich die zu installierende Entwicklungsumgebung CCEW32D, ein treiberähnliches Maschinensprache-Programm mit der Bezeichnung P5DRIV.S19 sowie 25 Beispielprogramme, die in 10 Kapiteln mit der Programmierung des CCRP5 vertraut machen sollen. Diese setzt allerdings generell Kenntnisse in der Programmierung der C-Control voraus, weswegen die Beispielprogramme aus deren Lieferumfang mit aufgenommen wurden.

Leider wurde der Umfang der Dokumentation zur C-Control seinerzeit in gleichem Maße spärlich gehalten, wie das heute auch beim CCRP5 der Fall ist - hier folgt Conrad Electronic bedauerlicherweise einer Tradition. Im (kostenpflichtigen) EAM-Magazin, welches vom VTP-Verlag Fürst herausgegeben wird, erschienen jedoch in loser Folge Artikel, in denen die C-Control und ihre Zusatzkomponenten hinreichend besprochen wurden. Diese Artikel können mittlerweile im PDF-Format von der Conrad-Website (siehe Weblinks) heruntergeladen werden. Die entsprechenden Hefte sind allerdings auch noch beim Verlag (siehe Weblinks) lieferbar.

Deren Inhalt kann natürlich nicht ohne weiteres auf den CCRP5 übertragen werden, doch sollte man sie zumindest in der Theorie einmal durchgearbeitet haben, bevor man sich als C-Control-Einsteiger mit dem CCRP5 beschäftigt. Die Simulationsfunktion der Entwicklungsumgebung kann hier gute Dienste leisten.

Erfolgt die Inbetriebnahme nach den Anweisungen der Bedienungsanleitung, trägt das erste Programm, mit dem man in Kontakt kommt, den Titel "Einfaches Beispiel zur Benutzung der LEDs". Dieses ist wie folgt gegliedert:


  • Programmkopf
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
'IIIIIIIIII       MOBILE ROBOT EVALUATION PROGRAM          IIIIIIIIIIII
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
'  EINFACHES BEISPIEL ZUR BENUTZUNG DER LEDs
'Die Ein/Ausgabemöglichkeiten des Roboters sind sehr beschränkt, sind
'aber jedoch für einen normalen Betrieb ausreichend. Benutzen Sie die LEDs
'um z.B. Betriebszustände des Roboters anzuzeigen.
' ---------------------------------------------------------------------
'                       FUNKTION DES PROGRAMMS
'----------------------------------------------------------------------
' Das Programm erzeugt ein Lauflicht mit den LEDs und zeigt wie sie
' angesteuert werden
' Für den Betrieb des Roboters ist ein spezieller Treiber erforderlich,
' der nur einmal geladen werden muss. er wird nur mit diesem Beispiel
' geladen. Bei allen anderen Beispielen ist die entsprechende Zeile
' am Ende des Programms auskommentiert.
'-----------------------------------------------------------------------
' ACHTUNG:
' Der erste Schritt in der Initialisierung ihres Programms sollte immer die Zeile
'                        REV_L=on:REV_R=on:SYS PLM_SLOW
' enthalten. Diese Zeile initialisiert die Ports für die Richtungsumschaltung
' des Antriebs und die PLM Frequenz. Initialisieren Sie die Ports auch, wenn der
' Antrieb nicht benutzt werden soll (wie z.B. hier in diesem Beispiel).
' DER BETRIEB DER MOTOREN OHNE DIESE INITIALISIERUNG FÜHRT UNWEIGERLICH ZUR
' ZERSTÖRUNG DER ANTRIEBSELEKTRONIK !!
'------------------------------------------------------------------------
'RESOURCEN:
'Sie finden in allen Beispielen sämtliche Systemroutinen die zum Betrieb des
'Roboters notwendig sind.
'Viele davon greifen auf Hardwareresourcen zu, die Sie von C-Control her nicht
'kennen, deren genaue Funktionsweise aber im File "Project5_intern" erklärt ist.
'
' Für dieses Beispiel sind folgende SYSTEMROUTINEN relevant:
' POWER:
' gosub SUBSYS_PWR_ON  ;Schaltet die Subsysteme EIN/AUS
' gosub SUBSYS_PWR_OFF
' AUSGABE:
' gosub LED1ON   ;zum Ein/Ausschalten der LED1 analog auch LED 2bis 4
' gosub LED1OFF  ;
' gosub LEDSOFF  ;schaltet alle LEDS aus
'----------------------------------------------------------------------------


  • Definitionsteil

Hier werden den kryptischen Portnummern, Speicher- und Einsprungadressen mit der Anweisung <DEFINE> semantische Bezeichnungen zugeordnet. Diese können entsprechend den eigenen Vorlieben geändert werden, müssen dann allerdings im weiteren Programm auch genau so verwendet werden. Tauscht man jedoch mit anderen Usern Programmdaten aus, empfiehlt es sich, die ursprünglichen, von Conrad Electronic gewählten Bezeichnungen beizubehalten.

'--------------------------
'------ I/O PORTS ---------
'--------------------------
'- INTERFACE LCD/EXTPORT --
define sdio         port[1]
define sclio        port[3]
define strobe       port[4]
'-- INTERFACE COM/NAV -----
define DATALINE     port[1]
define CLOCKLINE    port[2]
'--------------------------
'------ SENSORS ---------
'--------------------------
define LIGHT_L      ad[7]
define LIGHT_R      ad[6]
define SYS_VOLTS    ad[3]
define CHRG_CURRENT ad[2]
define SYS_CURRENT  ad[1]
define MIC          ad[4]
define TOUCH        ad[5]
'---------------------------
'------  DRIVE -------------
'---------------------------
define SPEED_L        da[1]
define SPEED_R        da[2]
define REV_L        port[6]
define REV_R        port[5]
'--------------------------
'---- SYSTEM MEMORY -------
'--------------------------
'--- INTERFACE BUFFER ----
define LBYTE         byte[1]
define HBYTE         byte[2]
define SUBCMD        byte[3]
'---- OPERATION DATA ------
define EXTPORT       byte[4]
define LED1_F        bit[29]
define LED2_F        bit[30]
define LED3_F        bit[31]
define LED4_F        bit[32]
define SYSTEM_STATUS byte[5]
'--------------------------
'----  USER MEMORY  -------
'--------------------------
define TIM           byte[6]
define PGM           byte[7]
'--- SYSTEMROUTINEN -----------
define PLM_SLOW      &H01C4
define SYSTEM        &H01C9
define COMNAV        &H0154
'- ERWEITERTE SYSTEM ROUTINEN -
define REVR          &H0101   'ANTRIEB RECHTS RÜCKWÄRTS
define REVL          &H0106   'ANTRIEB LINKS RÜCKWÄRTS
define FWDR          &H010B   'ANTRIEG RECHTS VORWÄRTS
define FWDL          &H0110   'ANTRIEB LINKS VORWÄRTS
define ROTR          &H0115   'RECHTS DREHEN
define ROTL          &H0119   'LINKS DREHEN
define REV           &H011D   'RÜCKWÄRTS
define FWD           &H0121   'VORWÄRTS
define COMNAV_STATUS &H0125   'UPDATED ALLE FLAGS IM STATUS-REGISTER
define ACS_LO        &H01E1   'ACS POWER LO
define ACS_HI        &H01E9   '
define ACS_MAX       &H01F1   '
define SEND_TLM      &H014A   'SENDET TELEMETRIE (CH=HBYTE,DATEN=LBYTE)
define SEND_SPEEDR   &H0134   'SENDET TLM KANAL 8,PLM RECHTS
define SEND_SPEEDL   &H013A   'SENDET TLM KANAL 7,PLM LINKS
define SEND_SYSSTAT  &H0144   'SENDET TLM KANAL 0,SYSTEM STATUS
                              '(FLAGS für ACS,FWD/REV, ACS_LO/HI/MAX)


  • Programmteil

Einem Initialisierungsteil folgt hier die für µC typische Endlosschleife, in welcher das eigentliche Programm in ständiger Wiederholung abgearbeitet wird.

'---------- INIT---------------
gosub SUBSYS_PWR_ON:REV_L=off:REV_R=off
beep 368,10,0:pause 50
'--------------------------------------------
'---       DEMO LED LAUFLICHT             ---
'--------------------------------------------
#LOOP
gosub LED1ON:pause 5:gosub LED1OFF
gosub LED2ON:pause 5:gosub LED2OFF
gosub LED3ON:pause 5:gosub LED3OFF
gosub LED4ON:pause 5:gosub LED4OFF
gosub LED3ON:pause 5:gosub LED3OFF
gosub LED2ON:pause 5:gosub LED2OFF
goto LOOP
'-------------------------------------------


  • Funktionsteil

Hier werden zwischen den Einsprungmarken im Format <#XXXXX> und der schließenden <RETURN>-Anweisung Funktionen definiert, auf welche vom Hauptprogramm in der Endlosschleife aus mittels der <GOSUB>-Anweisung zugegriffen werden kann.

'IIIIIIIIIII LED DRIVER IIIIIIIIIIIIIIIII
#LED1ON
LED1_F=on:goto EXTPORT_WRITE
#LED1OFF
LED1_F=off :goto EXTPORT_WRITE
#LED2ON
LED2_F=on:goto EXTPORT_WRITE
#LED2OFF
LED2_F=off:goto EXTPORT_WRITE
#LED3ON
LED3_F=on:goto EXTPORT_WRITE
#LED3OFF
LED3_F=off:goto EXTPORT_WRITE
#LED4ON
LED4_F=on:goto EXTPORT_WRITE
#LED4OFF
LED4_F=off:goto EXTPORT_WRITE
#LEDSOFF
EXTPORT=EXTPORT and &H0F:goto EXTPORT_WRITE
#EXTPORT_WRITE
SYS SYSTEM:pulse STROBE:RETURN
'IIIIII SYSTEMROUTINEN COMM/NAV SYSTEM  IIIII
#GET_IRDATA
SUBCMD=1:sys COMNAV:return
#SEND_IRDATA
SUBCMD=0:sys COMNAV:return
#RC5
SUBCMD=4:sys COMNAV:LBYTE= HBYTE and &HFC
HBYTE=00:SUBCMD=2:sys COMNAV:return
#RC5_INT
SUBCMD=4:sys COMNAV:LBYTE= (HBYTE and &HFE)or 2
HBYTE=00:SUBCMD=2:sys COMNAV:return
#REC80
SUBCMD=4:sys COMNAV:LBYTE= (HBYTE or &H01)and&HFD
HBYTE=00:SUBCMD=2:sys COMNAV:return
#REC80_INT
SUBCMD=4:sys COMNAV:LBYTE= (HBYTE or &H03)
HBYTE=00:SUBCMD=2:sys COMNAV:return
'IIIIII   SYSTEMROUTINEN SYSTEM  IIIIIIIIIIII
#NO_ACS_INT
SUBCMD=4:sys COMNAV:LBYTE= HBYTE and &HFB
HBYTE=00:SUBCMD=2:sys COMNAV:return
#ACS_INT_200
SUBCMD=4:sys COMNAV:LBYTE= HBYTE or &H04
HBYTE=50:SUBCMD=2:sys COMNAV:return
#SUBSYS_PWR_ON
sdio=on:sclio=on:strobe=off:EXTPORT=(EXTPORT and &HFE)or 8
sys SYSTEM:return
#SUBSYS_PWR_OFF
EXTPORT=(EXTPORT and &HF7)or 1:sys SYSTEM
deact sdio:deact sclio:return
#CLR_DISTANCE
SUBCMD=3:sys COMNAV:return
#L_DISTANCE
SUBCMD=6:sys COMNAV:return
#R_DISTANCE
SUBCMD=7:sys COMNAV:return


Anschließend wird noch das Maschinensprache-Programm P5DRIV.S19 geladen

'---------COM/NAV GERÄTEREIBER -------------
syscode "p5driv.s19"

Auf der Website von AREXX findet man das Assemblerlisting dieses Programms:

*********************************************************************************
* 
* File P5DRIV.ASM completly analysed and commented
*
* By  : Henk van Winkoop (henk@arexx.com)
*
* Date: 08-08-2004
*
*********************************************************************************

* comment between [] is original Conrad comment
*
*================================================================================
The real p5driv.s19

S1130101190116A5811B0118A581180117A5811ACA
S11301110119A581ADF920E8ADF020E9ADE720E0B2
S1130121ADED20E6A604B7A3AD29B6A5A4F8BAA1FE
S1130131B7A581A608BE0B2004A607BE0ABFA1B7B6
S1130141A220063FA2B6A5B7A1B6A14939A2493951
S1130151A23FA39BAD54AD38AE0C5A26FDB6A3CD38
S1130161017FB6A2CD017FB6A1CD017F1105130593
S1130171CD0198B7A2CD0198B7A1AD149A815F13AF
S1130181014411012402100112015CA30826F0812B
S1130191130112051005815F0201FD440301FD01F4
S11301A10102AA805CA30826EF81ADE41201AE0A24
S11301B15A26FD1305AE0A0201055A26FA20EB025E
S11301C101FD81A60CB70C81AE0839A411012402EA
S11301D11001150114015A26F139A41601170181E0
S11301E1AD1214A41CA520E0AD0A12A41AA520D8AE
S11001F1AD0220D415A413A41DA51BA581E7
S9030000FC
*================================================================================
p5driv.s19 somewhat expanded

S1 13 0101 19 01 16 A5 81 1B 01 18  A5 81 18 01 17 A5 81 1A    CA
S1 13 0111 01 19 A5 81 AD F9 20 E8  AD F0 20 E9 AD E7 20 E0    B2
S1 13 0121 AD ED 20 E6 A6 04 B7 A3  AD 29 B6 A5 A4 F8 BA A1    FE
S1 13 0131 B7 A5 81 A6 08 BE 0B 20  04 A6 07 BE 0A BF A1 B7    B6
S1 13 0141 A2 20 06 3F A2 B6 A5 B7  A1 B6 A1 49 39 A2 49 39    51
S1 13 0151 A2 3F A3 9B AD 54 AD 38  AE 0C 5A 26 FD B6 A3 CD    38
S1 13 0161 01 7F B6 A2 CD 01 7F B6  A1 CD 01 7F 11 05 13 05    93
S1 13 0171 CD 01 98 B7 A2 CD 01 98  B7 A1 AD 14 9A 81 5F 13    AF
S1 13 0181 01 44 11 01 24 02 10 01  12 01 5C A3 08 26 F0 81    2B
S1 13 0191 13 01 12 05 10 05 81 5F  02 01 FD 44 03 01 FD 01    F4
S1 13 01A1 01 02 AA 80 5C A3 08 26  EF 81 AD E4 12 01 AE 0A    24
S1 13 01B1 5A 26 FD 13 05 AE 0A 02  01 05 5A 26 FA 20 EB 02    5E
S1 13 01C1 01 FD 81 A6 0C B7 0C 81  AE 08 39 A4 11 01 24 02    EA
S1 13 01D1 10 01 15 01 14 01 5A 26  F1 39 A4 16 01 17 01 81    E0
S1 13 01E1 AD 12 14 A4 1C A5 20 E0  AD 0A 12 A4 1A A5 20 D8    AE
S1 10 01F1 AD 02 20 D4 15 A4 13 A4  1D A5 1B A5 81             E7
S9 03 0000                                                     FC
           |<--------------real-data--------------------->|
*================================================================================
p5driv.s19 only addresses and data
|--| addresses
     |<---------------data------------------------->|

0101 19 01 16 A5 81 1B 01 18  A5 81 18 01 17 A5 81 1A
0111 01 19 A5 81 AD F9 20 E8  AD F0 20 E9 AD E7 20 E0
0121 AD ED 20 E6 A6 04 B7 A3  AD 29 B6 A5 A4 F8 BA A1
0131 B7 A5 81 A6 08 BE 0B 20  04 A6 07 BE 0A BF A1 B7
0141 A2 20 06 3F A2 B6 A5 B7  A1 B6 A1 49 39 A2 49 39
0151 A2 3F A3 9B AD 54 AD 38  AE 0C 5A 26 FD B6 A3 CD
0161 01 7F B6 A2 CD 01 7F B6  A1 CD 01 7F 11 05 13 05
0171 CD 01 98 B7 A2 CD 01 98  B7 A1 AD 14 9A 81 5F 13
0181 01 44 11 01 24 02 10 01  12 01 5C A3 08 26 F0 81
0191 13 01 12 05 10 05 81 5F  02 01 FD 44 03 01 FD 01
01A1 01 02 AA 80 5C A3 08 26  EF 81 AD E4 12 01 AE 0A
01B1 5A 26 FD 13 05 AE 0A 02  01 05 5A 26 FA 20 EB 02
01C1 01 FD 81 A6 0C B7 0C 81  AE 08 39 A4 11 01 24 02
01D1 10 01 15 01 14 01 5A 26  F1 39 A4 16 01 17 01 81
01E1 AD 12 14 A4 1C A5 20 E0  AD 0A 12 A4 1A A5 20 D8
01F1 AD 02 20 D4 15 A4 13 A4  1D A5 1B A5 81
*================================================================================


*================================================================================
*=================== CONRAD 'DIE HARD' COMMENT ==================================
*================================================================================
*********************************************
*** CCRP5 C-CONTROL DRIVER (by DIE HARD)  ***
*********************************************
* - IR INTERFACE	      Byte 1-3	*****
* - PLM RATE OVERRIDE		        *****
* - EXTPORT DRIVER            Byte 1    *****
*********************************************
* -     EXTENDED VERSION, LCD DELETED
* - PA0 =  COMMON DATA
* - PA1 =  COMM INTERFACE CLOCK
* - PA2 =  EXTPORT/LCD CLOCK
* - PA3 =  EXTPORT STROBE
* - PA5 =  REVERSE LEFT (0=REVERSE)
* - PA4 =  REVERSE RIGHT (0=REVERSE)
*********************************************

*------------  TIMING -----------------------
* EXTPORT WRITE:       115us
*
* BASIC BYTES 1 AND 2 ARE OCCUPIED
* TRANSMIT ENTRY IS
* PORT B IST BASIC PORT 1-8 
* PROGRAM USES LABEL  "A"
*================================================================================



*--------------------------------------------------------------------------------
*  DEFINE 'EQUATIONS' FOR MICROCONTROLLER REGISTERS
*--------------------------------------------------------------------------------
*----- SYSTEM I/O -------
PADDR   EQU     $0005                   ;Data Direction Register port B (DDRB)  (not port A!)
PADAT   EQU     $0001                   ;data register           PORT B (PORTB) (not port A!)
PLMA    EQU     $000A                   ;Pulse Length Modulation A      (PLMA) (pin 20) (left  engine speed)
PLMB    EQU     $000B                   ;Pulse Length Modulation B      (PLMB) (pin 21) (right engine speed)
MISC    EQU     $000C                   ;MISCellaneous register         (MISC)

*--------------------------------------------------------------------------------
*  DEFINE 'EQUATIONS' FOR USER RAM MEMORY LOCATIONS
*--------------------------------------------------------------------------------
*----- COMM INTERFACE MEMORY -----
BUFFL    EQU    $00A1                   ;BUFFL is other name for LBYTE (used with Basic)
BUFFH    EQU    $00A2                   ;BUFFH is other name for HBYTE (used with Basic)
SUBCMD   EQU    $00A3                   ;SUBCMD  (used with Basic)
*--- EXTPORT INTERFACE MEMORY ----
EXTP     EQU    $00A4                   ;EXTPORT (used with Basic)
*---- SYSTEM STATUS ----------
SYSSTAT  EQU    $00A5                   ;SYSSTAT is other name for SYSTEM_STATUS (used with Basic)


*--------------------------------------------------------------------------------
*   ASSUME THAT FIRST INSTRUCTION IS PLACED AT ADRESS HEX 0x0101
*--------------------------------------------------------------------------------
.org $0101

*================================================================================
*
*address
*       opcode
*               label
*                       assembler
*                                               comment
*================================================================================

*#######################################
*###   define REVR          &H0101   ###
*#######################################
*--------------------------------------------------------------------------------
*  REVERSE RIGHT (SET RIGHT ENGINE DIRECTION TO REVERSE)
*--------------------------------------------------------------------------------
0101    19 01   REVR:   BCLR 4,PADAT            ;clr bit 4 in Port B (PORT5, PB4) = set right engine to reverse
0103    16 A5           BSET 3,SYSSTAT          ;set bit 3 in SYSTEM_STATUS (FWD_R) (undocumented)
0105    81              RTS                     ;return

*#######################################
*###   define REVL          &H0106   ###
*#######################################
*--------------------------------------------------------------------------------
*  REVERSE LEFT (SET LEFT ENGINE DIRECTION TO REVERSE)
*--------------------------------------------------------------------------------
0106    1B 01   REVL:   BCLR 5,PADAT            ;clr bit 5 Port B (PORT6, PB5) = set left engine to reverse
0108    18 A5           BSET 4,SYSSTAT          ;set bit 4 in SYSTEM_STATUS (FWD_L) (undocumented)
010A    81              RTS                     ;return

*#######################################
*###   define FWDR          &H010B   ###
*#######################################
*--------------------------------------------------------------------------------
*  FORWARD RIGHT (SET RIGHT ENGINE DIRECTION TO FORWARD)
*--------------------------------------------------------------------------------
010B    18 01   FWDR:   BSET 4,PADAT            ;set bit 4 Port B (PORT5,PB4) = set right engine to forward
010D    17 A5           BCLR 3,SYSSTAT          ;clr bit 3 in SYSTEM_STATUS (FWD_R) (undocumented)
010F    81              RTS                     ;return

*#######################################
*###   define FWDL          &H0110   ###
*#######################################
*--------------------------------------------------------------------------------
*  FORWARD LEFT (SET LEFT ENGINE DIRECTION TO FORWARD)
*--------------------------------------------------------------------------------
0110    1A 01   FWDL:   BSET 5,PADAT            ;set bit 5 Port B (PORT6,PB5) = set left engine to forward
0112    19 A5           BCLR 4,SYSSTAT          ;clr bit 4 in SYSTEM_STATUS (FWD_L) (undocumented)
0114    81              RTS                     ;return

*#######################################
*###   define ROTR          &H0115   ###
*#######################################
*--------------------------------------------------------------------------------
*  ROTATE RIGHT (SET LEFT ENGINE TO FORWARD AND SET RIGHT ENGINE TO REVERSE)
*--------------------------------------------------------------------------------
0115    AD F9   ROTR:   BSR FWDL                ;gosub FWDL, set left  engine forward
0117    2O E8           BRA REVR                ;goto  REVR, set right engine reverse

*#######################################
*###   define ROTL          &H0119   ###
*#######################################
*--------------------------------------------------------------------------------
*  ROTATE LEFT (SET RIGHT ENGINE TO FORWARD AND SET LEFT ENGINE TO REVERSE)
*--------------------------------------------------------------------------------
0119    AD F0   ROTL:   BSR FWDR                ;gosub FWDR, set right engine forward
011B    20 E9           BRA REVL                ;goto  REVR, set left  engine reverse

*#######################################
*###   define REV           &H011D   ###
*#######################################
*--------------------------------------------------------------------------------
*  MOVE REVERSE (SET LEFT ENGINE TO REVERSE AND SET RIGHT ENGINE TO REVERSE)
*--------------------------------------------------------------------------------
011D    AD E7   REV:    BSR REVL                ;gosub REVL, set left  engine reverse
011F    20 E0           BRA REVR                ;goto  REVR, set right engine reverse

*#######################################
*###   define FWD           &H0121   ###
*#######################################
*--------------------------------------------------------------------------------
*  MOVE FORWARD (SET LEFT ENGINE TO FORWARD AND SET RIGHT ENGINE TO FORWARD)
*--------------------------------------------------------------------------------
0121    AD ED   FWD:    BSR FWDL                ;gosub FWDL, set left  engine forward
0123    20 E6           BRA FWDR                ;goto  FWDR, set right engine forward

*#######################################
*###   define COMNAV_STATUS &H0125   ###
*#######################################
*--------------------------------------------------------------------------------
*  (CNSTAT) SEND SUBCMD(4)/HBYTE/LBYTE TO CO-PROCESOR, RECEIVE HBYTE/LBYTE...
*           ...REMOVE SYSTEM_STATUS BITS 0-2 AND COPY SET HBYTE BITS INTO SYSTEM_STATUS
*--------------------------------------------------------------------------------
0125    A6 04   CNSTAT: LDA #$04		;0x04 in accumulator
0127    B7 A3           STA SUBCMD		;store 0x04 in SUBCMD
0129    AD 29           BSR XX                  ;gosub XX, send SUBCMD/HBYTE/LBYTE to co-processor, receive HBYTE/LBYTE
012B    B6 A5           LDA SYSSTAT             ;get SYSTEM_STATUS
012D    A4 F8           AND #$F8                ;clear IR/ACR flag bits [CLEAR BITS]
012F    BA A1           ORA BUFFL               ;copy all bits set in HBYTE, into accu (=SYSTEM_STATUS), ...???...
0131    B7 A5           STA SYSSTAT             ;put accu into SYSTEM_STATUS
0133    81              RTS                     ;return

*********************************************************************************
*                 ACCU                             X-REGISTER
*  +---+---+---+---+---+---+---+---+    +---+---+---+---+---+---+---+---+
*  | . | . | . | . | a | . | . | . |    | b | . | . | . | . | . | . | c |
*  +---+---+---+---+---+---+---+---+    +---+---+---+---+---+---+---+---+
*                  |                                    |
*                  V                                    V
*                HBYTE                                LBYTE
*  +---+---+---+---+---+---+---+---+    +---+---+---+---+---+---+---+---+
*  | . | . | . | . | a | . | . | . |    | b | . | . | . | . | . | . | c |
*  +---+---+---+---+---+---+---+---+    +---+---+---+---+---+---+---+---+
*                    /                    /                           /
*                /               /                                /
*            /               /                                /
*  +---+---+---+---+---+---+---+---+    +---+---+---+---+---+---+---+---+
*  | . | . | a | . | . | . | b | . |    | . | . | . | . | . | c | . | . | Shift HBYTE/LBYTE 2x left
*  +---+---+---+---+---+---+---+---+    +---+---+---+---+---+---+---+---+
*
*  |-------|---4-bit-channel---|-------8-bit-data---------------| Modified RC5 IR-Data-Frame
*
*  Modified HBYTE and LBYTE are send to co-processor
*
*********************************************************************************

*#######################################
*###   define SEND_SPEEDR   &H0134   ###
*#######################################
*--------------------------------------------------------------------------------
*  (TXPLMB) TRANSMIT RIGHT ENGINE SPEED BY INFRARED TRANSMITTER
*--------------------------------------------------------------------------------
*---(TXPLMB)---prepair-right-engine-speed-to-be-transmitted-by-infrared-transmitter---
0134    A6 08   TXPLMB: LDA #8                  ;store code/channel for Right-Engine Pulse-Length-Modulation (8) in accu
0136    BE 0B           LDX PLMB                ;copy right engine speed in X-register
0138    20 04           BRA TXX                 ;prepair and send data by infrared tranmitter 

*#######################################
*###   define SEND_SPEEDL   &H013A   ###
*#######################################
*--------------------------------------------------------------------------------
*  (TXPLMA) TRANSMIT LEFT ENGINE SPEED BY INFRARED TRANSMITTER
*--------------------------------------------------------------------------------
*---(TXPLMB)---prepair-left-engine-speed-to-be-transmitted-by-infrared-transmitter---
013A    A6 07   TXPLMA: LDA #7                  ;store code/channel for Left-Engine Pulse-Length-Modulation (7) in accu
013C    BE 0A           LDX PLMA                ;copy left engine speed in X-register
013E    BF A1   TXX:    STX BUFFL		;copy X-register into LBYTE
*---copy-accu-and-x-register-into-hbyte-and-lbyte---
0140    B7 A2           STA BUFFH               ;copy accu into HBYTE
0142    20 06           BRA SENDTLM             ;send enginespeed by IR-transmitter

*#######################################
*###   define SEND_SYSSTAT  &H0144   ###
*#######################################
*---------- SYSTEM STATUS ------------------         
0144    3F A2  TXSTAT:CLR BUFFH                 ;clear HBYTE, to make code/channel 0 (0 = sending SYSTEM_STATUS)
0146    B6 A5         LDA SYSSTAT               ;get SYSTEM_STATUS
0148    B7 A1         STA BUFFL                 ;store SYSTEM_STATUS into LBYTE (LBYTE used by SENDTLM)

*#######################################
*###   define SEND_TLM      &H014A   ###
*#######################################
*---------- SEND TLM ---------- 
014A    B6 A1   SENDTLM:LDA BUFFL               ;get LBYTE, which holds the transmit data byte [FORMAT]
014C    49              ROL A                   ;rotate left LBYTE, b7 shifts into carry
014D    39 A2           ROL BUFFH               ;rotate left HBYTE, carry shifts into b0
014F    49              ROL A                   ;rotate left LBYTE, b7 shifts into carry
0150    39 A2           ROL BUFFH               ;rotate left HBYTE, carry shifts into b0
0152    3F A3           CLR SUBCMD              ;clear SUBCMD, = send Infrared data [->SEND]

*#######################################
*###   define COMNAV        &H0154   ###
*#######################################

*--------------------------------------------------------------------------------
*  (XX) SHIFT SUBCMD AND HBYTE AND LBYTE TO CO-PROCESSOR AND RECEIVE HBYTE AND LBYTE FROM CO-PROCESSOR
*--------------------------------------------------------------------------------
0154    9B      XX:     SEI		        ;set INTE bit, disabling interrupts (NO INTERRUPTS)
0155    AD 54           BSR SRQ	                ;REQUEST AND ACKNOWLEDGE
* on SRQ return: CLOCK is input, DATA is output
*------- SET LINES TO OUTPUT -------------
0157    AD 38           BSR SETDOUT             ;set PORT1 (DATA, PB0) and PORT2 (CLOCK, PB1) as output
*------- SOME DELAY ------
0159    AE 0C           LDX #12                 ;store 12 in x-register (DELAY AND CLR X)
015B    5A      ADEL:   DEC X                   ;decrement x-register
015C    26 FD           BNE ADEL                ;jump to increment
*------ SEND SUBCOMMAND -------
015E    B6 A3           LDA SUBCMD              ;put SUBCMD into accu
0160    CD 01 F7        JSR SOAKKU              ;clock/shift accu-value into coprocessor
*----- SEND COMMAND HI-BYTE ---
0163    B6 A2           LDA BUFFH               ;put HBYTE into accu
0165    CD 01 7F        JSR SOAKKU              ;clock/shift accu-value into coprocessor
*----- SEND COMMAND LO-BYTE ---
0168    B6 A1           LDA BUFFL               ;put LBYTE into accu
016A    CD 01 7F        JSR SOAKKU              ;clock/shift accu-value into coprocessor
*-----  SET LINES TO IN -------
016D    11 05           BCLR 0,PADDR            ;set PB0/Port1 as input (DATA LINE IN)
016F    13 05           BCLR 1,PADDR            ;set PB1/Port2 as input (CLOCK LINE IN)
*---receive-hbyte-and-lbyte-from-co-processor---
0171    CD 01 98        JSR SIAKKU              ;gosub SIAKKU, load byte received from co-processor into accu [GET HI-BYTE]
0174    B7 A2           STA BUFFH               ;store accu in HBYTE
0176    CD 01 98        JSR SIAKKU	        ;gosub SIAKKU, load byte received from co-processor into accu [GET LO-BYTE]
0179    B7 A1           STA BUFFL               ;store accu in LBYTE
*----- SET LINES TO OUT
017B    AD 14           BSR SETDOUT             ;gosub SETDOUT, set PORT1 (DATA, PB0) and PORT2 (CLOCK, PB1) as output
017D    9A              CLI                     ;enable all interrupts
017E    81              RTS                     ;return

*********************************************************************************
*
*                :---0---:---1---:---2---:---3---:---4---:---5---:---6---:---7---:
*
*     -----------+ +-----+ +-----+ +-----+ +-----+                 +-----+ +-----
* DATA-----------+ |  1  | |  1  | |  1  | |  1  |    0       0    |  1  | |  1    example byte
*     -----------+-+     +-+     +-+     +-+     +-------+-------+-+     +-+
*                    +-+     +-+     +-+     +-+     +-+     +-+     +-+     +-+
* CLOCK--+           |1|     |2|     |3|     |4|     |5|     |6|     |7|     |8|
*        +-----------+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-
*
*********************************************************************************
*--------------------------------------------------------------------------------
  (SOAKKU) SHIFT OUT ACCU (TO CO-PROCESSOR)
*--------------------------------------------------------------------------------
017F    5F      SOAKKU:  CLRX                   ;clear x-register
0180    13 01   S1BYT:   BCLR 1,PADAT           ;set PB1 low (CLOCK OUT L)
0182    44               LSRA                   ;shift accu to left (b0 FIRST) (into carry)
0183    11 01            BCLR 0,PADAT           ;set PB0 low (DATA OUT LO)
0185    24 02            BCC CLKOUT             ;if bit carry is clear, jump
0187    10 01            BSET 0,PADAT           ;set PB0 hig (DATA OUT HI)
0189    12 01   CLKOUT:  BSET 1,PADAT           ;set PB1 hig, CLOCK OUT H
018B    5C               INC X                  ;increment x-register
018C    A3 08            CPX #$8                ;check for x-register equals 8
018E    26 F0            BNE S1BYT              ;if not, jump
0190    81               RTS                    ;if yes, return

* - sets PB0/PB1 as output
*------------------------------
*---    SET DATA OUT    -------
*------------------------------
;	;	;	;	;	;	;
*SETDOUT: BSET 1,PADDR   ;SET CLOCKLINE OUT
0191    13 01   SETDOUT:BCLR 1,PADAT            ;set    CLOCK low        I12.14, PA1, [CLOCK LO]
0193    12 05           BSET 1,PADDR            ;switch CLOCK to output, I12.14, PA1, [SET CLOCKLINE OUT]
0195    10 05           BSET 0,PADDR            ;switch DATA  to output, I12.15, PA0, [SET DATALINE OUT]
0197    81              RTS                     ;return
*--------------------------------------------------------------------------------
*  (SHIFT IN AKKU) STORE SERIAL RECEIVED DATA FROM PORT1 (CLOCKED IN BY 'CLOCK') INTO ACCUMULATOR
*--------------------------------------------------------------------------------
0198    5F      SIAKKU: CLRX                    ;clr X-register
0199    02 01 FD R1BYT: BRSET 1,PADAT,R1BYT     ;loop here until PORT2 (CLOCK) is low [WAIT CLOCK L]
019C    44              LSRA                    ;shift accu left 1 bit (sets or clears carry)
019D    03 01 FD CLKIN: BRCLR 1,PADAT,CLKIN     ;loop here until PORT2 (CLOCK) is high [WAIT CLOCK H]
01A0    01 01 02        BRCLR 0,PADAT,SDT       ;if PORT1 (DATA) is low, then jump to SDT
01A3    AA 80           ORA #$80                ;if DATA is high, set bit 7 in accu
01A5    5C      SDT:    INC X                   ;increment X-register
01A6    A3 08           CPX #$08                ;check if X-register equals 8 (all 8 DATA bits received)
01A8    26 EF           BNE R1BYT               ;if X-register not equals 8, then jump back to R1BYT
01AA    81              RTS                     ;return

*--------------------------------------------------------------------------------
*  (SRQ) SERVICE REQUEST, CALL CO-PROCESSOR AND WAIT UNTIL CO-PROCESSOR IS READY TO RECEIVE DATA
*
* on exit: CLOCK is input, DATA is output
*--------------------------------------------------------------------------------
*********************************************************************************
*        -------+----------------------------------------
* DATA   ???????+
*        -------+----------------------------------------
*
*        ---+       +---//---+   +---wait-for-low---//---+
* CLOCK  ???+?+     |        +---+iiiiiiiiiiiiiiiiiiiiiii|
*        ---+-+---+-+            +------------------//---+-----
*                       //=36us                     //=100us(guess)
*         |-----------------endless-repeat-------------|
*
*********************************************************************************
* Conrad uses (confusing) name 'PADAT' (Port A DATa) for microcontroller 8-bits Port B(!)
* Conrad PORT1 = microprocessor port B bit 0 (PB0, pin 39), used as DATA  signal to/from Co-processor IC I2 (PA0, pin 15)
* Conrad PORT2 = microprocessor port B bit 1 (PB1, pin 38), used as CLOCK signal to/from Co-processor IC I2 (PA1, pin 14)
* - Microcontroller bits PORT1 and PORT2 are directly connected to the co-processor.
* - PORT1 is used as DATA  signal TO   the co-processor. main-processor is sending,   co-processor is receiving
* - PORT2 is used as CLOCK signal TO   the co-processor. main-processor is sending,   co-processor is receiving
* - PORT1 is used as DATA  signal FROM the co-processor. main-processor is receiving, co-processor is sending
* - PORT2 is used as CLOCK signal FROM the co-processor. main-processor is receiving, co-processor is sending
*
*********************************************************************************
01AB    AD E4   SRQ:    BSR SETDOUT             ;gosub SETDOUT (switch PORT1 and PORT2 as output [LINES TO OUT])
01AD    12 01           BSET 1,PADAT            ;set PORT2 high. (CLOCK = 1) (why?)
        *---delay-of-36us-(36-micro-seconds)---
01AF    AE 0A	        LDX #10                 ;put value 10 in x-register
01B1    5A      DEL1:   DEX		        ;decrement x-reg, [HOLD REQUEST 36 us]
01B2    26 FD           BNE DEL1                ;if x-register is nonzero, then jump back to DEL1
        *------ WAIT FOR ACKNOWLEDGE ---
01B4    13 05           BCLR 1,PADDR            ;switch PORT2 (CLOCK) to input [END REQUEST]
01B6    AE 0A           LDX #10                 ;store 10 in x-register
01B8    02 01 05 DEL2:  BRSET 1,PADAT,ACKN      ;if PORT1 (CLOCK) is high (by co-processor), then goto ACKN
01BB    5A              DEX		        ;decrement x-register [WAIT ACKN]
01BC    26 FA           BNE DEL2                ;if x-register is not 0, goto DEL2
01BE    20 EB           BRA SRQ	                ;goto SRQ [REPEAT AFTER TIMEOUT]
         *----- ACKNOWLEDGE RECEIVED ----
01C0    02 01 FD ACKN:  BRSET 1,PADAT,ACKN      ;if CLOCK is high, goto ACKN (current line repeating), if low, goto next line
01C3    81              RTS                     ;return

*#######################################
*###   define PLM_SLOW      &H01C4   ###
*#######################################
*
*********************************************************************************
*
* Warnig from b6r4.pdf microcontroller documentation
*
* Warning: Because the SFA bit and SFB bit are not double buffered, it is mandatory to set the SFA
* bit and SFB bit to the desired values before writing to the PLMA/PLMB registers; not doing so
* could temporary give incorrect values at the PLM outputs.
*
*********************************************************************************
01C4    A6 0C	        LDA #$0C                ;set FSA bit and FSC bit for MISC reggister
01C6    B7 0C           STA MISC                ;store settings into MISC register 
01C8    81              RTS                     ;return


*#######################################
*###   define SYSTEM        &H01C9   ###
*#######################################
*
*--+ +---+ +---+ +---+             +---+ +---+
*  | | 1 | | 1 | | 1 |   0     0   | 1 | | 1 |   0           PB0, Serial-Data (sdio) 
*  +-+   +-+   +-+   +-----+-----+-+   +-+   +-----+-------
*     +-+   +-+   +-+   +-+   +-+   +-+   +-+   +-+
*     |1|   |2|   |3|   |4|   |5|   |6|   |7|   |8|          PB2, Serial Clock (sclio)
*-----+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +--------
*                                                     +-+
*                                                     | |    PB3, Strobe (strobe)
*-----------------------------------------------------+ +--
*
*--------------------------------------------------------------------------------
*  PDRIVE: (0x01C9) COPY DATA FROM EXTPORT REGISTER INTO SHIFTEGISTER CHIP IC I11
*--------------------------------------------------------------------------------
* REMAINS PA3=0, PA2=1 ;Conrad comment
;	;	;	;	;	;	;	;	;	;
01C9    AE 08   PDRIVE: LDX #8          ;load 0x08 in X-register
01cB    39 A4   LP2:    ROL EXTP        ;rotate left EXTPORT (carry is set or clr, according outshifted bit)
01CD    11 01           BCLR 0,PADAT    ;clr port B bit 0 (PORT1, IC I11.2) Serial-Data=0 (LO OUT)
01CF    24 02           BCC LP1         ;if no carry, branch to LP1
01D1    10 01           BSET 0,PADAT    ;set port B bit 0 (PORT1, IC I11.2) Serial-Data=1 (HI OUT)
*---negative-pulse-on-clock---(inverted by harware to positive puls)
01D3    15 01   LP1:    BCLR 2,PADAT    ;clr port B bit 2 (PORT3, IC I11.3) Serial-Clck=1 (inverted) s(CLOCK)
01D5    14 01           BSET 2,PADAT    ;set port B bit 2 (PORT3, IC I11.3, Serial-Clck=0 (inverted) s(CLOCK)
*---count-bits-done---
01D7    5A              DEX             ;decrement X-register (8->7->6->5->4->3->2->1->0)
01D8    26 F1           BNE LP2         ;if X-register is not zero, then jump back to LP2
*---rotate-one-extra-to-make-bit0-in-carry-go-into-bit0-position---
01DA    39 A4           ROL EXTP        ;rotate left EXTPORT (carry is set or clr, according outshifted bit)
*---generate-a-positive-pulse-on-strobe---
01DC    16 01           BSET 3,PADAT    ;set port B bit 3 (PORT4, IC I11.1) Strobe=1 [STROBE]
01DE    17 01           BCLR 3,PADAT    ;clr port B bit 3 (PORT4, IC I11.1, Strobe=0 [STROBE]
*---return---
01E0    81              RTS             ;return

*#######################################
*###   define ACS_LO        &H01E1   ###
*#######################################
*--------------------------------------------------------------------------------
*  ACSLO: (0x01E1) SET ACS INFRARED TRANSMIT SIGNAL TO LOW POWER
*--------------------------------------------------------------------------------
01E1    AD 12   ACSLO:  BSR CLRF        ;call subroutine CRLF (clear all ACS bits)
01E3    14 A4           BSET 2,EXTP     ;set bit 2 in EXTPORT       (ACS_PWR_HI)
01E5    1C A5           BSET 6,SYSSTAT  ;clr bit 6 in SYSTEM_STATUS (ACS_PWR_HI)
01E7    20 E0           BRA PDRIVE      ;goto PDRIVE

*#######################################
*###   define ACS_HI        &H01E9   ###
*#######################################
*--------------------------------------------------------------------------------
*  ACSHI: (0x01E9) SET ACS INFRARED TRANSMIT SIGNAL TO HIGH POWER
*--------------------------------------------------------------------------------
01E9    AD 0A   ACSHI:  BSR CLRF        ;call subroutine CRLF (clear all ACS bits)
01EB    12 A4           BSET 1,EXTP     ;set bit 1 in EXTPORT       (ACS_PWR_LO)
01ED    1A A5           BSET 5,SYSSTAT  ;set bit 6 in SYSTEM_STATUS (ACS_PWR_HI)
01EF    20 D8           BRA PDRIVE      ;goto PDRIVE

*#######################################
*###   define ACS_MAX       &H01F1   ###
*#######################################
*--------------------------------------------------------------------------------
*  ACSMAX: (0x01F1) SET ACS INFRARED TRANSMIT SIGNAL TO MAXIMUM POWER
*--------------------------------------------------------------------------------
01F1    AD 02   ACSMAX: BSR CLRF        ;call subroutine CRLF (clear all ACS bits)
01F3    20 D4           BRA PDRIVE      ;goto PDRIVE
        
*--------------------------------------------------------------------------------
*  CRLF: (0x01F5) CLEAR ACS BITS IN EXTPORT REGISTER AND IN SYSTEM_STATUS REGISTER
*--------------------------------------------------------------------------------
01F5    15 A4   CLRF:	BCLR 2,EXTP     ;clr bit 2 in EXTPORT       (ACS_PWR_HI)
01F7    13 A4           BCLR 1,EXTP     ;clr bit 1 in EXTPORT       (ACS_PWR_LO)
01F9    1D A5           BCLR 6,SYSSTAT  ;clr bit 6 in SYSTEM_STATUS (ACS_PWR_HI)
01FB    1B A5           BCLR 5,SYSSTAT  ;clr bit 5 in SYSTEM_STATUS (ACS_PWR_LO)
01FD    81              RTS             ;return

Durch diese wirklich hervorragende Arbeit von Henk ist es möglich, den Programmlauf auch über die Sprünge in das Maschinensprache-Programms hinweg zu verfolgen und nachzuvollziehen.

Kleiner Programmierkurs

Hello_World oder "I'm alive"

In guter, "alter" Tradition trägt das erste Beispiel jeder Programmiersprache (hoffentlich ;-) ...) den Titel "Hello World!" - und gibt nichts anderes als diese beiden Worte auf dem Bildschirm aus. Bei µC ist dies mangels angeschlossener Peripherie erstmal nicht möglich und man begnügt sich in der Regel mit dem Leuchten oder Blinken einer LED, die an einem Ausgang angeschlossen wird. "Hello World" wird so zu "I'm alive!".


Beim CCRP5 sind die vier nutzbaren LED an einem Schieberegister angeschlossen, welches vom Hauptprozessor gesteuert wird.


Schieberegister an Hauptprozessor


Möchte man Ausgänge dieses Schieberegisters setzen oder löschen, so muß man es über die drei Leitungen DATA (oder auch: Serial In), CLOCK und STROBE entsprechend beschreiben. Soll beispielsweise die LED1/D13 zum Leuchten gebracht werden, so lautet die Bitfolge hierzu:


Bitfolge "setzen"


Folgende Tabelle gibt Auskunft über die programmierbaren Ports:

µC-Bezeichnung Pin-Nummer CCBASIC-Portnummer Funktion
PB0 Pin39 Port1 DAT (gemeinsame Datenleitung von Hauptprozessor, Subsystem und Schieberegister)
PB1 Pin38 Port2 SUC (Taktleitung zwischen Hauptprozessor und Subsystem)
PB2 Pin37 Port3 SRC (Taktleitung zwischen Hauptprozessor und Schieberegister)
PB3 Pin36 Port4 STR (Steuerleitung zwischen Hauptprozessor und Schieberegister)
PB4 Pin35 Port5 LIV (Motordrehrichtungssteuerung, links-)
PB5 Pin34 Port6 REV (Motordrehrichtungssteuerung, rechts-)
PB6 Pin33 Port7 Frei
PB7 Pin32 Port8 Frei
PC0 Pin49 Port9 Frei
PC1 Pin48 Port10 Frei
PC2 Pin47 Port11 Frei
PC3 Pin46 Port12 Frei
PC4 Pin45 Port13 Frei
PC5 Pin44 Port14 Frei
PC6 Pin43 Port15 Frei
PC7 Pin42 Port16 Frei


Schreiben wir also unser erstes Programm:

'Zuerst müssen den Ausgängen Variablen zugewiesen werden,
'damit so auf sie zugegriffen werden kann.


define DATA port[1]
define CLOCK port[3]
define STROBE port[4]


'Mit jedem Impuls auf der CLOCK-Leitung wird ein Bit eingelesen,
'welches den Wert des auf der DATA-Leitung herrschenden Signalpegels
'annimmt.


'Bit7 *** LED4 AUS ***

DATA=0
pulse CLOCK


'Bit6 *** LED3 AUS ***

DATA=0
pulse CLOCK


'Bit5 *** LED2 AUS ***

DATA=0
pulse CLOCK


'Bit4 *** LED1 EIN ***

DATA=1
pulse CLOCK


'Bit3 *** MOTORSTROMSENSOR, REFERENZSPANNUNGSERZEUGUNG, SENSORFELD, MIKROFON UND LICHTSENSOR AUS ***

DATA=0
pulse CLOCK


'Bit2 *** AE2 LOW ***

DATA=0
pulse CLOCK


'Bit1 *** AE1 LOW ***

DATA=0
pulse CLOCK


'Bit0 *** SUBSYSTEM, IR-/ACS-EMPFÄNGER UND ODOMETRIE-SENSORIK AUS ***

DATA=0
pulse CLOCK


'Mit einem Impuls auf der STROBE-Leitung wird der Inhalt des Registers
'an die Ausgänge durchgeschaltet.

pulse STROBE


END


Nach dem Kompilieren, Übertragen und Ausführen sollte nun LED1 leuchten - aber wie bekommt man sie wieder aus?


Zum Löschen dieses Ausgangs schreibt man diese Bitfolge in das Schieberegister:


Bitfolge "löschen"


Wiederholen sich Befehlssequenzen, so wie hier das achtmalige Schreiben einer "Null" in das Schieberegister, bietet sich die Programmierung einer Schleife an. Programmschleifen sind durch Anfang und Ende gekennzeichnet und der dazwischen befindliche Programmcode wird so lange ausgeführt, bis eine definierte Austrittsbedingung erfüllt ist. Bei dieser Definition ist darauf zu achten, daß die Austrittsbedingung auch wirklich erfüllt werden kann, denn sonst kommt es zu einer sog. "Endlosschleife". Bei Programmen für µC ist dies im Fall des Hauptprogrammes erwünscht, da diese sonst ja unbedienbar würden.


Eine der Möglichkeiten, in CCBASIC eine Schleife zu programmieren, bietet sich mit den Schlüsselwörtern <FOR...TO...(STEP)> und <NEXT>:


Flußdiagramm FOR-NEXT-Schleife


Hier wird die Definition einer Schleifenvariablen (im Beispiel N) notwendig, deren Wert am Ende der Schleife (<NEXT>) abgefragt wird. Entspricht dieser dem zuvor festgelegten Maximalwert (<TO>), wird die Schleife verlassen. Anderenfalls wird der Wert dieser Variablen erhöht (<STEP>) und die Schleife fortgesetzt.


So ergibt sich folgender Code für ein Programm, welches LED1 wieder verlöschen läßt:

'Zuerst müssen den Ausgängen Variablen zugewiesen werden,
'damit so auf sie zugegriffen werden kann.


define DATA port[1]
define CLOCK port[3]
define STROBE port[4]


'Ohne vorhergehende Definition einer Schleifenvariablen
'tut's der Compiler nicht ...


define N byte


'Der Schleifenanfang, in dem auch gleich Maximalwert
'und Schrittweite definiert werden ...

FOR N=0 TO 7 STEP 1


'Achtmal (N=0 bis N=7) ein "Null"-Bit einlesen ...

DATA=0
pulse CLOCK

'Schleifenende

NEXT N


'Mit einem Impuls auf der STROBE-Leitung wird der Inhalt des Registers
'an die Ausgänge durchgeschaltet.

pulse STROBE


END


Dies wäre schon das grundsätzliche Rüstzeug, um diese LED auch blinken lassen zu können.


Nach deren Einschalten wird das Programm mit der <PAUSE>-Anweisung für einen Moment angehalten - die genaue Länge dieses Moments wird in Schritten von 20ms definiert. "pause 50" sorgt also für eine Unterbrechung von einer Sekunde.

Um den Blinkeffekt zu erzeugen, muß allerdings auch nach dem Ausschalten für die gleiche Zeitdauer pausiert werden!

Mit einer <GOTO>-Anweisung am Ende des Programms wird ein Sprung zu der Marke ausgeführt, die am Programmanfang eingefügt wird.


Der Programmcode für eine blinkende LED:

'Zuerst müssen den Ausgängen Variablen zugewiesen werden,
'damit so auf sie zugegriffen werden kann.


define DATA port[1]
define CLOCK port[3]
define STROBE port[4]


'Ohne vorhergehende Definition einer Schleifenvariablen
'tut's der Compiler nicht ...


define N byte


'Beginn des Hauptprogramms -> Endlosschleife

#LOOP


'Mit jedem Impuls auf der CLOCK-Leitung wird ein Bit eingelesen,
'welches den Wert des auf der DATA-Leitung herrschenden Signalpegels
'annimmt.


'LED1 einschalten

'Bit7 *** LED4 AUS ***

DATA=0

pulse CLOCK


'Bit6 *** LED3 AUS ***

DATA=0

pulse CLOCK


'Bit5 *** LED2 AUS ***

DATA=0

pulse CLOCK


'Bit4 *** LED1 EIN ***

DATA=1

pulse CLOCK


'Bit3 *** MOTORSTROMSENSOR, REFERENZSPANNUNGSERZEUGUNG, SENSORFELD, MIKROFON UND LICHTSENSOR AUS ***

DATA=0

pulse CLOCK


'Bit2 *** AE2 LOW ***

DATA=0

pulse CLOCK


'Bit1 *** AE1 LOW ***

DATA=0

pulse CLOCK


'Bit0 *** SUBSYSTEM, IR-/ACS-EMPFÄNGER UND ODOMETRIE-SENSORIK AUS ***

DATA=0

pulse CLOCK


'Mit einem Impuls auf der STROBE-Leitung wird der Inhalt des Registers
'an die Ausgänge durchgeschaltet.

pulse STROBE


'Eine kleine Pause von 50*20 ms = 1 s

pause 50


'LED1 ausschalten


'Der Schleifenanfang, in dem auch gleich Maximalwert
'und Schrittweite definiert werden ...

FOR N=0 TO 7 STEP 1


'Achtmal (N=0 bis N=7) ein "Null"-Bit einlesen ...

DATA=0

pulse CLOCK


'Schleifenende

NEXT N


'Mit einem Impuls auf der STROBE-Leitung wird der Inhalt des Registers
'an die Ausgänge durchgeschaltet.

pulse STROBE


'Eine kleine Pause von 50*20 ms = 1 s

pause 50


'Zurück zum Anfang

goto LOOP


END


Läßt sich das Einschalten der LED nicht auch so elegant in einer Schleife zusammenfassen?


Jein - mit der bedingten Verzweigung:


Flußdiagramm IF-THEN-Verzweigung


Hier wird eine Bedingung abgefragt (<IF>), die abhängig von ihrem Erfüllen oder Nichterfüllen in den einen (<THEN>), bzw. anderen (<ELSE>) Programmteil verzweigt. Im Fall des Beispiels muß beim vierten Durchlauf der Schleife (N=3) die Datenleitung gesetzt werden (DATA=1).


So ergibt sich folgender Programmcode:

'Zuerst müssen den Ausgängen Variablen zugewiesen werden,
'damit so auf sie zugegriffen werden kann.

define DATA port[1]
define CLOCK port[3]
define STROBE port[4]


'Ohne vorhergehende Definition einer Schleifenvariablen
'tut's der Compiler nicht ...

define N byte


'Beginn des Hauptprogramms -> Endlosschleife

#LOOP


'LED1 einschalten


'Der Schleifenanfang, in dem auch gleich Maximalwert
'und Schrittweite definiert werden ...

for N=0 to 7


'Hier wird überprüft, ob es sich um den vierten Schleifendurchlauf
'handelt (N=3). Im positiven Fall (THEN) wird die Datenleitung gesetzt
'(DATA=0), ansonsten (ELSE) wird die Datenleitung gelöscht (DATA=0).

if N=3 then DATA=1 else DATA=0


'Mit jedem Impuls auf der CLOCK-Leitung wird ein Bit eingelesen,
'welches den Wert des auf der DATA-Leitung herrschenden Signalpegels
'annimmt.

pulse CLOCK


'Schleifenende

next N


'Mit einem Impuls auf der STROBE-Leitung wird der Inhalt des Registers
'an die Ausgänge durchgeschaltet.

pulse STROBE


'Eine kleine Pause von 50*20 ms = 1 s

pause 50


'LED1 ausschalten


'Der Schleifenanfang, in dem auch gleich Maximalwert
'und Schrittweite definiert werden ...

FOR N=0 TO 7 STEP 1


'Achtmal (N=0 bis N=7) ein "Null"-Bit einlesen ...

DATA=0

pulse CLOCK


'Schleifenende

NEXT N


'Mit einem Impuls auf der STROBE-Leitung wird der Inhalt des Registers
'an die Ausgänge durchgeschaltet.

pulse STROBE


'Eine kleine Pause von 50*20 ms = 1 s

pause 50


'Zurück zum Anfang

goto LOOP


END


Diese Lösung funktioniert zwar, ist aber weder elegant noch transparent. Wünschenswerter wäre, die erforderliche Bitfolge im Programmcode nachvollziehbar darzustellen.

In CCBASIC können Variablen und Konstanten dezimal, hexadezimal oder binär dargestellt werden. Dies ermöglicht die Darstellung von LED1 als Konstante im binären Format, welches exakt der Bitfolge entspricht.


define LED1 &B00001000


Analog dazu ergeben sich folgende Konstanten für die Ausgänge des Schieberegisters im CCRP5:

Konstante Funktion des Ausgangs
&B10000000 Subsystem, IR-/ACS-Empfänger und Odometrie-Sensorik
&B01000000 ACS-Sendeleistung
&B00100000 ACS-Sendeleistung
&B00010000 Motorstromsensor, Referenzspannungserzeugung, Sensorfeld, Mikrofon und Lichtsensor
&B00001000 LED1/D13
&B00000100 LED2/D14
&B00000010 LED3/D15
&B00000001 LED4/D16


Doch wie läßt sich nun die der jeweiligen Konstante entsprechende Bitfolge erzeugen?

Zuerst wird eine Schleife benötigt, die das Byte, welches die Konstante darstellt, (z.B. 00001000) Bit für Bit abtastet. In dieser Schleife wird dann durch eine logische Verknüpfung der Wert von jedem einzelnen Bit ermittelt und auf die Datenleitung übertragen. Für solche Bitmaskierungsoperationen kann der Schiebeoperator SHL (SHiftLeft), bzw. SHR (SHiftRight) benutzt werden.

Verknüpft mit der Schleifenvariablen N nimmt der Ausdruck

1 SHL N

bei jedem Durchlauf der Schleife einen anderen Wert an:

N (1 SHL N)
0 0000 0001
1 0000 0010
2 0000 0100
3 0000 1000
4 0001 0000
5 0010 0000
6 0100 0000
7 1000 0000

Wird der Wert dieses Ausdrucks mit der Konstanten für z.B. LED1 logisch UND-verknüpft,

A 0 0 1 1
B 0 1 0 1
A^B 0 0 0 1

so erhält man folgende Ergebnisse:

N (1 SHL N) LED1 LED1^(1 SHL N)
0 0000 0001 0000 1000 0
1 0000 0010 0000 1000 0
2 0000 0100 0000 1000 0
3 0000 1000 0000 1000 1
4 0001 0000 0000 1000 0
5 0010 0000 0000 1000 0
6 0100 0000 0000 1000 0
7 1000 0000 0000 1000 0

Das Ergebnis dieser Verknüpfung kann direkt der Variablen DATA und somit dem entsprechenden Ausgang zugewiesen werden:

DATA=LED1 and (1 shl N)

Der Code für ein Programm zum Einschalten der LED1 sähe auf diese Weise so aus:

'Zuerst müssen den Ausgängen Variablen zugewiesen werden,
'damit so auf sie zugegriffen werden kann.

define DATA port[1]
define CLOCK port[3]
define STROBE port[4]

'Ohne vorhergehende Definition einer Schleifenvariablen
'tut's der Compiler nicht ...

define N byte

'Darstellung der Bitfolge als Konstante ...

define LED1 &B00001000

'Der Schleifenanfang, in dem auch gleich Maximalwert
'und Schrittweite definiert werden ...

for N=0 to 7

'Die Verknüpfung zwischen LED1 und dem wandernden Bit ...

DATA=LED1 and (1 shl N)

'Mit jedem Impuls auf der CLOCK-Leitung wird ein Bit eingelesen,
'welches den Wert des auf der DATA-Leitung herrschenden Signalpegels
'annimmt.

pulse CLOCK

'Schleifenende

NEXT N

'Mit einem Impuls auf der STROBE-Leitung wird der Inhalt des Registers
'an die Ausgänge durchgeschaltet.

pulse STROBE

END

Durch weitere Abstraktion können die beiden Programmschleifen zusammengelegt werden. Dazu ist die Einführung einer weiteren Variablen notwendig, welche stets den aktuellen Inhalt des Schieberegisters darstellt.

define SHIFT_REGISTER byte

Dieser kann dann im Hauptprogramm beliebig manipuliert werden. Zum Übertragen des jeweils aktuellen Inhalts schließt sich an die Endlosschleife des Hauptprogramms folgendes Unterprogramm an:

'Sprungmarke

#WRITE_SHIFT_REGISTER

'Der Schleifenanfang, in dem auch gleich Maximalwert
'und Schrittweite definiert werden ...

for N=0 to 7

'Die Verknüpfung zwischen dem aktuellen Inhalt des
'Schieberegisters und dem wandernden Bit ...

DATA=SHIFT_REGISTER and (1 shl N)

'Mit jedem Impuls auf der CLOCK-Leitung wird ein Bit eingelesen,
'welches den Wert des auf der DATA-Leitung herrschenden Signalpegels
'annimmt.

pulse CLOCK

'Schleifenende

NEXT N

'Mit einem Impuls auf der STROBE-Leitung wird der Inhalt des Registers
'an die Ausgänge durchgeschaltet.

pulse STROBE

'Rücksprung ins Hauptprogramm

return

Für das Blinken der LED1 ergibt sich somit folgender Programmcode:

'Zuerst müssen den Ausgängen Variablen zugewiesen werden,
'damit so auf sie zugegriffen werden kann.

define DATA port[1]
define CLOCK port[3]
define STROBE port[4]

'Ohne vorhergehende Definition einer Schleifenvariablen
'tut's der Compiler nicht ...

define N byte

'Eine Variable für Inhalt des Schieberegisters ...

define SHIFT_REGISTER byte

'Darstellung der Bitfolge als Konstante ...

define LED1 &B00001000

'Schieberegister löschen, um definierte Ausgangsbedingungen
'zu haben ...

SHIFT_REGISTER=&B00000000

'Schieberegister beschreiben ...

gosub WRITE_SHIFT_REGISTER

'Beginn des Hauptprogramms -> Endlosschleife 

#LOOP

'Die logische Verknüpfung mit Exklusiv-ODER wechselt
'bei jedem Durchlauf den aktuellen Zustand ...

SHIFT_REGISTER=SHIFT_REGISTER xor LED1

'Schieberegister beschreiben ...

gosub WRITE_SHIFT_REGISTER

' 1 Sekunde Unterbrechung

pause 50

'Zurück zum Anfang

goto LOOP
 

'Funktion zum Beschreiben des Schieberegisters

'Sprungmarke

#WRITE_SHIFT_REGISTER

'Der Schleifenanfang, in dem auch gleich Maximalwert
'und Schrittweite definiert werden ...

for N=0 to 7

'Die Verknüpfung zwischen dem aktuellen Inhalt des
'Schieberegisters und dem wandernden Bit ...

DATA=SHIFT_REGISTER and (1 shl N)

'Mit jedem Impuls auf der CLOCK-Leitung wird ein Bit eingelesen,
'welches den Wert des auf der DATA-Leitung herrschenden Signalpegels
'annimmt.

pulse CLOCK

'Schleifenende

NEXT N

'Mit einem Impuls auf der STROBE-Leitung wird der Inhalt des Registers
'an die Ausgänge durchgeschaltet.

pulse STROBE

'Rücksprung ins Hauptprogramm

return

'Ende der Funktion

end

Wahrheitstabelle der Exklusiv-ODER-Verknüpfung (XOR):

A 0 0 1 1
B 0 1 0 1
A⊕B 0 1 1 0

Damit dürfte dieses kleine Beispiel ziemlich ausgereizt sein. Weiter geht's mit den A/D-Wandlern und Motoren des CCRP5:

Messen, Steuern und Regeln

Baustelle.gif An diesem Artikel arbeitet gerade Mitglied Pischke.

Am besten momentan noch keine gravierenden Ergänzungen / Änderungen vornehmen.

Dieser Hinweis verschwindet wenn der Autor soweit ist. Sollte dieser Hinweis länger als drei Tage auf einer Seite sein, bitte beim Autor Pischke per PM / Mail oder Forum nachfragen ob er vergessen wurde.

<Wird fortgesetzt ...>

Technische Daten

(mit montierter Hauptplatine)

Länge ca. 200 mm
Breite ca. 130 mm
Höhe ca. 90 mm
Gewicht ca. 750 g (mit sechs AA-Zellen)
Geschwindigkeit ca. 22 cm/s

Stromaufnahme ca. 400 mA (im leerlaufenden Fahrbetrieb mit ANTRIEB.BAS)

Autor/en

Siehe auch

Weblinks





LiFePO4 Speicher Test