ARDUINO attiny85 прерывание по нажатию

ViDi79

✩✩✩✩✩✩✩
1 Окт 2023
31
0
Оформи код соответствующим тэгом, см. Правила
Ребят, подскажите. Порыскал на форуме, не нашел.
Нашел пример по смене пинов прерывания на attiny85, немного откорректировал под себя.

#include <avr/interrupt.h>
volatile int value=0;

void setup(){
GIMSK = 0b00100000; // включение прерывание на PCMSK
PCMSK = 0b00000010; // пин прерывания PB1 в данном случаи.
sei(); // включить прерывание
}

void loop(){
// остальные процессы
}

ISR(PCINT0_vect){
value++; // если прерывание сработало.
}

Подскажите, Срабатывает и на нажатие и отпускание, то есть 2 раза. Есть ли какое то решение по срабатыванию только на нажатие? Еще момент, можно конечно логически написать, чтоб value рос только по нажатию, но не хотелось бы скеч нагружать. Может есть какое то решение аппаратное? Или подскажите где можно почитать на эту тему.
 
Изменено:

Bruzzer

★★★✩✩✩✩
23 Май 2020
501
149
Чтобы реагировало только на нажатие, можно как варианты
  • или использовать прерывание INT0, на нем есть настройки по какому фронту срабатывать
  • или в PCINT0_vect проверять уровень сигнала, и определять нажатие это или отпускание.
Как работает attiny85 можно прочитать в даташите.
Как писать алгоритмы нажатия кнопок - где хорошо описано не подскажу. Возможно у гайвера что то есть.
 

bort707

★★★★★★✩
21 Сен 2020
3,076
915
Срабатывает и на нажатие и отпускание, то есть 2 раза.
Так и должно быть
Есть ли какое то решение по срабатыванию только на нажатие?
В прерывании читать уровень пина и увеличивать счётчик только при нажатии.

А вообще странно, что оно у вас всего два раза срабатывает. Из-за дребезга и 22 раза может. Читать кнопку прерываниями - такая себе идея
 

ViDi79

✩✩✩✩✩✩✩
1 Окт 2023
31
0
В прерывании читать уровень пина и увеличивать счётчик только при нажатии.
не пойму, как например?

А вообще странно, что оно у вас всего два раза срабатывает. Из-за дребезга и 22 раза может. Читать кнопку прерываниями - такая себе идея
Просто там не кнопка, а схема с четкой единицей и нулем. Кнопку упомянул, так проще для понимания.
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
501
149
@ViDi79,
if((PINB & 0b00000010) == 0 ) value++; // если нет дребезга, и сигнал не слишком короткий
Это к словам - "Читать уровни, это скеч логикой нагружать."
 
  • Лойс +1
Реакции: ViDi79 и bort707

ViDi79

✩✩✩✩✩✩✩
1 Окт 2023
31
0
@ViDi79,
if((PINB & 0b00000010) == 0 ) value++; // если нет дребезга, и сигнал не слишком короткий
Это к словам - "Читать уровни, это скеч логикой нагружать."
Спасибо за идею для меня. Я вот не знал, что так можно читать уровень. Коротко и весит мало.
 

ViDi79

✩✩✩✩✩✩✩
1 Окт 2023
31
0
Ребят, еще вопрос:
Большой массив прерывания. Если не дойдя до конца массива, еще раз срабатывает прерывание. Массив дообрабатывает до конца и возвращается void loop{} как и должно. Или при срабатывании он опять начинает массив прерывания заново? Некто не тестировал?
 

poty

★★★★★★✩
19 Фев 2020
3,266
950
@ViDi79, что такое "массив прерывания"? Вообще, по окончании обработки процедуры прерывания, выполняется как минимум одна команда из основного кода.
 

ViDi79

✩✩✩✩✩✩✩
1 Окт 2023
31
0
@ViDi79, что такое "массив прерывания"? Вообще, по окончании обработки процедуры прерывания, выполняется как минимум одна команда из основного кода.
На прерывание, прерывается выполнения процедур и переходит в процедуру прерывания. Как МРК процедуру прерывания полностью выполнил, МКР возвращается к выполнению основного скеча на место на котором его прервали. Вот мне и интересно стало, процедуру самого прерывание при срабатывании он тоже прерывает или нет? :)
 

poty

★★★★★★✩
19 Фев 2020
3,266
950
В нормальных условиях - нет, при входе в обработчик прерывания выполняется запрет всех остальных прерываний, но данное поведение можно изменить.
Из нормальных условий можно сделать вывод, что обработчик прерывания нужно делать как можно более быстрым.
Если поведение изменяется Вы должны точно знать, что делаете, поскольку под риском оказывается много вещей (стек, переменные, последовательность выполнения и проч.).
 

bort707

★★★★★★✩
21 Сен 2020
3,076
915
тоб можно было сказать, что "Да, прерывание не прерывает саму процедуру прерывания"
прерывание никогда не прерывает само себя, оно может прервать только другое прерывание более низкого приоритета. А на тини85, по моему, вообще нет настраиваемых приоритетов прерываний.

Если во время работы обработчика возникнет ещё одно такое же прерывание - оно либо будет проигнорировано, либо поставлено в очередь и обработано после текущего. Если во время работы обработчика возникает более одного нового прерывания, то все кроме последнего игнорируются, что приведет к пропуску импульсов. Именно поэтому, как уже сказал @poty , обработчик должен быть максимально коротким, как минимум короче интервала между входящими импульсами.
 
  • Лойс +1
Реакции: ViDi79

poty

★★★★★★✩
19 Фев 2020
3,266
950
@bort707, не совсем. Согласно datasheet
When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts are disabled. The user software can write logic one to the I-bit to enable nested interrupts. All enabled interrupts can then interrupt the current interrupt routine. The I-bit is automatically set when a Return from Interrupt instruction – RETI – is executed.
Т.е., при возникновении любого прерывания запрещаются все остальные прерывания. А вот если за время запрета прерываний (или при нормальной работе) произошло два прерывания, то их выполнение приоритезируется в соответствии с адресом прерывания (чем меньше, тем больший приоритет имеет).