Всем привет! Помогите разобраться с примером взятого со http://www.piclist.ru/S-COM-THREAD-RUS/S-COM-THREAD-RUS.html
| Код | //главная функция потока, реализует приём байтов из COM-порта void __fastcall ReadThread::Execute() { COMSTAT comstat; //структура текущего состояния порта, в данной программе используется для определения количества принятых в порт байтов DWORD btr, temp, mask, signal; //переменная temp используется в качестве заглушки
overlapped.hEvent = CreateEvent(NULL, true, true, NULL); //создать сигнальный объект-событие для асинхронных операций SetCommMask(COMport, EV_RXCHAR); //установить маску на срабатывание по событию приёма байта в порт while(!Terminated) //пока поток не будет прерван, выполняем цикл { WaitCommEvent(COMport, &mask, &overlapped); //ожидать события приёма байта (это и есть перекрываемая операция) signal = WaitForSingleObject(overlapped.hEvent, INFINITE); //приостановить поток до прихода байта if(signal == WAIT_OBJECT_0) //если событие прихода байта произошло { if(GetOverlappedResult(COMport, &overlapped, &temp, true)) //проверяем, успешно ли завершилась перекрываемая операция WaitCommEvent if((mask & EV_RXCHAR)!=0) //если произошло именно событие прихода байта { ClearCommError(COMport, &temp, &comstat); //нужно заполнить структуру COMSTAT btr = comstat.cbInQue; //и получить из неё количество принятых байтов if(btr) //если действительно есть байты для чтения { EscapeCommFunction(COMport,CLRRTS); ReadFile(COMport, bufrd, btr, &temp, &overlapped); //прочитать байты из порта в буфер программы counter+=btr; //увеличиваем счётчик байтов Synchronize(Printing); //вызываем функцию для вывода данных на экран и в файл } } } } CloseHandle(overlapped.hEvent); //перед выходом из потока закрыть объект-событие }
//-------------------------------------------------------------------------------------------------------------------------------- void __fastcall ReadThread::Printing() { // Form1->Caption=TimeToStr(Now()); Form1->Memo1->Lines->Add((char*)bufrd); //выводим принятую строку в Memo Form1->StatusBar1->Panels->Items[2]->Text = "Всего принято " + IntToStr(counter) + " байт"; //выводим счётчик в строке состояния
if(Form1->CheckBox3->Checked == true) //если включен режим вывода в файл { write(handle, bufrd, size_send); //записать в файл данные из приёмного буфера } memset(bufrd, 0, BUFSIZE); //очистить буфер (чтобы данные не накладывались друг на друга) }
|
Все хорошо работает, просто замечательно. Но есть одно "Но": Ответ приходит через раз по частям. То есть может быть вот так: Ответ1: "0123456789" - правильно. Ответ2:"0123" - не правильно. Ответ3: "456789" - не правильно. и т.д.
Как это исправить? В чем может быть причина в функции опроса или в функции вывода?
|