Форум: "Система";
Текущий архив: 2004.05.23;
Скачать: [xml.tar.bz2];
ВнизЧтение и запись в COM-порт в Win XP/NT Найти похожие ветки
← →
nec (2004-04-08 03:00) [0]Помогите пожалуйста!!!
Я пишу прогу, которая должна посылать команды и считывать данные с прграммируемого контроллера через COM-порт. Под мастдай 98 прога работает, а NT/XP не дает читать и писать в порт. Реально ли реализовать чтение/запись под ХР/NT/2000 чисто средствами Делфа без подключения левых драйверов (прямого доступа)??? Если можно то как? Помогите чем сможете.
Заранее спасибо!!!
← →
GanibalLector © (2004-04-08 03:04) [1]У меня все работает.
Сразу возникает вопрос, как написано???Если через асемблерные вставки,то и не будет.А если на чистом WinApi , то
покажи как инициализируешь порт(обычно там траблы)!
Да и вообще,PortMon-рулит!!!Запускай и смотри.
← →
tesseract © (2004-04-08 13:36) [2]Рекомендуется к прочтению книга "Последовательные интерфейсы ПК. Практика программирования". О ней можно в "Книгах" прочитать.
только цена её пониже - на Совке 199 р.
← →
nec (2004-04-09 01:52) [3]Gорт инициализирую стандартом, через CreateFile(...
← →
nec (2004-04-09 01:59) [4]Sorry за глупую опечатку:-)
Если быть точнее:
CreateFile("COM1",GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
← →
jack128 © (2004-04-09 11:13) [5]type
TTransferFunc = function (Handle: THandle; DataPtr: Pointer;
MaxDataSize: DWORD; var lpNumberOfBytesTranser: DWORD;
lpOverlapped: POverlapped): BOOL; stdcall;
TTransferDirection = (tdRead, tdWrite);
const
TransferFuncs: array[TTransferDirection] of Pointer = (@ReadFile, @WriteFile);
function TAsyncCommPortDriver.TransferData(Direction: TTransferDirection;
DataPtr: pchar; DataSize, Timeout: DWORD): DWORD;
var
nTransfer: DWORD;
ov: TOverlapped;
bTransferCompleted: boolean;
begin
// Do nothing if port has not been opened
Result := 0;
if not Connected then
exit;
bTransferCompleted := True;
// Pause polling
PausePolling;
try
if not Assigned(FEvent) then
FEvent := TEvent.Create(nil, False, False, "");
ZeroMemory(@ov, SizeOf(ov));
ov.hEvent := FEvent.Handle;
bTransferCompleted :=
TTransferFunc(TransferFuncs[Direction])(FHandle, DataPtr, DataSize, nTransfer, @ov);
if not bTransferCompleted and (GetLastError <> ERROR_IO_PENDING) then
begin
// Передача данных закончена, а то что с ошибкой, ну дык, что поделаешь..
bTransferCompleted := True;
Exit;
end;
Result := nTransfer;
while True do
begin
FEvent.WaitFor(Timeout);
bTransferCompleted := GetOverlappedResult(FHandle, ov, nTransfer, False);
// Если нечего не прочитали/записали с прошлого раза, то на выход...
if nTransfer = Result then Exit;
Result := nTransfer;
if bTransferCompleted then Exit;
end;
finally
if not bTransferCompleted then Cancel;
// Continue polling
ContinuePolling;
end;
end;
function TAsyncCommPortDriver.ReadDataEx(DataPtr: pchar; MaxDataSize,
Timeout: DWORD): DWORD;
begin
Result := TransferData(tdRead, DataPtr, MaxDataSize, Timeout);
end;
function TAsyncCommPortDriver.SendDataEx(DataPtr: pchar; DataSize,
Timeout: DWORD): DWORD;
begin
Result := TransferData(tdWrite, DataPtr, DataSize, Timeout);
end;
← →
GanibalLector © (2004-04-10 00:49) [6]>>>Nec
убери FILE_FLAG_OVERLAPPED и поставь FILE_ATTRIBUTE_NORMAL.
← →
jack128 © (2004-04-10 12:01) [7]И если последуешь совету Лектора, то почитай про настройку таймаутов. Обычно это больная тема
← →
nec (2004-04-10 16:55) [8]Jack182"у
Пожалуйста объясни, что есть TAsyncCommPortDriver.... Делфа на него ругается.
← →
Jack128 © (2004-04-10 17:06) [9]У-у-у как все запущено.. ;-)
TAsyncCommPortDriver - это мой компонентик для работы ком портами, основан на TCommPortDriver©Marco Cocco (советую скачать, вроде тут в кладовке валялся, на torry.net - точно есть)
Этот код я просто выдрал для примера...
P.S. Учи Object pascal - без него в Delphi никак
← →
Atrebuncev (2004-04-10 18:23) [10]Есть специальные компоненты для работы с COM-портами. Один из лучших - Comdrw32 (их сайт http://www.mdlive.com/d3k/delphi4). там уже все написано и таймауты в том числе. А с АСМ конечно не надо дергаться. Это уже язык только микроконтроллеров, да и то пока у них память маленькая.
← →
GanibalLector © (2004-04-11 02:17) [11]А че Вы так WinApi не взлюбили???
Все просто.Вот ложу пример:
function LStr(const Source:Ansistring;Count:Integer):Ansistring;
begin
Result:=Copy(Source,1,Count);
end;
function OpenComm(Mode:AnsiString):THandle;
var
DCB : TDCB;
TOut: TCommTimeouts;
I:Integer;
Bfr:AnsiString;
begin
Bfr:=Mode;
UniqueString(Bfr);
I:=Pos(":",Bfr)-1;
if I<=0 then I:=4;
Result := CreateFile(PChar(LStr(Bfr,I)),GENERIC_READ or GENERIC_WRITE,
0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
GetCommState( Result, DCB) ;
BuildCommDCB(PChar(Bfr),DCB);
DCB.EvtChar := #13;
SetCommState( Result, DCB) ;
//
TOut.ReadIntervalTimeout := MAXDWORD;
TOut.ReadTotalTimeoutMultiplier := 0;
TOut.ReadTotalTimeoutConstant := 0;
TOut.WriteTotalTimeoutMultiplier := 0;
TOut.WriteTotalTimeoutConstant := 0;
SetCommTimeOuts( Result, TOut);
SetCommMask(Result,EV_RLSD OR EV_RXFLAG);
PurgeComm(Result,PURGE_TXCLEAR); //clear transmit buffer
PurgeComm(Result,PURGE_RXCLEAR); //clear receive buffer
end;
function ReadComm(Handle:THandle; var Bfr:AnsiString):Integer;
var
I,J:DWord;
begin
Result:=0;
J:=Length(Bfr);
repeat
ReadFile(Handle, Bfr[Result+1], J-DWord(Result), I, nil);
Inc(Result,Integer(I));
if DWord(Result)=J then break;
until I=0;
end;
function WriteComm(Handle:THandle; const Bfr:AnsiString):Integer;
var
I,J:DWord;
begin
Result:=0;
J:=Length(Bfr);
repeat
WriteFile(Handle, Bfr[Result+1], J-DWord(Result), I, nil);
Inc(Result,Integer(I));
if DWord(Result)=J then break;
until I=0;
end;
function CloseComm(Handle:THandle):boolean;
begin
CloseHandle(Handle);
result:=true;
end;
function SetRxTime(Handle:THandle; const TimeC,TimeM:Integer):Boolean;
var
TOut:TCommTimeouts;
begin
if (TimeC=0) AND (TimeM=0) then
TOut.ReadIntervalTimeout := MAXDWORD
else TOut.ReadIntervalTimeout := 0;
TOut.ReadTotalTimeoutMultiplier := TimeM;
TOut.ReadTotalTimeoutConstant := TimeC;
TOut.WriteTotalTimeoutMultiplier := 0;
TOut.WriteTotalTimeoutConstant := 0;
Result:=SetCommTimeOuts(Handle, TOut);
end;
Вызывать так :
...
Handle:=OpenComm("COM"+co+":BAUD="+baud+" PARITY=N DATA=8 STOP=1");
if Handle=INVALID_HANDLE_VALUE then begin result:=false;exit;end;
setrxtime(handle,100,25);
...
← →
Jack128 © (2004-04-11 11:59) [12]
> А че Вы так WinApi не взлюбили???
А кто не взлюбил? ;-)
← →
GanibalLector © (2004-04-11 13:11) [13]>А кто не взлюбил? ;-)
Та даже ты!!!Используешь TAsyncCommPortDriver,а зачем???
← →
Jack128 © (2004-04-11 13:31) [14]
> Та даже ты!!!Используешь TAsyncCommPortDriver,а зачем???
Могу расказать.
Первая моя программа - как работа с устройством через ком порт. Тогда я ни о каких апи, естественно не знал.. Скачал компонент TCommPortDriver и использовал его..Со временем я узнал, что оказывается существует такая вещь как апи, и можно использовать их для работы с портом, но меня это не впечетлило ибо нафиг? Я привык работать с этим компонентом, он меня всем устаивал..Некоторое время назад мне потребовался компонент для работы с портом открытым с флагом FILE_FLAG_OVERLAPPED. Интерфейс работы с портом, который предоставлял TCommPortDriver меня вполне устраивал, и я переписал иерархию так: TCustomCommPortDriver - в котором весь общий код (установка параметров порта (скорость, контроль четности и ежи с ними)) от него наследуются TSyncCommPortDriver и TAsyncCommPortDriver, в которых перекрываются базовые методы чтения/записи и коннект к порту..
По поводу не любви к апи: не всяк кто пользуется компонентами - не знает апи, если бы я не знал апи (в части работы с портами), то я бы никогда не смог написать свой компонентик.. Тут дело в другом - тебе скорее всего по нраву процедурное программирование, а мне ООП ;-)
← →
GanibalLector © (2004-04-11 16:58) [15]>Jack128
Да,возможно это дело вкуса.
Я и сам начинал работать с портом через компоненты серии TurboPower(под названием AsyncProf...).Но позже возникли некоторые сложности при реализации проекта.В часности,необходимо было ответить устройству в течении 2-5мсек. и все попытки сводились на НЕТ(с этим ПОГАНЫМ компонентом).Вот тогда я и начал юзать WimApi,естественно возникали сотни вопросов\ошибок,но со временем все уляглось и ЩА все ОК.
З.Ы. И еще,я как-то посмотрел работу этого компонента через PortMon.Я был просто в ужасе!!!С тех пор категорически НЕТ.
← →
Jack128 © (2004-04-11 17:32) [16]
> [15] GanibalLector © (11.04.04 16:58)
Хе, я использую только компоненты с исходниками, в случае чего всегда можно напильником обработать ;-)
Страницы: 1 вся ветка
Форум: "Система";
Текущий архив: 2004.05.23;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.036 c