Шрифт:
Интервал:
Закладка:
ct.ReadTotalTimeoutMultiplier=ct.ReadTotalTimeoutConstant=0;
ct.WriteTotalTimeoutMultiplier=ct.WriteTotalTimeoutConstant=0;
port=CreateFile(COM2",GENERIC_READ|GENERIC_WRIТЕ,0,NULL,OPEN_EXISTING,0,NULL);
SetCommState(port,dсb);
SetCommTimeouts(port,&ct);
HeapFree(GetProcessHeap 0,0,dсb);
…
CloseHandle(port);
В этом примере полностью убрана обработка ошибок. Обрабатывать ошибки необходимо, но сейчас главное разобраться в работе с портом, а обработка ошибок уменьшает наглядность.
Первым делом, с помощью функции HeapAlloc, выделяется и заполняется нулями область памяти для DCB. Затем в поле DCBlength заносится размер структуры DCB в байтах. Зачем это нужно обсуждалось выше, при описании данного поля. Для общего (и наглядного) заполнения DCB использована функция BuildCommDCB. Будем считать, что нас устраивает информация занесенная в DCB, но требуется игнорировать нулевые байты при приеме. Так как BuildCommDCB не выполняет требуемых действий мы вручную изменяем соответствующее поле. Далее мы заполняем информацию о таймаутах. Общие тайм-ауты операций чтения и записи не используются, конец сообщения определяется по тайм-ауту между двумя последовательными символами большему 10 миллисекунд. Теперь можно открыть порт, что делается функцией CreateFile, и выполнить его настройку вызвав функции SetCommState и SetCommTimeots. После установки параметров порта структура DCB становится не нужной, поэтому можно освободить занимаемую ей память. Структура COMMTIMEOUTS в примере размещена статически, поэтому выделять под нее память и освобождать ее не требуется. Наконец, мы закрываем порт перед завершением.
Функции HeapAlloc и HeapFree занимаются выделением и освобождением памяти из куч, которых в программе может быть несколько. Вместо этих функций можно использовать malloc (calloc) и free. Однако использование функций предоставляемых Win32 API позволяет сократить размер программы, что может быть не маловажно, если работа с портами ведется из DLL (например Вы пишете своеобразный псевдодрайвер для своего устройства). Есть и другие аргументы в пользу этой точки зрения, которую я Вам, впрочем, не навязываю.
Рассмотренные структуры и функции позволяют программировать порт на достаточно низком уровне. Их, в большинстве случаев, более чем достаточно даже для тонкой настройки порта. Однако бывают и исключения. Например, под именем СОМ1 может скрываться вовсе не привычный порт RS-232, а какая-нибудь экзотика. Или порт может не позволять задавать скорость более 9600.
Структура COMMPROP
Исчерпывающая информация о возможностях коммуникационного устройства и драйвера содержится в структуре COMMPROP:
typedef struct _COMMPROP {{
WORD wPacketLength; // packet size, in bytes
WORD wPacketVersion; // packet version
DWORD dwServiceMask; // services implemented
DWORD dwReservedl; // reserved
DWORD dwMaxTxQueue; // max Tx bufsize, in bytes
DWORD dwMaxRxQueue; // max Rx bufsize, in bytes
DWORD dwMaxBaud; // max baud rate, in bps
DWORD dwProvSubType; // specific provider type
DWORD dwProvCapabilities; // capabilities supported
DWORD dwSettableParams; // changable parameters
DWORD dwSettableBaud; // allowable baud rates
WORD wSettableData; // allowable byte sizes
WORD wSettablestopParity; // stop bits/parity allowed
DWORD dwCurrentTxQueue; // Tx buffer size, in bytes
DWORD dwCurrentRxQueue; // Rx buffer size, in bytes
DWORD dwProvSpec1; // provider-specific data
DWORD dwProvSpec2; // provider-specific data
WCHAR wcProvChar[1]; // provider-specific data
} COMMPROP;
Поля этой структуры описывают все возможности драйвера. Вы не можете выйти за пределы этих возможностей. Вот какое значение имеют поля:
∙ wPacketLength
Задает размер, в байтах, структуры COMMPROP.
∙ wPacketVersion
Номер версии структуры.
∙ dwServiceMask
Битовая маска. Для коммуникационных устройств всегда SPSERIALCOMM, включая модемы.
∙ dwReserved1
Зарезервировано и не используется.
∙ dwMaxTxQueue
Максимальный размер, в байтах, внутреннего буфера передачи драйвера. Нулевое значение свидетельствует об отсутствии ограничения.
∙ dwMaxRxQueue
Максимальный размер, в байтах, внутреннего буфера приема драйвера. Нулевое значение свидетельствует об отсутствии ограничения.
∙ dwMaxBaud
Максимально допустимая скорость обмена, в битах в секунду (бпс). Возможны следующие значения данного поля:
• BAUD_075 — 75 бпс
• BAUD_110 — 110 бпс
• BAUD_134_5 — 134.5 бпс
• BAUD_150 — 150 бпс
• BAUD_300 — 300 бпс
• BAUD_600 — 600 бпс
• BAUD_1200 — 1200 бпс
• BAUD_1800 — 1800 бпс
• BAUD_2400 — 2400 бпс
• BAUD_4800 — 4800 бпс
• BAUD_7200 — 7200 бпс
• BAUD_9600 — 9600 бпс
• BAUD_14400 — 14400 бпс
• BAUD_19200 — 19200 бпс
• BAUD_38400 — 38400 бпс
• BAUD_56K — 56К бпс
• BAUD_57600 — 57600 бпс
• BAUD_115200 — 115200 бпс
• BAUD_128K — 128К бпс
• BAUD_USER — Допускается программирование скорости обмена
∙ dwProvSubType
Тип коммуникационного порта. Возможны следующие значения данного поля:
• PST_FAX — Факс
• PST_LAT LAT — протокол
• PST_MODEM — Модем
• PST_NETWORK_BRIDGE — Сетевой мост
• PST_PARALLELPORT — Параллельный порт
• PST_RS232 — Последовательный порт RS-232
• PST_RS422 — Порт RS-422
• PST_RS423 — Порт RS-423
• PST_RS449 — Порт RS-449
• PST_SCANNER — Сканнер
• PST_TCPIP_TELNET — Протокол TCP/IP TelnetR
• PST_UNSPECIFIED — Неизвестное устройство
• PST_Х25 — Устройство стандарта X.25
∙ dwProvCapabilities
Битовая маска. Определяет возможности предоставляемые устройством. Возможны следующие значения:
• PCF_16BITMODE — Поддерживается специальный 16-битный режим.
• PCF_DTRDSR — Поддерживаются сигналы DTR/DSR.
• PCF_INTTIMEOUTS — Поддерживается межсимвольный тайм-аут.
• PCF_PARITY_CHECK — Поддерживается контроль четности.
• PCF_RLSD — Поддерживается определение наличия сигнала в приемной линии.
• PCF_RTSCTS — Поддерживаются сигналы RTS/CTS.
• PCF_SETXCHAR — Поддерживаются задаваемые символы XON/XOFF.
• PCF_SPECIALCHARS — Поддерживаются спецсимволы.
• PCF_TOTALTIMEOUTS — Поддерживаются общие тайм-ауты (ожидаемое время).
• PCF_XONXOFF — Поддерживается программное (XON/XOFF) управление потоком.
• PCF_XONXOFF — Поддерживается программное (XON/XOFF) управление потоком.
∙ dwSettableParams
Битовая маска. Определяет допустимые для изменения параметры. Возможны следующие значения:
• SP_BAUD — Скорость обмена.
• SP_DATABITS — Бит в символе.
• SP_HANDSHAKING — Рукопожатие (управление потоком).
• SP_PARITY — Четность.
• SP_PARITY_CHECK — Контроль четности.
• SP_RLSD — Детектирование наличия сигнала в приемной линии.
• SP_STOPBITS — Количество стоповых бит.
∙ dwSettableBaud
Битовая маска. Определяет допустимый набор скоростей обмена. Допустимые для данного поля значения указаны в описании поля dwMaxBaud.
∙ wSettableData
Битовая