Шрифт:
Интервал:
Закладка:
Функция PuraeComm
Коммуникационный порт не совсем обычный файл. Например, для него нельзя выполнить операцию позиционирования файлового указателя. С другой стороны, порт позволяет управлять потоком, что нельзя делать с обычным файлом. Настало время познакомиться с функциями управления приемом/передачей данных через коммуникационные порты. Поскольку первой операцией, после открытия порта, является его сброс, то и начнем с функции выполняющей требуемые действия.
BOOL PurgeComm(
HANDLE hFile,
DWORD dwFlags
);
Вызов этой функции позволяет решить две задачи: очистить очереди приема/передачи в драйвере и завершить все находящиеся в ожидании запросы ввода/вывода. Какие именно действия выполнять, задается вторым параметром (значения можно комбинировать с помощью побитовой операции OR):
• PURGE_TXABORT — Немедленно прекращает все операции записи, даже если они не завершены
• PURGE_RXABORT — Немедленно прекращает все операции чтения, даже если они не завершены
• PURGE_TXCLEAR — Очищает очередь передачи в драйвере
• PURGE_RXCLEAR — Очищает очередь приема в драйвере
Вызов этой функции нужен для отбрасывания мусора, который может находиться в приемном буфере на момент запуска программы, или как результат ошибки в работе устройства. Очистка буфера передачи и завершение операций ввода/вывода так же потребуются при ошибке, как процедура восстановления, и при завершении программы, для красивого выхода.
Функция FlushFileBuffers
Следует помнить, что очистка буфера передачи, как и экстренное завершение операции записи, не выполняют передачу данных находящихся в этом буфере. Данные просто отбрасываются. Если же передача остатка данных необходима, то перед вызовом PurgeComm следует вызвать функцию:
BOOL FlushFileBuffers(
HANDLE hFile
);
Приведу пример выполнения настройки порта и выполнения чтения/записи данных.
#include <windows.h>
#include <string.h>
…
DCB dсb;
COMMTIMEOUTS ct;
HANDLE port;
DWORD bс;
char *buf out="Test string";
char *buf_in;
…
dсb.DCBlength=sizeof(DCB);
BuildCommDCB("baud=9600 parity=N data=8 stop=l",&dcb);
dсb.fNull=TRUE;
ct.ReadIntervalTimeout=10;
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);
PurgeComm(port,PURGE_TXCLEAR PURGE_RXCLEAR);
SetupComm(port,25 6,256);
…
buf_in=(char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,strlen(buf_out)+1);
WriteFile(port,buf_out,strlen(buf_out),&bc,NULL);
ReadFile(port,buf in,strlen(buf out),&bc,NULL);
HeapFree(GetProcessHeap 0,0,buf_in);
CloseHandle(port);
…
Если на COM2 установить перемычку между сигналами TxD и RxD, то переменная bufin, после выполнения ReadFile, будет содержать ту же информацию, что и buf_out. Других пояснений пример не требует, все уже было подробно рассмотрено раньше.
Функция TransmitCommChar
Иногда требуется срочно передать символ, имеющий определенное специальное значение, а в очереди передатчика уже есть данные, которые нельзя терять. В этом случае можно воспользоваться функцией:
BOOL TransmitCommChar(
HANDLE hFile,
char cChar
);
Данная функция передает один (и только один) внеочередной байт в линию, не смотря на наличие данных в очереди передатчика, и перед этими данными. Однако управление потоком действует. Функцию можно вызвать только синхронно. Более того, если байт экстренных данных, от предыдущего вызова этой функции, еще не передан в линию (например, из-за функций управления потоком), то попытка экстренной передачи еще одного байта завершится ошибкой. Если Вы используете программное управление потоком, то символы приостановки и возобновления передачи (обычно CTRL-S и CTRL-Q), лучше всего передавать именно этой функцией.
Функции SetCommBreak и ClearCommBreak
Последовательный канал передачи данных можно перевести в специальное состояние, называемое разрывом связи. При этом передача данных прекращается, а выходная линия переводится в состояние "0". Приемник, обнаружив, что за время необходимое для передачи стартового бита, битов данных, бита четности и стоповых битов, приемная линия ни разу не перешла в состояние "1", так же фиксирует у себя состояние разрыва.
BOOL SetCommBreak(
HANDLE hFile
);
BOOL ClearCommBreak(
HANDLE hFile
);
Функция EscapeCommFunction
Следует заметить, что состояние разрыва линии устанавливается аппаратно. Поэтому нет другого способа возобновить прерванную, с помощью SetCommBreak, передачу данных, кроме вызова ClearCommBreak. Более тонкое управление потоком данным позволяет осуществить функция:
BOOL EscapeCommFunction(
HANDLE hFile,
DWORD dwFunc
);
Выполняемое действие определяется вторым параметром, который может принимать одно из следующих значений:
• CLRDTR — Сбрасывает сигнал DTR
• CLRRTS — Сбрасывает сигнал RTS
• SETDTR — Устанавливает сигнал DTR
• SETRTS — Устанавливает сигнал RTS
• SETXOFF — Симулирует прием символа XOFF
• SETXON — Симулирует прием символа XON
• SETBREAK — Переводит выходную линию передатчика в состояние разрыва. SetCommBreak является упрощенной формой данного вызова.
• CLRBREAK — Снимает состояние разрыва для выходной линии передатчика. ClearCommBreak является упрощенной формой данного вызова.
Функция ClearCommError
Приостановить прием/передачу данных может и возникновение любой ошибки при установленном в TRUE поле fAbortOnError в структуре DCB использованной для настройки режимов работы коммуникационного порта. В этом случае, для восстановления нормальной работы порта, следует использовать функцию:
BOOL ClearCommError(
HANDLE hFile,
LPDWORD IpErrors,
LPCOMSTAT IpStat
);
Эта функция не только сбрасывает признак ошибки для соответствующего порта, но и возвращает более подробную информацию об ошибке. Кроме того, возможно получение информации о текущем состоянии порта. Вот что означают параметры:
∙ hFile
Описатель открытого файла коммуникационного порта.
∙ IpErrors
Адрес переменной, в которую заносится информация об ошибке. В этой переменной могут быть установлены один или несколько из следующих бит:
• CE_BREAK — Обнаружено состояние разрыва связи
• CE_DNS — Только для Windows95. Параллельное устройство не выбрано.
• CE_FRAME — Ошибка обрамления.
• СЕ_IOЕ — Ошибка ввода-вывода при работе с портом
• СЕ_MODE — Запрошенный режим не поддерживается, или неверный описатель hFile. Если данный бит установлен, то значение остальных бит не имеет значение.
• СЕ_ООР — Только для Windows95. Для параллельного порта установлен сигнал "нет бумаги".
• CE_OVERRUN — Ошибка перебега (переполнение аппаратного буфера), следующий символ потерян.
• СЕ_РТО — Только для Windows95. Тайм-аут на параллельном порту.
• CE_RXOVER