Я пытаюсь заставить простую подпрограмму прерывания работать на ATMega328P. Есть светодиод, подключенный к PD6, и встроенная кнопка на PB7. Светодиод должен нормально мигать до тех пор, пока кнопка не будет нажата, а затем погаснет на 1,5 секунды, прежде чем снова начнет мигать. Вот код:
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
int main(void)
{
// Enable pull-ups and set pin directions
MCUCR |= (1<<PUD);
PORTD &= ~(1<<PORTD6);
DDRD |= (1<<DDD6);
PORTB |= (1<<PORTB7);
DDRB &= ~(1<<DDB7);
// Enable pin change interrupt
PCICR = 0x01;
PCMSK0 = 0x80;
sei();
while (1)
{
// Blink LED at standard rate
_delay_ms(500);
PORTD ^= (1<<PORTD6);
_delay_ms(500);
PORTD ^= (1<<PORTD6);
}
}
ISR(PCINT0_vect,ISR_BLOCK)
{
PORTD &= ~(1<<PORTD6);
_delay_ms(500);
PORTD |= (1<<PORTD6);
_delay_ms(1500);
PORTD &= ~(1<<PORTD6);
}
Прерывание срабатывает правильно, однако процедура ISR повторяется дважды. Я предполагаю, что это какая-то проблема с отскоком кнопки, но я не знаю, как с этим бороться. Я попытался ввести задержку в 500 мс в начале, и я также попытался очистить флаг прерывания смены выводов в ISR, чтобы он не запускался снова, но все же срабатывает. Заранее спасибо за любую помощь!