Com порт максимально быстро. Как?

  • Автор темы zi4rox
  • Дата начала
Z

zi4rox

Гость
#1
Всем привет,

Прошу помочь разобраться. Работаю с COM-портом

компоненты для работы с ком портом: BCPort, Com Port Library - все они работают жутко медленно (если ставить задержку хотя бы в 1 милисекунду (а это ужасно долго) между отправляемыми данными - они не успевают различать принятые байты и лепят всё в одно) - вобщем в топку их.

Пожалуйста посоветуйте максимально быстрый способ чтения/записи/работы с ком-портом?
 
S

set2333

Гость
#2
А что если попробовать работать с помощью WinApi. Не давно писал программу для работы с ИБП. Вобщем-то даволен.

Вот код моих функций и процедур

Код:
function ComConnect : THandle; //соединение с портом
var
DCB : TDCB;
begin
Result := CreateFile(PChar('COM1'), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); 
GetCommState(Result, DCB);
DCB.BaudRate := 2400;
DCB.Flags := 17;
DCB.ByteSize := 8;
DCB.XonChar := chr(0);
DCB.XoffChar := chr(0);
DCB.ErrorChar := chr(0);
DCB.EofChar := chr(0);
DCB.EvtChar := chr(13);
SetCommState(Result, DCB); //задаем DCB структуру
PurgeComm(Result, PURGE_TXCLEAR or PURGE_RXCLEAR);
SetCommMask(Result, EV_RXFLAG); //ставим маску 
end;

procedure ComWrite(var ComHand : THandle; Commanda : string); //запись в порт
var
dwWrite : DWORD;
OverWrite : TOverlapped;
WriteByte : array[0..20] of char;
len : integer;
begin
len := Length(Commanda);
StrPCopy(@WriteByte, Commanda);
WriteByte[len] := chr(13);
OverWrite.hEvent := CreateEvent(nil, true, false, nil);
WriteFile(ComHand, WriteByte, len + 1, dwWrite, @OverWrite);
end;

function ComRead(ComHand : THandle) : string; //чтение из порта
var
ComStat : TComStat;
dwMask, dwError : DWORD;
OverRead : TOverlapped;
Buf : array[0..50] of char;
dwRead : DWORD;
begin
FillChar(Buf, SizeOf(Buf), #0);
OverRead.hEvent := CreateEvent(nil, true, false, nil);
if not WaitCommEvent(ComHand, dwMask, @OverRead) then
begin
WaitForSingleObject(OverRead.hEvent, 10000);
end;
ClearCommError(ComHand, dwError, @ComStat);
dwRead := ComStat.cbInQue;
if dwRead > 0 then
begin
ReadFile(ComHand, Buf, dwRead, dwRead, @OverRead);
Result := string(Buf);
end;
end;

procedure ComDisConnect(ComHand : THandle); //закрытие порта
begin
CloseHandle(ComHand);
end;
Может где-то и кривовато, да и проверок никаких нет(а они были бы не лишними), но работает.
 
A

alexey

Гость
#3
Я использую компоненты AfComPort и ApdComPort, последний корректно получает длинные пакеты, но иногда вываливает ошибки, первый наоборот :newconfus: