Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с RS-232, Разбор примера 
:(
    Опции темы
mishapk
Дата 11.7.2012, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 26.1.2012

Репутация: нет
Всего: нет



Всем привет!
Помогите разобраться с примером взятого со стать

Код

//главная функция потока, реализует приём байтов из 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" - не правильно.
и т.д.

Как это исправить? В чем может быть причина в функции опроса или в функции вывода?



PM MAIL   Вверх
Dem_max
Дата 11.7.2012, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 14
Всего: 39



У тебя же асинхронная операция чтения данных с порта так что варианты
Ответ1: "0123456789" - правильно.
Ответ2:"0123" - правильно.
Ответ3: "456789" - правильно.

Если тебе нужно принять 10 байт, то принимай 10 байт по частям как в Ответ2 и Ответ3, а потом "склеивай" Ответ2 и Ответ3 и получишь те же 10 байт.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
sawfish
Дата 12.7.2012, 07:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 30.7.2008
Где: Новосибирск

Репутация: 8
Всего: 8



А вообще, лучше уйти от асинхронного приема. 
Если ждете ответ от устройства, после передачи запроса поставьте небольшую задержку и потом читайте (в синхронном режиме) с хорошим запасом таймаута.
PM MAIL   Вверх
mishapk
Дата 12.7.2012, 09:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 26.1.2012

Репутация: нет
Всего: нет



Я поставил маленькую задержку перед определением количества байт в буфере, теперь все успевает полностью.
Код

 Sleep(25);
        ClearCommError(COMport, &temp, &comstat);        //нужно заполнить структуру COMSTAT
        btr = comstat.cbInQue;                           //и получить из неё количество принятых байтов
        if(btr)                                  //если действительно есть байты для чтения

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0416 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.