Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Работа с COM-портом, ошибка при попытке отправить данные  (Прочитано 9605 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Josefina
Участник

ru
Offline Offline

« : 12-01-2011 10:36 » 

Всем доброго времени суток  Улыбаюсь

Обновляю программу, чтобы она кроме работы по Ethernet умела общаться через COM.

--- подключаемся к COM, функция выполняется, hCOM присваивается хендлер не равный INVALID_HANDLE_VALUE
Код:
int COMport::Connect()
{
if (on_connected) Disconnect();

hCOM = CreateFile(SelComPort,
GENERIC_READ | GENERIC_WRITE,
0, // ни с кем делить не будем
NULL, // без секюрити
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, //будем и писать, и читать
NULL);

if (hCOM == INVALID_HANDLE_VALUE)
{
on_connected = false;
return -1;
}

else
{
on_connected = true;
int set = SetupSettings();
if (set == 0)
{
com_tread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&COMport::SetupThread, this, 0, NULL);  //запуск потока на чтение
return 0;
}
else return -1;
}
}

настройки порта
Код:
int COMport::SetupSettings()
{
BOOL bSuccess = GetCommState(hCOM,&dcb); // read current parametr from COM

if (bSuccess)
{
dcb.DCBlength = sizeof(DCB);             // длина структурв DCB
dcb.BaudRate = CBR_9600; // скорость передачи
dcb.fBinary = TRUE;      // включаем двоичный режим, другой виндовс не поддерживает
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = FALSE;
dcb.fNull = TRUE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fAbortOnError = FALSE;
dcb.ByteSize = 8;
dcb.Parity = 0;
dcb.StopBits = ONESTOPBIT;

if(!SetCommState(hCOM,&dcb)) // применяем новые параметры для COM
{
Disconnect();
}
}
else return -1;

PurgeComm(hCOM, PURGE_RXCLEAR); // чистим входящий буфер
PurgeComm(hCOM, PURGE_TXCLEAR); // чистим исходящий буфер

// defines the time-out parameters for COM
ct.ReadIntervalTimeout = 0;
ct.ReadTotalTimeoutMultiplier = 0;
ct.ReadTotalTimeoutConstant = 0;
ct.WriteTotalTimeoutMultiplier = 0;
ct.WriteTotalTimeoutConstant = 0;

if (!SetCommTimeouts(hCOM,&ct))
{
Disconnect();
}

SetupComm(hCOM, buffer.N, buffer.N); // устанавливаем размер буферов чтения/записи

return 0;
}

Пытаемся что-нить отправить в порт
Код:
int COMport::SendMessage(char *message, int message_lenght)
{
DWORD temp;
COMSTAT comstat;

ClearCommError(hCOM, &temp, &comstat);   //очищаем буфер ошибок

if (!temp)
{

int ret = WriteFile(hCOM, message, message_lenght, &temp, &overlappedwr);

if (ret == 0) //если запись не удалась
{
int err = GetLastError();   //получаем код ошибки
TerminalCallback("Запись в COM не удалась", 23, NULL, RECEIVE_MESSAGE); //отправляем сообщение о том, что запись не удалась в лог
return -1;
}
else
{
TerminalCallback("Сообщение отправлено в COM", 26, NULL, RECEIVE_MESSAGE); //отправляем в лог сообщение об удачном завершении операции записи
return 0;
}
}

}

Так вот операция записи возвращает 0, то есть неудача.
GetLastError() возвращает 6, то есть Invalid handler
НО при создании хендлера hCOM все проходит на ура... параметры успешно применяются.
В чем может быть проблема?

Еще при закрытии данного хэндлера, возвращается S_FAILE, то есть с ним действительно что-то не так  А черт его знает... При попытке повторно закрыть, генерируется исключение, пишет, что хендлера нет.

Добавлено через 1 час, 28 минут и 13 секунд:
Продолжаю пытать программулину....

Что-то толкает меня к мысли что я неправильно понимаю как нужно использовать перекрываемые операции и все дело в них.

Удаляю Комментарю все упонимания overlapped в программе, то есть дескриптор порта открываю как:

Код:
	hCOM = CreateFile(SelComPort, 
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
NULL,
NULL);

соответственно, функции чтения и записи, как

WriteFile(hCOM, message, message_lenght, &temp, NULL);

и

ReadFile(pth->hCOM, pth->buffer.MString, btr, &temp, NULL);

вместо адреса структуры overlapped ставлю NULL и вуаля, программа работает  Не может быть...

теперь я совсем в ступоре, так как в моем понимании overlapped как раз таки и нужно использовать если чтение и запись используются одновременно  Здесь была моя ладья...
« Последнее редактирование: 12-01-2011 12:04 от Josefina » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 12-01-2011 14:58 » 

overlapped не нужно, ставь 0 Улыбаюсь

компорт прекрасно справляется со встречными отправкой-чтением
Записан

Josefina
Участник

ru
Offline Offline

« Ответ #2 : 13-01-2011 04:48 » new

overlapped не нужно, ставь 0 Улыбаюсь

компорт прекрасно справляется со встречными отправкой-чтением

Не подскажешь, где об этом можно почитать. В той информации, которую я накопала четко описывается, что нужно overlapped, особенно в моем случае, так как чтение обязательно висит в отдельном потоке. То есть работа с портом идет в асинхронном режиме  :Улыбаюсь

Скромно так... Добавлено позже:
Залезла в MSDN, пишут, что Overlapped Unsupported. Set to NULL. (не поддерживается, установите в NULL)
FILE_FLAG_OVERLAPPED - This flag is not supported. However, multiple read/write operations pending on a device at a time are supported.
(этот флаг не поддерживается, хотя, множественные операции одновременного чтения/записи на устройстве поддерживаются).

Теперь все понятно  Да-да

« Последнее редактирование: 13-01-2011 06:12 от Josefina » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 13-01-2011 10:26 » 

Алексей1153++, COM-порт почти всегда в дуплексном режиме и работает, поскольку по самой распространённой схеме коммутации 2 физические линии крест-накрест соединяют входы и выходы между двумя устройствами.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 13-01-2011 14:58 » 

Dimka, ну я по личному опыту и говорю - очень много приходилось с комом работать - я даже ни разу не делал критическую секцию, всегда работает правильно
Записан

Josefina
Участник

ru
Offline Offline

« Ответ #5 : 28-01-2011 06:09 » 

Алексей1153++ , Dimka, спасибо  Улыбаюсь
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines