Статьи Королевства Дельфи

         

Некоторые правила для работы с портами


Следует иметь в виду что при разработке программ имеющих дело работы с портами следует учитывать следующие факторы :

  • а) Стараться использовать функции высокого уровня для доступа к портам (в частности WinAPI) и не прибегать к низкоуровневым операциям чтения/записи портов. Если вы все-таки решили писать низкоуровневое чтение то эти процедуры нужно выносить в отдельную DLL или VXD, по следующим причинам - известно, что операционная система Windows95/98 а особенно NT являются по своей сути многозадачными системами. То есть если ваша программа обращается конкретно к порту не через динамический вызов функции DLL или VXD ( использования механизма DLL) а напрямую то это может сказаться на корректной работе системы или даже завалить ее. И даже если в Windows95/98 такой подход вполне может работать то в Windows NT вследствие его архитектуры не разрешит непосредственное чтение/запись напрямую, а использование механизма DLL или VXD позволяет обойти эту проблему.
  • б)Если вы работаете с каким-то нестандартным портом ввода-вывода (например портом хранящим состояние кнопок пульта ДУ TVTunera то наверняка в комплекте поставки родного софта найдется DLL или VXD для управления этим устройством и отпадет нужда писать код, так я при работе с пультом ДУ TVTunerа использую стандартную DLL поставляемую в комплекте, это сразу решило вопросы связанные с управлением портами данного тюнера)
Итак, отступление — немного практики…
Маленький пример для работы с портами (первый пример был уже опубликован в королевстве Дельфи и представлял собой пример работы с весами ПетрВес) function PortInit : boolean; //инициализация var f: THandle; ct: TCommTimeouts; dcb: TDCB; begin f := Windows.CreateFile(PChar('COM1'), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (f < 0) or not Windows.SetupComm(f, 2048, 2048)or not Windows.GetCommState(f, dcb) then exit; //init error dcb.BaudRate := скоpость; dcb.StopBits := стоп-биты; dcb.Parity := четность; dcb.ByteSize := 8; if not Windows.SetCommState(f, dcb) or not Windows.GetCommTimeouts(f, ct) then exit; //error ct.ReadTotalTimeoutConstant := 50; ct.ReadIntervalTimeout := 50; ct.ReadTotalTimeoutMultiplier := 1; ct.WriteTotalTimeoutMultiplier := 0; ct.WriteTotalTimeoutConstant := 10; if not Windows.SetCommTimeouts(f, ct) or not Windows.SetCommMask(f, EV_RING + EV_RXCHAR + EV_RXFLAG + EV_TXEMPTY) then exit; //error result := true; end; function DoneComm: boolean; //закpыть поpт begin result := Windows.CloseHandle(f); end; function PostComm(var Buf; size: word): integer; //пеpедача в поpт var p: pointer; i: integer; begin p := @Buf; result := 0; while size > 0 do begin if not WriteFile(f, p^, 1, i, nil) then exit; inc(result, i); inc(integer(p)); dec(size); Application.ProcessMessages; end; end; function ReadComm(var Buf; size: word): integer; //пpием из поpта var i: integer; ovr: TOverlapped; begin fillChar(buf, size, 0); fillChar(ovr, sizeOf(ovr), 0); i := 0; result := -1; if not windows.ReadFile(f, buf, size, i, @ovr) then exit; result := i; end; Данный пример был взят мной из многочисленный FAQ посвященных в DELPHI в сети ФИДО



Содержание  Назад  Вперед