Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаФотогалереяГазетаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » C++ vs COM-port

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2

Открыть новую тему     Написать ответ в эту тему

Craftman



Junior Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Народ кто может кинте реально работающий код! Если можно с коментариями!

Всего записей: 49 | Зарегистр. 28-07-2004 | Отправлено: 15:55 10-11-2004
WiseAlex



Софтовых дел М...
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
http://www.sources.ru/cpp/cpp_system.shtml#7

Всего записей: 1001 | Зарегистр. 02-03-2003 | Отправлено: 18:21 10-11-2004
wiwiw

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
http://www.rs232.ru/doc002.html

Всего записей: 127 | Зарегистр. 20-03-2004 | Отправлено: 22:02 10-11-2004
ArtSh

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
посмотрите MSDN найдете отличный пример.

Всего записей: 92 | Зарегистр. 30-03-2004 | Отправлено: 22:54 10-11-2004
Craftman



Junior Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
А кто нибуть пробовал их на практике. У мея проблема такая что нужно передать модему висящему на COM3 пару АТ комманд. Три дня провозился и безрезультатно. Модем возвращает что угодно кроме того что надо!!!

Всего записей: 49 | Зарегистр. 28-07-2004 | Отправлено: 12:34 11-11-2004
ArtSh

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Конечно пробовал, тот самый пример из MSDN.
На счет того, что возвращает не то, что надо, Вы кабель полный модемный используете?
И не мешело бы код увидедть, а так - дигноз по телефону.

Всего записей: 92 | Зарегистр. 30-03-2004 | Отправлено: 19:34 11-11-2004
Eugen3d



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Никак не могу разобратся с чтением COM-порта (пишу на VC++). Вот маленькая часть кода, отвечающая за чтение:
 

Код:
 
char *SelPort = "COM2";
char buffer[10];
HANDLE hCom;
DWORD nb;
DCB dcb;
byte byterec;
OVERLAPPED overlapped;
 
hCom = CreateFile(SelPort,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hCom == INVALID_HANDLE_VALUE) MessageBox("Error CreateFile()!");
else {
 ReadFile(hCom,&byterec,1,&nb,&overlapped);
 sprintf(buffer,"Number %d", &byterec);
 MessageBox(buffer);
}
 

 
Собственно, что-то читается из порта - байтовая переменная постоянно меняется. Вот теперь вопрос - как заставить порт ловить сигнал четко по его форуме? То есть, не когда вызывается функция ReadFile, а когда в порт приходит стартовый бит. Подозреваю, это через потоки делается... Но как?
 
Добавлено:
Впринципе, уже и сам разобрался с этим - нужно было поставить "ожидания" стартового бита:
SetCommMask(hCom,EV_RXCHAR);
WaitCommEvent(hCom,&mask,NULL);
Теперь разбираюсь в работе асинхронного режима чтения (RS232.ru в этом не мало помогает), хотелось бы увидить живой пример - а то как-то туговато идет...

Всего записей: 1096 | Зарегистр. 28-02-2003 | Отправлено: 22:36 10-07-2005
segeich

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Eugen3d
Ничего особо сложного в асинхронном режиме нет.
- Открываешь порт (CreateFile) с флагом FILE_FLAG_OVERLAPPED
- Инициализируешь одну или две (одна на чтение, другая на запись, если нужно) структуры OVERLAPPED:
   = зануляешь их
   = создаешь event (overlapped.hEvent = CreateEvent(...))
- Вызываешь ReadFile, WriteFile, WaitCommEvent, передавая им указатели на структуры OVERLAPPED
- Если ф-ция возвращает TRUE, то все сделано
- Иначе проверяешь код ошибки (GetLastError)
   = если ERROR_IO_PENDING, то началась асинхронная операция (по ее завершении event, указанный в структуре OVERLAPPED, будет переведен в сигнальное состояние)
   = ждешь ее окончания (если нужно), используя ф-ции вроде WaitForSingleObject(hEvent,...) или GetOverlappedResult(..., TRUE)
   = По завершении операции (в случае WaitForSingleObject) вызываешь GetOverlappedResult(...,FALSE)  
- В итоге получаешь кол-во байт прочитанных (записанных) или вываливаешь из-за ошибки
  = Если кол-во прочитанных данных меньше чем заказано (и не было ошибок), зацикливаешься и делаешь дочтение, т.е. опять ReadFile и т.д.
- Освобождаешь ресурсы (CloseHandle)
 
Все вышесказанное применимо не только к портам, но и к файлам и т.д.

Всего записей: 112 | Зарегистр. 03-01-2003 | Отправлено: 01:53 11-07-2005
mr_eoi



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Eugen3d
23:36 10-07-2005
Цитата:
что-то читается из порта - байтовая переменная постоянно меняется

Чтобы прочистить внутненние буфера COM порта делаем

Код:
PurgeComm(hCom,PURGE_TXCLEAR | PURGE_RXCLEAR);

Для задания времени ожидания до прихода ответа можно использовать функцию SetCommTimeouts  
 
P.S. А мусор из порта может лезть из-за рассогласования скоростей обмена модема и COM порта. Чтобы согласовать эти скорости, в модем надо чего-нибудь "плюнуть", чтобы он смог определить скорость COM порта.

----------
Per Aspera Ad Astra...

Всего записей: 1324 | Зарегистр. 10-08-2003 | Отправлено: 06:45 11-07-2005 | Исправлено: mr_eoi, 06:49 11-07-2005
Eugen3d



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Что-то с портом у меня не важно

Код:
 
char *SelPort = "COM2";
int Number;
HANDLE hCom;
BYTE aaa;
DWORD nb;
OVERLAPPED overlapped;
hCom = CreateFile(SelPort,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
if (hCom == INVALID_HANDLE_VALUE) MessageBox("Error CreateFile()!");
else {
memset(&overlapped,0,sizeof(overlapped));
WriteFile(hCom,&Number,1,&nb,&overlapped);
aaa = 0;
Sleep(11);
ReadFile(hCom,&aaa,1,&nb,&overlapped);
}
 

 
Тут цикл, сперва посылает данные и ждет ответа. Более-менее работает как-то. Пытался через создание события и ожидания приема - совсем плохо. Всмысле как-то непонятно работает.
 
Но мне теперь нужно будет принимать серию до 40 или даже 50 байт. И надо будет каждый раз после успешного чтения байта забирать данные из буфера aaa - но как отловить этот момент?

Всего записей: 1096 | Зарегистр. 28-02-2003 | Отправлено: 11:42 16-07-2005
segeich

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Eugen3d

Цитата:
Тут цикл, сперва посылает данные и ждет ответа

В упор не вижу цикла в твоем куске кода.
 

Цитата:
Пытался через создание события и ожидания приема - совсем плохо. Всмысле как-то непонятно работает.

Читай мой пост выше - там все по шагам расписано как работать асинхронно.
 
И кстати, как уже указывалось выше, для надежной работы с портом может быть необходимо правильно выставить параметры порта (вроде скорости) и таймауты (SetCommState, SetCommTimeouts).

Всего записей: 112 | Зарегистр. 03-01-2003 | Отправлено: 03:58 19-07-2005
Eugen3d



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Кто может обяснить - какая разница между синхронным и асинхронный приемом/передачей?
 
segeich
Цикл там внешний - я его просто вырезал из кода, дабы не загромождать чтение.

Всего записей: 1096 | Зарегистр. 28-02-2003 | Отправлено: 19:04 02-08-2005
raspe



Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Кто может обяснить - какая разница между синхронным и асинхронный приемом/передачей?  

 
Синхронный прием/передача  - это ожидание завершения приема/передачи до перехода к выполнению других инструкций, асинхронная операция не требует такого ожидания

Всего записей: 348 | Зарегистр. 22-07-2005 | Отправлено: 08:04 03-08-2005
AxVPast

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Есть примеры. Все примеры проверенные и живые.
http://www.anthillsolutions.com/cpp.html
Реально работающий код на C++, под Linux, Windows. И вообще на чем угодно.

Всего записей: 5 | Зарегистр. 03-08-2005 | Отправлено: 11:50 03-08-2005
Eugen3d



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
raspe
Спасибо - теперь понял
 
AxVPast
Спасибо за пример - но это синхронная передача. Она еще более-менее понятна. А вот примерчики асинхронной бы...  
 
 
Добавлено:
В моем случае программа будет сканировать порт, и наверное, придется создать 2 потока: один на чтение, один на запись. Ну и взаимблокировать их дабы создать синхронность. Вот проблем же...

Всего записей: 1096 | Зарегистр. 28-02-2003 | Отправлено: 20:07 03-08-2005
AxVPast

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Eugen3d
Асинхроной это как ?
2 Thread один читает другой пишет? В чем проблема-то?

Всего записей: 5 | Зарегистр. 03-08-2005 | Отправлено: 17:40 04-08-2005
Eugen3d



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
AxVPast
Асинхронный это когда при открытии порта указывается FILE_FLAG_OVERLAPPED, тогда работа с портом (ReadFile и WriteFile) будут происходить в фоновом режиме не блокируя поток до завершения.
Я уже более-менее реализовал работу, но всеравно грабли. Открываю порт(асинхронный) и вызывается функция для работы:
 
WriteFile(hCom,&ToSend,1,&nb,&ov);
GetOverlappedResult(hCom,&ov,&nb,TRUE);
Sleep(10);
 
WriteFile(hCom,&ToSend2,2,&nb,&ov);
GetOverlappedResult(hCom,&ov,&nb,TRUE);
Sleep(10);
 
Temp=1;
while (Temp!=0) {
 Temp=0;
 ov.hEvent=CreateEvent(NULL, 1, 1, NULL);
 SetCommMask(hCom,EV_RXCHAR);  
 WaitCommEvent(hCom,&mask,&ov);
 WaitForSingleObject(ov.hEvent, 500);
 ReadFile(hCom,&Temp,2,&nb,&ov);
 if (Temp!=0) Recives.Add(Temp);
}
::PostMessage(HWND(pParam),WM_USERMSGA,0,0);
 
WriteFile(hCom,&ToSend,1,&nb,&ov);
GetOverlappedResult(hCom,&ov,&nb,TRUE);
Sleep(10);
 
Что она должна делать? Передать в порт однобайтное число (например 123), подождать, отправить двубайтное  
число (123+16768), принять все, что идет с порта, отправить один байт (123).
Собственно, работает это через раз - наверняка из-за очень корявого кода. Подскажите, что исправить?

Всего записей: 1096 | Зарегистр. 28-02-2003 | Отправлено: 19:07 06-08-2005
AxVPast

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Eugen3d
Очень кривое железо
В муравьях (http://www.anthillsolutions.com) сделано что-то подобное. Открывается порт в него пишут из него читают.
Используется блокирующий ввод-вывод.
Отадли команду (для 08го муравья - включить выключатель A, выключить b), например
>08=Ab
получили ответ (сделано)
>+08=
Длинна ответа не фиксирована, но четко определяется наличием в конце символа 0x0D.
Если надо это все делать параллельно основной программе - просто создай отдельный процесс (Thread) - пишет, ждет когда запишется, ждет чего-то там (если єто вобще будет надо), читает оттуда "все". Правда в этом случае тяжело говорить про "все" так как нету явного маркера конца принимаемых данных. В принципе можно в качестве этого маркера использовать таймауты (они обычно задаются при настройке DCB структуры). Если их "правильно" привязать к скорости - операция чтения будет завершаться по таймауту (после приема последнего символа прошло больше чем столько-то времени).

Всего записей: 5 | Зарегистр. 03-08-2005 | Отправлено: 19:26 06-08-2005
DeviL



Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Народ не подскажите про события ComPort'а!
Когда использую компонент ComPort с sourceforge.net то все понятно во вкладке Events создаю обработчик события (например приема символа RxChar) и пишу код который нужен. Тут же досталась программа которую нужно доработать а работа с ком-портом реализована через класс SerailPort. Меня интересует как создать обработчик "руками"?  


----------
а вот и моя подпись :))

Всего записей: 268 | Зарегистр. 24-10-2003 | Отправлено: 10:28 10-11-2005
KazimiR



Newbie
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Тема конечно старенькая и я явно припозднился, но все же, на будущее тем, кто будет тему просматривать...
 
В 2005-й студии есть второй фреймворк, в нем есть компонент ком-порта. На мой взгляд пользование этого компонента снимает любые вопросы по ком-порту. По крайней мере для начинающих рабоать с портами.

Всего записей: 29 | Зарегистр. 31-08-2004 | Отправлено: 09:18 11-01-2006
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » C++ vs COM-port

Имя:
Пароль:
Сообщение

Для вставки имени, кликните на нем.

Опции сообщенияДобавить свою подпись
Подписаться на получение ответов по e-mail
Добавить тему в личные закладки
Разрешить смайлики?
Запретить коды


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.Board
© Ru.Board 2000-2011