Der integrierte UART ist ein universelles Mittel zum Datenaustausch mit dem PC, anderen Microcontrollern oder diversen
Geräten, die ebenfalls serielle Kommunikation beherrschen. Aber ohne einiges an Zusatzbeschaltung ist der UART immer
drahtgebunden und damit für mobile Geräte von Datenloggern über Wetterstationen bis hin zu Fernbedienungen ungeeignet.
Dabei ist das integrierte serielle Protokoll zur drahtlosen Kommunikation sehr gut geeignet, da man zum einen die
ohnehin vorhandene eingebaute Hardware benutzen kann, zum anderen die zu ergänzende Hardware flexibel eingesetzen oder
ohne Änderungen an der Software das Übertragungsverfahren austauschen kann. |
Eine Möglichkeit zur Datenübermittlung besteht in der Verwendung von Ultraschall-Kapseln. Einen Sender zu bauen, der das Ausgangssignal TxD auf einer Ultraschallkapsel ausgibt, ist nicht kompliziert. | |
Zunächst wird das Signal moduliert, das heißt in eine Schwingung umgesetzt, deren Frequenz mit der Ultraschallsendekapsel und dem
Empfänger besonders gut gesendet/empfangen werden kann. Bei Ultraschallkapseln von Murata - einer der wenigen Hersteller, auch
die Conrad-Kapseln sind von diesem - liegt die Übertragungsfrequenz bei ziemlich genau 40 kHz.
Um die 40 kHz zu erzeugen wird ein 555 eingesetzt. Damit dieser die Versorgungsspannung nicht mit Impulsspitzen 'verunreinigt',
wurde er hinter einem 22 Ohm-Widerstand platziert, ebenso wie ein Kondensator, der dessen Versorgungsspannung stabilisiert.
Das Eingangssignal wird moduliert, indem ein NAND-Gatter dieses sowie die ständig
|
erzeugte Schwingung zusammenführt. Die beiden als Inverter nachgeschalteten NAND-Gatter dienen dazu,
die Lautstärke des Signals zu erhöhen, indem die Amplitude des Signals
- vereinfacht gesagt - verdoppelt wird, indem nach jeder Halbschwingung High und Low auf beiden Seiten der Sendekapsel
vertauscht werden, anstatt nur auf einer Seite zwischen High und Low zu wechseln. Die Schaltung mit den NAND-Gattern
ist zwei mal vorhanden, um die Belastung für ein einzelnes Logikgatter zu verringern - zudem besitzt ein 7400 sowieso
4 Gatter. Zum Abgleich hängt man an den Empfänger einfach eine LED (mit Vorwiderstand natürlich!), platziert ihn ein Stückchen vom Sender entfernt, legt High an den Eingang des Senders und spielt so lange an R2, bis man die maximale Reichweite erzielt hat. Besser ist es natürlich, ein Oszilloskop zu benutzen. zurück zum Anfang |
Der Empfänger bildet das Gegenstück zum Sender, er muß die empfangenen Signale verstärken und wieder demodulieren,
damit die 40 kHz-Schwingungen wieder zu vom Controller verwertbaren Signalen werden. | |
Ein Transistor BC547A dient als Vorverstärker. Damit das eintreffende Signal im Arbeitspunkt des Transistors liegt, wird er mit R1 und R2 'vorgespannt'. Dessen Ausgangssignal wird mit einem Operationsverstärker in Differenzverstärkerschaltung weiter verstärkt, und dann mit einem 74HCT14 (6x invertierender Schmitt-Trigger) zuerst in TTL-konforme Pegel umgewandelt. Durch die Diode lädt sich der Kondensator sehr schnell auf, durch den Widerstand entlädt es sich aber nur langsam wieder - so langsam, daß die Pause zwischen zwei Pulsen, die empfangen werden, nicht ausreichen, um den dahintergeschalteten invertierenden Trigger auf Low zu bringen. Nach mehr als 2 Pulsen ist er aber entladen: die 40 kHz-Schwingung hat aufgehört, der Trigger wechselt auf High. Auf diese Weise wird das übertragene Signal demoduliert. Der nachfolgende Inverter wandelt das Signal wieder in TTL-Pegel, und der danach invertiert ihn wieder. Dadurch ist es möglich, auch invertiert gesendete Signale richtig auszugeben. |
Geeicht wird der Empfänger, indem man mit Hilfe eines Multimeters am Ausgang des Operationsverstärkers
R5 so einstellt, daß der Ausgang grade auf dem niedrigeren Spannungslevel liegt (kein TTL-Pegel am Ausgang!).
zurück zum Anfang |
Die Datenübertragung per Infrarot geschieht im Prinzip genauso wie die mit Ultraschall, mit dem Unterschied,
daß die Modulationsfrequenz 38 statt 40 kHz beträgt. Ansonsten hat der Sender fast den gleichen Aufbau.
| |
Die serielle Schnittstelle des Microcontrollers ist ohne Datensignal auf High geschaltet. Damit nicht unnötig Strom
verschwendet wird, wird das Signal zuerst invertiert, da ansonsten in Idle-Zustand der Leitung ständig gesendet würde.
Nebenbei würde dies einen eventuell implementierten Rückkanal behindern, der ebenfalls mit Infrarot sendet. Bei der
Erstellung des Ultraschallübertragers wurde dies allerdings vergessen, sollte aber unbedingt mit eingeplant werden! Die restlichen beiden NAND-Gatter des 7400 dienen als NOT-Gatter und zugleich als Treiber für die anzuschließenden Infrarot-LED's, bei denen auf keinen Fall die Vorwiderstände vergessen werden dürfen. |
In dieser Schaltung wurde ein Standard TTL-Gatter verwendet, dem der starken Pullup von 82 Ohm am Ausgang keine
Schwierigkeiten bereitet. Bei leistungsschwächeren Chipfamilien sollte jedoch ein größerer Widerstand verwandt werden, und
für den transprotablen und netzunabhängigen Einsatz sollte man zwecks Stromersparnis ohnehin auf eine Transistorschaltung
(Emitterfolger) als Ausgangstreiber ausweichen. Zum Testen ist es weiterhin sinnvoll, nicht nur eine oder mehrere
Infrarot-LED's sondern auch noch eine Low Current-LED zur direkten visuellen Kontrolle an den Ausgang zu schalten. Eingeregelt wird der Sender ebenso wie der Ultraschallsender: man kurbelt so lange an R2, bis man die maximale Reichweite erzielt, oder benutzt einen Frequenzzähler oder ein Oszilloskop. zurück zum Anfang |
Der Selbstbau eines Infrarotempfängers ist glücklicherweise nicht notwendig. Es ist nur zu empfehlen,
ein fertiges Modul, das schon die Infrarotdiode, Vorverstärker, Komparator, Tageslichtfilter und Pegelwandler
beinhaltet, zu verwenden, das schon für rund 6 DM zu haben ist. Der Nachbau war zumindest bei meinem Modul,
ausgelötet aus einem alten Reciver, nicht möglich, da bei dem eingesetzten SMD-IC die Beschriftung abgeschliffen war. Der Ausgang des Moduls liefert mit Hilfe eines 4k7-Pullups einen schönen normgerechten TTL-Pegel, der zudem schon invertiert ist, und wird einfach an RxD des Controllers angeschlossen. Mittlerweile gibt es zum Beispiel von Siemens (Infenion) auch komplette Empfänger in einem einzigen kleinen fest vergossenem Gehäuse in der Größe eines TO220-Transistors und kleiner. |
Einziger Nachteil dieser Module ist die nicht anpaßbare sehr hohe Empfindlichkeit, die den Einsatz in einer Lichtschranke wirksam verhindert, wenn man keinen exorbitant hohen Aufwand für Abschirmung und Spannungsstabilisierung betreibt. zurück zum Anfang |
Die Ansteuerung der Hardware besteht hauptsächlich in der Programmierung der seriellen Schnittstelle des 2051.
Wichtig ist allerdings noch die Fehlererkennung: wenn ein Byte empfangen wird, steht noch
lange nicht fest, ob die Übermittlung nicht zu früh abbrach oder einfach einzelne Bits 'gekippt' sind.
Darum wird in diesem Programmbeispiel zunächst der Datenwert und dann das XOR dieses Wertes mit 01010101b gesendet.
Der Empfänge dekodiert den empfangenen Datenstrom entsprechend, und wenn der zuvor gesendete Wert mit dem XOR des
jetzt empfangenen übereinstimmt, wurde er korrekt empfangen. Im Prinziep ist jede mathematische Methode zur
Fehlererkennung geeignet, mit Ausnahme des zweimaligen Sendend des Datenwertes: es kommt durchaus vor, daß das
selbe Bit zweimal verfälscht wird. Gesendet werden die Zahlen von 9 bis 0 mit einer kleinen Pause dazwischen. Und so sieht das Sendeprogramm aus: $NOMOD51 $INCLUDE (89C1051.MCU) ;Startadresse des Codes: org 0h ajmp start ser_Baud EQU 600 ; hier werden die Funktionen eingebunden $INCLUDE (time.inc) $INCLUDE (uart.inc) ;Stack auf 30h hinter Registerbänke und Bit-Area setzen start: mov sp,#30h ; UART und Timer1 einrichten call F_set_Baud setb SCON.5 main: mov R0,#10 main_back01: mov a,R0 dec a push ACC ; Daten senden pop ACC call F_serial_out ; zur Fehlerüberprüfung XOR von ACC und 01010101b senden xrl a,#01010101b push ACC mov a,#25 call F_wait_m pop ACC call F_serial_out mov a,#255 call F_wait_m call F_wait_m djnz R0,main_back01 ajmp main ENDFür den Einsatz als Fernbedienung kommt es nicht auf eine hohe Datenübertragungsrate an, es ist eigentlich nur notwendig, ein einzelnes Byte zu senden. Dieses sollte man dann eine Sekunde wiederholt übermitteln, um dem Benutzer allzu genaues Zielen zu ersparen. Dann muß man in der Software des Empfangsprogrammes noch dafür sorgen, daß mehrfach empfangene Werte erst nach einem gewissen Timeout wieder akzeptiert werden. Das Empfangsprogramm schickt empfangene Werte zur Kontrolle an P1. Und so sieht es aus (Ausschnitt): main: mov R0,1 ; das selbe wie mov R0,R1 ; das XOR der Daten entgegennehmen call F_serial_in ; auf korrekte Daten überprüfen mov R1,a xrl a,#01010101b cjne a,0,main mov P1,a ajmp mainUm die Empfangsreichweite weiter zu erhöhen, könnte man das serielle Protokoll im Porgramm auswerten, ohne den UART zu benutzen. Liegt während der Zeit, in der ein einzelnes Bit gesendet wurde, länger High als Low am Eingang, so war das empfangene Bit High, anderenfalls Low. Der UART nimmt einfach einen Wert aus der Mitte der Übertragung, wenn grade da ein kurzer Fehler auftrat, ist das empfangene Byte ungültig. zurück zum Anfang |