Страница 1 из 1

Как поместить прерывание в цикл?

Добавлено: Пн апр 28, 2014 10:46:13
aLedorn
Здравствуйте.
Я начал разбираться с прерываниями и возник вопрос.

Как поместить прерывание в цикл while?
вот пример:

Код: Выделить всё

void main(void)
{
  while(1)
   {
       if(bool == 1)
         {
           interrupt [TIM1_COMPA] void timer1_compa_isr(void)
              {
                 s++; // увеличиваем переменную каждую секунду
                 if(s>59) // обнуляем секунды после 59
                   {
                      s=0;
                   } 
              }
         }
   }
}
Ругается: Error: 'interrupt' or '__interrupt' attributes not allowed in this context.

Re: Как поместить прерывание в цикл?

Добавлено: Пн апр 28, 2014 10:59:38
Kavka
Мнда.... И, вот, опять... и снова... :))
Такого поворота мысли я ещё не встречал. :)) :))
Это на правах лирического отступления, так сказать.

А если серьёзно...
Во-первых, почитайте как работают прерывания вообще.
Во-вторых, как работает таймер, который вы пытаетесь использовать.
В-третьих, самое главное, обратите внимание как запускается код находящийся в прерывании.
В-четвёртых, компилятор правильно ругается. По стандарту Си так делать нельзя. Обработчик прерывание это отдельная процедура.

Какой, кстати, компилятор (среда разработки)? А то TIM1_COMPA в квадратных скобках как-то в глаза бросается.

Re: Как поместить прерывание в цикл?

Добавлено: Пн апр 28, 2014 11:01:42
Gudd-Head
aLedorn писал(а):Как поместить прерывание в цикл while?
Что значит "поместить прерывание в цикл"??? :shock:
Прерывание — это событие.

Как поместить День Рождения в цикл?

Re: Как поместить прерывание в цикл?

Добавлено: Пн апр 28, 2014 11:03:56
kobzar
Gudd-Head писал(а):
aLedorn писал(а):Как поместить прерывание в цикл while?
Как поместить День Рождения в цикл?
А оно и так в цыкле - каждый год в одно и то же время :)

Re: Как поместить прерывание в цикл?

Добавлено: Пн апр 28, 2014 11:24:14
aLedorn
Среда разработки CodeVisionAVR Evaluation.

У меня задача включить секундомер по условию(изменение значения переменной).
Т.е. прерывание нельзя запустить по условию(if)?

Re: Как поместить прерывание в цикл?

Добавлено: Пн апр 28, 2014 11:32:31
Gudd-Head
aLedorn писал(а):Т.е. прерывание нельзя запустить по условию(if)?
Что вы подразумеваете под "запустить прерывание"?

Re: Как поместить прерывание в цикл?

Добавлено: Пн апр 28, 2014 11:49:36
aLedorn
Вот у внешнего прерывание есть условие для прерывания: изменения логического уровня к примеру.
Вот такого же условия я добиваюсь.

Проще говоря прерывание по условию с дополнительным условием.
У меня прерывание происходит каждую десятую секунды. Но мне хотелось бы еще условие, начать прерывание после изменения переменной.

Re: Как поместить прерывание в цикл?

Добавлено: Пн апр 28, 2014 11:54:44
metan
aLedorn писал(а):Т.е. прерывание нельзя запустить по условию(if)?
Аппаратное прерывание и так выполняется по условию. Но можно в прерывании проверить еще какие-то условия (без фанатизма конечно :)).

Код: Выделить всё

interrupt [TIM1_COMPA] void timer1_compa_isr(void) {
  if (bool)  {
    s++; // увеличиваем переменную каждую секунду
    if (s>59) // обнуляем секунды после 59
      s=0;
  }
}

Re: Как поместить прерывание в цикл?

Добавлено: Пн апр 28, 2014 12:17:22
ARV

Код: Выделить всё

if(bool)
      sei(); // разрешаем прерывания
else
      cli(); // запрещаем прерывания
или выборочно - разрешение/запрет только прерывания от таймера.

Re: Как поместить прерывание в цикл?

Добавлено: Пн апр 28, 2014 19:29:00
dosikus
ARV писал(а):......
А если подумать , то что затеял ТС и на не нужно .
И надо то всего-то подумать ...
Верно же было озвучено - нельзя нубам своеволничать ...

Re: Как поместить прерывание в цикл?

Добавлено: Пн апр 28, 2014 22:55:12
mrFox
aLedorn писал(а): Как поместить прерывание в цикл while?

Код: Выделить всё

void main(void)
{
  while(1)
   {
       if(bool == 1)
         {
           interrupt [TIM1_COMPA] void timer1_compa_isr(void)
              {
                 s++; // увеличиваем переменную каждую секунду
                 if(s>59) // обнуляем секунды после 59
                   {
                      s=0;
                   } 
              }
         }
   }
}
Ругается: ...
не ну можно что-то делать не особо разбираясь, но чтоб ТАК :cry:

вообще-то нужно просто включать/выключать таймер
и в прерывании считать

а вообще есть гугл, есть яндекс - набираешь там
микроконтроллер AVR таймер
микроконтроллер AVR прерывания
микроконтроллер AVR для начинающих
информации море и все на русском

Re: Как поместить прерывание в цикл?

Добавлено: Вт апр 29, 2014 00:35:21
YS
aLedorn, ваша задача 100% имеет другое алгоритмическое решение, без прерываний в цикле. :)) Может статься, вам и прерывания-то не нужны.

А так, внеочередное срабатывание прерывания можно принудительно вызвать, руками установив его флаг. Включать/выключать прерывания можно тоже соответствующим флагом, либо глобально, сразу все (sei()/cli(), не знаю, как оно конкретно называется в CVAVR).

Re: Как поместить прерывание в цикл?

Добавлено: Вт апр 29, 2014 01:24:25
dr.doc
Судя по вопросу человек пока не имеет понятия об устройстве МК. А ему "локально, глобально, алгоритмическое решение" - не издевайтесь.
PS Если МК ничего не делает - постоянно проверяете свое условие (или несколько раз в основном цикле программы). Как только оно истинно (нужно запустить таймер) - переходите на подпрограмму, разрешающую работу этого таймера. Если быстродействие критично, то выполняете все настройки (инициализацию), кроме подачи тактовой частоты на счетный вход таймера (регистр TCCR1B) и делаете это уже по условию.

Re: Как поместить прерывание в цикл?

Добавлено: Вт апр 29, 2014 17:57:07
dosikus
dr.doc писал(а):Судя по вопросу человек пока не имеет понятия об устройстве МК. А ему "локально, глобально, алгоритмическое решение" - не издевайтесь.
Сие было бы верно , если бы человек просто повторял чужую конструкцию.
Коли пишешь код - изволь и "кишки" досконально изучить .
А так все это детским садом и аурдуньей попахивает.