(→Schaltungsauszug) |
K (→Kleiner Programmierkurs) |
||
(96 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
− | + | [[Bild:ccrp5.gif|thumb|Arexx Roboter]] | |
− | + | ||
==Einleitung== | ==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. | 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== | ==Mechanik== | ||
Zeile 212: | Zeile 207: | ||
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. | 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-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. | + | 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 | + | 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==== | ====Freie Resourcen==== | ||
Zeile 313: | Zeile 308: | ||
|} | |} | ||
− | 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 | + | 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=== | ===Schieberegister=== | ||
− | |||
− | |||
− | |||
− | |||
====Schaltungsauszug==== | ====Schaltungsauszug==== | ||
Zeile 362: | Zeile 353: | ||
− | 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 ständig an den Parallel-Ausgängen sichtbar. Diese Ausgänge sind gemäß Datenblatt mit 25 mA belastbar. | + | 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 | Über den Parallel-Ausgang 0, Pin 4, wird die Versorgungsspannung für | ||
*Subsystem, | *Subsystem, | ||
− | *IR-Empfänger und | + | *IR-/ACS-Empfänger und |
*Odometrie-Sensorik | *Odometrie-Sensorik | ||
ein-, bzw. ausgeschaltet. | ein-, bzw. ausgeschaltet. | ||
Zeile 380: | Zeile 371: | ||
*Sensorfeld, | *Sensorfeld, | ||
*Mikrofon und | *Mikrofon und | ||
− | * | + | *Lichtsensor |
mit Spannung versorgt, dieser Ausgang kann somit als Ein-/Ausschalter für diese Komponenten betrachtet werden. | mit Spannung versorgt, dieser Ausgang kann somit als Ein-/Ausschalter für diese Komponenten betrachtet werden. | ||
Zeile 397: | Zeile 388: | ||
===Subsystem=== | ===Subsystem=== | ||
− | |||
− | |||
− | |||
− | |||
====Schaltungsauszug==== | ====Schaltungsauszug==== | ||
Zeile 437: | Zeile 424: | ||
====Schaltungsbeschreibung==== | ====Schaltungsbeschreibung==== | ||
− | Subsystem, IR-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 U<sub>BEsat</sub> ab und mangels Potentialunterschiedes - da VCC-U<sub>BEsat</sub> =U<sub>Pin4(HIGH)</sub> - 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. | + | 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 U<sub>BEsat</sub> ab und mangels Potentialunterschiedes - da VCC-U<sub>BEsat</sub> =U<sub>Pin4(HIGH)</sub> - 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. | 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. | ||
Zeile 449: | Zeile 436: | ||
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). | 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-Empfängers IC6 (TSOP1836). | + | 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. | 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. | ||
Zeile 463: | Zeile 450: | ||
Ü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. | Ü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, | + | 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. | 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. |
− | | | + | |
+ | |||
+ | [[Bild:CCRP5 Referenzspannung.png|framed|center|Referenzspannungserzeugung im CCRP5]] | ||
+ | |||
+ | |||
+ | Nachfolgend eine alphabetische Auflistung der im Schaltungsauszug verwendeten Leitungskürzel und deren Zuordnungen: | ||
+ | |||
+ | {| {{Blauetabelle}} | ||
+ | |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. | ||
− | |||
+ | [[Bild:CCRP5 Sensorfeld.png|framed|center|Sensorfeld]] | ||
− | |||
+ | Nachfolgend eine alphabetische Auflistung der im Schaltungsauszug verwendeten Leitungskürzel und deren Zuordnungen: | ||
+ | |||
+ | {| {{Blauetabelle}} | ||
+ | |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 p<sub>amb</sub>. 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'' | ||
+ | |||
+ | |||
+ | |||
+ | [[Bild:CCRP5 Mikrofon.png|framed|center|Mikrofon]] | ||
+ | |||
+ | |||
+ | Nachfolgend eine alphabetische Auflistung der im Schaltungsauszug verwendeten Leitungskürzel und deren Zuordnungen: | ||
+ | |||
+ | {| {{Blauetabelle}} | ||
+ | |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=== | ||
− | Um die | + | 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.). |
Zeile 493: | Zeile 562: | ||
====Schaltungsauszug==== | ====Schaltungsauszug==== | ||
− | Da beide | + | 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. |
− | [[Bild:CCRP5 | + | [[Bild:CCRP5 Lichtsensor.png|framed|center|Lichtsensor]] |
====Schaltungsbeschreibung==== | ====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 | + | 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: |
Zeile 513: | Zeile 582: | ||
− | [[Bild: | + | [[Bild:Lichtsensor Versuchsaufbau 1.png|200px|framed|center|Lichtsensor: Versuchsaufbau 1]] |
Zeile 631: | Zeile 700: | ||
− | [[Bild: | + | [[Bild:Lichtsensor Diagramm.png|framed|center|Lichtsensor: Versuchsaufbau 1 - Gesamtwiderstand über der Versorgungsspannung]] |
Zeile 637: | Zeile 706: | ||
− | [[Bild: | + | [[Bild:Lichtsensor Versuchsaufbau 2.png|framed|center|Lichtsensor: Versuchaufbau 2]] |
Zeile 682: | Zeile 751: | ||
Im Versuchsaufbau wurde der Wert von 2,25 Volt für U<sub>R7</sub> nicht überschritten. | Im Versuchsaufbau wurde der Wert von 2,25 Volt für U<sub>R7</sub> nicht überschritten. | ||
− | === | + | ===Batterie-Sensor=== |
====Schaltungsauszug==== | ====Schaltungsauszug==== | ||
− | |||
+ | [[Bild:CCRP5 Batteriesensor.png|framed|center|Batteriespannungssensor]] | ||
− | |||
+ | Nachfolgend eine alphabetische Auflistung der im Schaltungsauszug verwendeten Leitungskürzel und deren Zuordnungen: | ||
− | |||
{| {{Blauetabelle}} | {| {{Blauetabelle}} | ||
+ | |BAT | ||
+ | |Batteriesensor | ||
+ | |- | ||
|GND | |GND | ||
|Masse | |Masse | ||
|- | |- | ||
− | | | + | |VBA |
− | | | + | |Batteriespannung |
− | + | ||
− | + | ||
− | + | ||
|} | |} | ||
====Schaltungsbeschreibung==== | ====Schaltungsbeschreibung==== | ||
− | Die | + | Die beiden Widerstände R6 und R7 bilden einen Spannungsteiler mit einem Gesamtwiderstand von 4kOhm. Dabei fließt ein Strom von I<sub>Ges</sub> = U<sub>VBA</sub> / R<sub>Ges</sub> = 7,2 V / 4000 Ohm = 1,8 mA. Dementsprechend fallen an R6 (U<sub>R6</sub> = R<sub>6</sub> x I<sub>Ges</sub> = 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 (U<sub>VBA</sub> = U<sub>VCC</sub> - U<sub>R6</sub> = 7,2 V - 5,4 V =) 1,8 V. Diese Spannung entspricht einem Wandlerwert von (255 x U<sub>BAT</sub> / U<sub>REF</sub> = 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==== | ====Schaltungsauszug==== | ||
− | + | Die Schaltung des Ladestromsensors (grau hinterlegt) ist identisch mit der Schaltung des Batteriesensors. | |
− | [[Bild:CCRP5 | + | [[Bild:CCRP5 Ladestromsensor.png|framed|center|Ladestromsensor]] |
Zeile 723: | Zeile 795: | ||
|Masse | |Masse | ||
|- | |- | ||
− | | | + | |LAD |
− | | | + | |Ladestrom |
|- | |- | ||
− | | | + | |VBA |
− | | | + | |Batteriespannung |
+ | |- | ||
+ | |VCC | ||
+ | |Versorgungsspannung | ||
|} | |} | ||
====Schaltungsbeschreibung==== | ====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==== | ====Schaltungsauszug==== | ||
− | + | Da beide Antriebe identisch sind, wird im folgenden nur der rechte behandelt. Die Seitenbezeichnungen beziehen sich hier auf die Fahrtrichtung. | |
− | + | [[Bild:CCRP5 Antrieb.png|framed|center|Antrieb]] | |
− | |||
+ | Nachfolgend eine alphabetische Auflistung der im Schaltungsauszug verwendeten Leitungskürzel und deren Zuordnungen: | ||
− | + | {| {{Blauetabelle}} | |
+ | |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. | |
+ | {|{{Blauetabelle}} | ||
+ | |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 U<sub>GS</sub> = 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. | ||
− | [[Bild:CCRP5 | + | 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 U<sub>GS</sub> 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 U<sub>GS</sub> 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. | ||
+ | |||
+ | |||
+ | [[Bild:CCRP5 Motorstromsensor.png|framed|center|Motorstromsensor]] | ||
Zeile 763: | Zeile 894: | ||
|Masse | |Masse | ||
|- | |- | ||
− | | | + | |IAN |
− | | | + | |Spannungsabfall R20, Antrieb |
|- | |- | ||
|SV2 | |SV2 | ||
|Spannungsversorgung, Zweig 2 | |Spannungsversorgung, Zweig 2 | ||
+ | |- | ||
+ | |MTS | ||
+ | |Motorstromsensor | ||
|} | |} | ||
====Schaltungsbeschreibung==== | ====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 | |
+ | <pre> | ||
+ | '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 | ||
+ | '---------------------------------------------------------------------------- | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | *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. | ||
+ | |||
+ | <pre> | ||
+ | '-------------------------- | ||
+ | '------ 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) | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | *Programmteil | ||
+ | |||
+ | Einem Initialisierungsteil folgt hier die für µC typische Endlosschleife, in welcher das eigentliche Programm in ständiger Wiederholung abgearbeitet wird. | ||
+ | |||
+ | <pre> | ||
+ | '---------- 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 | ||
+ | '------------------------------------------- | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | *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. | ||
+ | |||
+ | <pre> | ||
+ | '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 | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | Anschließend wird noch das Maschinensprache-Programm P5DRIV.S19 geladen | ||
+ | |||
+ | <pre> | ||
+ | '---------COM/NAV GERÄTEREIBER ------------- | ||
+ | syscode "p5driv.s19" | ||
+ | </pre> | ||
+ | |||
+ | Auf der Website von AREXX findet man das Assemblerlisting dieses Programms: | ||
+ | |||
+ | <pre> | ||
+ | ********************************************************************************* | ||
+ | * | ||
+ | * 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 | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | 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. | ||
+ | |||
+ | |||
+ | [[Bild:CCRP5-Schieberegister an Hauptprozessor.png|735px|center|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: | ||
+ | |||
+ | |||
+ | [[Bild:CCRP5-Schieberegister an Hauptprozessor Bitfolge.png|center|framed|Bitfolge "setzen"]] | ||
+ | |||
+ | |||
+ | Folgende Tabelle gibt Auskunft über die programmierbaren Ports: | ||
{| {{Blauetabelle}} | {| {{Blauetabelle}} | ||
− | | | + | |µ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: | |
+ | <pre> | ||
+ | '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 | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | 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: | ||
+ | |||
+ | |||
+ | [[Bild:CCRP5-Schieberegister an Hauptprozessor Bitfolge II.png|center|framed|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 <u>Hauptprogrammes</u> 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>: | ||
+ | |||
+ | |||
+ | [[Bild:CCRP5 Flussdiagramm 1.png|center|framed|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: | ||
+ | |||
+ | <pre> | ||
+ | '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 | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | 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: | ||
+ | |||
+ | <pre> | ||
+ | '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 | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | |||
+ | Läßt sich das Einschalten der LED nicht auch so elegant in einer Schleife zusammenfassen? | ||
+ | |||
+ | |||
+ | Jein - mit der bedingten Verzweigung: | ||
+ | |||
+ | |||
+ | [[Bild:CCRP5 Flussdiagramm 2.png|center|framed|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: | ||
+ | |||
+ | <pre> | ||
+ | '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 | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | |||
+ | 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. | ||
+ | |||
+ | |||
+ | <pre> | ||
+ | define LED1 &B00001000 | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | Analog dazu ergeben sich folgende Konstanten für die Ausgänge des Schieberegisters im CCRP5: | ||
{| {{Blauetabelle}} | {| {{Blauetabelle}} | ||
− | | | + | |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 | |
+ | <pre> | ||
+ | 1 SHL N | ||
+ | </pre> | ||
+ | bei jedem Durchlauf der Schleife einen anderen Wert an: | ||
− | + | {| {{Blauetabelle}} | |
+ | |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, | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | == | + | {| {{Blauetabelle}} |
+ | |A | ||
+ | |0 | ||
+ | |0 | ||
+ | |1 | ||
+ | |1 | ||
+ | |- | ||
+ | |B | ||
+ | |0 | ||
+ | |1 | ||
+ | |0 | ||
+ | |1 | ||
+ | |- | ||
+ | |A^B | ||
+ | |0 | ||
+ | |0 | ||
+ | |0 | ||
+ | |1 | ||
+ | |- | ||
+ | |} | ||
+ | |||
+ | so erhält man folgende Ergebnisse: | ||
+ | |||
+ | {| {{Blauetabelle}} | ||
+ | |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: | ||
+ | |||
+ | <pre> | ||
+ | DATA=LED1 and (1 shl N) | ||
+ | </pre> | ||
+ | |||
+ | Der Code für ein Programm zum Einschalten der LED1 sähe auf diese Weise so aus: | ||
+ | |||
+ | <pre> | ||
+ | '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 | ||
+ | </pre> | ||
+ | |||
+ | 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. | ||
+ | |||
+ | <pre> | ||
+ | define SHIFT_REGISTER byte | ||
+ | </pre> | ||
+ | |||
+ | 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: | ||
+ | |||
+ | <pre> | ||
+ | '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 | ||
+ | </pre> | ||
+ | |||
+ | Für das Blinken der LED1 ergibt sich somit folgender Programmcode: | ||
+ | |||
+ | <pre> | ||
+ | '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 | ||
+ | </pre> | ||
+ | |||
+ | Wahrheitstabelle der Exklusiv-ODER-Verknüpfung (XOR): | ||
+ | |||
+ | {| {{Blauetabelle}} | ||
+ | |A | ||
+ | |0 | ||
+ | |0 | ||
+ | |1 | ||
+ | |1 | ||
+ | |- | ||
+ | |B | ||
+ | |0 | ||
+ | |1 | ||
+ | |0 | ||
+ | |1 | ||
+ | |- | ||
+ | |A⊕B | ||
+ | |0 | ||
+ | |1 | ||
+ | |1 | ||
+ | |0 | ||
+ | |- | ||
+ | |} | ||
==Technische Daten== | ==Technische Daten== | ||
Zeile 859: | Zeile 2.568: | ||
Höhe ca. 90 mm<br/> | Höhe ca. 90 mm<br/> | ||
Gewicht ca. 750 g (mit sechs AA-Zellen)<br/> | Gewicht ca. 750 g (mit sechs AA-Zellen)<br/> | ||
+ | Geschwindigkeit ca. 22 cm/s<br/> | ||
Stromaufnahme ca. 400 mA (im leerlaufenden Fahrbetrieb mit ANTRIEB.BAS) | Stromaufnahme ca. 400 mA (im leerlaufenden Fahrbetrieb mit ANTRIEB.BAS) | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
==Autor/en== | ==Autor/en== | ||
Zeile 882: | Zeile 2.581: | ||
==Weblinks== | ==Weblinks== | ||
− | * [http:// | + | * [http://www2.produktinfo.conrad.com/cgi-bin/dlc/dlc.cgi?art=950572&lang=&dokument=&page=main&searchtype=volltext Alle Unterlagen zur C-Control 1 von Conrad Electronic] |
− | * [http://www2.produktinfo.conrad.com/cgi-bin/dlc/dlc.cgi?art=190333&lang=&dokument=&page=main&searchtype=volltext Alle Unterlagen von Conrad Electronic] | + | * [http://www2.produktinfo.conrad.com/cgi-bin/dlc/dlc.cgi?art=190333&lang=&dokument=&page=main&searchtype=volltext Alle Unterlagen zum CCRP5 von Conrad Electronic] |
+ | |||
+ | |||
* [http://www.roboternetz.de/phpBB2/viewforum.php?f=43 Roboternetz CCRP5 Forum] | * [http://www.roboternetz.de/phpBB2/viewforum.php?f=43 Roboternetz CCRP5 Forum] | ||
− | * [http://www. | + | * [http://www.itis.dl.am Projekt ITIS mit dem CCRP5 als Basis] |
− | + | ||
− | + | ||
* [http://www.conrad.de/goto.php?artikel=190333 CCRP5 bei Conrad Electronik] | * [http://www.conrad.de/goto.php?artikel=190333 CCRP5 bei Conrad Electronik] | ||
+ | * [http://www.c-control.de/c-robotics/ccrp5/ccrp5.html CCRP5-Seite bei C-Control.de (Conrad Electronic)] | ||
+ | * [http://www.arexx.com/arexx.php?cmd=system&cparam=set_pg_lang(p_rp5.dat|DE|true) CCRP5-Seite bei AREXX] | ||
+ | |||
+ | |||
+ | * [http://www.eam-magazin.de/ EAM-Magazin] | ||
* [http://ccintern.dharlos.de/ C-Control intern] | * [http://ccintern.dharlos.de/ C-Control intern] | ||
[[Kategorie:Robotikeinstieg]] | [[Kategorie:Robotikeinstieg]] | ||
[[Kategorie:Praxis]] | [[Kategorie:Praxis]] |
Aktuelle Version vom 3. Juli 2007, 12:48 Uhr
Inhaltsverzeichnis
- 1 Einleitung
- 2 Mechanik
- 3 Elektromechanik
- 4 Elektronik
- 5 Software
- 6 Technische Daten
- 7 Autor/en
- 8 Siehe auch
- 9 Weblinks
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
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:
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.
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.
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.
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.
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.
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.
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
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.).
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.
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.
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.
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.
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:
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
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.
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.
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.
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.
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:
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:
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>:
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:
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 |
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
- Alle Unterlagen zur C-Control 1 von Conrad Electronic
- Alle Unterlagen zum CCRP5 von Conrad Electronic