Netze [Material] [historische Beispiele] [Einstieg] [Grundbegriffe] [Netzhardware] [Universal-Empfänger] [mini-Sender] [mini-Empfänger] [miniEthernet] [Transceiver] [Fehlererkennung] [Fehlerbehandlung] [Bus] [Rahmen] [Medium Access Control] [Routing] [Schichtenmodell] [Sockets] [Dienste im Internet] [Real-Experimente] [Sicherheit] [Codes] [Programme] [Hardware] [Protokolle] [Glossar] [Bautipps] [Unterricht]
Pfad: [Startseite] / [Fächer] / [Informatik] / [Netze] / [Transceiver]
Hohenstaufen-Gymnasium
Kaiserslautern
Autor: mk
Letzte Änderung dieser Seite: 10.12.2007 08:58:01  2428
Transceiver

Transceiver

Ein Transceiver ist gleichzeitig Sender und Empfänger.

Um den miniSender und den miniEmpfänger in einem Programm zu vereinen, müssen mindestens zwei Threads parallel laufen. Es soll nun der Empfänger als Thread implementiert werden.

Empfänger als Thread

  1. Unit classes einbinden
  2. Typvereinbarung hinzufügen, z.B. TEmpf = class(TThread)
  3. Variable vereinbaren, z.B. Empf : TEmpf;
  4. Objekt Empf erzeugen, wegen Parameterübergabe zunächst suspended
  5. Prozedur execute anpassen, dabei fällt auf, dass baud und NetzHW benötigt werden
  6. baud und NetzHW plus benötigte Set-Methoden einbauen
  7. parameterlose update-Prozedur zur Ausgabe schreiben
  8. update-Prozedur mit synchronize in execute einbauen
  9. Startprozedur für Thread schreiben, zuerst Parameterübergabe, dann resume

Sender ebenfalls als Thread

Gui zu Transceiver 1 Es zeigt sich, dass das Programm (transceiver0.zip) noch nicht wunschgemäß arbeitet. Eigentlich klar, wenn man dem main-Thread keine Zeit für die VCL-Komponenten einräumt. Daher muss auch der Sender als Thread implementiert werden. Zumindest im vorliegenden Testfall bekam man erst befriedigende Ergebnisse, wenn die Zeit-Granularität mit timeBeginPeriod(1); auf 1ms gestellt wurde. Am Ende des Programms (transceiver1.zip) sollte diese Einstellung mit timeEndPeriod(1); zurückgenommen werden. Die beiden Prozeduren benötigen die Unit mmsystem.

Der Quelltext

unit uTransceiver1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, mTNetzHW, mmsystem;

type
  TEmpf  = class(TThread)
  private
    baud   : integer;
    b      : byte;
    NetzHW : TNetzHW;
  public
    procedure execute; override;
    procedure SetBaud(pBaud : integer);
    procedure SetNetzHW(pNetzHW : TNetzHW);
    procedure update;
  end;

  TSend  = class(TThread)
  private
    baud      : integer;
    sendetext : String;
    NetzHW    : TNetzHW;
  public
    procedure execute; override;
    procedure SetBaud(pBaud : integer);
    procedure SetNetzHW(pNetzHW : TNetzHW);
    procedure SetSendeText(pText : string);
  end;

  TForm1 = class(TForm)
    eBaud: TEdit; lBaud2: TLabel;
    bSende: TButton;
    mSend: TMemo;
    mEmpf: TMemo;
    eEmpf: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure eEmpfClick(Sender: TObject);
    procedure bSendeClick(Sender: TObject);
  private
    NetzHW : TNetzHW;
    Empf   : TEmpf;
    Send   : TSend;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TEmpf.execute;
var
  bitzeit : integer;
  i,j     : byte;
begin
  bitzeit := round(1000/baud);
  while not Terminated do
  begin
    // warten auf StartBit
    while Not NetzHW.GetEin do sleep(0);
    // 1,5 Bitlängen warten
    sleep(bitzeit+bitzeit div 2);
    // Datenbits einlesen
    b := 0;
    for i := 7 downto 0 do
    begin
      b := b shl 1;
      if NetzHw.GetEin then Inc(b);
      sleep(bitzeit);
    end;
    synchronize(update);
  end;
end;

procedure TEmpf.SetBaud(pBaud : integer);
begin
  baud := pBaud;
end;

procedure TEmpf.SetNetzHW(pNetzHW : TNetzHW);
begin
  NetzHW := pNetzHW;
end;

procedure TEmpf.update;
begin
  // Zeichen anhängen
  Form1.mEmpf.Text := Form1.mEmpf.Text+chr(b);
  // Bildaufbau erzwingen
  Form1.Refresh;
end;

procedure TSend.execute;
var
  bitzeit : integer;
  b,i,j   : byte;
begin
  bitzeit := round(1000/baud);
  for j := 1 to Length(SendeText) do
  begin
    b := ord(SendeText[j]);
    // StartBit
    NetzHW.SetAus(true); sleep(bitzeit);
    // Datenbits
    for i := 7 downto 0 do
    begin
      NetzHW.SetAus(odd(b shr i)); sleep(bitzeit);
    end;
    // StoppBit
    NetzHW.SetAus(false); sleep(bitzeit);
  end;
end;
procedure TSend.SetBaud(pBaud : integer);
begin
  baud := pBaud;
end;

procedure TSend.SetNetzHW(pNetzHW : TNetzHW);
begin
  NetzHW := pNetzHW;
end;

procedure TSend.SetSendeText(pText : string);
begin
  SendeText := pText;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  timeBeginPeriod(1);
  NetzHW := TNetzHW.Create;
  Empf := TEmpf.Create(true); // suspended starten 
  netzHW.Start(1);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Empf.Terminate;
  NetzHW.Free;
  timeEndPeriod(1);
end;

procedure TForm1.eEmpfClick(Sender: TObject);
begin
  Empf.SetBaud(StrToInt(eBaud.text));
  Empf.SetNetzHW(NetzHW);
  Empf.FreeOnTerminate := true;
  Empf.Resume;
end;

procedure TForm1.bSendeClick(Sender: TObject);
begin
  Send := TSend.Create(true);
  Send.SetBaud(StrToInt(eBaud.text));
  Send.SetSendeText(mSend.Text);
  Send.SetNetzHW(NetzHW);
  Send.FreeOnTerminate := true;
  Send.Resume;
end;

end.

Technischer Tipp

Man kann Windows zu einem entscheidend - für unsere Zwecke - besseren Zeitverhalten veranlassen, wenn man mit dem Taskmanager (Strg-Alt-Entf) dem Prozess mit der rechten Maustaste eine höhere Priorität zuweist. Die Priorität 'Echtzeit' erreicht man nur mit Administratorrechten.

Valid XHTML 1.0 Strict