COM-порт в Windows (программирование): различия между версиями
Содержимое удалено Содержимое добавлено
DannyS712 (обсуждение | вклад) м <source> -> <syntaxhighlight> (phab:T237267) |
|||
Строка 56:
Открытый порт должен быть закрыт перед завершением работы [[программа|программы]]. В [[Win32 (программирование)|Win32]] закрытие объекта по его [[дескриптор]]у выполняет функция <code>CloseHandle</code>:
<
BOOL CloseHandle(
HANDLE hObject
);
</syntaxhighlight>
При успешном завершении функция возвращает не нулевое значение, при ошибке нуль.
=== Пример открытия/закрытия на языке [[Си (язык программирования)|C]] ===
<
#include <windows.h>
//. . .
Строка 77:
CloseHandle(Port);
//. . .
</syntaxhighlight>
В данном [[пример]]е открывается порт <code>СОМ2</code> для [[чтение|чтения]] и [[запись|записи]], используется синхронный режим обмена. Проверяется успешность открытия порта, при ошибке выводится сообщение и программа завершается. Если порт открыт успешно, то он закрывается.
Строка 256:
winbase.h
<
typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout; /* Maximum time between read chars. */
Строка 264:
DWORD WriteTotalTimeoutConstant; /* Constant in milliseconds. */
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
</syntaxhighlight>
'''ReadIntervalTimeout''' - время в миллисекундах, задающее максимальное время, для интервала между поступлением двух символов по линии связи. Если интервал между поступлением каких-либо двух символов будет больше этой величины, операция ReadFile завершается и любые буферизированные данные возвращаются.
Чтобы операция ReadFile немедленно возвращала управление со всеми полученными данными (асинхронный режим) следует задавать следующие значения:
<
ReadIntervalTimeout=0xFFFFFFFF;
ReadTotalTimeoutConstant=0;
ReadTotalTimeoutMultiplier=0;
</syntaxhighlight>
'''ReadTotalTimeoutMultiplier''' - Множитель, используемый, чтобы вычислить полный период времени простоя для операций чтения, в миллисекундах. Для каждой операции чтения, это значение умножается на затребованное число байтов, которые читаются.
Строка 291:
Вариант 1: (максимальная задержка при чтении и записи = TIMEOUT)
<
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
Строка 298:
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = TIMEOUT;
</
Вариант 2: Инициализация значениями (без задержки при чтении)
<
COMMTIMEOUTS CommTimeOuts={0xFFFFFFFF,0,0,0,1500};
</syntaxhighlight>
== Пример настройки порта ==
Строка 315:
Настройку структуры можно выполнить вручную или при помощи функции GetCommConfig().
Например:
<
/* Получение существующих настроек */
unsigned long new_size = 0;
Строка 326:
goto error;
}
</
== Выделение памяти для структуры COMMPORT ==
Строка 333:
Прием и передача данных для последовательного порта может выполнятся в синхронном или асинхронном режимах. Асинхронный режим позволяет реализовать работу по событиям, в то время как синхронный лишен этой возможности, но является более простым в реализации.
Для работы в синхронном режиме, порт должен быть открыт следующим образом:
<
CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
</syntaxhighlight>
Предпоследний параметр '''dwFlagsAndAttributes''' должен быть равен 0.
После успешного открытия порта, данные могут быть считаны или записаны при помощи функций ReadFile() и WriteFile().
<
HANDLE port = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);
Строка 348:
if(ReadFile(port,dst,size, &size,0))
printf("\nRead %d bytes",size);
</syntaxhighlight>
Функция ReadFile/WriteFile осуществляет чтение/запись из файла (устройства) начиная с текущей позиции после окончания чтения обновляет указатель в файле.
<
BOOL ReadFile(
HANDLE hFile, // хендл файла
Строка 359:
LPOVERLAPPED lpOverlapped //структура OVERLAPPED
);
</syntaxhighlight>
Недостатком этого способа является то, что вызывая функцию ReadFile(), мы не знаем есть ли данные для чтения. Можно циклически проверять их наличие, но это приводит к дополнительным расходам времени ЦП.
Поэтому на практике часто удобней использовать асинхронный режим. Для этого при вызове функции CreateFile() параметр '''dwFlagsAndAttributes''' должен быть равен '''FILE_FLAG_OVERLAPPED'''.
<
CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
</syntaxhighlight>
Далее, необходимо настроить реакцию порта на события при помощи функции SetCommMask() и используя функции WaitCommEvent() и WaitForSingleObject() ожидать событие или тайм аут.
Например:
<
const int READ_TIME = 100;
OVERLAPPED sync = {0};
Строка 397:
}
CloseHandle(sync.hEvent);
</syntaxhighlight>
== Сброс порта ==
Строка 404:
=== tty.h ===
<
#ifndef TTY_H
#define TTY_H
Строка 437:
#endif
</syntaxhighlight>
=== tty.cpp ===
<
#include "tty.h"
#include <iostream>
Строка 616:
}
</syntaxhighlight>
{{Темы|Программирование}}
|