ikm 3 1 ноября, 2017 Опубликовано 1 ноября, 2017 · Жалоба Здравствуйте нужна помощь в применении внешнего прерывания PCINIT. У меня в программе есть три цикла, первые два это настройка железа, завершаются по достижения нужных параметров. Последний бесконечный - контроль параметров. И есть внешняя кнопка, которая переводит в режим ожидания. Вот на эту ногу и надо сделать прерывание, нажата она может быть в любой момент исполнения программы, даже перед включением. Как мне понятно, что эта функция работает про простому изменение уровня. То есть нажали кнопку произошло прерывание, отпустили, опять произошло прерывание? Подскажите как можно организовать работу с этим прерыванием, чтобы при нажатии конпки мы выполняли один и тот же цикл (например мигание светодиодом), а при отпускании начинали тот цикл в котором произошло прерывание? И еще такой вопрос это прерывание всё таки на весь порт, или на отдельную ногу? меня смущает, то что мне CAVR предлагает создать свою функцию по этому прерываню, как весь порт: interrupt [PC_INT2] void pin_change_isr2(void) { // Place your code here } Но при этом есть настройка указать какую ногу использовать : // 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); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
АлександрК 0 1 ноября, 2017 Опубликовано 1 ноября, 2017 · Жалоба ... функция работает про простому изменение уровня. То есть нажали кнопку произошло прерывание, отпустили, опять произошло прерывание? Да, прерывание возникает при каждом изменении уровня. ...как можно организовать работу с этим прерыванием, чтобы при нажатии конпки мы выполняли один и тот же цикл (например мигание светодиодом), а при отпускании начинали тот цикл в котором произошло прерывание? При возникновении прерывания проверяете состояние порта: при 1-выполняется одна задача, при 0-другая. ... это прерывание всё таки на весь порт, или на отдельную ногу? В регистре PCICR – Pin change interrupt control registe разрешаются прерывания на группу выводов, а в регистрах PCMSK0(1,2) – Pin change mask register 0(1,2) на каждый конкретный вывод порта. В ДШ все описано. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ikm 3 1 ноября, 2017 Опубликовано 1 ноября, 2017 · Жалоба При возникновении прерывания проверяете состояние порта: при 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 такое не прокатит, эта операция не может выполняться из одной функции в другую. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 1 9 ноября, 2017 Опубликовано 9 ноября, 2017 · Жалоба правильное ли такое рассуждение? не правильное. 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){ // цикл второй задачи } } } как-то так в общих чертах Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ikm 3 9 ноября, 2017 Опубликовано 9 ноября, 2017 · Жалоба не правильное. как-то так в общих чертах Спасибо, да я уже почти разобрался. Точнее подсказали, что после прерывания код продолжает исполнятся с того момента где был прерван, я этого не знал, поэтому и спрашивал: как мне вернуться в то место где произошло прерывание? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться