Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Объясните мне, почему зависает такая конструкция? 
:(
    Опции темы
=Женек=
Дата 7.2.2012, 07:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Господа, использую Builder XE

Объявляю глобальную переменную tick - для отсчета времени, типа флажка, ставлю Timer1 100 мсек и кнопку Button4
Код


unsigned int tick;
//---------------------------------------------------------------------------

void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
tick++;
}
//---------------------------------------------------------------------------



void __fastcall TForm1::Button4Click(TObject *Sender)
{

Timer2->Enabled=true;
while(tick<10) {}
}



Виснет.
Если же пишу 
Код

Timer2->Enabled=true;
ShowMessage(tick);
ShowMessage(tick);
while(tick<10) {}




То программа выводит 0, сразу после запуска таймера, потом пока среагриую, нажму кнопку - цифр скажем 7, а потом программа идет дальше.

В чем дело? Как организовать ожидание в программе?
Для чего это нужно - пишу прогу для работы с UART. Вначале я настроил таймер и по его срабатыванию читаю из буфера приема и вывожу на экран, а по нажатию кнопки пишу что-либо. Все получалось. Но возникла необходимость по нажатию одной кнопки вызвать последовательную протокольную цепь обмена символами (программа для передачи прошивки в микроконтроллер), организовать которую запуском по таймеру одного и того же кода затруднительно.
Хочется написать в одном обработчике что-о вроде:
putchar(0xDA);
while (в буфере пусто) {читаем буфер}
if (в буфере что-то есть) {переносим из буфера в переменную}

но именно на конструкции while все виснет.


Это сообщение отредактировал(а) =Женек= - 7.2.2012, 07:05
PM MAIL   Вверх
rodnover
Дата 7.2.2012, 07:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Потому что код в TForm1::Timer2Timer не выполнится никогда. Попробуйте так:

Код

Timer2->Enabled = true;
while(tick<10) 
{
    Application->ProcessMessages();
}


Только зачем так паузу делать?

Это сообщение отредактировал(а) rodnover - 7.2.2012, 07:31
PM MAIL   Вверх
=Женек=
Дата 7.2.2012, 08:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Объясните мне, что такое ProcessMessages(); ?
Да учтите, что я в итоговой программе не ShowMessage буду крутить, а код общения с UART.
Почему код в Timer1Timer никогда не выполнится?

Добавлено через 5 минут и 5 секунд
И как правильно делать паузу?

Добавлено через 11 минут и 27 секунд
И еще - мне на самом деле нужна не пауза, а ожидание, когда в буфере приема появится необходимое количество байт.
Короче вот набросок кода, который не работает, как правильно сделать безо всяких таймеров?
Код

USBStat=FT_Write(hUSB,TxBytes,&dwBytesWritten); //отправили.

// А теперь ждем когда же в буфере появится 4 байта

while (RxBytes<4) USBStat=FT_GetStatus(hUSB,RxBytes, RxBuffer);// Вот тут у меня зависает.
// 4 байта получено

VARIABLE=RxBuffer[0];




PM MAIL   Вверх
xvr
Дата 7.2.2012, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Поместите всю работу с UART в отдельный thread (класс TThread)

Цитата(=Женек= @  7.2.2012,  08:19 Найти цитируемый пост)
while (RxBytes<4) USBStat=FT_GetStatus(hUSB,RxBytes, RxBuffer);

Самое простое (после помещения этого в отдельный thread) вставить в цикл Sleep - сейчас у вас этот цикл жрет 100% CPU

PM MAIL   Вверх
sawfish
Дата 7.2.2012, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(=Женек= @ 7.2.2012,  08:19)
Объясните мне, что такое ProcessMessages(); ?

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


Опытный
**


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

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



Все равно какая-то хрень получается....

while(RxBytes==0)
{
  Application->ProcessMessages();
 USBStat=FT_GetStatus(hUSB,&RxBytes,&TxBytes,&EventDWord);
}

ПРограммма либо зависает ненадолго, либо выдает RxBytes огромными цифрами....
PM MAIL   Вверх
=Женек=
Дата 7.2.2012, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Как мне получить немедленную реакцию на поступление символа? И в тоже время не перестать слушать, не дождавшись символа?
PM MAIL   Вверх
=Женек=
Дата 7.2.2012, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Хм, как ни странно, получилось без ProcessMessages() следующим образом:
Код

recieve_ok=0;

    while(recieve_ok==0) // В который раз убеждаюсь - флажок это наше все.
    {
      //Application->ProcessMessages();
      USBStat=FT_GetStatus(hUSB,&RxBytes,&TxBytes,&EventDWord);// спокойно проверяем посылку
        if (RxBytes > 0)
         {
           USBStat=FT_Read(hUSB,RxBuffer,RxBytes,&dwBytesReceived);
             if (!USBStat == FT_OK)
                 {
                  USBErr(USBStat);
                  return;
                  };
        RxBuffer[RxBytes]=0;
       RichEdit1->Lines->Add("Получено: "+AnsiString(RxBytes)+":"+ AnsiString((const char*)RxBuffer));
       recieve_ok=1; // ставим флажок
      }
    }

PM MAIL   Вверх
xvr
Дата 8.2.2012, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(=Женек= @  7.2.2012,  21:50 Найти цитируемый пост)
Хм, как ни странно, получилось без ProcessMessages() следующим образом:

Если UART прекратит передавать символы, все ваше приложение мертво зависнет.
И если ваше приложение постоянно общается с UART'ом (в этом цикле), то зависнет все остальное  smile 

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


Опытный
**


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

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



ну таймаут добавить не проблема, это, как говорит Леонид Каневский, уже совсем другая история.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

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

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

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

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


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

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


 




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


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

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