ATMEGA ОБРАБОТЧИК КНОПКИ ПО ПРЕРЫВАНИЮ

 

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
 
// === Настройки пинов ===
#define LED_DDR   DDRB
#define LED_PORT  PORTB
#define LED_PIN   PB0
 
#define BUTTON_DDR   DDRB
#define BUTTON_PORT  PORTB
#define BUTTON_PINR  PINB
#define BUTTON_BIT   PB3
 
// === Инициализация ===
void io_init(void) {
    // Настроить PB0 как выход (светодиод)
    LED_DDR |= (1 << LED_PIN);
    LED_PORT &= ~(1 << LED_PIN);  // Выключить светодиод
 
    // Настроить PB3 как вход с подтяжкой
    BUTTON_DDR &= ~(1 << BUTTON_BIT);         // вход
    BUTTON_PORT |= (1 << BUTTON_BIT);         // подтягивающий резистор
 
    // Разрешить прерывание по изменению на PB3 (PCINT3)
    PCICR |= (1 << PCIE0);                    // Разрешить прерывания для PCINT[7:0] (PORTB)
    PCMSK0 |= (1 << PCINT3);                  // Разрешить прерывание по PB3
 
    sei();  // Глобальное разрешение прерываний
}
 
// === Обработчик прерывания PCINT0_vect (PORTB: PCINT[7:0]) ===
ISR(PCINT0_vect) {
    // Простейшая программная задержка для антидребезга
    _delay_ms(20);
 
    // Проверка: кнопка нажата (низкий уровень на входе)
    if (!(BUTTON_PINR & (1 << BUTTON_BIT))) {
        LED_PORT |= (1 << LED_PIN);   // Включить светодиод
        _delay_ms(500);               // Подержать немного
        LED_PORT &= ~(1 << LED_PIN);  // Выключить светодиод
    }
}
 
int main(void) {
    io_init();
    while (1) {
        // Пустой цикл, вся логика в обработчике прерывания
    }
}