Danke Leute ich bin nun schon etwas weiter.
Zur Verwendung: Ich will damit mit Harware zur steuerung einer Modellbahn communizieren. Dazu brauche ich 3 Schnittstellen.
1.Umsetzer der Seuerinformationen in das DCC Format.
2. Abfrage von Kontaktinformationen im Gleis.
3. Anschaltung eines Reglers zur Geschwindigketssteuerung.
Es gibt auch keine Modems, die Karten werden direkt angeschlossen. (über gekreuzte Leitungen)
Ich habe das hier nicht optimal gepostet. Das war natürlich nur ein Teil des Codes. Ich wollte da schrittweise vorgehen, ist aber blöd gewesen.
Da kommt natürlich noch mehr. Hier nun alles:
Code: Alles auswählen
{*******************************************************}
{ }
{ SerCOM 1.2 (3) Windows }
{ }
{ Copyright (c) 1990,2005 DYNAMO Software }
{ }
{*******************************************************}
{
Pascal Routinen für die Verwendung der seriellen
Schnittstelle. Diese Unit existiert in 3 Versionen
für folgende Plattformen:
(1) MS-DOS (Turbo Pascal)
(2) Macintosh (CodeWarrior)
(3) Windows (Delphi)
Dieser Quellcode ist Freeware und darf NICHT verkauft
werden. Download der aktuellen Version unter:
http://www.dynamo-software.de/serial/code.htm
Viel Spaß am Gerät!
Jens-Erich Lange
info@dynamo-software.de
}
unit SerCom;
interface
uses
Windows;
const
SER_OK = 0; // Kein Fehler
SER_NIL = -1; // SerialPtr nicht initialisiert / Zuwenig RAM für Puffer
SER_ERR = -2; // Unzulässige Parameter oder Schnittstelle geschlossen
SER_SYS = -3; // Fehlermeldung vom Betriebssystem. Nummer in "SerialCode"
type
SerialRec = record
SysErr: longint;
ComName: array [0..5] of char;
hFile: tHandle;
sBaud: longint;
sData: integer;
sStop: integer;
sParity: char;
Output: longint;
SizeIn: longint;
SizeOut: longint;
TimeOut: tCommTimeOuts;
end;
SerialPtr = ^SerialRec;
SerialErr = longint;
{-------------------------------------------------------}
{ Initialisierung / Deinitialisierung }
{-------------------------------------------------------}
function SerialInit(PortNr, InBuffer, OutBuffer: integer): SerialPtr;
function SerialCode(SerialPort: SerialPtr): SerialErr;
function SerialExit(SerialPort: SerialPtr): SerialErr;
{-------------------------------------------------------}
{ Öffnen / Schließen / Parametrieren }
{-------------------------------------------------------}
function SerialPara(SerialPort: SerialPtr; Baud: longint; Data, Stop: integer; Parity: char): SerialErr;
function SerialOpen(SerialPort: SerialPtr): SerialErr;
function SerialStop(SerialPort: SerialPtr): SerialErr;
{-------------------------------------------------------}
{ Senden / Empfangen }
{-------------------------------------------------------}
function SerialXmit(SerialPort: SerialPtr; data: byte): SerialErr;
function SerialRecv(SerialPort: SerialPtr; var data: byte): SerialErr;
function SerialDone(SerialPort: SerialPtr): SerialErr;
function SerialRSet(SerialPort: SerialPtr; Value: byte): SerialErr;
function SerialRGet(SerialPort: SerialPtr): SerialErr;
implementation
uses unit21;
{----------------------------------------------------------------------}
{ Funktion "SerialOpen" }
{ Öffnet die serielle Schnittstelle und ermöglicht somit den Daten- }
{ verkehr. Nachdem die Schnittstelle geöffnet ist, werden alle ein- }
{ gehenden Zeichen im Zwischenpuffer gespeichert bis diese mit der }
{ Funktion "SerialRecv" aus dem Puffer entnommen werden. }
{ Das Gegenstück zu "SerialOpen" ist die Funktion "SerialStop". }
{ Die Zwischenpuffer werden beim öffnen und schließen einer Schnitt- }
{ stelle gelöscht. }
{----------------------------------------------------------------------}
function SerialOpen(SerialPort: SerialPtr): SerialErr;
var commprop: tCommProp;
begin
result := SER_OK;
if (SerialPort <> nil) then with SerialPort^ do
begin
if hFile = INVALID_HANDLE_VALUE then
begin
hFile := CreateFile(ComName, GENERIC_READ + GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0);
Hier geht es woh dann tatsächlich zu Windows ?
Code: Alles auswählen
if (hFile <> INVALID_HANDLE_VALUE) then
begin
if GetCommProperties(hfile, commprop) then
begin
SetupComm(hfile, SizeIn, SizeOut);
SetParameter(SerialPort);
SetCommTimeouts(hfile, TimeOut);
SetCommMask(hfile, 0);
Output := commprop.dwCurrentTxQueue;
end
else begin
SysErr := GetLastError;
result := SER_SYS;
end;
end
else begin
SysErr := GetLastError;
result := SER_SYS;
end;
end;
end
else result := SER_NIL;
end;
{----------------------------------------------------------------------}
{ Funktion "SerialPara" }
{ parametriert die serielle Schnittstelle. Es ist dabei unerheblich, }
{ ob die Schnittstelle bereits geöffnet ist oder nicht. }
{ Für eine ordentliche Kommunikation ist es erforderlich, daß alle }
{ Parameter mit denen der Gegenstelle übereinstimmen. Viele Modems }
{ können die verwendeten Parameter selbständig erkennen und können }
{ daher mit verschiedenen Parametern angesprochen werden. }
{ Die Standardeinstellung für Daten- und Stopbits sowie Parität sind }
{ 8 - 1 - Keine (None). }
{----------------------------------------------------------------------}
function SerialPara(SerialPort: SerialPtr; Baud: longint; Data, Stop: integer; Parity: char): SerialErr;
begin
if (SerialPort <> nil) then with SerialPort^ do
begin
sBaud := Baud;
sData := Data;
sStop := Stop;
sParity := Parity;
result := SetParameter(SerialPort);
end
else result := SER_NIL;
end;
{----------------------------------------------------------------------}
{ Funktion "SerialStop" }
{ schließt die serielle Schnittstelle. Die Datenkommunikation wird }
{ unterbunden und der Gegenstelle wird auf den Handshakeleitungen }
{ signalisiert, daß die Schnittstelle geschlossen ist. Ein ordent- }
{ lich konfiguriertes Modem sollte dadurch eine bestehende Telefon- }
{ verbindung trennen. }
{----------------------------------------------------------------------}
function SerialStop(SerialPort: SerialPtr): SerialErr;
begin
if (SerialPort <> nil) then with SerialPort^ do
begin
if hFile <> INVALID_HANDLE_VALUE then
begin
EscapeCommFunction(hFile, CLRRTS);
SetCommMask(hfile, 0);
CloseHandle(hFile);
hFile := INVALID_HANDLE_VALUE;
end;
result := SER_OK;
end
else result := SER_NIL;
end;
{----------------------------------------------------------------------}
{ Funktion "SerialXmit" }
{ Übergibt ein Zeichen an den Sendepuffer. Falls die Schnittstelle }
{ zu diesem Zeitpunkt geöffnet ist, werden die Zeichen im Hinter- }
{ grund asynchron übertragen. Die Funktion kehrt nach ihrem Aufruf }
{ schnell zurück und wartet nicht auf das Ende der Ðbertragung. }
{ Zeichenketten und binäre Arrays werden vom Aufrufer in einer }
{ Schleife an diese Funktion übergeben. }
{ Mit der Funktion "SerialDone" kann geprüft werden, ob schon alle }
{ Zeichen übertragen wurden. }
{----------------------------------------------------------------------}
function SerialXmit(SerialPort: SerialPtr; data: byte): SerialErr;
var
count: DWORD;
comstat: tComstat;
begin
if (SerialPort <> nil) then with SerialPort^ do
begin
if hFile <> INVALID_HANDLE_VALUE then
begin
ClearCommError(hfile, count, @comstat);
if (((Output - SerialErr(comstat.cbOutQue)) - 1) <= 0) then
begin
if WriteFile(hfile, data, 1, count, nil) then result := count
else begin
SysErr := GetLastError;
result := SER_SYS;
end;
end
else result := SER_NIL;
end
else result := SER_ERR;
end
else result := SER_NIL;
end;
{----------------------------------------------------------------------}
{ Funktion "SerialRecv" }
{ holt das nächste Zeichen aus dem Empfangspuffer. Voraussetzung ist }
{ eine geöffnete Schnittstelle. Ist das Ergebnis dieser Funktion "1" }
{ so wurde die Funktion erfolgreich ausgeführt. Alle anderen Werte }
{ bedeuten, daß kein Zeichen empfangen wurde. }
{----------------------------------------------------------------------}
function SerialRecv(SerialPort: SerialPtr; var data: byte): SerialErr;
var count: DWORD;
begin
if (SerialPort <> nil) then with SerialPort^ do
begin
if hFile <> INVALID_HANDLE_VALUE then
begin
if windows.ReadFile(hfile, data, 1, count, nil) then result := count
else begin
SysErr := GetLastError;
result := SER_SYS;
end;
end
else result := SER_ERR;
end
else result := SER_NIL;
end;
{----------------------------------------------------------------------}
{ Funktion "SerialDone" }
{ ermittelt wieviele Zeichen sich momentan im Sendepuffer befinden. }
{ Ist das Ergebnis "0", sind keine Zeichen mehr im Sendepuffer. }
{----------------------------------------------------------------------}
function SerialDone(SerialPort: SerialPtr): SerialErr;
begin
if (SerialPort <> nil)
then result := SerialPort^.Output
else result := SER_NIL;
end;
{----------------------------------------------------------------------}
{ Funktion "SerialRSet" }
{ setzt einzelne Handshakeleitungen der seriellen Schnittstelle. }
{ Diese Funktion ist nur in dieser Wondows Version vorhanden. }
{----------------------------------------------------------------------}
function SerialRSet(SerialPort: SerialPtr; Value: byte): SerialErr;
begin
if (SerialPort <> nil) then with SerialPort^ do
begin
if hFile <> INVALID_HANDLE_VALUE then
begin
EscapeCommFunction(hFile, Value);
result := SER_OK;
end
else result := SER_ERR;
end
else result := SER_NIL;
end;
{----------------------------------------------------------------------}
{ Funktion "SerialRGet" }
{ liest den Status der Handshakeleitungen. }
{ Diese Funktion ist nur in dieser Wondows Version vorhanden. }
{----------------------------------------------------------------------}
function SerialRGet(SerialPort: SerialPtr): SerialErr;
var Reg: Cardinal;
begin
if (SerialPort <> nil) then with SerialPort^ do
begin
if (hFile <> INVALID_HANDLE_VALUE) then
begin
if GetCommModemStatus(hFile, Reg)
then Result := Reg
else Result := SER_ERR;
end
else result := SER_ERR;
end
else result := SER_NIL;
end;
end.
Bei SerialInit wird offensichtlich nur der Record angelegt, und ein Pointer darauf installiert.
Schön langsam wird das für mich schon durchsichtiger.