COM-порт в Windows (программирование): различия между версиями
Нет описания правки |
(нет различий)
|
Версия от 09:56, 30 мая 2006
Написать программу, управляющую устройством через COM-порт, для MS-DOS не так сложно. С платформой Win32 дело обстоит сложнее. Но только на первый взгляд. Конечно напрямую работать с регистрами портов нельзя, Windows это не позволяет, зато можно не обращать внимания на тонкости различных реализаций (i8055, 16450, 16550A) и не возиться с обработкой прерывание.
Открытие порта
С последовательными и параллельными портами в Win32 работают как с файлами. Для открытия порта используется функция CreateFile
. Эта функция предоставляется Win32 API. Ее прототип выглядит так:
HANDLE CreateFile( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDistribution, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile );
lpFileName
Указатель]] на строку с именем открываемого или создаваемого файла. Формат этой строки может быть очень «хитрым». В частности можно указывать сетевые имена для доступа к файлам на других компьютерах. Можно открывать логические разделы или физические диски и работать в обход файловой системы.
Последовательные порты имеют имена «COM1», «COM2», «COM3», «COM4» и так далее. Точно так же они назывались в MS-DOS. Параллельные порты называются «LPT1», «LPT2» и так далее.
dwDesiredAccess
Задает тип доступа к файлу. Возможно использование следующих значений:
0
Опрос атрибутов устройства без получения доступа к нему.GENERIC_READ
Файл будет считываться.GENERIC_WRITE
Файл будет записываться.GENERIC_READ|GENERIC_WRITE
Файл будет и считываться и записываться.
Задает параметры совместного доступа к файлу. Коммуникационные порты нельзя делать разделяемыми, поэтому данный параметр должен быть равен 0.
lpSecurityAttributes
Задает атрибуты защиты файла. Поддерживается только в Windows NT. Однако при работе с портами должен в любом случае равняться NULL
.
dwCreationDistribution
Управляет режимами автосоздания, автоусечения файла и им подобными. Для коммуникационных портов всегда должно задаваться OPEN_EXISTING
.
dwFlagsAndAttributes
Задает атрибуты создаваемого файла. Так же управляет различными режимами обработки. При работе с портом этот параметр должен быть или равным 0
, или FILE_FLAG_OVERLAPPED
. Нулевое значение используется при синхронной работе с портом, а FILE_FLAG_OVERLAPPED
при асинхронной, или другими словами, при фоновой обработке ввода/вывода. Подробнее про асинхронный ввод/вывод я расскажу позже.
hTemplateFile
Задает описатель файла-шаблона. При работе с портами всегда должен быть равен NULL
.
При успешном открытии файла, в данном случае порта, функция возвращает дескриптор (HANDLE
) файла. При ошибке [[|INVALID_HANDLE_VALUE
]]. Код ошибки можно получитить вызвав функцию [[|GetLastError
]].
Закрытие порта
Открытый порт должен быть закрыт перед завершением работы программы. В Win32 закрытие объекта по его дескриптору выполняет функция [[|CloseHandle
]]:
BOOL CloseHandle( HANDLE hObject };
При успешном завершении функция возвращает не нулевое значение, при ошибке нуль.
Пример открытия/закрытия на языке C
#include <windows.h> . . . HANDLE port; . . . Port=CreateFile("COM2",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); if(port==INVALID_HANDLE_VALUE) { MsgBox(NULL,"Не возможно открыть последовательный порт","Error",MB_OK); ExitProcess(1); } . . . CloseHandle(Port); . . .
В данном примере открывается порт СОМ2
для чтения и записи, используется синхронный режим обмена. Проверяется успешность открытия порта, при ошибке выводится сообщение и программа завершается. Если порт открыт успешно, то он закрывается.
Структура DCB
Основные параметры последовательного порта описываются структурой DCB
. Временные параметры структурой COMMTIMEOUTS
. Существует еще несколько информационных и управляющих структур, но они используются реже. Настройка порта заключается в заполнении управляющих структур и последующем вызове функций настройки.
Основную информацию содержит структура DCB
:
typedef struct _DCB { DWORD DCBlength; // sizeof(DCB) DWORD BaudRate; // current baud rate DWORD fBinary:1; // binary mode, no EOF check DWORD fParity:1; // enable parity checking DWORD fOutxCtsFlow:1; // CTS output flow control DWORD fOutxDsrFlow:1; // DSR output flow control DWORD fDtrControl:2; // DTR flow control type DWORD fDsrSensitivity:1; // DSR sensitivity DWORD fTXContinueOnXoff:1; // XOFF continues Tx DWORD fOutX:1; // XON/XOFF out flow control DWORD fInX:1; // XON/XOFF in flow control DWORD fErrorChar:1; // enable error replacement DWORD fNull:1; // enable null stripping DWORD fRtsControl:2; // RTS flow control DWORD fAbortOnError:1; // abort reads/writes on error DWORD fDummy2:17; // reserved WORD wReserved; // not currently used WORD XonLim; // transmit XON threshold WORD XoffLim; // transmit XOFF threshold BYTE ByteSize; // number of bits/byte, 4-8 BYTE Parity; // 0-4=no,odd,even,mark,space BYTE StopBits; // 0,1,2 = 1, 1.5, 2 char XonChar; // Tx and Rx XON character char XoffChar; // Tx and Rx XOFF character char ErrorChar; // error replacement character char EofChar; // end of input character char EvtChar; // received event character WORD wReserved1; // reserved; do not use } DCB;
Эта структура содержит почти всю управляющую информацию, которая в реальности располагается в различных регистрах последовательного порта.
DCBlength
Задает длину, в байтах, структуры 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
. Эти константы соответствуют всем стандартным скоростям обмена. На самом деле, это поле содержит числовое значение скорости передачи, а константы просто являются символическими именами. Поэтому можно указывать, например, и CBR_9600
, и просто 9600
. Однако рекомендуется указывать символические константы.
fBinary
Включает двоичный режим обмена. Win32 не поддерживает недвоичный режим, поэтому данное поле всегда должно быть равно 1
, или логической константе TRUE
(что предпочтительней). В Windows 3.1, если это поле было равно FALSE
, включался текстовый режим обмена. В этом режиме поступивший на вход порта символ заданый полем EofChar
свидетельствовал о конце принимаемых данных.
fParity
Включает режим контроля четности. Если это поле равно TRUE
, то выполняется проверка четности, при ошибке, в вызывающую программу, выдается соответсвующий код завершения.
fOutxCtsFlow
Включает режим слежения за сигналом [[|CTS
]]. Если это поле равно [[|TRUE
]] и сигнал [[|CTS
]] сброшен, передача данных приостанавливается до установки сигнала CTS
. Это позволяет подключеному к компьютеру прибору приостановить поток передаваемой в него информации, если он не успевает ее обрабатывать.
fOutxDsrFlow
Включает режим слежения за сигналом [[|DSR
]]. Если это поле равно TRUE
и сигнал DSR
сброшен, передача данных прекращается до установки сигнала DSR
.
fDtrControl
Задает режим управления обменом для сигнала [[|DTR
]]. Это поле может принимать следующие значения:
- DTR_CONTROL_DISABLE Запрещает использование линии DTR
- DTR_CONTROL_ENABLE Разрешает использование линии DTR
- DTR_CONTROL_HANDSHAKE Разрешает использование рукопожатия для выхода из ошибочных ситуаций. Этот режим используется, в частности, модемами при восстановленни в ситуации потери связи.
fDsrSensitivity
Задает чувствительсть коммуникационного драйвера к состоянию линии [[|DSR
]]. Если это поле равно TRUE
, то все принимаемые данные игнорируются драйвером (коммуникационный драйвер расположен в операционной системе), за исключением тех, которые принимаются при установленом сигнале DSR
.
fTXContinueOnXoff
Задает, прекращается ли передача при переполнении приемного буфера и передаче драйвером символа XoffChar
. Если это поле равно TRUE
, то передача продолжается, несмотря на то, что приемный буфер содержит более XoffLim
символов и близок к переполнению, а драйвер передал символ XoffChar
для приостановления потрока принимаемых данных. Если поле равно
, то передача не будет продолжена до тех пор, пока в приемном буфере не останется меньше 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 когда приемный буфер заполнен менее, чем на половину, и сбрасывает, когда буфер заполняется более чем на три четверти. 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
Зарезервировано и не используется. Поля структуры: