Problem polega na tym że chyba mam coś źle skonfigurowane na COMie.
Jak urządzenie zewnętrze dostarcza mi dane po 256bajtów to ja za pierwszym odczytem otrzymuje 33bajty, kolejny odczyt to dane po 33bajcie
Czyli buffor wypełnia się na dwa razy.
Czy posiadacie może sprawdzony sposób na odbiór danych przez RS'a bez gubienia danych w buforze?
Jak sprawdzam w Serial Port Monitor to moje zewnętrzne urządzenie wysyła dane OK i powtarzalnie!
Może znacie sposób jak działają te monitory portów. Czyli kod w Delphi jest niedoskonały!
const
// -- wartości flag sterujących portu szeregowego --
dcb_fBinary = $0001;
dcb_fParity = $0002;
dcb_fOutxCtsFlow = $0004;
dcb_fOutxDsrFlow = $0008;
// -- fDtrControl --
DTR_CONTROL_ENABLE = $0010;
DTR_CONTROL_HANDSHAKE = $0020;
dcb_fDsrSensitivity = $0040;
dcb_fTXContinueOnXoff = $0080;
dcb_fOutX = $0100;
dcb_fInX = $0200;
dcb_fErrorChar = $0400;
dcb_fNull = $0800;
// -- fRtsControl --
RTS_CONTROL_ENABLE = $1000;
RTS_CONTROL_HANDSHAKE = $2000;
RTS_CONTROL_TOGGLE = $3000;
dcb_fAbortOnError = $4000;
cbInQueue = 255;
cbOutQueue = 255;
var
//hfile_s : HFILE; // identyfikator pliku źródłowego
Buffer_O : ARRAY[0..cbOutQueue] of Char; // bufor wyjściowy
Buffer_I : ARRAY[0..cbInQueue] of Char; // bufor wejściowy
Number_Bytes_Read : DWORD;
hCommDev : THANDLE;
lpFileName : LPCSTR;
fdwEvtMask : DWORD;
Stat : TCOMSTAT;
Errors : DWORD;
dcb : TDCB;
resourcestring
s1 = 'Niewłaściwa nazwa portu lub jest aktywny ';
function TForm2.OpenCOM: Boolean;
begin
Result:=FALSE;
hCommDev:= CreateFile(lpFileName, GENERIC_READ or
GENERIC_WRITE, 0, NIL,
OPEN_EXISTING, 0, 0);
if (hCommDev <> INVALID_HANDLE_VALUE) then
begin
SetupComm(hCommDev, cbInQueue, cbOutQueue);
dcb.DCBlength := sizeof(dcb);
GetCommState(hCommDev, dcb);
dcb.BaudRate:=CBR_115200;
//-przykładowe ustawienia flag sterujących DCB-
//dcb.Flags := dcb.Flags or dcb_fParity;
dcb.Parity := NOPARITY;
dcb.StopBits := ONESTOPBIT;
dcb.ByteSize := 8;
SetCommState(hCommDev, dcb);
GetCommMask(hCommDev, fdwEvtMask);
SetCommMask(hCommDev, EV_TXEMPTY);
Result:=TRUE;
end
else
case hCommDev of
IE_BADID: MessageDlg(s1 + lpFileName,
mtError, [mbOk], 0);
end;
end;
//---------------------------------------------------------
function TForm2.Write_Comm(hCommDev: THANDLE; lpBuffer: PChar;
nNumberOfBytesToWrite: DWORD): BOOL;
var
NumberOfBytesWritten : DWORD;
begin
WriteFile(hCommDev, Buffer_O, nNumberOfBytesToWrite,
NumberOfBytesWritten, NIL);
Result := WaitCommEvent(hCommDev, fdwEvtMask, NIL);
end;
//---------------------------------------------------------
function TForm2.Read_Comm(hCommDev: THANDLE;
Buf_Size: DWORD): BOOL;
var
nNumberOfBytesToRead: DWORD;
begin
Result := FALSE;
ClearCommError(hCommDev, Errors, @Stat);
if (Stat.cbInQue > 0) then
begin
if (Stat.cbInQue > Buf_Size) then
nNumberOfBytesToRead := Buf_Size
else
nNumberOfBytesToRead := Stat.cbInQue;
Result := ReadFile(hCommDev, Buffer_I,
nNumberOfBytesToRead,
Number_Bytes_Read, NIL);
end;
end;
//---------------------------------------------------------
function TForm2.CloseCOM: Boolean;
begin
Result:=FALSE;
if (hCommDev <> INVALID_HANDLE_VALUE) and (hCommDev > 0) then
begin
CloseHandle(hCommDev);
Result:=TRUE;
end;
end;
//Odbiór danych
begin
repeat
Application.ProcessMessages;
until Form2.Read_Comm(hCommDev, SizeOf(Buffer_I)) = TRUE;
end;