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

 
 
 
Reply to this topicStart new topic
> Работа с прерываниями PCINIT Atmega88, подскажите как правильно построить структуру?
ikm
сообщение Nov 1 2017, 08:04
Сообщение #1


Знающий
****

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



Здравствуйте нужна помощь в применении внешнего прерывания PCINIT.

У меня в программе есть три цикла, первые два это настройка железа, завершаются по достижения нужных параметров. Последний бесконечный - контроль параметров.
И есть внешняя кнопка, которая переводит в режим ожидания. Вот на эту ногу и надо сделать прерывание, нажата она может быть в любой момент исполнения программы, даже перед включением.
Как мне понятно, что эта функция работает про простому изменение уровня. То есть нажали кнопку произошло прерывание, отпустили, опять произошло прерывание?
Подскажите как можно организовать работу с этим прерыванием, чтобы при нажатии конпки мы выполняли один и тот же цикл (например мигание светодиодом), а при отпускании начинали тот цикл в котором произошло прерывание?
И еще такой вопрос это прерывание всё таки на весь порт, или на отдельную ногу? меня смущает, то что мне CAVR предлагает создать свою функцию по этому прерываню, как весь порт:
CODE
interrupt [PC_INT2] void pin_change_isr2(void)
{
// Place your code here

}

Но при этом есть настройка указать какую ногу использовать :
CODE
// Interrupt on any change on pins PCINT16-23: On
EICRA=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EIMSK=(0<<INT1) | (0<<INT0);
PCICR=(1<<PCIE2) | (0<<PCIE1) | (0<<PCIE0);
PCMSK2=(1<<PCINT23) | (0<<PCINT22) | (0<<PCINT21) | (0<<PCINT20) | (0<<PCINT19) | (0<<PCINT18) | (0<<PCINT17) | (0<<PCINT16);
PCIFR=(1<<PCIF2) | (0<<PCIF1) | (0<<PCIF0);



--------------------
ОБХОДЯ РАЗЛОЖЕННЫЕ ГРАБЛИ - ТЫ ТЕРЯЕШЬ ДРАГОЦЕННЫЙ ОПЫТ!!!
Go to the top of the page
 
+Quote Post
Александр1
сообщение Nov 1 2017, 10:49
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 465
Регистрация: 13-05-15
Из: Запорожье
Пользователь №: 86 663



Цитата(ikm @ Nov 1 2017, 11:04) *
... функция работает про простому изменение уровня. То есть нажали кнопку произошло прерывание, отпустили, опять произошло прерывание?

Да, прерывание возникает при каждом изменении уровня.

Цитата(ikm @ Nov 1 2017, 11:04) *
...как можно организовать работу с этим прерыванием, чтобы при нажатии конпки мы выполняли один и тот же цикл (например мигание светодиодом), а при отпускании начинали тот цикл в котором произошло прерывание?

При возникновении прерывания проверяете состояние порта: при 1-выполняется одна задача, при 0-другая.

Цитата(ikm @ Nov 1 2017, 11:04) *
... это прерывание всё таки на весь порт, или на отдельную ногу?

В регистре PCICR – Pin change interrupt control registe разрешаются прерывания на группу выводов, а в регистрах PCMSK0(1,2) – Pin change mask register 0(1,2) на каждый конкретный вывод порта.
В ДШ все описано.
Go to the top of the page
 
+Quote Post
ikm
сообщение Nov 1 2017, 13:14
Сообщение #3


Знающий
****

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



Цитата(Александр1 @ Nov 1 2017, 13:49) *
При возникновении прерывания проверяете состояние порта: при 1-выполняется одна задача, при 0-другая.

Это то понятно, у меня вопрос был в другом как выйти из цикла по этому прерыванию и вернуться в начало этого цикла обратно.
Поясню:
Возникло прерывание на порту стало 1, на это у меня прописана функция мигать светодиодом. При этом программа выполняла какую то другую задачу из моих трёх основных циклов. Возникло повторное прерывание, я проверил, что стало 0, и мне надо вернуться именно в тот цикл (причем в начало), откуда я вышел.
Мне это видится так:
в функции
interrupt [PC_INT2] void pin_change_isr2(void)
я пишу, цикл в котором мигаю светодиодом, пока на этой ноге 1.
Как только там стало 0, я выхожу из цикла и прописываю условия перехода обратно в ранее исполняемые циклы:
начинаю сравнивать значения переменных которые меняются в двух первых циклах.
Если предположим первая переменная не приняла значение 1, то я ставлю на этот цикл метку М1: , и отправляюсь туда операцией goto M1.
Если значения переменных во втором цикле 0, то ставлю туда метку М2:, и отправлюсь туда goto M2.
Если значения переменных обоих циклов приняли значения 1, то значил в момент прерывания выполнялся третий цикл, и я отправляюсь туда goto M3.

правильное ли такое рассуждение?

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


--------------------
ОБХОДЯ РАЗЛОЖЕННЫЕ ГРАБЛИ - ТЫ ТЕРЯЕШЬ ДРАГОЦЕННЫЙ ОПЫТ!!!
Go to the top of the page
 
+Quote Post
ARV
сообщение Nov 9 2017, 08:16
Сообщение #4


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Цитата(ikm @ Nov 1 2017, 16:14) *
правильное ли такое рассуждение?

не правильное.
Код
volatile char mode = 0;

interrupt [PC_INT2] void pin_change_isr2(void){
   if(PINB & (1<<PB0))
      mode = 1;
   else
      mode = 0;
}

int main(void){
   while(1){ // главный цикл
      while(mode == 0){
         // цикл первой задачи
      }
      while(mode == 1){
         // цикл второй задачи
      }
   }
}
как-то так в общих чертах


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
ikm
сообщение Nov 9 2017, 08:57
Сообщение #5


Знающий
****

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



Цитата(ARV @ Nov 9 2017, 11:16) *
не правильное.

как-то так в общих чертах

Спасибо, да я уже почти разобрался. Точнее подсказали, что после прерывания код продолжает исполнятся с того момента где был прерван, я этого не знал, поэтому и спрашивал: как мне вернуться в то место где произошло прерывание?


--------------------
ОБХОДЯ РАЗЛОЖЕННЫЕ ГРАБЛИ - ТЫ ТЕРЯЕШЬ ДРАГОЦЕННЫЙ ОПЫТ!!!
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 16th April 2024 - 19:51
Рейтинг@Mail.ru


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