Работа с COM портами

Работа с COM портами

Получение списка имеющихся в системе портов
Существует как минимум два способа:
Список доступных портов можно узнать, проанализировав ключ реестра
HKEY_LOCAL_MACHINEHARDWAREDEVICEMAPSERIALCOMM
Можно поочередно попробовать открыть порты COM1 .. COM9, таким образом удасться
установить все доступные порты (т.е. порты, не открытые другими приложениями)

…………………..

Работа с COM портами

Получение списка имеющихся в системе портов
Существует как минимум два способа:
Список доступных портов можно узнать, проанализировав ключ реестра
HKEY_LOCAL_MACHINEHARDWAREDEVICEMAPSERIALCOMM
Можно поочередно попробовать открыть порты COM1 .. COM9, таким образом удасться
установить все доступные порты (т.е. порты, не открытые другими приложениями)

Открытие и настройка COM порта
Работу с СOM портом проще всего пояснить на примере

var DCB : TDCB; hPort : THandle;begin //
1. Открываем файл hPort := CreateFile(PChar(‘COM’+IntToStr(<номер порта>)),
GENERIC_READ + GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
//
2. Контроль ошибок if hPort = INVALID_HANDLE_VALUE then begin // Обнаружена
ошибка, порт открыть не удалось exit; end; //
3. Чтение текущих настроек порта if GetCommState(hPort, DCB) then ; //
4. Настройки: // Скорость обмена DCB.BaudRate := [скорость обмена]; // Число бит
на символ DCB.ByteSize := [размер "байта" при обмене по COM порту — обычно 8
бит]; // Стоп-биты DCB.StopBits := [константа, определяющая кол-во стопбитов];
// Четность DCB.Parity := [константа, определяющая режим контроля четности];
DCB.Flags := 20625; //
5. Передача настроек if not SetCommState(hPort, DCB) then {ошибка настройки
порта}; //
6. Настройка буферов порта (очередей ввода и вывода) if not SetupComm(hPort, 16,
16) then {ошибка настройки буферов}; //
7. Сброс буфферов и очередей if PurgeComm(hPort, PURGE_TXABORT or PURGE_RXABORT
or PURGE_TXCLEAR or PURGE_RXCLEAR) then ; …………… //
8. Закрытие порта CloseHandle(hPort);end;

Теперь рассмотрим все шаги по порядку:
Шаг 1 — открытие порта. Порт открывается стандартной командой CreateFile, только
в качестве имени файла передается имя порта (например, "COM1")
Шаг 2 — проверка успешности шага 1. Если порт открылся, то функция CreateFile
возвращает его Handle, иначе hPort = INVALID_HANDLE_VALUE, что свидетельствует
об ошибке
Шаг 3 — загрузка текущих настроек порта при помощи функции GetCommState. Этот
шаг не является обязательным, т.к. можно настроить порт, как говорится, "с
нуля". После выполнения GetCommState структура DCB заполняется текущими
настройками
Шаг 4 — занесение в структуру DCB необходимых настроек
Шаг 5 — Настрока порта при помощи функции SetCommState. После настройки с портом
уже можно работать, но в примере я выполняю полную настроку (шаги 6 и 7)
Шаг 6 — Настрока размеров буфера приема и предачи при помощи SetupComm. В моем
примере заданы буфера очень небольшого размера, рекомендуется задать окого 1 кб

Шаг 7 — Очистка буферов и очередей порта — второй параметра функции PurgeComm
является битовой маской и задает, что именно необходимо очитстить — в нашем
случае все по максимуму
Шаг 8 — закрытие порта после завершения работы с ним

Чтение и запись данных
Запись данных производится следующим образом:

Result := WriteFile(hPort, Buffer, Size, NumberOfBytesWritten, nil);
параметр NumberOfBytesWritten после выполнения содержит количество реально
переданных байт.
Чтение данных:
Result := ReadFile(hPort, Buffer, Size, NumberOfBytesReaded, nil);
параметр Size задает читаемый объем информации (его значение должно быть меньше
объема буфера), NumberOfBytesReaded получает количество реально прочитанных байт

Настройка таймаутов приема и передачи
Настройку таймаутов можно провести при помощи слудующей функции:

function SetComPortTimeouts: boolean;var CommTimeouts : TCommTimeouts; ComErrors
: DWORD;begin Result := false; // Если соединение есть, то перенастроим его if
hPort <> INVALID_HANDLE_VALUE then begin // Чтение текущих таймаутов
GetCommTimeouts(hPort, CommTimeouts); … настройка параметров структуры
CommTimeouts … // Установка таймаутов SetCommTimeouts(hPort, CommTimeouts);
Result := true; end;end;

Запрос ошибки
Запрос ошибки производится при помощи функции ClearCommError

var ComErrors : DWORD;begin ClearCommError(hPort, ComErrors, nil);end;
Данная функция сбрасывает состояние ошибки, передавая код ошибки в переменную
ComErrors
 

Комментариев нет

  1. Аноним:

    Это конечно хорошо, но Дельфям, как системный программист я бы не доверился, особенно в Windows 2003 Server…

    Прямое обращение все-таки :upset

  2. Аноним:

    Написано, хорошо, правильно, но для Win2k3 этот код не пойдет, особенно после компилятора Борланда, у меня такое ощущение что МелкоСофт, направило свои силы против борладна, дабы отсечь «кривые» компиляторы…
    Это все упадет при первом же прямом обращении к порту …
    Вот так точнее будет

  3. Аноним:

    Можно ли переделать кабель PL-2303 чтоб заряжал тело када в инете висишь .

Добавить комментарий