|
|
  |
Как перейти к началу функции по внешнему прерыванию?, подробнее внутри |
|
|
|
Aug 15 2008, 13:30
|
Местный
  
Группа: Свой
Сообщений: 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 чемн-ниьбудь отличаются?
|
|
|
|
|
Aug 15 2008, 13:38
|
Профессионал
    
Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008

|
Цитата Как сделать чтобы по внешнему прерыванию от пина AVR функция loop завершала свою работу? выполнялась функция afterINT(), после чего вновь запускалась функция loop(). При возникновении прерывания так и будет, только после прерывания функция loop() продолжит работу с прерванного места(потому это и называется прерыванием), а то что вы написали внутри функции afterINT вам надо написать прямо в обработчике прерывания, или вам надо чтобы после прерывания функция loop() начала свою работу с i=0? Цитата И еще - в ATMEGA32 INT0, INT1 и INT2 чемн-ниьбудь отличаются? Как минимум, отличаются пинами на которые они выведены.
--------------------
|
|
|
|
|
Aug 15 2008, 13:46
|
Местный
  
Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563

|
Цитата прерывания, или вам надо чтобы после прерывания функция loop() начала свою работу с i=0? не просто с i=0, а с самого начала. Есть некий процесс - в идеале, по его окончанию механика должна послать синхронизирующий сигнал. Если же контроллер не успел выполнить все что в функции loop(), то поезд ушел, все что не доделано должно забыться, и функция должна вновь начать свою работу с чистого листа. Можно конечно сделать i глобальной переменной,в обработчике прерывания ее обнулять. Но я боюсь что в функции loop перед циклом будет еще несколько строк инициализации. Цитата Как минимум, отличаются пинами на которые они выведены. А все-таки? Собираюсь прицепить 3 датчика Холла, которые будут снимать сигнал частотой максимум 200 Гц, с длительностью импульса не более 70 мкс. Будут прерываяни одинаково работать?
|
|
|
|
|
Aug 15 2008, 16:00
|
Местный
  
Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563

|
Цитата Только не забудьте присвоить переменной флага квалификатор volatile, чтобы избежать уже известных граблей. Так как я в разделе для начинащих и сам я ламер - имею полное морально право попросить разъяснить про грабли. Плз...
|
|
|
|
|
Aug 15 2008, 16:27
|
Гуру
     
Группа: Свой
Сообщений: 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
|
|
|
|
|
Aug 15 2008, 16:57
|
Местный
  
Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563

|
Цитата { cntr--; } Эта строчка "от балды" или играет непонятную мне роль в переходе в начало функции? Господа, я могу извернуться и сделать так чтобы по прерыванию выполнялось то что мне нужно, но ради принципа хотелось бы прервать функцию вообще и запустить ее заново уже в главном цикле. Можно так сделать?
|
|
|
|
|
Aug 15 2008, 17:17
|
Гуру
     
Группа: Свой
Сообщений: 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; ... }
|
|
|
|
|
Aug 15 2008, 17:49
|

Гуру
     
Группа: Свой
Сообщений: 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тоятельного изучения
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|