COM port with WIN32 API
От: Roman_M rgmroman.narod.ru
Дата: 28.06.01 07:59
Оценка:
Хотелось бы получить какие-нибудь полезные советы, подсказки и комментарии от тех кто уже освоил программирование COM портов на Win32 API. На данный момент я застрял на посылке данных в модем. Вот в кратце приведу код, который я написал:

ZeroMemory(&ov, sizeof(OVERLAPPED)); // Подготовка к асинхронным
ov.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); // операциям ввода-вывода

/* Открытие определенного порта */
hCom = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);


fResult = SetCommState(hCom, &comdcb); // Инициализация порта

dwBaudRate = comdcb.BaudRate;

/* Очистка порта */
fResult = PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);

fResult = SetupComm(hCom, 0x1000, 0x1000); // Установка размеров буферов I/O

cto.ReadIntervalTimeout = 0xFFFFFFFF; // Расчет и установка задержек. Идея взята из
cto.ReadTotalTimeoutConstant = 1000; // примеров в SDK. Вот тут хотелось бы
cto.WriteTotalTimeoutMultiplier = 2*CBR_9600/dwBaudRate; // каких-нибудь пояснений
fResult = SetCommTimeouts(hCom, &cto); //

fResult = SetCommMask(hCom, EV_RXCHAR); // Ставится маска событий

/* Запись строки инициализации. Я использую ATZ\r */
dwTemp = 0;
ResetEvent(ov.hEvent);
fResult = WriteFile(hCom, InitString, lstrlenA(InitString), &dwTemp, &ov);
if (fResult == FALSE)
{
array[0] = hExit;
array[1] = ov.hEvent;
dwTemp = WaitForMultipleObjects(2, array, FALSE, INFINITE);
if (dwTemp == WAIT_OBJECT_0)
{
CloseHandle(hCom);
/* здесь выход из цикла */
}
dwTemp = 0;
fResult = GetOverlappedResult(hCom, &ov, &dwTemp, TRUE);
if (fResult == FALSE)
{
/* Закрытие описателя, сообщение об ошибке, выход*/
}
}

// !!! Вот тут то у меня почему то часто dwTemp!=4, что видно по эхо выводу
// А Portmon'е может быть статус TIMEOUT.


array[0] = hExit;
array[1] = ov.hEvent;
dwTemp = 0;
ResetEvent(ov.hEvent);
fResult = WaitCommEvent(hCom, &dwTemp, &ov); // Тут ставлю ожидание ответа(эхо) из модема
if (fResult == FALSE)
{
dwError = GetLastError();
/* Ошибки кроме ERROR_IO_PENDING у меня здесь не возникает*/
if (dwError != ERROR_IO_PENDING) ErrorMessage("WaitCommError():", dwError);
}
dwTemp = WaitForMultipleObjects(2, array, FALSE, INFINITE); // А здесь жду события
if (dwTemp == WAIT_OBJECT_0)
{
CloseHandle(hCom);
/* Выход*/
}

/* Читаю данные из порта */
ZeroMemory(Buffer, 0x104);
dwTemp = 0;
ResetEvent(ov.hEvent);
fResult = ReadFile(hCom, Buffer, 0x100, &dwTemp, &ov);
if (fResult == FALSE)
{
array[0] = hExit;
array[1] = ov.hEvent;
dwTemp = WaitForMultipleObjects(2, array, FALSE, INFINITE);
if (dwTemp == WAIT_OBJECT_0)
{
CloseHandle(hCom);
/* Выход*/
}
dwTemp = 0;
fResult = GetOverlappedResult(hCom, &ov, &dwTemp, TRUE);
if (fResult == FALSE)
{
/* Сообщение и завершение */
}
}

// А здесь я вижу эхо, но не вижу OK от модема


Делается это на NT4, порт называется "COM1" или "COM2". Некоторые дополнительные проверки ошибок из исходника
убраны. С помощью Portmon'а я поглядел как работают некоторые другие программы. От того что у меня они отличаются в основном настройками, связанными с корекцией ошибок. Некоторые пишут в порт по одному байту(терминалы), но без TransmitCommChar(). Мне бы все же хотелось писать сразу всю строку инициализации, тем более я делаю не терминал.

Заранее спасибо. И еще хотелось бы что-нибудь найти по TAPI, референс в MSDN мне мало чем помог. Хочется что-нибудь типа "How to write TAPI 2.x applications.", чтобы была подробно описана сама методика работы с TAPI 2.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.