Форум: "Система";
Текущий архив: 2003.12.30;
Скачать: [xml.tar.bz2];
ВнизCom порт в XP Найти похожие ветки
← →
div123 (2003-10-20 20:19) [0]Привет старожилам, может чем поможете.
Программа общается с девайсом через комовский порт, в 95, 98, МЕ все нормально, в ХР отказывается работать.
При просмотре работы порта окозалось что ХР собирает все команды вместе и посылает в порт куском, а потом пытается что то прочитать.
Т.Е. при
for i:=0 to 5 do begin
WriteFile(...,i,1,...);
ReadFile(...,X,1,...);
end;
НЕ в ХР: <1; >X; <2; >X; <3; >X; <4; >X; <5; >X;
в ХР: <12345; >X;
Сам поборол это с помощью банальной задержки в 20 мс, но может кто подскажет способ покоректней
← →
miek (2003-10-20 23:05) [1]Действовать напрямую через API или компоненты-обертки.
А ты скорость-то обмена задал или дефолтную оставил?
← →
div_123 (2003-10-21 12:42) [2]Спасибо за отклик
Скорость задавал,
не подскажешь функции апишные для работы
← →
div_123 (2003-10-21 13:38) [3]Сейчас сам посмотрел, оказалось что WriteFile и ReadFile API функции и есть, так что дело не в ентом
← →
Fredericco (2003-10-21 13:55) [4]Поищи TCommPortDriver, вроде даже был на этом сайте. У меня с ним проблем никаких.
← →
miek (2003-10-21 16:39) [5]API-то они API, но главное - как конфигурация устройства производилась.
← →
jack128 (2003-10-21 22:03) [6]Что то я не понимаю как тако возможно..
Ты в синхронном или асинхр. режиме работаешь?
Если первое попробуй тайм ауты побольше сделать, если втрое то где ждешь пока из порта инфа прочитается??
← →
Fredericco (2003-10-22 11:10) [7]Задержки в малые величины (20 мс) на разных осях и разных компах будут далеко не одинаковые.
← →
div_123 (2003-10-22 16:53) [8]Установки такие:
Hwd:=createFile( name,
GENERIC_READ or GENERIC_WRITE,
0,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,
0);
GetCommState(Hwd,PlacePort);
with PlacePort do begin
BaudRate:=Rate; //?CBR_9600
Parity:=Parit; //ODDPARITY
ByteSize:=ByteS; //8
StopBits:=StopBit;//ONESTOPBIT
EvtChar:=#00;
end;
GetCommTimeouts(Hwd,timOut);
timOut.ReadIntervalTimeout:=MAXDWORD;
timOut.ReadTotalTimeoutMultiplier:=MAXDWORD;
timOut.ReadTotalTimeoutConstant:=200;
timOut.WriteTotalTimeoutMultiplier:=20;
timOut.WriteTotalTimeoutConstant:=0;
SetCommTimeouts(Hwd,timOut);
Девайс самопальный, не мой, я только переписал старый ДОСовский интерфейс на ВИНДовский.
Режим работы такой:
1) посылка в прибор команды, от 2 до 4 байт длиной
2) прибор обрабатывает команду и выдает на порт ответ устанавливая на одной из ног порта признак ответа
3) программа читает ответ, 1 байт
4) и т.д.
под ДОСом чтение и запись в порт на Асемблере написаны, соответственно под винды на АРI переведено. Но проблема не в том что под виндами не работает, все работает замечательно (так что работа прибора с портом сделана человеком вполне корректно, если через АРI все нормально отрабатывает), но под ХР эфект сбора команд в кучу точно есть.
ясно что 20 мс на старых машинах могут растянутся до 80, а то и больше, но врядли на них будет ХР стоять
Кстати о коде
function TApparat.SendData(dat: string): byte;
var
Bb: TDataP; //array [0..5] of byte
i: integer;
begin
if _Device=nil then Exit;
Result:=0;
i:=Length(dat);
CopyMemory(@Bb,PChar(dat),i);
Bb[5]:=i;
_Device.SetToPort(Bb);
//общая задержка
if TIME_OUT>0 then Delay(TIME_OUT);
Bb:=_Device.GetFromPort;
if Bb[1]=1 then Result:=Smallint(Bb[0]);
end;
function TComPort.GetFromPort: TDataP;
var
num: longint;
begin
Result[0]:=0;
Result[1]:=0;
Result[2]:=0;
Result[3]:=0;
Result[4]:=0;
Result[5]:=0;
if not(Hwd=INVALID_HANDLE_VALUE) then begin
ReadFile(Hwd,Result,1,num,@an);
Result[1]:=1;
ClearCommError(Hwd,Errs,@Stat);
end;
end;
procedure TComPort.SetToPort(D: TDataP);
var
num: longint;
begin
if Hwd>INVALID_HANDLE_VALUE then begin
if not PurgeComm(Hwd,PURGE_TXCLEAR) then Exit;
if not PurgeComm(Hwd,PURGE_RXCLEAR) then Exit;
num:=D[5];
WriteFile(Hwd,D,num,num,@an);
ClearCommError(Hwd,Errs,@Stat);
end;
end;
← →
div_123 (2003-10-22 17:14) [9]Прошу прощения в описании установок при удалении сторонних строчек вытер
SetCommState(Hwd,PlacePort);
Функция присутствует где ей положено, после присвоения значений полям PlacePort
← →
jack128 (2003-10-22 21:46) [10]
> Hwd:=createFile( name,
> GENERIC_READ or GENERIC_WRITE,
> 0,
> nil,
> OPEN_EXISTING,
> FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,
> 0);
ты открываешь порт асинхронно, после WiteFile стоит подождать пока данные реально уйдет в порт(GetOverlappedResult)..
← →
div_123 (2003-10-23 13:47) [11]Спасибо всем откликнувшимся, особо jack128
После убирания FILE_FLAG_OVERLAPPED заработало, но только пришлось при каждой приостановке тренда вычищать буфер порта и принудительно приостанавливать чтение/запись, иначе прога подвисала.
Непонятно только почему при работе с портом практически все мануалы рекомендуют именно FILE_FLAG_OVERLAPPED
Пока
Страницы: 1 вся ветка
Форум: "Система";
Текущий архив: 2003.12.30;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.009 c