|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Сен 5, 2003 18:40:12 Простите, что как всегда не в тему, но просто это, можно сказать, срочно надо ... Несколько дней уже парюсь, глаза на лоб лезут, а строку правильно принять не могу - то со смещением получается, то вообще какие-то иероглифы принимаю. заколебался ... ковыряю тут сом-порт и в упор(!) не могу разобраться с тем, как синхронизировать прием данныx если передатчик работает в непрерывном режиме ??? А именно: имеется нуль-модемный кабель, по которому одна прога без перерыва передает данные (строку длиной 22 символа), а вторая прога, соответственно, принимает последнюю. Если сначала включить приемник, а потом передатчик, то синхронизация происходит сама собой и строка выводится на экран как полагается ... но если сначала включить передатчик, то строка принимается с каким-то непонятным смещением: т.е. так 'FFFFFFFF0KG'#10#13'AB,CD,EF,' или так 'FFFF0KG'#10#13'AB,CD,EF,FFFF' или глюканы какие-то, но не так как полагается - 'AB,CD,EF,FFFFFFFF0KG'#10#13' !!!
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
прога, которая передает данные (отдельный поток):
var
str: string[22];
..............
str := 'AB,CD,EF,FFFFFFFF0KG'#10#13;
Port := CreateFile(PChar('COM1'), GENERIC_WRITE, 0, nil,
OPEN_EXISTING, 0, 0);
GetCommState(Port, DCB);
DCB.BaudRate := 9600;
DCB.ByteSize := 8;
DCB.Parity := NOPARITY;
DCB.StopBits := ONESTOPBIT;
SetCommState(Port, DCB);
repeat
WriteFile(Port, str[1], 22, count, nil);
until Terminated;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
прога, которая принимает данные (тоже отдельный поток)
var
str: array[1..22] of byte;
................
Port := CreateFile(PChar('COM2'), GENERIC_READ, 0, nil,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
GetCommState(Port, DCB);
DCB.BaudRate := 9600;
DCB.ByteSize := 8;
DCB.Parity := NOPARITY;
DCB.StopBits := ONESTOPBIT;
DCB.EvtChar := #13; //<- последний символ-событие в посылке за который хочу зацепиться
SetCommState(Port, DCB);
GetCommTimeOuts(Port, TM);
TM.ReadIntervalTimeout := 50;
TM.ReadTotalTimeoutMultiplier := 2;
TM.ReadTotalTimeoutConstant := 100;
SetCommTimeOuts(Port, TM);
FillChar(ov, sizeof(ov), 0);
ov.hEvent := CreateEvent(nil, true, false, nil);
mask := EV_RXFLAG;
SetCommMask(Port, mask); //<- ставлю соответствующую маску порта (по символу-событию)
mask := 0;
if not WaitCommEvent(Port, mask, @ov) then
// если надо ожидать события
if GetLastError = ERROR_IO_PENDING then
case WaitForSingleObject(ov.hEvent, 1000) of
WAIT_OBJECT_0: begin
GetOverlappedResult(Port, ov, count, false);
if mask = EV_RXFLAG then begin
ResetEvent(ov.hEvent); //<- если символ словили переопределяем событие
PurgeComm(Port, PURGE_RXABORT + PURGE_RXCLEAR); //<- очищаем приемный буфер дабы читать след. строку
ClearCommError(Port, mask, nil);
repeat
count := 0;
ReadFile(Port, str[1], 22, count, @ov); //<- читаем как обычно
if GetLastError = ERROR_IO_PENDING then
WaitForSingleObject(ov.hEvent, INFINITE); //<- здесь мне кажется можно и так
Synchronize(ShowBuffer);
until Terminated;
end;
WAIT_TIMEOUT: begin
mask := $FFFFFFFF;
Synchronize(ShowBuffer);
end;
end
else begin
// если ожидать события не надо
if mask = EV_RXFLAG then begin
ResetEvent(ov.hEvent); //<- переопределяем события для чтения
PurgeComm(Port, PURGE_RXABORT + PURGE_RXCLEAR);
ClearCommError(Port, mask, nil);
repeat
count := 0;
ReadFile(Port, str[1], 22, count, @ov);
if GetLastError = ERROR_IO_PENDING then
WaitForSingleObject(ov.hEvent, INFINITE);
Synchronize(ShowBuffer);
until Terminated;
end;
end;
until Terminated;
CloseHandle(ov.hEvent);
CloseHandle(Port);
end;
по идее если произошло событие по порту, то значит в буфер записан последний символ посылки - #13, соответственно если я очищу буфер, то следующим чтением обзательно прочитаю нормальную строку, однако(!!!) происходит так как происходит - строка получается со смещением и все тут ... при чем события WAIT_OBJECT_0 никогда не происходит, срабатывает WAIT_TIMEOUT, как будто последнего символа нет !!! Кто-нить сталкивался с такой замарочкой ? |
|
|
Дата: Сен 6, 2003 14:26:22 Тебе просто надо НЕ воспринимать входящие данные пока не придет 13,10 (или 10,13). Короче, ты сначала должен отловить момент, когда передатчик закончил передачу строки, а только потом воспринимать данные от передатчика как последовательность строк и обрабатывать их. |
|
|
Дата: Сен 6, 2003 22:02:55 Так в том-то и прикол, что это символ не отлавливается !!! Например: repeat ReadFile(Port, One, 1, count, nil); if One = 13 then begin //читаю желаемую последовательность символов end; until Terminated; замарочка, символ отлавливается либо случайно(!), после нескольких минут ожидания, либо если сначала включить приемник, а потом передатчик !!! Причем аналогичная прога написанная под DOS работает 100-процентно правильно, проверял. Там аналогично, сначала ожидаю 13-й символ, а потом считываю всю строку:
repeat
repeat
b := port[$2FD];
until (b and 1) > 0 //<- проверяю состояние линии
b := port[$2F8]; //<- читаю принятый символ
until b = 13
for i := 1 to 22 do begin
repeat
b := port[$2FD];
until (b and 1) > 0
byte(str[i]) := port[$2F8]; //<- считываю строку
end;
|
|
|
Дата: Сен 6, 2003 22:10:08 как я только не пытался отловить этот символ - и с ожиданиями и без них и х## знает как ! А даже если он и отлавливался, то прием все равно происходил со смещением, если сначала был включен передатчик... я просто фигею !!! ;(((... держите меня а то шАс выматерюсь от души... |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.081 |