Форум: "WinAPI";
Текущий архив: 2008.08.31;
Скачать: [xml.tar.bz2];
ВнизCE_FRAME Найти похожие ветки
← →
balepa © (2007-11-13 07:50) [0]Есть программа которая обменивается с прибором по Comm порту по принципу команда-ответ. На одном ПК программа работает без ошибок и сбоев (все передается и принимается к прибору и от него). Ставим все это на др. ПК, "команда" отправляется "ответ" приходит:
1. правильный т.е. все поля (адрес устр., команда, данные, CRC) правильные.
2. Адрес уст. = правильный, номер команды = правильный, данные неправильные, CRC = соответствует CRC пункта 1 (фактически неправильный исходя из того что поля имеют др. значения).
3. В поле "адрес" адресс неправильный, CRC соответствует п. 1, данные = правильные.
и т.д.
В последних двух случаях при ClearCommError(hComm,error) error = CE_FRAME
У обоих ПК одинаковые мат. платы (по крайней мере версия BIOS"а и модель), процы, ОЗУ и т.д. , все шнуры и приборы одни и те же, версии ОС тоже.
Нашел про CE_FRAME:
Сбои кадра (framing errors) происходят тогда, когда биты данных в последовательном потоке не завершаются корректным стоповым битом, который всегда должен иметь значение 1. Как и в случае ошибок четности, сбои кадра обычно возникают вследствие несоответствия параметров линии между приемником и передатчиком. Получив сбои кадра, проверьте параметры обоих сторон. Сбои кадра, чаще, чем ошибки четности, могут быть вызваны электрическими помехами. И снова решением проблемы может стать укорачивание кабеля, и удаление его от источников помех.
Никто не сталкивался ?
← →
atruhin © (2007-11-13 15:34) [1]Ну, я сталкивался, и что? Вроде все понятно сказанно:
> Как и в случае ошибок четности, сбои кадра обычно возникают
> вследствие несоответствия параметров линии между приемником
> и передатчиком. Получив сбои кадра, проверьте параметры
> обоих сторон. Сбои кадра, чаще, чем ошибки четности, могут
> быть вызваны электрическими помехами. И снова решением проблемы
> может стать укорачивание кабеля, и удаление его от источников
> помех.
← →
balepa © (2007-11-14 08:19) [2]
> atruhin © (13.11.07 15:34) [1]
> Ну, я сталкивался, и что? Вроде все понятно сказанно:
И что делали ?
И как объяснить что на одно ПК работает с тем же кабелем и прибором, а с др. нет.
← →
Юрий Иванов (2007-11-14 09:56) [3]А вы устанавливаете из программы парметры RS-232? Скорость передачи, количество stop bit и т.п.? Если нет, то при обмене все это берется из настроек COM-порта в Windows - они одинаковые на обоих компьютерах?
← →
Jeer © (2007-11-14 09:58) [4]
> balepa © (14.11.07 08:19) [2]
>
>
Использовать правильно согласованный кабель, в особо трудных случаях переходить на токовую петлю или даже опто-развязку.
← →
balepa © (2007-11-14 13:02) [5]
> Юрий Иванов (14.11.07 09:56) [3]
> А вы устанавливаете из программы парметры RS-232? Скорость
> передачи, количество stop bit и т.п.? Если нет, то при обмене
> все это берется из настроек COM-порта в Windows - они одинаковые
> на обоих компьютерах?
Да.
← →
tesseract © (2007-11-14 18:02) [6]Кабель тот-же самый ? холодильников кругом нет ?
← →
balepa © (2007-11-15 05:55) [7]
> tesseract © (14.11.07 18:02) [6]
> Кабель тот-же самый ? холодильников кругом нет ?
Нет только два компа и все.
Еще на одном компе заработало только через примерно 5 опросов CE_FRAME вылазит и все.
← →
tesseract © (2007-11-15 10:53) [8]
> Еще на одном компе заработало только через примерно 5 опросов
> CE_FRAME вылазит и все.
Такое бывает когда кварц который частоту опроса задаёт сбоит. Но такое очень редко происходит. Причем, ты скажи когда у тебя когда ошибка при приемке или при передаче ? И установка параметров, точно проходит ? бывает, что не все драйверы COM- портов одинаковы по содержанию.
← →
balepa © (2007-11-15 12:58) [9]
> tesseract © (15.11.07 10:53) [8]
>
> > Еще на одном компе заработало только через примерно 5
> опросов
> > CE_FRAME вылазит и все.
>
>
> Такое бывает когда кварц который частоту опроса задаёт сбоит.
> Но такое очень редко происходит. Причем, ты скажи когда
> у тебя когда ошибка при приемке или при передаче ? И установка
> параметров, точно проходит ? бывает, что не все драйверы
> COM- портов одинаковы по содержанию.
При приемке. Если верить SetCommState, то проходит.
← →
tesseract © (2007-11-15 13:03) [10]просмотри PortMon-ом, покажет примерно где рыть. Сравни логи на двух компах.
← →
guav © (2007-11-15 23:55) [11]Как заполняется сруктура для SetCommState ? нет ли там неинициализированных полей или полей инициализированных GetCommState ?
← →
balepa © (2007-11-16 05:28) [12]
TRx = packed record
ADDR: Word;
CMD: Byte;
nnnn: Single;
//nnnn: array[0..3] of BYTE;
CODE: Byte;
CRC: Word;
end;//RxTTx = packed record
ADDR: Word;
CMD: Byte;
param: Byte;
CRC: Word;
end; //Tx
> guav © (15.11.07 23:55) [11]
> Как заполняется сруктура для SetCommState ? нет ли там неинициализированных
> полей или полей инициализированных GetCommState ?function TNagThread.OpenPort: Boolean;
begin
hComm:= CreateFile("\\.\COM1",GENERIC_READ or GENERIC_WRITE,
0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if hComm<>INVALID_HANDLE_VALUE then begin
GetcommState(hComm,ComDCB);
ComDCB.DCBlength:= sizeof(ComDCB);
ComDCB.BaudRate:= CBR_9600;
ComDCB.StopBits:= OneStopBit;
ComDCB.Parity:= 0;
ComDCB.ByteSize:= 8;
ComDCB.Flags:= ComDCB.Flags xor ComDCB.Flags;
ComDCB.Flags:= ComDCB.Flags or $00000001 or ($00000030
xor $00000020) or $00004000 or $00003000;
//RTS_CONTROL_TOGGLE $00003000}
SetCommState(hComm,ComDCB);
GetCommTimeouts(hComm,ComTimeouts);
ComTimeouts.ReadIntervalTimeout:= 0;
ComTimeOuts.ReadTotalTimeoutMultiplier:= 0;
ComTimeOuts.ReadTotalTimeoutConstant:= 0;
ComTimeOuts.WriteTotalTimeoutMultiplier:= 0;
ComTimeouts.WriteTotalTimeoutConstant:= 0;
SetCommTimeouts(hComm,ComTimeouts);
Result:= true;
end
else begin
Result:= false;
end;
end;
ЧтениеCRCError:= 0;
Tx.ADDR:= Addr;//1190;
Tx.CMD:= $40;
Tx.param:= 0;
Tx.CRC:= CalculateCRC16(@Tx,4); // ; 44370
RX.ADDR:= 0;
Rx.CMD:=0;
Rx.nnnn:=0;
Rx.CODE:=0;
Rx.CRC:=0;
ClearCommError(hComm,errors,@stat);
SetCommMask(hComm,EV_TXEMPTY);
WriteFile(hComm,Tx,6,RWBytes,nil);
WaitCommEvent(hComm,mask,nil);
ReadFile(hComm,Rx,10,RWBytes,nil);
CRC:= CalculateCRC16(@Rx,8);
PurgeComm(hComm,PURGE_RXCLEAR or PURGE_TXCLEAR);
sleep(6);
Выдержка из протокола обмена:
Признаком конца пакета служит отсутствие передачи на линии в течении времени, необходимого для передачи 5-6 байт, после окончания передачи стоп-бита последнего байта.
← →
tesseract © (2007-11-16 10:38) [13]
> WaitCommEvent(hComm,mask,nil); ReadFile(hComm,Rx,10,RWBytes,
> nil)
А почему бы лучше overlapped не использовать?
Задержки
ComTimeouts.ReadIntervalTimeout:= 0;
ComTimeOuts.ReadTotalTimeoutMultiplier:= 0;
ComTimeOuts.ReadTotalTimeoutConstant:= 0;
ComTimeOuts.WriteTotalTimeoutMultiplier:= 0;
ComTimeouts.WriteTotalTimeoutConstant:= 0;
Так не пишут. Особенно на скорости 9600 + задержка реакции девайса составит 100-200 мс. Перед инициализацией порта,всегда чисть буфер - там может какая-нить дрйнь после прошлого запуска остаться. Может поэтому и CE_FRAME.
ЗЫ: И кстати оригинальный способ ждать окончания записи :-)
← →
Slym © (2007-11-16 10:45) [14]tesseract © (16.11.07 10:38) [13]
способ ждать окончания записи
у мня тоже на этом глаз споткнутся при беглом чтении :) с таким жестким пессимизмом подход к делу :)
а не может EV_TXEMPTY возникнуть раньше вызова WaitCommEvent(hComm,mask,nil) что приведет к блокировке?
← →
guav © (2007-11-16 10:59) [15]> ComDCB.Flags:= ComDCB.Flags xor ComDCB.Flags;
Интересный способ обнулить флаги :)
> GetcommState(hComm,ComDCB);
Это плохая идея. Те поля которые явно не инициализированы - не будут в определённом состоянии, состояние будет зависеть от предыдущих параметров
тем более ComDCB.DCBlength не заполнено перед вызовом GetcommState - имеем там Undefined Behaviour. Вомзожно в этом и дело - на одной машине в стеке на месте ComDCB.DCBlength и других структур оказываются допустимые значения, на другой - нет.
Я бы заменилGetcommState(hComm,ComDCB);
наZeroMemory(@ComDCB, SizeOf(ComDCB));
АComDCB.Flags:= ComDCB.Flags xor ComDCB.Flags; ComDCB.Flags:= ComDCB.Flags or ...
наComDCB.Flags:= ...
;
Кстати, GetcommState, SetCommState, GetCommTimeouts и SetCommTimeouts это функции. Функции возвращают результат.
← →
tesseract © (2007-11-16 11:25) [16]
> Кстати, GetcommState, SetCommState, GetCommTimeouts и SetCommTimeouts
> это функции. Функции возвращают результат.
Который обязательно должен проверяться.
> а не может EV_TXEMPTY возникнуть раньше вызова WaitCommEvent(hComm,
> mask,nil) что приведет к блокировке?
Запросто, поэтому и говорю про оригинальный.
← →
balepa (2007-11-17 06:17) [17]
> Slym © (16.11.07 10:45) [14]
> tesseract © (16.11.07 10:38) [13]
> способ ждать окончания записи
> у мня тоже на этом глаз споткнутся при беглом чтении :)
> с таким жестким пессимизмом подход к делу :)
> а не может EV_TXEMPTY возникнуть раньше вызова WaitCommEvent(hComm,
> mask,nil) что приведет к блокировке?
Но результат она все равно вернет, в mask будут события.
Все равно после отправки запроса надо подождать немного "время для отправки 5-6 байт", а вот как его (время это) посчитать ?
> tesseract © (16.11.07 11:25) [16]
>
> > Кстати, GetcommState, SetCommState, GetCommTimeouts и
> SetCommTimeouts
> > это функции. Функции возвращают результат.
>
>
> Который обязательно должен проверяться.
Ну проверял я их все возвращают положительный результат.
> А почему бы лучше overlapped не использовать?
> Задержки
>
> ComTimeouts.ReadIntervalTimeout:= 0;
> ComTimeOuts.ReadTotalTimeoutMultiplier:= 0;
> ComTimeOuts.ReadTotalTimeoutConstant:= 0;
> ComTimeOuts.WriteTotalTimeoutMultiplier:= 0;
> ComTimeouts.WriteTotalTimeoutConstant:= 0;
> Так не пишут. Особенно на скорости 9600 + задержка реакции
> девайса составит 100-200 мс. Перед инициализацией порта,
> всегда чисть буфер - там может какая-нить дрйнь после прошлого
> запуска остаться. Может поэтому и CE_FRAME.
>
> ЗЫ: И кстати оригинальный способ ждать окончания записи
> :-)
Еще вчера начал переделывать на overlapped. Буфер чищу.
Откуда цифры 100-200 мс ?
← →
balepa (2007-11-17 06:21) [18]
> Slym © (16.11.07 10:45) [14]
> tesseract © (16.11.07 10:38) [13]
> способ ждать окончания записи
> у мня тоже на этом глаз споткнутся при беглом чтении :)
> с таким жестким пессимизмом подход к делу :)
> а не может EV_TXEMPTY возникнуть раньше вызова WaitCommEvent(hComm,
> mask,nil) что приведет к блокировке?
Но результат она все равно вернет, в mask будут события.
Все равно после отправки запроса надо подождать немного "время для отправки 5-6 байт", а вот как его (время это) посчитать ?
> tesseract © (16.11.07 11:25) [16]
>
> > Кстати, GetcommState, SetCommState, GetCommTimeouts и
> SetCommTimeouts
> > это функции. Функции возвращают результат.
>
>
> Который обязательно должен проверяться.
Ну проверял я их все возвращают положительный результат.
> А почему бы лучше overlapped не использовать?
> Задержки
>
> ComTimeouts.ReadIntervalTimeout:= 0;
> ComTimeOuts.ReadTotalTimeoutMultiplier:= 0;
> ComTimeOuts.ReadTotalTimeoutConstant:= 0;
> ComTimeOuts.WriteTotalTimeoutMultiplier:= 0;
> ComTimeouts.WriteTotalTimeoutConstant:= 0;
> Так не пишут. Особенно на скорости 9600 + задержка реакции
> девайса составит 100-200 мс. Перед инициализацией порта,
> всегда чисть буфер - там может какая-нить дрйнь после прошлого
> запуска остаться. Может поэтому и CE_FRAME.
>
> ЗЫ: И кстати оригинальный способ ждать окончания записи
> :-)
Еще вчера начал переделывать на overlapped. Буфер чищу.
Откуда цифры 100-200 мс ?
← →
guav © (2007-11-17 14:47) [19]> balepa
Попробуй таки убрать вызов GetcommState или хотя бы исправить в нём ошибку, у меня были проблемы именно с этим.
← →
balepa (2007-11-18 15:14) [20]Переделал "чтение" с использованием overlapped, но есть подозрения что Overlapped структуру сделать одну и сбрасывать event после использования ResetEvent"ом или оставить как есть ?
Код неопробован на работоспособность, потому что писалось сие дома.
Жду замечаний, предложений и рекомендаций.function TCP8501Thread.ReadParam(addr: Word; var param:
Single): boolean;
var
Signaled, errors: Cardinal;
Tx: TTx;
Rx: TRx;
stat: TComStat;
OvrW,OvrR: Overlapped;
begin
OvrW.hEvent:= CreateEvent(
nil, // default security attribute
TRUE, // manual-reset event
TRUE, // initial state = signaled
nil); // unnamed event object
OvrW.Internal:= 0;
OvrW.InternalHigh:= 0;
OvrW.Offset:= 0;
OvrW.OffsetHigh:= 0;
Tx.ADDR:= addr;
Tx.CMD:= $40;
Tx.param:= 0;
Tx.CRC16:= CalculateCRC16(@Tx,4);
PurgeComm(hComm, PURGE_TXABORT or PURGE_RXABORT or PURGE_RXCLEAR
or PURGE_TXCLEAR);
ClearCommError(hComm,errors,@stat);
if not WriteFile(hComm,Tx,6,RWBytes,@OvrW) then begin
if GetLastError = ERROR_IO_PENDING then begin
Signaled:= WaitForSingleObject(OvrW.hEvent,WRITE_TIMEOUT);
if (Signaled=WAIT_OBJECT_0) and (GetOverlappedResult(hComm,
OvrW,RWBytes,false)) then begin
//ResetEvent(OvrW.hEvent);
CloseHandle(OvrW.hEvent);
Sleep(10);
FillChar(Rx,sizeof(TRx),0);
OvrR.hEvent:= CreateEvent(
nil, // default security attribute
TRUE, // manual-reset event
TRUE, // initial state = nonsignaled
nil); // unnamed event object
OvrR.Internal:= 0;
OvrR.InternalHigh:= 0;
OvrR.Offset:= 0;
OvrR.OffsetHigh:= 0;
ClearCommError(hComm,errors,@stat);
if not ReadFile(hComm,Rx,10,RWBytes,@OvrR) then
begin
if GetLastError = ERROR_IO_PENDING then begin
Signaled:= WaitForSingleObject(OvrR.hEvent,READ_TIMEOUT);
if (Signaled=WAIT_OBJECT_0) and (GetOverlappedResult(hComm,
OvrR,RWBytes,false)) then begin
CloseHandle(OvrR.hEvent);
CRC:= CalculateCRC16(@Rx,8);
if CRC=Rx.CRC16 then begin
asm
PUSHA
mov DWORD PTR eax,Rx.nnnn
bswap eax
mov Rx.nnnn, eax
POPA
end;
param:= Rx.nnnn;
Result:= true;
end else begin //if CRCfalse
if CRCError < 4294967294 then CRCError:=
CRCError + 1
else CRCError:= 1;
CloseHandle(OvrR.hEvent);
Result:= true;
end;
end else begin //if read failed
RErrors:= RErrors + 1;
CloseHandle(OvrR.hEvent);
Result:= false;
end;
end; //GetLastError Read
end
end else begin //if write failed;
WErrors:= WErrors + 1;
CloseHandle(OvrW.hEvent);
Result:= false;
end;
end else Result:= false; //GetLastError write
end; //if not write
if Result=false then begin
case addr of
1183: b1:= false;
1182: b2:= false;
1180: K:= false;
end;
end else begin
case addr of
1183: b1:= true;
1182: b2:= true;
1180: K:= true;
end;
end;
end;
← →
Slym © (2007-11-19 04:26) [21]а Вы говорите процедурный язык...
← →
balepa © (2007-11-19 05:27) [22]
> balepa (18.11.07 15:14) [20]
> end else begin //if CRCfalse
> if CRCError < 4294967294 then CRCError:=
>
> CRCError + 1
> else CRCError:= 1;
> CloseHandle(OvrR.hEvent);
> Result:= true;
> end;
CloseHandle(OvrR.hEvent); лишнее оказывается :)
А так вроде работает пока.
← →
balepa © (2007-11-19 05:55) [23]
> balepa © (19.11.07 05:27) [22]
>
> > balepa (18.11.07 15:14) [20]
> > end else begin //if CRCfalse
> > if CRCError < 4294967294 then CRCError:
> =
> >
> > CRCError + 1
> > else CRCError:= 1;
> > CloseHandle(OvrR.hEvent);
> > Result:= true;
> > end;
>
> CloseHandle(OvrR.hEvent); лишнее оказывается :)
>
> А так вроде работает пока.
CE_FRAME вылазит иногда.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2008.08.31;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.008 c