|
Чтение данных из ком-порта в WINXP, избитая тема, но решения для Builder 6 нигде не нашел |
|
|
|
 |
Ответов
|
May 4 2006, 14:07
|

Участник

Группа: Свой
Сообщений: 65
Регистрация: 31-08-05
Из: Moscow
Пользователь №: 8 124

|
Цитата(Aleks17 @ May 4 2006, 16:24)  Я правда в Билдере нифига не понимаю - на Visual C++ пишу, но думаю принципы те же:
Вариант 1) Многопоточное приложение.
Вариант 2) Открываешь порт для асинхронных операций (FILE_FLAG_OVERLAPPED по-моему)
и организуешь процедуру таймера, внутри которой (а не в процедуре) проверяешь на получение данных. вот посмотрите Код MComPort.Write(&lpBuf,1); // отправили байт в устройство Timer1->Enabled=true; //включили таймер
memset(&MComPort.Overlap,0,sizeof(MComPort.Overlap)); //это для overlap MComPort.Overlap.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL); //MComPort.Overlap - сама структура оверлап MComPort.Read(SystemAnswer,1); //читаем байт в переменную SystemAnswer
//обработчик события таймера void __fastcall TForm1::Timer1Timer(TObject *Sender) { if(WaitForSingleObject(MComPort.Overlap.hEvent,10000)==WAIT_OBJECT_0) { GetOverlappedResult(MComPort.handle,&MComPort.Overlap,&byte_counter,FALSE); } else { Application->MessageBoxA("Нет отзыва о выполнении движения","Внимание",MB_OK); } } мне кажется, что я сделал что-то не так...
|
|
|
|
|
May 5 2006, 05:25
|
Местный
  
Группа: Свой
Сообщений: 238
Регистрация: 17-01-05
Из: Новосибирск
Пользователь №: 2 003

|
Цитата(skopus @ May 4 2006, 21:07)  вот посмотрите Код MComPort.Write(&lpBuf,1); // отправили байт в устройство Timer1->Enabled=true; //включили таймер
memset(&MComPort.Overlap,0,sizeof(MComPort.Overlap)); //это для overlap MComPort.Overlap.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL); //MComPort.Overlap - сама структура оверлап MComPort.Read(SystemAnswer,1); //читаем байт в переменную SystemAnswer
//обработчик события таймера void __fastcall TForm1::Timer1Timer(TObject *Sender) { if(WaitForSingleObject(MComPort.Overlap.hEvent,10000)==WAIT_OBJECT_0) { GetOverlappedResult(MComPort.handle,&MComPort.Overlap,&byte_counter,FALSE); } else { Application->MessageBoxA("Нет отзыва о выполнении движения","Внимание",MB_OK); } } мне кажется, что я сделал что-то не так... Ну в целом похоже. Только место для структуры помнится надо задавать до открытия порта (не помню точно). И Event смотреть не обязательно (да и создавать тоже) если GetOverlappedResult пользуешь, функция же возвращает ссостояние.
|
|
|
|
|
May 5 2006, 06:39
|

Участник

Группа: Свой
Сообщений: 65
Регистрация: 31-08-05
Из: Moscow
Пользователь №: 8 124

|
Цитата(Aleks17 @ May 5 2006, 09:25)  Цитата(skopus @ May 4 2006, 21:07)  вот посмотрите Код MComPort.Write(&lpBuf,1); // отправили байт в устройство Timer1->Enabled=true; //включили таймер
memset(&MComPort.Overlap,0,sizeof(MComPort.Overlap)); //это для overlap MComPort.Overlap.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL); //MComPort.Overlap - сама структура оверлап MComPort.Read(SystemAnswer,1); //читаем байт в переменную SystemAnswer
//обработчик события таймера void __fastcall TForm1::Timer1Timer(TObject *Sender) { if(WaitForSingleObject(MComPort.Overlap.hEvent,10000)==WAIT_OBJECT_0) { GetOverlappedResult(MComPort.handle,&MComPort.Overlap,&byte_counter,FALSE); } else { Application->MessageBoxA("Нет отзыва о выполнении движения","Внимание",MB_OK); } } мне кажется, что я сделал что-то не так... Ну в целом похоже. Только место для структуры помнится надо задавать до открытия порта (не помню точно). И Event смотреть не обязательно (да и создавать тоже) если GetOverlappedResult пользуешь, функция же возвращает ссостояние. но че-то это так и не заработало. Кнопку остановки так и нельзя нажать, пока программа ждет приема из КОМ-порта. Ща попробую ожидание приема в отдельный поток вынести
|
|
|
|
|
May 5 2006, 08:14
|

Знающий
   
Группа: Свой
Сообщений: 697
Регистрация: 26-07-05
Из: Могилев
Пользователь №: 7 095

|
Цитата(skopus @ May 5 2006, 09:39)  Цитата(Aleks17 @ May 5 2006, 09:25)  Цитата(skopus @ May 4 2006, 21:07)  вот посмотрите Код MComPort.Write(&lpBuf,1); // отправили байт в устройство Timer1->Enabled=true; //включили таймер
memset(&MComPort.Overlap,0,sizeof(MComPort.Overlap)); //это для overlap MComPort.Overlap.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL); //MComPort.Overlap - сама структура оверлап MComPort.Read(SystemAnswer,1); //читаем байт в переменную SystemAnswer
//обработчик события таймера void __fastcall TForm1::Timer1Timer(TObject *Sender) { if(WaitForSingleObject(MComPort.Overlap.hEvent,10000)==WAIT_OBJECT_0) { GetOverlappedResult(MComPort.handle,&MComPort.Overlap,&byte_counter,FALSE); } else { Application->MessageBoxA("Нет отзыва о выполнении движения","Внимание",MB_OK); } } мне кажется, что я сделал что-то не так... Ну в целом похоже. Только место для структуры помнится надо задавать до открытия порта (не помню точно). И Event смотреть не обязательно (да и создавать тоже) если GetOverlappedResult пользуешь, функция же возвращает ссостояние. но че-то это так и не заработало. Кнопку остановки так и нельзя нажать, пока программа ждет приема из КОМ-порта. Ща попробую ожидание приема в отдельный поток вынести Естественно через таймер не заработает, так как процедура-обработчик стоит на месте пока не сработает WaitForSingleObject, а так как таймер работает в главном потоке - то главный поток стоит. Выход - организовать процедуру чтения в отдельном потоке - это позволит управлять главным потоком приложения (нажимать на кнопки), но надо иметь в виду, что пока таймаут у WaitForSingleObject не кончится (если еще байты от устройства не пришли во входной буфер ком-порта) поток чтения все равно не убъешь, только если закрыть приложение. На C++Builder поток реализуется следующим образом: Код DWORD WINAPI ReadBites()//процедура потока { if(WaitForSingleObject(MComPort.Overlap.hEvent,10000)==WAIT_OBJECT_0) { GetOverlappedResult(MComPort.handle,&MComPort.Overlap,&byte_counter,FALSE); } else { Application->MessageBoxA("Нет отзыва о выполнении движения","Внимание",MB_OK); } }
HANDLE ht=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ReadBites, NULL, 0, &ind);//запускаем поток CloseHandle(ht);
|
|
|
|
Сообщений в этой теме
skopus Чтение данных из ком-порта в WINXP May 4 2006, 11:27 _artem_ rezim overlapped IO ne podxodit ? May 4 2006, 12:23 skopus Цитата(Aleks17 @ May 4 2006, 16:24) Я пра... May 4 2006, 12:33     javalenok Вообще, потоки для коммуникации нафиг не нужны. По... May 7 2006, 18:58 _artem_ Eto standartniy API - builder ili visualC ne dolze... May 4 2006, 13:22 one_man_show Уже писалось не раз: ищешь на torry.net TComPort (... May 4 2006, 14:02 skopus Цитата(one_man_show @ May 4 2006, 18:02) ... May 4 2006, 14:28 Aleks17 Так ты, сдается мне, открыл порт без надлежащего ф... May 5 2006, 07:35 unichorn Кстати неплохой пример работы с COM портами есть у... May 8 2006, 10:33
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|