Datenfernübertragung

An vielen Schulen ist das Programmpaket MS-Works installiert. Dieses Programm ermöglicht Datenfernübertragung zwischen zwei Rechnern auf einfache Weise, die Rechner müssen nur mit einem Nullmodemkabel über die serielle Schnittstelle miteinander verbunden werden. Das funktioniert sehr gut, aber der Nachteil dieser Art der Datenübertragung ist, daß der Betreiber nicht erkennen kann, wie die Übertragung technisch funktioniert. Die Kombiampel bietet die Möglichkeit, dies auf einfache Weise sichtbar zu machen, indem zunächst ein Bit, dann ein Byte und zuletzt ein ganzer Text gesendet und empfangen werden.


Ferngesteuert ein- und ausschalten, der Optokoppler

Die einfachste Art der Übertragung von Daten mit Hilfe zweier Kombiampeln von einem Rechner auf den anderen ist, die beiden Kombiampeln so aufeinander zu legen, daß die LED Bit 7 der einen Ampel den Sensor der anderen Ampel beleuchten kann.

Auf dem Senderrechner wird das Programm BITSEND.PAS gestartet, das die LED 7 im Sekundentakt blinken läßt.

PROGRAM Bitsend;
USES Komampel;

BEGIN
	Lauflicht_ein;
	REPEAT
		binaus ('10000000');
		warte(1);
		binaus ('00000000');
		warte (1);
	UNTIL Tastatur;
END.
BITSEND.PAS

Auf dem Empfängerrechner wird das Programm BITEMPF.PAS gestartet, das den Sensor abfragt und die LED 0 einschaltet, wenn der Sensor beleuchtet ist und sie ausschaltet, wenn der Sensor dunkel ist.

program Bitempfaenger;
uses komampel;

begin
  lauflicht_ein;
  repeat
    if sensor then
      begin
        binaus('00000001');
      end
    else
      begin
        binaus('00000000');
      end;
  until tastatur;
end.
BITEMPF.PAS

Die Rollen der beiden Rechner lassen sich leicht vertauschen.






Das Prinzip der seriellen Datenübertragung

Sollen mehr als ein Bit über eine Leitung übertragen werden, so kann das nur zeitlich nacheinander geschehen. Soll z.B. das parallele Bitmuster "10101010" seriell übertragen werden, so muß zunächst festgelegt werden, wann die Übertragung beginnt. Wenn keine Datenübertragung stattfindet, hat die Leitung den Wert 0. Um anzuzeigen , daß eine Datenübertragung stattfinden soll, wird als erstes ein "1"-Signal als Startbit gesendet. Danach folgen in festem Zeitabstand die Zustände der einzelnen Datenbits, beginnend mit dem niederwertigen Bit 0. Den Abschluß bildet das Stopbit mit dem Wert "0". Danach ist die Leitung wieder frei für die nächste Übertragung. Für jedes Bit steht eine bestimmte Zeit, die Bitzeit, zur Verfügung.

Zeitablauf beim Senden:

Der Empfänger muß die seriell übertragenen Bits wieder in das richtige parallele Bitmuster umwandeln. Der Empfänger wartet zunächst, bis der Startimpuls mit dem Wert "1" kommt und beginnt dann mit dem Einlesen des darauf folgenden Bitmusters. Das Einlesen muß nun im gleichen Takt der Bitzeit geschehen, wie beim Senden. Um die Werte der einzelnen Bits zuverlässig erkennen zu können, wird immer in der Mitte der zugehörigen Bitzeit nachgesehen, welchen Wert das gerade empfangene Datenbit hat. Um nach dem Startimpuls die Mitte des Bits 0 zu erreichen, muß der Empfänger zunächst die 1,5 fache Bitzeit abwarten, bis er das Bit liest. Danach wartet er 7 mal die Bitzeit ab und liest dann jeweils die Datenbits 1 bis 7 ein. Den Abschluß bildet noch einmal eine Bitzeit, um in das Stopbit zu kommen. Das Bit wird aber nicht mehr ausgewertet. Während des Einlesens ordnet der Empfänger die empfangenen Bits wieder als korrektes paralleles Bitmuster an.

Zeitablauf beim Empfang:






Die serielle Datenübertragung mit der Kombiampel

Für die folgenden Programme werden die beiden Kombiampeln so nebeneinander gelegt, wie es die Abbildung zeigt. Die Leuchtdioden sind dann auf beiden Kombiampeln gut zu sehen. Der externe Fotosensor wird an den Schaltereingang angeschlossen. Bei den Empfangsprogrammen wird die Sensorabfrage gegen die Schalterabfrage getauscht.

Senden eines Bytes

Das erste Sendeprogramm BYTESEND.PAS für ein Byte setzt den oben geschilderten Zeitablauf unmittelbar in Software um.

program byte_senden;
uses komampel;

begin
  lauflicht_ein;    (* Ausgabe des Bitmuster 01010101 auf Bit 0 *)
  binaus('0000000');   (*  Startimpuls senden *)
  warte(1);
  binaus('00000000'); (*  Bit 0 senden *)
  warte(1);
  binaus('00000001'); (*  Bit 1 senden *)
  warte(1);
  binaus('00000000'); (*  Bit 2 senden *)
  warte(1);
  binaus('00000001'); (*  Bit 3 senden *)
  warte(1);
  binaus('00000000'); (*  Bit 4 senden *)
  warte(1);
  binaus('00000001'); (*  Bit 5 senden *)
  warte(1);
  binaus('00000000'); (*  Bit 6 senden *)
  warte(1);    
  binaus('00000001'); (*  Bit 7 senden *)
  warte(1);
  binaus('00000000'); (*  Stopbit senden*)
  warte(1);
end.
BYTESEND.PAS

Mit dem Programm OSZI.EXE auf der Diskette kann der Impulsverlauf des obigen Programms als Oszillogramm, wie in der Grafik dargestellt, auf dem Bildschirm verfolgt werden. Im selben Verzeichnis wie das Programm OSZI.EXE muß auch der passende Grafiktreiber vorhanden sein ( z.B. EGAVGA.BGI ). Die Treiber sind alle auf der Diskette zu finden.





Empfangen eines Bytes

Das erste Empfangsprogramm BYTEEMPF.PAS für ein Byte bildet den Zeitablauf auf die gleiche Weise ab.

Für eine saubere Übertragung müssen die Bitzeiten auf dem Sende- und Empfangsrechner übereinstimmen.

program byte_empfaenger;
uses komampel;

var  empfangsbyte : integer;

begin
  lauflicht_ein;
  empfangsbyte := 0;
  repeat until schalter; (* warten, bis der Startimpuls kommt.*)
  warte(1.5);   (* die Mitte des ersten Datenbits abwarten *)
  if schalter then               (* Bit 0 einlesen *)
    begin
      empfangsbyte := empfangsbyte + 128;
    end;
  ausgeben(empfangsbyte);
  warte(1);
  empfangsbyte := empfangsbyte DIV 2;
  if schalter then               (* Bit 1 einlesen *)
    begin
      empfangsbyte := empfangsbyte + 128;
    end;
  ausgeben(empfangsbyte);
  warte(1);
  empfangsbyte := empfangsbyte DIV 2;
  if schalter then               (* Bit 2 einlesen *)
    begin
      empfangsbyte := empfangsbyte + 128;
    end;
  ausgeben(empfangsbyte);
  warte(1);
  empfangsbyte := empfangsbyte DIV 2;
  if schalter then               (* Bit 3 einlesen *)
    begin
      empfangsbyte := empfangsbyte + 128;
    end;
  ausgeben(empfangsbyte);
  warte(1);
  empfangsbyte := empfangsbyte DIV 2;
  if schalter then               (* Bit 4 einlesen *)
    begin
      empfangsbyte := empfangsbyte + 128;
    end;
  ausgeben(empfangsbyte);
  warte(1);
  empfangsbyte := empfangsbyte DIV 2;
  if schalter then               (* Bit 5 einlesen *)
    begin
      empfangsbyte := empfangsbyte + 128;
    end;
  ausgeben(empfangsbyte);
  warte(1);
  empfangsbyte := empfangsbyte DIV 2;
  if schalter then                (* Bit 6 einlesen *)
    begin
      empfangsbyte := empfangsbyte + 128;
    end;
  ausgeben(empfangsbyte);
  warte(1);
  empfangsbyte := empfangsbyte DIV 2;
  if schalter then                 (* Bit 7 einlesen *)
    begin
      empfangsbyte := empfangsbyte + 1;
    end;
  ausgeben(empfangsbyte);
  warte(1);                        (* Stopbit abwarten *)
end.
BYTEEMPF.PAS



Senden eines Bytes auf elegantere Art

Das folgende Sendeprogramm BYTESENS.PAS erlaubt es, eine beliebige Zahl von 0 bis 255, die auf dem Senderechner eingegeben wird, auf den Empfangsrechner zu übertragen. Dabei ist die Sendung der Datenbits in eine Schleife gekleidet.

program byte_senden;
uses komampel;

VAR
  ausgabezahl : integer;
  bitzaehler : integer;

begin
  lauflicht_ein;
  write('Welche Zahl soll übertragen werden ? ');
  readln(ausgabezahl);
  binaus('0000001'); (* Startimpuls*)
  warte(1);
  bitzaehler := 8;
  repeat
    ausgeben(ausgabezahl);
    ausgabezahl := ausgabezahl DIV 2;
    warte(1);
    bitzaehler := bitzaehler - 1;
  until bitzaehler = 0;
  binaus('0000000'); (* Stopbit *)
  warte(1);
end.
BYTESENS.PAS




Empfangen eines Bytes auf elegantere Art

Das Empfangsprogramm BYTEEMPS.PAS empfängt das gesendete Byte und schreibt die empfangene Zahl sowie das zugehörige ASCII-Zeichen auf den Bildschirm. Auch hier ist das Einlesen der Datenbits in eine Schleife gekleidet.

program byte_empfaenger;
uses komampel;
var
  empfangsbyte : integer;
  bitzaehler : integer;

begin
  lauflicht_ein;
  empfangsbyte := 0;
  bitzaehler := 8;
  repeat until schalter;(* warten, bis der Startimpuls kommt. *)
  warte(1.5);           (* die Mitte des ersten Datenbits abwarten *)
  repeat
    empfangsbyte := empfangsbyte div 2;    	
              (* Empfangene Bits um eine Stelle nach unten schieben *)
    if schalter then           (* Datenbit einlesen *)
      begin
        empfangsbyte := empfangsbyte + 128;
      end;
    ausgeben(empfangsbyte);
    warte(1);
    bitzaehler := bitzaehler - 1;
  until bitzaehler = 0;
  writeln('Empfangener Zahlenwert: ',empfangsbyte);
  writeln('Empfangenes Zeichen : ',chr(empfangsbyte));
  repeat until tastatur;
end.
BYTEEMPS.PAS




Übertragen von einzelnen Zeichen

Zur Vorbereitung auf die angestrebte Textübertragung hier ein Programm "ZEICHSEN.PAS" zur Übertragung eines Zeichens von der Tastatur des einen Rechners auf den Bildschirm des anderen Rechners. Als Empfänger dient wieder das Programm BYTEEMPS.PAS, das ja auch das Zeichen ausgibt.

program byte_senden;
uses komampel, crt;

VAR
  ausgabezahl : integer;
  bitzaehler : integer;
  zeichen : char;

begin
  lauflicht_ein;    
  write('Druecke eine Taste auf der Tastatur ');
  zeichen := readkey;
  ausgabezahl := ord(zeichen);
  writeln;
  writeln(ausgabezahl);
  binaus('00000001'); (* Startimpuls*)
  warte(1);
  bitzaehler := 8;
  repeat
    ausgeben(ausgabezahl);
    ausgabezahl := ausgabezahl div 2;
    warte(1);
    bitzaehler := bitzaehler - 1;
  until bitzaehler = 0;
  binaus('00000000'); (* Stopbit *)
  warte(1);
end.
ZEICHSEN.PAS




Übertragen von Text

Das Programmpaar TEXTSEND.PAS und TEXTEMPF.PAS bildet, aufbauend auf BYTESENS.PAS und BYTEEMPS.PAS, ein serielles Kommunikationssystem zwischen zwei Rechnern, bei dem sich die beteiligten Schüler beliebige Texte von der Tastatur des Senderechners auf den Bildschirm des Empfängers übertragen können.

program text_senden;
uses komampel,crt;

const  pause = 0.1;

VAR  ausgabezeichen : char;

procedure senden(ausgabezahl:integer);
  var  bitzaehler : integer;
  begin
    binaus('00000001'); (* Startimpuls*)
    warte(pause);
    bitzaehler := 8;
    repeat
      ausgeben(ausgabezahl);
      ausgabezahl := ausgabezahl div 2;
      warte(pause);
      bitzaehler := bitzaehler - 1;
    until bitzaehler = 0;
    binaus('00000000'); (* Stopbit *)
    warte(1);
  end;

begin
  lauflicht_ein;    
    writeln('Gib eine Textzeile ein : ');
  ausgabezeichen := ' ';
  repeat
    ausgabezeichen := readkey;
    write(ausgabezeichen);
    senden(ord(ausgabezeichen));
  until ausgabezeichen < #31;
end.
TEXTSEND.PAS



program text_empfangen;
uses komampel;

const  pause = 0.1;

var  empfangszeichen : integer;

procedure empfaenger(var empfangsbyte : integer);
  var  bitzaehler : integer;
  begin
    empfangsbyte := 0;
    bitzaehler := 8;
    repeat until schalter;(* warten, bis der Startimpuls kommt. *)
    warte(1.5*pause); (* die Mitte des ersten Datenbits abwarten *)
    repeat                                                          
      empfangsbyte := empfangsbyte div 2; 
            (* Empfangene Bits um eine Stelle nach unten schieben *)
      if schalter then             (* Datenbit einlesen *)
        begin
          empfangsbyte := empfangsbyte + 128;
        end;
      ausgeben(empfangsbyte);
      warte(pause);
      bitzaehler := bitzaehler - 1;
    until bitzaehler = 0;
  end;

begin
  lauflicht_ein;
  repeat
    empfaenger(empfangszeichen);
    write(chr(empfangszeichen));
  until (empfangszeichen < 32) or tastatur;
  repeat until tastatur;
end.
TEXTEMPF.PAS




Zurück zur Hauptseite

© Burkhard John, Volker Ludwig
Burkhard John
29.6.1999