Announcement

Collapse
No announcement yet.

einzele/n Port/s der seriellen Schnittstelle ansprechen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • einzele/n Port/s der seriellen Schnittstelle ansprechen

    Hallo,
    ich habe den Hinweis erhalten, daß mein Wunsch nur mit assembler zu erfüllen wäre, da keine entspr. WIN API Funktion vorhanden sei.
    Ich will nur mit 2 Pins der Seriellen Schnittstelle umgehen ohne eine sereielle Kommunikation aufzubauen. Ein PIN soll Spannung (+5 V) an einen Temperatursensor liefern (TXD) und der andere (CTS) soll zum auslesen der Ergebnise verwendet werden. Ich habe anbei einen Programmausschnitt des Tubo-PASCAL-Programms für DOS angefügt. An sich keine Hexerei, aber ... bei meiner Erfahrung mit Schnittstellenprogrammierung. Der Ergebnsiwert ist übrigens eine Temperatur eines SMT-160-30) und ich brauche das ganze zur Steuerung und Überwachung meiner Heizungsanlage.
    Es wäre super wenn ich einen Hinweis bekommen könnte. Ich habe von Assembler leider überhaupt keine Ahnung.

    Program T_mess; {scant und gibt T aus, n=500.000}

    Uses CRT,Dos;

    const

    BA=$3F8; {COM1} Var

    CTS,n,z: longint;

    T: real;

    Procedure scan;

    Begin

    Port[BA+3] := 64; {TXD an }

    CTS := 0;

    Z := 0;

    N := 500000;

    Repeat

    CTS := CTS + ((Port[BA+6] and 16) DIV 16 + 1);

    Inc(z);

    Until z=n;

    T := 212.766*(((CTS-n)/n-0.32-0.003);

    GOTOXY (10,8);

    Writeln(„ T: ‚,,T:2:2, „ Grad C „);

    Port[BA+3]:=0; {TXD aus }

    End;

    {Hauptprogramm } begin

    clrscr;

    repeat scan;

    delay(1000);

    untiil keypressed;

    end;

  • #2
    Hallo Christoph,

    unter dem Thema "Wie kann ich Töne mit Assembler erzeugen", findest Du einen Beispielcode, wie Du den Befehl "port" simulieren kannst.

    Zwei Anmerkungen:

    1) Das ganze funktioniert nicht unter NT
    2) Wenn Du eine Leitung der seriellen Schnittstelle auf logisch 1
    setzt, entspricht dies einem Spannungspegel von +10..+12 V, wenn
    Du eine Leitung auf log. 0 setzt, wirst Du -12..-10 V messen

    Viele Grüße Hans-Pete

    Comment


    • #3
      <pre>

      <code><font face="Courier New"><font color="#000000">Hi
      <br>
      <font color="#000000"><b>var
      </b></font>Handle<font color="#000000">: </font>THandle<font color="#000000">;
      <b>begin
      </b></font>Handle <font color="#000000">:= </font>CreateFile<font color="#000000">(</font><font color="#0000FF">'COM1'</font><font color="#000000">, </font>GENERIC_READ <font color="#000000"><b>or </b></font>GENERIC_WRITE<font color="#000000">, </font><font color="#0000FF">0</font><font color="#000000">, <b>nil</b>, </font>OPEN_EXISTING<font color="#000000">, </font><font color="#0000FF">0</font><font color="#000000">, </font><font color="#0000FF">0</font><font color="#000000">);
      <b>if </b></font>Handle <font color="#000000">&lt;&gt; </font>INVALID_HANDLE_VALUE <font color="#000000"><b>then
      try
      </b></font>EscapeCommFunction<font color="#000000">(</font>Handle<font color="#000000">, </font>SETDTR<font color="#000000">);
      </font>EscapeCommFunction<font color="#000000">(</font>Handle<font color="#000000">, </font>CLRDTR<font color="#000000">);
      <br>
      </font><font color="#008080"><i>// snip from windows.pas
      // SETXOFF = 1; { Simulate XOFF received }
      // SETXON = 2; { Simulate XON received }
      // SETRTS = 3; { Set RTS high }
      // CLRRTS = 4; { Set RTS low }
      // SETDTR = 5; { Set DTR high }
      // CLRDTR = 6; { Set DTR low }
      // RESETDEV = 7; { Reset device if possible }
      // SETBREAK = 8; { Set the device break line. }
      // CLRBREAK = 9; { Clear the device break line. }
      </i></font><font color="#000000"><b>finally
      </b></font>CloseHandle<font color="#000000">(</font>Handle<font color="#000000">);
      <b>end</b>;
      <b>end</b>;
      <br>
      </font>Gru<font color="#000000">&szlig; </font>Hagen
      <br>
      </font>
      </code></pre&gt

      Comment


      • #4
        Hallo,<p>
        @Hagen: Okey, wir wissen, dass CreateFile nicht die Datei COM1 anlegt, sondern die Schnittstelle COM1 öffnet. Hier kommt(en) die Frage(n). Was macht CreateFile eigentlich bei diesem Aufruf genau? Welche Daten "mix" die Funktion alles mit dazu oder wir der Signalprozessor direkt angesprochen? Tritt zweites in Kraft, so erscheint mir dieser Weg zu "riskant". Fakt ist, beide Signalprozessoren PC/Regler müssen identisch arbeiten da ansonsten nur Datenmüll entstehen würde

        Comment


        • #5
          Kein Ahnung so tief steck ich nicht drin. Es gibt aber Wege auch unter NT und Win95 Ports korrekt anzusprechen, aus Delphi heraus. Ich betone WIN95/98 da dort entgegen der landläufigen Meinung nicht alle Ports direkt verfügbar sind. D.h. auch Win95/98 nutzt Schutzmechanismen wie NT/2000, z.b. all Ports > $100 können nicht direkt angesprochen werden. Im gegensatz zu NT/2000 das beim Lesen oder Schreiben eine Zugriffsverletzung erzeugt wird unter Win95/98 nichts passieren, d.h. Daten die geschrieben werden gehen ins Nirwana und die gelesenen Daten kommen nicht vom Gerät. In Win95/98 gibt es Wege ohne VXD Trieber die Ports anzusprechen indem man aus der Application auf Ring 3 Code auf Ring 0 laufen lässt. Unter NT/2000 benötigt man mindestens einen Gerätetreiber (SYS) der die IO-Permission Map für die Ring 3 Anwendung freischaltet. So arbeitet der frei verfügbare Treiber GiveIO.

          Gruß Hage

          Comment


          • #6
            <pre>

            <code><font size=2 face="Courier New"><b>interface
            <br>
            type
            </b>TPort = <b>class
            private
            function </b>GetByte(Index: Word): Byte;
            <b>procedure </b>SetByte(Index: Word; Value: Byte);
            <b>public
            destructor </b>Destroy; <b>override</b>;
            <b>property </b>PortB[<b>Index</b>: Word]: Byte <b>read </b>getByte <b>write </b>SetByte; <b>default</b>;
            <b>end</b>;
            <br>
            <b>function </b>Port: TPort;
            <br>
            <b>implementation
            <br>
            var
            </b>FPort: TPort = <b>nil</b>;
            <br>
            <b>function </b>Port: TPort;
            <b>begin
            if </b>FPort = <b>nil then </b>FPort := TPort.Create;
            Result := FPort;
            <b>end</b>;
            <br>
            <b>function </b>TPort.GetByte(Index: Word): Byte;
            <b>asm
            </b><font color="#008080">IN AL,DX
            </font><b>end</b>;
            <br>
            <b>procedure </b>TPort.SetByte(Index: Word; Value: Byte);
            <b>asm
            </b><font color="#008080">MOV AL,CL
            OUT DX,AL
            </font><b>end</b>;
            <br>
            <b>destructor </b>TPort.Destroy;
            <b>begin
            if </b>Self = FPort <b>then </b>FPort := <b>nil</b>;
            <b>inherited </b>Destroy;
            <b>end</b>;
            <br>
            <b>initialization
            finalization
            </b>FPort.Free;
            <b>end</b>.
            <br>
            <br>
            <font color="#008080"><i>// example
            <br>
            </i></font><b>if </b>Port[<font color="#0000FF">$61</font>] <b>and </b><font color="#0000FF">3 </font>&lt;&gt; <font color="#0000FF">3 </font><b>then </b>Port[<font color="#0000FF">$43</font>] := <font color="#0000FF">$B6</font>;
            Port[<font color="#0000FF">$42</font>] := <font color="#0000FF">$34</font>;
            Port[<font color="#0000FF">$42</font>] := <font color="#0000FF">$AA</font>;
            Port[<font color="#0000FF">$61</font>] := Port[<font color="#0000FF">$61</font>] <b>or </b><font color="#0000FF">3</font>;
            </font>
            </code></pre&gt

            Comment


            • #7
              obiger code läuft unter Win95

              gruß Hage

              Comment


              • #8
                <pre>

                <code><font size=2 face="Courier New"><font color="#008080"><i>// ohne aufwendigere implementation
                <br>
                </i></font><b>procedure </b>SetPort(Value: Byte<font color="#008080"><i>{EAX}</i></font>; Port: Word<font color="#008080"><i>{EDX}</i></font>);
                <b>asm
                </b><font color="#008080">OUT DX,AL
                </font><b>end</b>;
                <br>
                <b>function </b>GetPort(Dummy: Byte<font color="#008080"><i>{EAX}</i></font>; Port: Word<font color="#008080"><i>{EDX}</i></font>): Byte;
                <b>asm
                </b><font color="#008080">IN AL,DX
                </font><b>end</b>;
                </font>
                </code></pre&gt

                Comment


                • #9
                  Hi,<p>
                  was ich eingentlich damit anscheiden wollte ist, wenn der Signalprozessor direkt (und ohne Protkoll) angesprochen wird, verwendet dieser das vorgegebene Grundprotokoll (derzeit. u.a. 9600 Baud). Das mag zwar derzeit alles funktionieren (int. Standart) - wer sagt aber, dass sich das nicht in den nächsten Jahren verändern wird? Jetzt haste zwar das fertige Programm, es werden (später) zwei unterschiedliche Signalprozessoren verwendet - und schon ist das Programm Müll, da der Anwender keine Möglichkeit hat, Einstellungen am COM-Port/Signalprozessor vorzunehmen. Deshalb sollte man in der Schnittstellenübertragung dem Anwender die Möglichkeit geben, hardwaretechnisch Einstellungen anzupassen - auch wenn dies einen erhöhten Programmieraufwand benötigt... Meiner Meinung nach..

                  Comment


                  • #10
                    Ich ahbe mal Programm geschrieben mit dem man LEDs blinken lassen konnte. Das geht über Win-API.

                    <PRE>
                    unit Unit1;

                    interface

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

                    type
                    TForm1 = class(TForm)
                    StatusBar1: TStatusBar;
                    Panel1: TPanel;
                    Open: TButton;
                    Close: TButton;
                    ComboBox1: TComboBox;
                    Panel2: TPanel;
                    Panel3: TPanel;
                    Timer1: TTimer;
                    RadioGroup1: TRadioGroup;
                    RadioGroup2: TRadioGroup;
                    TrackBar1: TTrackBar;
                    TrackBar2: TTrackBar;
                    Panel4: TPanel;
                    Panel5: TPanel;
                    Timer2: TTimer;
                    Button1: TButton;
                    Button2: TButton;
                    procedure ComboBox1Change(Sender: TObject);
                    procedure OpenClick(Sender: TObject);
                    procedure CloseClick(Sender: TObject);
                    procedure Button2Click(Sender: TObject);
                    procedure Timer1Timer(Sender: TObject);
                    procedure Button1Click(Sender: TObject);
                    procedure TrackBar1Change(Sender: TObject);
                    private
                    { Private-Deklarationen }
                    public
                    { Public-Deklarationen }
                    Com :Thandle;
                    end;

                    var
                    Form1: TForm1;

                    implementation

                    {$R *.DFM}

                    Var x,y : integer;

                    procedure TForm1.ComboBox1Change(Sender: TObject);
                    begin
                    if combobox1.text <> '' then open.Enabled := true;
                    end;

                    procedure TForm1.OpenClick(Sender: TObject);
                    Var dcb : TDCB;
                    begin
                    Com := CreateFile('COM1'+#0, Generic_READ OR Generic_WRITE,0,NIL,Open_Existing, File_Attribute_Normal,0);
                    SetupComm(Com,2028,1024);
                    BuildCommDCB('T',dcb);
                    dcb.flags := dcb.Flags or $201c;
                    Close.enabled := true;
                    open.enabled := false;
                    panel2.Visible := true;
                    end;

                    procedure TForm1.CloseClick(Sender: TObject);
                    begin
                    panel2.Visible := false;
                    open.enabled := true;
                    close.enabled := false;
                    CloseHandle(Com);
                    end;

                    procedure TForm1.Button2Click(Sender: TObject);
                    begin
                    timer1.Interval := 0;
                    end;

                    procedure TForm1.Timer1Timer(Sender: TObject);
                    begin
                    if x = 0 then
                    begin
                    EscapeCommFunction(Com,setDTR);
                    x := 1;
                    end
                    else
                    begin
                    EscapeCommFunction(Com,clrDTR);
                    x := 0;
                    end;
                    end;

                    procedure TForm1.Button1Click(Sender: TObject);
                    begin
                    timer1.interval := Round(60 / trackbar1.position);
                    end;

                    procedure TForm1.TrackBar1Change(Sender: TObject);
                    begin
                    timer1.interval := Round(60 / trackbar1.position);
                    end;

                    end.
                    </PRE&gt

                    Comment

                    Working...
                    X