реклама на сайте
подробности

 
 
4 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Как перейти к началу функции по внешнему прерыванию?, подробнее внутри
Зверюга
сообщение Aug 15 2008, 13:30
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563



Господа есть код в CodeVision примерно такой:

Код
void  loop()
{
for (i=0;i<360;i++)
  {
     .................      
  }


}

void afterINT()
{
.....
}


void main ()
{
  while (1==1)
    {
      ......
       loop();
      .....
   }
}



Как сделать чтобы по внешнему прерыванию от пина AVR функция loop завершала свою работу? выполнялась функция afterINT(), после чего вновь запускалась функция loop(). Пишу в CodeVision, но буду рад примеру и в WinAVR.


И еще - в ATMEGA32 INT0, INT1 и INT2 чемн-ниьбудь отличаются?
Go to the top of the page
 
+Quote Post
GDI
сообщение Aug 15 2008, 13:38
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Цитата
Как сделать чтобы по внешнему прерыванию от пина AVR функция loop завершала свою работу? выполнялась функция afterINT(), после чего вновь запускалась функция loop().

При возникновении прерывания так и будет, только после прерывания функция loop() продолжит работу с прерванного места(потому это и называется прерыванием), а то что вы написали внутри функции afterINT вам надо написать прямо в обработчике прерывания, или вам надо чтобы после прерывания функция loop() начала свою работу с i=0?

Цитата
И еще - в ATMEGA32 INT0, INT1 и INT2 чемн-ниьбудь отличаются?
Как минимум, отличаются пинами на которые они выведены.


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
Зверюга
сообщение Aug 15 2008, 13:46
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563



Цитата
прерывания, или вам надо чтобы после прерывания функция loop() начала свою работу с i=0?

не просто с i=0, а с самого начала.
Есть некий процесс - в идеале, по его окончанию механика должна послать синхронизирующий сигнал. Если же контроллер не успел выполнить все что в функции loop(), то поезд ушел, все что не доделано должно забыться, и функция должна вновь начать свою работу с чистого листа.
Можно конечно сделать i глобальной переменной,в обработчике прерывания ее обнулять. Но я боюсь что в функции loop перед циклом будет еще несколько строк инициализации.


Цитата
Как минимум, отличаются пинами на которые они выведены.

А все-таки? Собираюсь прицепить 3 датчика Холла, которые будут снимать сигнал частотой максимум 200 Гц, с длительностью импульса не более 70 мкс. Будут прерываяни одинаково работать?
Go to the top of the page
 
+Quote Post
GDI
сообщение Aug 15 2008, 14:00
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Можно в цикле что внутри loop() проверять некий флаг, который будет выставляться в прерывании, и по этому флагу прерывать цикл, а т.к. ваша функция стоит в главном цикле программы, то произойдет очередная итерация главного цикла и выполнятся все команды которые стоят до фунrции loop(), да и те что после.

Цитата
Как минимум, отличаются пинами на которые они выведены.

А все-таки?
Вы хотите заставить меня заглянуть в даташит? smile.gif


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Aug 15 2008, 14:14
Сообщение #5


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Можно в прерывании подменять адрес возврата. Но это грязный хакsmile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 15 2008, 15:01
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



В plain Си функция не может перезапустить саму себя. Это должна сделать внешняя по отношению к ней функция. Напомню, что main это тоже функция.
Вам вполне подойдет вариант с семафором (флагом), который устанавливается в прерывании, а цикле функции анализируется.
Только не забудьте присвоить переменной флага квалификатор volatile, чтобы избежать уже известных граблей.
Go to the top of the page
 
+Quote Post
Kuzmi4
сообщение Aug 15 2008, 15:01
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 3 304
Регистрация: 13-02-07
Из: 55°55′5″ 37°52′16″
Пользователь №: 25 329



2 Зверюга
Цитата
А все-таки?

0 от 1 отличаются вроде только тем что у 0 - приоритет в прерываниях выше. А 2 от предыдущих отличается асинхронностью, приоритетом в конце таблицы и очень урезанными условиями по которым генерится прерывание.. Более подробно- смотрите в ДШ..
Go to the top of the page
 
+Quote Post
Зверюга
сообщение Aug 15 2008, 16:00
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563



Цитата
Только не забудьте присвоить переменной флага квалификатор volatile, чтобы избежать уже известных граблей.



Так как я в разделе для начинащих и сам я ламер - имею полное морально право попросить разъяснить про грабли. Плз...
Go to the top of the page
 
+Quote Post
bzx
сообщение Aug 15 2008, 16:14
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 482
Регистрация: 5-07-05
Из: Санкт-Петербург
Пользователь №: 6 528



Цитата(AHTOXA @ Aug 15 2008, 18:14) *
Можно в прерывании подменять адрес возврата. Но это грязный хакsmile.gif

Только не "подменять" (!!!), а загрузить в стек адрес на нужную функцию, т.е. стек увеличится на 1 слово. При выходе из прерывания окажешься в нужном месте с самого начала, а уже из этого места вернешься в первоначальное состояние.


--------------------
Для связи email: info собака qbit.su
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 15 2008, 16:16
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Зверюга @ Aug 15 2008, 18:00) *
Так как я в разделе для начинащих и....

Moderator:
Вы создали свою тему НЕ в разделе для начинающих. Тему перенес.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 15 2008, 16:27
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Зверюга @ Aug 15 2008, 22:00) *
Так как я в разделе для начинащих и сам я ламер - имею полное морально право попросить разъяснить про грабли. Плз...
Флаг у вас будет изменяться в обработчике прерывания, который логически никак не связан с другими функциями. Поэтому компилятор может (имеет право) оптимизировать обращение к переменной флага таким образом, что считывание ее значения будет производится только один раз при вызове функции в которой вы его проверяете или даже вообще выкинуть из ассемблерного кода обращение к ней. Ведь по логике программы в данной функции флаг не модифицируется, зачем же считывать его значение? Чтобы избежать таких граблей и "заставить" компилятор отменить оптимизацию обращения к переменной, каждый раз при обращении к ней считывая ее реальное значение, нужно использовать квалификатор volatile.
Пример.
Код
unsigned int cntr;
void main (void)
{
...
  cntr=10;
  while(cntr>0);  //<<--здесь программа навсегда зациклится
  ...
}

#pragma vector=TIMER0_VECTOR
__interrupt void TimerISR(void)
{ if (cntr>0) cntr--;
}

Программа в примере зациклится, т.к. компилятор "видя", что значение переменной внутри цикла while не модифицируется и посчитав ее константой, преобразует условие проверки в команду типа jmp сам_на_себя. Чтобы в примере программа не попадала в вечный цикл, нужно обявление делать как
Код
volatile unsigned int cntr;


Сообщение отредактировал rezident - Aug 15 2008, 17:08
Go to the top of the page
 
+Quote Post
Зверюга
сообщение Aug 15 2008, 16:57
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563



Цитата
{ cntr--;
}


Эта строчка "от балды" или играет непонятную мне роль в переходе в начало функции?


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

Можно так сделать?
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 15 2008, 17:17
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Зверюга @ Aug 15 2008, 22:57) *
Эта строчка "от балды" или играет непонятную мне роль в переходе в начало функции?
Опс! Исправил. Она не от балды. Пример иллюстрирует ситуацию, когда переменная изменяется в прерывании, а проверка идет в другой функции. Без квалификатора volatile тут ситуацию не разрулить.
Цитата(Зверюга @ Aug 15 2008, 22:57) *
Можно так сделать?
Вам же уже описали как это можно сделать.
Код
void  loop()
{ for (i=0;i<360;i++)
  { if (flag!=0)
      goto STOP;
     .................      
  }
STOP:
  __no_operation();
}

void afterINT()
{
.....
}

void main ()
{
  while (1==1)
    {
      ......
RESTART:
      loop();
      if (flag!=0)
      { flag=0;
        afterINT();
        goto RESTART;
      }
      .....
   }
}

#pragma vector=INT0_VECTOR
__interrupt void INT0_ISR(void)
{ flag=1;
  ...
}
Go to the top of the page
 
+Quote Post
Зверюга
сообщение Aug 15 2008, 17:37
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563



Спасибо, теперь я разобрался. Это точно для CodeVision?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 15 2008, 17:49
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(rezident @ Aug 15 2008, 19:17) *
...как это можно сделать.

грамотнее.....
Код
for (i=0;i<360;i++)             for( int i=360; i; i-- )
  if (flag!=0)                     if( flag )
goto STOP;                break;
while (1==1)              for(;; )
goto RESTART;           continue;


Цитата(Зверюга @ Aug 15 2008, 19:37) *
Это точно для CodeVision?

А это для вопрос для самоcтоятельного изучения smile.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 04:07
Рейтинг@Mail.ru


Страница сгенерированна за 0.01499 секунд с 7
ELECTRONIX ©2004-2016