BOOL GetCommState( HANDLE hFile, LPDCB lpDCB );

Таким образом, нет необходимости вникать во все тонкости структуры.

После этого некоторые поля DCB заполняются вручную, а именно:

BaudRate — скорость передачи данных. Возможно указание следующих констант: CBR_110, CBR_300, CBR_600, CBR_1200, CBR_2400, CBR_4800, CBR_9600, CBR_14400, CBR_19200, CBR_38400, CBR_56000, CBR_57600, CBR_115200, CBR_128000, CBR_256000.

ByteSize — определяет число информационных бит в передаваемых и принимаемых байтах. Может принимать значение 4, 5, 6, 7, 8.

Parity — определяет выбор схемы контроля четности. Данное поле должно содержать одно из следующих значений:

  • EVENPARITY — дополнение до четности;
  • MARKPARITY — бит четности всегда равен 1;
  • NOPARITY— бит четности отсутствует;
  • ODDPARITY — дополнение до нечетности;
  • SPACEPARITY — Бит четности всегда 0.

StopBits — задает количество стоповых бит. Поле может принимать следующие значения:

  • ONESTOPBIT — один стоповый бит;
  • ONE5STOPBIT — полтора стоповых бита (практически не используется);
  • TWOSTOPBIT — два стоповых бита.

 

 

После того как все поля структуры DCB заполнены, необходимо произвести конфигурирование порта, вызвав функцию SetCommState:

BOOL SetCommState(
HANDLE hFile,
LPDCB lpDCB
);

В случае успешного завершения функция вернет отличное от нуля значение, а в случае ошибки — нуль.

Второй обязательной структурой для настройки порта является структура COMMTIMEOUTS. Она определяет параметры временных задержек при приеме-передаче.

Вот описание этой структуры:

typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout;
DWORD ReadTotalTimeoutMultiplier;
DWORD ReadTotalTimeoutConstant;
DWORD WriteTotalTimeoutMultiplier;
DWORD WriteTotalTimeoutConstant;
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;

Поля структуры COMMTIMEOUTS имеют следующие значения:

  • ReadIntervalTimeout — максимальное временной промежуток (в миллисекундах), допустимый между двумя считываемыми с коммуникационной линии последовательными символами. Во время операции чтения временной период начинает отсчитываться с момента приема первого символа. Если интервал между двумя последовательными символами превысит заданное значение, операция чтения завершается и все данные, накопленные в буфере, передаются в программу. Нулевое значение данного поля означает, что данный тайм-аут не используется.
  • ReadTotalTimeoutMultiplier — задает множитель (в миллисекундах), используемый для вычисления общего тайм-аута операции чтения. Для каждой операции чтения данное значение умножается на количество запрошенных для чтения символов.
  • ReadTotalTimeoutConstant — задает константу (в миллисекундах), используемую для вычисления общего тайм-аута операции чтения. Для каждой операции чтения данное значение плюсуется к результату умножения ReadTotalTimeoutMultiplier на количество запрошенных для чтения символов. Нулевое значение полей ReadTotalTimeoutMultiplier и ReadTotalTimeoutConstant означает, что общий тайм-аут для операции чтения не используется.
  • WriteTotalTimeoutMultiplier — задает множитель (в миллисекундах), используемый для вычисления общего тайм-аута операции записи. Для каждой операции записи данное значение умножается на количество записываемых символов.
  • WriteTotalTimeoutConstant — задает константу (в миллисекундах), используемую для вычисления общего тайм-аута операции записи. Для каждой операции записи данное значение прибавляется к результату умножения WriteTotalTimeoutMultiplier на количество записываемых символов. Нулевое значение полей WriteTotalTimeoutMultiplier и WriteTotalTimeoutConstant означает, что общий тайм-аут для операции записи не используется.

Немного поподробнее о тайм-аутах. Пусть мы считываем из порта 50 символов со скоростью 9 600 бит/с. Если при этом используется 8 бит на символ, дополнение до четности и один стоповый бит, то на один символ в физической линии приходится 11 бит (включая стартовый бит). Значит, 50 символов на скорости 9 600 бит/с будут приниматься

50x11/9600=0,0572916 с

или примерно 57,3 миллисекунды, при условии нулевого интервала между приемом последовательных символов.

Если же интервал между символами составляет примерно половину времени передачи одного символа, т. е. 0,5 миллисекунд, то время приема будет

50x11/9600+49x0,0005=0,0817916 с

или примерно 82 миллисекунды. Если в процессе чтения прошло более 82 миллисекунд, то мы вправе предположить, что произошла ошибка в работе внешнего устройства и можем прекратить считывание, тем самым избежав зависания программы. Это и есть общий тайм-аут операции чтения. Аналогично существует и общий тайм-аут операции записи.

Формула для вычисления общего тайм-аута операции, например, чтения, выглядит так:

NumOfChar x ReadTotalTimeoutMultiplier + ReadTotalTimeoutConstant

где NumOfChar — число символов, запрошенных для операции чтения.

В нашем случае тайм-ауты записи можно не использовать и установить их равными нулю.

После заполнения структуры COMMTIMEOUTS, необходимо вызвать функцию установки тайм-аутов: