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

 

#define F_CPU 16000000UL  // Тактовая частота 16 МГц
 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdbool.h>
 
// === Настройки пинов ===
#define LED_DDR   DDRB
#define LED_PORT  PORTB
#define LED_PIN   PB3
 
#define BUTTON_DDR   DDRD
#define BUTTON_PORT  PORTD
#define BUTTON_PINR  PIND
#define BUTTON_BIT   PD6
 
// === Флаг состояния кнопки ===
volatile bool button_pressed = false;
 
// === Инициализация ===
void io_init(void) {
    // Настроить PB3 как выход (светодиод)
    LED_DDR |= (1 << LED_PIN);
    LED_PORT &= ~(1 << LED_PIN);  // Выключить светодиод
 
    // Настроить PD6 как вход с подтяжкой
    BUTTON_DDR &= ~(1 << BUTTON_BIT);         // вход
    BUTTON_PORT |= (1 << BUTTON_BIT);         // подтягивающий резистор
 
    // Разрешить прерывание по изменению на PD6 (PCINT22)
    PCICR |= (1 << PCIE2);                    // Разрешить прерывания для PCINT[23:16] (PORTD)
    PCMSK2 |= (1 << PCINT22);                 // Разрешить прерывание по PD6
 
    sei();  // Глобальное разрешение прерываний
}
 
// === Обработчик прерывания PCINT2_vect (PORTD: PCINT[23:16]) ===
ISR(PCINT2_vect) {
    // Простейшая программная задержка для антидребезга
    _delay_ms(20);
 
    // Проверка: кнопка нажата (низкий уровень на входе)
    if (!(BUTTON_PINR & (1 << BUTTON_BIT))) {
        button_pressed = true;
    }
}
 
int main(void) {
    io_init();
 
    while (1) {
        if (button_pressed) {
            LED_PORT |= (1 << LED_PIN);   // Включить светодиод
            _delay_ms(500);               // Подержать немного
            LED_PORT &= ~(1 << LED_PIN);  // Выключить светодиод
            button_pressed = false;
        }
    }
}