Re: in serielle Schnittstelle schreiben



Hallo Sieghard,
vielen Dank für Dein Posting, war allerdings bis gestern in Urlaub und habe
es erst jetzt gelesen.

Dass die Datentypen übereinstimmen müssen, ist natürlich logisch, und ich
habe daraufhin das folgende geändert:
program display;
var ch: string;
var disp: file of string;


begin
assign(disp, '/dev/ttyS0');
reset(disp);
ch := 'XYZ';
write(disp, ch);


close(disp);
end.

Das lässt sich kompilieren und funktioniert auch "irgendwie". Doch erscheint
die Schrift nur kurz, und das Display wird sofort danach zur Gänze
invertiert. Doch das ist wohl ein anderer Thread...

Ein geeigneter halt - wie gesagt, das hängt primär davon ab, was Du damit
machen willst.

Ich brauche eine Anwendung in einem Messgerät. Ich möchte per serieller
Schnittstelle auf einem (seriellen 4-zeiligen) Display kurze Texte und
einzelne (ASCII-) Zeichen ausgeben (auch nicht-druckbare, die Steuercodes
für das Display darstellen)(und später auch Messdaten über die 2.
Schnittstelle einlesen).

(Baudrate etc.
sind im System per stty bereits eingestellt).

Dann sollte das eigentlich trivial sein.
Falls Du aber doch mal die Schnittstellenparameter in Deinem Programm
einstellen willst,
Ja. Wenn diese trivialen Probleme gelöst sind.
könntest Du Dir evtl. mal meine vor längerer Zeit hier
gepostete Unit "AsynUnit" anschauen. Die müßte eigentlich noch irgendwo
bei dem datensammelnden Moloch im internet 'rumliegen. Falls nicht, kann
ich die gern nochmal posten, ich möchte das aber nicht einfach ungefragt
hier 'reinkippen...
Hab' ich gefunden. Steigt jedoch beim Kompilieren aus: Am Ende steht ein
END. zu dem möglicherweise das BEGIN verlorengegangen ist? (Siehe Anhang).


--
Richard Müller - r-dot-mueller-at-oeko-sorpe-dot-deUNIT AsynUnit;
{
Textfile Device Driver for serial port, interrupt driven.
After Turbo 4.0 ASYNC.INC by Michael Quinlan
and ASYNC4U.PAS by Scott Gurvey, see below.

Main Procedure exported is

PROCEDURE AssignCOM (VAR F: text; Channel: PortString;
BaudRate: word; Parity: ParityDef;
DataBits, StopBits: byte);
with Parameters
F - the text file variable
Channel - the DOS port name 'COMn', n in the range 1..4.
BaudRate - the baud rate to set, values like MODE command.
Parity - specify one of (noPty, evenPty, oddPty)
for no, even or odd Parity, resp.
DataBits - number of data bits, may be 7 or 8.
StopBits - number of stop bits, may be 1 or 2.

Text file assigned may be opened, written to or read from with standard
TP routines; both input and output are interrupt driven.
Any neccessary initialisations, installations and deinstallations are
fully automatic.
Port parameters for input file always take preference!

Additional utility procedure:

FUNCTION COMready - tells if it's worthwhile to attempt
to read from the COM port file;
same basical function as KeyPressed.

Plus a couple of Constants and Variables:

AsyncHandshake - boolean, default value: false.
Defines initial setting for CTS/RTS
handshake. Can be changed before
assignment, will NOT be reset after
AssignCOM.
AsyncSetHandshake - boolean, default value: true.
Specifies whether to do initial setup
for DTR and RTS.
Can be used in conjunction with
AsyncHandshake to disable handshaking
completely.
AsyncTimeout - word, default value: 18 (about 1 sec).
Number of clock ticks to wait until
timeout error. Globally used.

{ References: }
{----------------------------------------------------------------------}
{ ASYNC4U.PAS }
{ }
{ This is a faithful translation of the famous ASYNC.INC by Michael }
{ Quinlan into a Turbo 4.0 unit. No extra frills, no modification of }
{ types, nothing fancy. But with this code you should be able to }
{ delete your $I ASYNC.INC directive, add a USES ASYNC4U statement, }
{ and recompile your existing program. If you want to add support }
{ for more ports, other computers, or change to use the new data }
{ types, all good ideas, go right ahead. With this you don't have to. }
{ }
{ Scott Gurvey, November 29 1987 }
{----------------------------------------------------------------------}
{ }
{ ASYNC.INC }
{ }
{ Async Communication Routines }
{ by Michael Quinlan }
{ with a bug fixed by Scott Herr }
{ made PCjr-compatible by W. M. Miller }
{ Highly dependant on the IBM PC and PC DOS 2.0 }
{ }
{ based on the DUMBTERM program by CJ Dunford in the January 1984 }
{ issue of PC Tech Journal. }
{ }
{----------------------------------------------------------------------}

{ Textfile Device Driver for Linux serial devices }

INTERFACE

USES Dos, OldLinux, SysUtils;

TYPE
{$PACKENUM 1}
ParityDef = (noPty, evenPty, oddPty);
PortString = string [5];

CONST
CS: ARRAY [5..8] OF longint = (CS5, CS6, CS7, CS8);
CSTOP: ARRAY [1..2] OF longint = (0, CSTOPB);
PAR: ARRAY [ParityDef] OF longint = (0, PARENB, PARENB OR PARODD);
CTL: ARRAY [boolean] OF longint = (CLOCAL, CRTSCTS);

CONST
MinBaud = 75; { minimum permissible baud rate }
MaxBaud = 115200; { maximum permissible baud rate }

UnusedHandle = -1; { handle value for inactive file }

AsyncHandshake: boolean = false; { may be set true for CTS/RTS
handshake }
AsyncSetHandshake: boolean = true;
AsyncTimeout: longint = 1000{ms};

LockBase: PathStr = '/var/lock/LCK..';


FUNCTION COMready (VAR F: text): boolean;

FUNCTION reserveCOM (Channel: PortString): boolean;

PROCEDURE releaseCOM (VAR F: text);

PROCEDURE AssignCOM (VAR F: text; Channel: PortString; BaudRate: longint;
Parity: ParityDef; DataBits, StopBits: byte);


IMPLEMENTATION


CONST
BaudCount = 9;

BaudRate: ARRAY [0..BaudCount] OF longint
(300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200);
BaudCode: ARRAY [0..BaudCount] OF word
(B300, B600, B1200, B2400, B4800, B9600, B19200, B38400, B57600,
B115200);

TYPE
COMdata = PACKED RECORD
Data: byte;
Pty: ParityDef;
Stop: byte;
Handsh: boolean;
Baud: longint;
unused: ARRAY [9..32] OF byte;
END;


PROCEDURE MapError;
{
Convert ErrNo error to the correct Inoutres value
}
BEGIN
IF LinuxError = 0 THEN Exit; { Else it will go through all the cases }

CASE LinuxError OF
Sys_ENFILE,
Sys_EMFILE: InOutRes:= 4;
Sys_ENOENT: InOutRes:= 2;
Sys_EBADF: InOutRes:= 6;
Sys_ENOMEM,
Sys_EFAULT: InOutRes:= 217;
Sys_EINVAL: InOutRes:= 218;
Sys_EPIPE,
Sys_EINTR,
Sys_EIO,
Sys_EAGAIN,
Sys_ENOSPC: InOutRes:= 101;
Sys_ENAMETOOLONG,
Sys_ELOOP,
Sys_ENOTDIR: InOutRes:= 3;
Sys_EROFS,
Sys_EEXIST,
Sys_EACCES: InOutRes:= 5;
Sys_ETXTBSY: InOutRes:= 162;
END;
END;


PROCEDURE InputCOM (VAR F: TextRec);
VAR
waiting: longint;
COMset: fdSet;

BEGIN
WITH F DO BEGIN
waiting:= 1 {AsyncTimeout}; { minimal time out }
FD_ZERO (COMset); FD_Set (Handle, COMset);
waiting:= Select (succ (Handle), @COMset, NIL, NIL, waiting);

IF waiting > 0 THEN BEGIN
waiting:= BufSize;
BufEnd:= fdRead (Handle, BufPtr^, waiting {BufSize});
BufPos:= 0; MapError;
END (* IF waiting > 0 *)
ELSE InOutRes:= 161; { device read error }
END (* WITH F *);
END (* InputCOM *);


PROCEDURE OutputCOM (VAR F: TextRec);
VAR
Written: word;

BEGIN
WITH F DO BEGIN
Written:= fdWrite (Handle, BufPtr^, BufPos);
MapError;
IF Written <> BufPos THEN InOutRes:= 101;
BufPos:= 0;
END (* WITH F *);
END (* OutputCOM *);

{
FUNCTION IgnoreCOM (VAR F: TextRec): integer;
BEGIN IgnoreCOM:= 0; END;
}

PROCEDURE CloseCOM (VAR F: TextRec);
BEGIN
IF FLock (F.Handle, LOCK_UN)
THEN fdClose (F.Handle)
ELSE InOutRes:= LinuxError;
F.Handle:= UnusedHandle; MapError;
END (* CloseCOM *);


PROCEDURE OpenCOM (VAR F: TextRec);

FUNCTION BaudSel (Baud: longint): word;
VAR
i: integer;

BEGIN (* BaudSel *)
i:= BaudCount;
WHILE (i > 0) AND (Baud < BaudRate [i]) DO Dec (i);
BaudSel:= BaudCode [i];
END (* BaudSel *);


FUNCTION opened: boolean;
VAR
BaseMode: longint;
DeviceCtrl: TermIOS;

BEGIN (* opened *)
opened:= false;
BaseMode:= Open_NoCtty OR Open_Sync; { not controlling terminal }

IF F.Mode = fmInput
THEN BaseMode:= Open_RdOnly OR BaseMode
ELSE IF F.Mode = fmOutput
THEN BaseMode:= Open_WrOnly OR BaseMode
ELSE InOutRes:= 151; { unknown unit }

WITH F DO BEGIN
Handle { file handle }:= fdOpen (Name { file name }, BaseMode
{ attribute: read/write });

IF Handle >= 0 THEN BEGIN
IF FLock (Handle, LOCK_SH) THEN BEGIN
IF tcGetAttr (Handle, DeviceCtrl) THEN BEGIN
WITH DeviceCtrl, COMdata (UserData) DO BEGIN
c_iflag:= IGNBRK OR BRKINT;
c_oflag:= 0;
c_cflag:= CS [Data] OR CSTOP [Stop] OR PAR [Pty] OR
CTL [Handsh] OR CREAD; c_lflag:= 0;
cfSetISpeed (DeviceCtrl, BaudSel (Baud));
cfSetOSpeed (DeviceCtrl, BaudSel (Baud));
END (* WITH DeviceCtrl, COMdata (UserData) *);

opened:= tcSetAttr (Handle, TCSAFLUSH, DeviceCtrl);
END (* IF tcGetAttr (Handle, DeviceCtrl) *)
END (* IF FLock (Handle LOCK_SH) *)
END (* IF Handle >= 0 *)
END (* WITH F, COMdata (UserData) *)
END (* opened *);

BEGIN
WITH F DO
IF opened THEN BEGIN
IF Mode = fmInput THEN BEGIN
InOutFunc:= @InputCOM;
FlushFunc:= NIL; {@IgnoreCOM;}
BufPos:= 0; BufEnd:= 0;
END (* IF Mode = fmInput *)
ELSE IF Mode = fmOutput THEN BEGIN
InOutFunc:= @OutputCOM;
FlushFunc:= @OutputCOM;
END (* IF Mode = fmOutput *);

CloseFunc:= @CloseCOM;
MapError;
END (* IF opened *)
ELSE InOutRes:= 103; { file not open }
END (* OpenCOM *);


PROCEDURE releaseCOM (VAR F: text);
BEGIN
DeleteFile (LockBase+ BaseName (StrPas (TextRec (F).Name), ''));
END (* releaseCOM *);


FUNCTION reserveCOM (Channel: PortString): boolean;
VAR
H: longint;
P: string [11];

BEGIN
H:= fdOpen (LockBase+ Channel, Open_WrOnly OR Open_Creat OR Open_Excl);
IF H >= 0 THEN BEGIN
Str (GetPID: 10, P); P:= P+ ^J; fdWrite (H, P [1], Length (P));
fdClose (H);
END (* IF H >= 0 *);
reserveCOM:= H >= 0;
END (* reserveCOM *);


FUNCTION COMready (VAR F: text): boolean;
VAR
waiting: longint;

BEGIN
COMready:= true; { mal auf Verdacht annehmen }
WITH TextRec (F) DO
IF Mode = fmInput THEN BEGIN
IF BufPos >= BufEnd THEN BEGIN
IOCtl (Handle, FIONREAD, @waiting);
COMready:= waiting > 0;
END (* IF BufPos >= BufEnd *);
END (* IF Mode = fmInput *)
ELSE RunError (104); { file not open for input }
END (* COMready *);


PROCEDURE AssignCOM (VAR F: text; Channel: PortString; BaudRate: longint;
Parity: ParityDef; DataBits, StopBits: byte);
CONST
dev: ARRAY [1..5] OF char = '/dev/';

BEGIN
IF (Length (Channel) < 5) OR
(Pos ('tty', Channel) <> 1)
THEN RunError (151); { unknown unit }

IF NOT ((StopBits IN [1, 2]) AND (DataBits IN [5..8]) AND
(MinBaud <= BaudRate) AND (BaudRate <= MaxBaud))
THEN RunError (153); { unknown command }

WITH TextRec (F), COMdata (UserData) DO BEGIN
FillChar (F, SizeOf (TextRec), 0);
Handle:= UnusedHandle;
Mode:= fmClosed;
BufSize:= TextRecBufSize; { SizeOf (Buffer); }
BufPtr:= @Buffer;
OpenFunc:= @OpenCOM;
Baud:= BaudRate;
Pty:= Parity;
Data:= DataBits;
Stop:= StopBits;
HandSh:= AsyncHandshake;
FillChar (Name, SizeOf (Name), 0);
Move (dev, Name, SizeOf (dev));
Move (Channel [1], Name [5], Length (Channel));
END (* WITH TextRec (F) *);
END (* AssignCOM *);

END.

Relevant Pages

  • Re: ttyS0-Unit
    ... Text file assigned may be opened, written to or read from with standard ... IF waiting> 0 THEN BEGIN ... END; ...
    (de.comp.lang.pascal)
  • Boolean incompréhensible
    ... Pourquoi le programme suivant affiche-t-il true? ...
    (comp.lang.pascal.delphi.misc)
  • Re: MouseLeave - Mouseenter oder Enter - Exit
    ... Integer read FBorderWidth write SetBorderWidth ... Begin ... If FocusControl Nil Then Begin ...
    (de.comp.lang.delphi.misc)
  • >> Custom Packetsniffer
    ... Procedure cmdCLHookMSGClick(Sender: TObject); ... If fHookLibrary 0 Then Begin ... End Else Begin ...
    (de.comp.lang.delphi.misc)
  • Applikation crasht nach Callback Aufruf
    ... Public Type ReqCntrlT ... End Type ... With vbReqCntrlT ... Dim callbackCntxtData As AppCntxtDataT ...
    (microsoft.public.de.vb)