Задает чувствительсть коммуникационного драйвера к состоянию линии DSR. Если это поле равно TRUE, то все принимаемые данные игнорируются драйвером (коммуникационный драйвер расположен в операционной системе), за исключением тех, которые принимаются при установленом сигнале DSR.
fTXContinueOnXoff
Задает, прекращается ли передача при переполнении приемного буфера и передаче драйвером символа XoffChar. Если это поле равно TRUE, то передача продолжается, несмотря на то, что приемный буфер содержит более XoffLim символов и близок к переполнению, а драйвер передал символ XoffChar для приостановления потрока принимаемых данных. Если поле равно FALSE, то передача не будет продолжена до тех пор, пока в приемном буфере не останется меньше XonLim символов и драйвер не передаст символ XonChar для возобновления потока принимаемых данных. Таким образом это поле вводит некую зависимость между управлением входным и выходным потоками информации.
fOutX
Задает использование XON/XOFF управления потоком при передаче. Если это поле равно TRUE, то передача останавливается при приеме символа XoffChar, и возобновляется при приеме символа XonChar.
fInX
Задает использование XON/XOFF управления потоком при приеме. Если это поле равно TRUE, то драйвер передает символ XoffChar, когда в приемном буфере находится более XoffLim, и XonChar, когда в приемном буфере остается менее XonLim символов.
fErrorChar
Указывает на необходимость замены символов с ошибкой четности на символ задаваемый полем ErrorChar. Если это поле равно TRUE, и поле fParity равно TRUE, то выполняется замена.
fNull
Определяет действие выполняемое при приеме нулевого байта. Если это поле TRUE, то нулевые байты отбрасываются при передаче.
fRtsControl
задает режим управления потоком для сигнала RTS. Если это поле равно 0, то по умолчанию подразумевается RTS_CONTROL_HANDSHAKE. Поле может принимать одно из следующих значений:
| RTS_CONTROL_DISABLE | Запрещает использование линии RTS |
| RTS_CONTROL_ENABLE | Разрешает использование линии RTS |
| RTS_CONTROL_HANDSHAKE | Разрешает использование RTS |
| RTS_CONTROL_TOGGLE | Задает, что сигнал RTS установлен, когда есть данные для передачи. Когда все символы из передающего буфера переданы, сигнал сбрасывается. |
fAbortOnError
Задает игнорирование всех операций чтения/записи при возникновении ошибки. Если это поле равно TRUE, драйвер прекращает все операции чтения/записи для порта при возникновении ошибки. Продолжать работать с портом можно будет только после устранения причины ошибки и вызова функции ClearCommError.
fDummy2
Зарезервировано и не используется.
wReserved
Не используется, должно быть установлено в 0.
XonLim
Задает минимальное число символов в приемном буфере перед посылкой символа XON.
XoffLim
Определяет максимальное количество байт в приемном буфере перед посылкой символа XOFF. Максимально допустимое количество байт в буфере вычисляется вычитанием данного значения из размера применого буфера в байтах.
ByteSize
Определяет число информационных бит в передаваемых и принимаемых байтах.
Parity
Определяет выбор схемы контроля четности. Данное поле должно содержать одно из следующих значений:
| EVENPARITY | Дополнение до четности |
| MARKPARITY | Бит четности всегда 1 |
| NOPARITY | Бит четности отсутствует |
| ODDPARITY | Дополнение до нечетности |
| SPACEPARITY | Бит четности всегда 0 |
StopBits
Задает количество стоповых бит. Поле может принимать следующие значения:
| ONESTOPBIT | Один стоповый бит |
| ONE5STOPBIT | Полтора стоповых бита |
| TWOSTOPBIT | Два стоповых бита |
XonChar
Задает символ XON используемый как для примема, так и для передачи.
XoffChar
Задает символ XOFF используемый как для примема, так и для передачи.
ErrorChar
Задает символ, использующийся для замены символов с ошибочной четностью.
EofChar
Задает символ, использующийся для сигнализации о конце данных.
EvtChar
Задает символ, использующийся для сигнализации о событии.
wReserved1
Зарезервировано и не используется.
Так как поля структуры DCB используются для конфигурирования микросхем портов, на них накладываются некоторые ограничения. Размер байта должен быть 5, 6, 7 или 8 бит. Комбинация из пяти битного байта и двух стоповых бит является недопустимой. Так же как и комбинация из шести, семи или восьми битного байта и полутора стоповых бит.
Только что рассмотренная нами структура DCB самая большая из всех, использующихся для настройки последовательных портов. Но она и самая важная. Заполнение всех полей этой структуры может вызвать затруднения, так как надо очень четко представлять как работает последовательный порт. Поэтому ручную установку полей можно порекомендовать опытным программистам. Если же Вы чувствуете себя не очень уверено, воспользуйтесь функцией BuildCommDCB, которая позволяет заполнить поля структуры DCB на основе строки, по синтаксису аналогичной строке команды mode. Вот как выглядит прототип этой функции:
BOOL BuildCommDCB(LPCTSTR lpDef, LPDCB lpDCB);
Как видно, функция очень проста и имеет всего два параметра:
lpDef
Указатель на строку с конфигурационной информацией в формате команды mode. Например, следующая строка задает скорость 1200, без четности, 8 бит данных и 1 стоповый бит.
baud=1200 parity=N data=8 stop=1
lpDCB
Указатель на заполняемую структуру DCB. При этом структура должна быть уже создана и заполнена нулями, кроме поля DCBlength, которое должно содержать корректное значение. Возможно так же использование уже заполненой структуры DCB, например полученой вызовом одной из функций чтения параметров порта.
В случае успешного завершения функция BuildCommDCB возвращает ненулевое значение. В случае ошибки возвращается 0.
Обычно функция BuldCommDCB изменяет только явно перечисленые в строке lpDef поля. Однако существуют два исключения из этого правила:
• При задании скорости обмена 110 бит в секунду автоматически устанавливается формат обмена с двумя стоповыми битами. Это сделано для совместимости с командой mode из MS-DOS или Windows NT.
• По умолчанию запрещается программное (XON/XOFF) и аппаратное управление потоком. Вы должны вручную заполнить требуемые поля DCB если требуется управление потоком.
Функция BuilCommDCB поддерживает как новый, так и старый форматы командной строки mode. Однако, Вы не можете смешивать эти форматы в одной строке.
Новый формат строки позволяет явно задавать значения для полей DCB отвечающих за управление потоком. При использовании старого формата существуют следующие соглашения:
• Для строк вида 9600,n,8,1 (не заканчивающихся символами x или p):
○ fInX, fOutX,fOutXDsrFlow, fOutXCtsFlow устанавливаются в FALSE
○ fDtrControl устанавливается в DTR_CONTROL_ENABLE
○ fRtsControl устанавливается в RTS_CONTROL_ENABLE
• Для строк вида 9600,n,8,1,x (заканчивающихся символом х):
○ fInX, fOutX устанавливаются в TRUE
○ fOutXDsrFlow,fOutXCtsFlow устанавливаются в FALSE
○ fDtrControl устанавливается в DTR_CONTROL_ENABLE
○ fRtsControl устанавливается в RTS_CONTROL_ENABLE
• Для строк вида 9600,n,8,1,p (заканчивающихся символом p):
○ fInX, fOutX устанавливаются в FALSE
○ fOutXDsrFlow,fOutXCtsFlow устанавливаются TRUE
○ fDtrControl устанавливается в DTR_CONTROL_HANDSHAKE
○ fRtsControl устанавливается в RTS_CONTROL_HANDSHAKE
Следует заметить, что функция BuildCommDCB только заполняет поля DCB указанными значениями. Это подготовительный шаг к конфигурированию порта, но не само конфигурирование, которое выполняется рассматриваемыми далее функциями. Поэтому Вы можете вызвать BuildCommDCB для общего заполнения структуры DCB, затем изменить значения не устраивающих Вас полей, и после этого вызывать функцию конфигурирования порта.
Заполнить DCB можно еще одним способом. Вызовом функции GetCommState. Эта функция заполняет DCB информацией о текущем состоянии устройства, точнее о его настройках. Вот как она выглядит:
BOOL GetCommState(HANDLE hFile, LPDCB lpDCB);
Функция очень проста и имеет всего два параметра:
hFile
Описатель открытого файла коммуникационного порта. Этот описатель возвращается функцией CreateFile. Следовательно, прежде чем получить параметры порта, Вы должны его открыть. Для функции BuildCommDCB это не требовалось.
lpDCB
Указатель на DCB. Для DCB должен быть выделен блок памяти.
При успешном завершении функция возвращает ненулевое значение. При ошибке нуль. Получить параметры порта можно в любой момент, а не только при начальной настройке.
Заполнив DCB можно приступать к собственно конфигурированию порта. Это делается с помощью функции SetCommState:
BOOL SetCommState(HANDLE hFile, LPDCB lpDCB);
Эта функция имеет точно такие же параметры, как GetCommState. Различается только направление передачи информации. GetCommState считывает информацию из внутренних управляющих структур и регистров порта, а SetCommState наоборот заносит ее. Следует быть осторожным при вызове функции SetCommState, поскольку она изменит параметры даже в том случае, если очереди приема/передачи не пусты, что может вызвать искажение потока передаваемых или принимаемых данных.
Еще одна тонкость этой функции заключется в том, что она завершится с ошибкой, если поля XonChar и XoffChar в DCB содержат одинаковые значения.
Как всегда, в случае успешного завершения возвращается отличное от нуля значение, а в случае ошибки – нуль.
Следующей важной управляющей структурой является COMMTIMEOUTS. Она определяет параметры временных задержек при приеме и передаче. Значения, задаваемые полями этой структуры, оказывают большое влияние на работу функций чтения/записи.
typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout;
DWORD ReadTotalTimeoutMultiplier;
DWORD ReadTotalTimeoutConstant;
DWORD WriteTotalTimeoutMultiplier;
DWORD WriteTotalTimeoutConstant;
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
Поля структуры COMMTIMEOUTS имеют следующие значения:
ReadIntervalTimeout
Максимальное время, в миллисекундах, допустимое между двумя последовательными символами считываемыми с коммуникационной линии. Во время операции чтения временной период начинает отсчитываться с момента приема первого символа. Если интервал между двумя последовательными символами превысит заданое значение, операция чтения завершается и все данные, накопленые в буфере, передаются в программу. Нулевое значение данного поля означает, что данный тайм-аут не используется. Значение MAXDWORD, вместе с нулевыми значениями полей ReadTotalTimeoutConstant и ReadTotalTimeoutMultiplier, означает немедленный возврат из операции чтения с передачей уже принятого символа, даже если ни одного символа не было получено из линии.
ReadTotalTimeoutMultiplier