/*
Duas chaves ideais são conectadas as entradas INT0 e INT1. As chaves geram interrupções.
As interrupções são geradas nas bordas de subida em INT0 e nas bordas de descida em
INT1. A sub-rotina de interrupção de INT0 acende um LED em PB0. A sub-rotina de
interrupção de INT1 apaga este LED.
*/
//Bibliotecas:
#define __ATmega2560__
#define __AVR_ATmega2560__
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#define LED PB0
#define CHAVE_1 PD0
#define CHAVE_2 PD1
void main (){
DDRB |= (1 << LED); // Configura LED como saída
DDRD &= ~(1 << CHAVE_1); // Configura chave como entrada
PORTD |= (1 << CHAVE_1); // Habilita o pull-up na chave
DDRD &= ~(1 << CHAVE_2); // Configura chave como entrada
PORTD |= (1 << CHAVE_2); // Habilita o pull-up na chave
/*ISC01 ISC00 Tipo de Interrupção PARA INT0
0 0 Nível baixo
0 1 Qualquer mudança
1 0 Borda de descida
1 1 Borda de subida
*/
/*ISC10 ISC11 Tipo de Interrupção PARA INT1
0 0 Nível baixo
0 1 Qualquer mudança
1 0 Borda de descida
1 1 Borda de subida
*/
// Configura INT0 para interrupção na borda de descida
EICRA |= ((1 << ISC01 | 1<< ISC00) | (1 << ISC11));
EIMSK |= ((1 << CHAVE_1)|(1 << CHAVE_2)) ; // Habilita a interrupção externa INT0 e INT1
sei(); // Habilita interrupções globais
while (1) {
// Loop principal vazio; troca de estado ocorre na interrupção
}
return 0;
}
// Sub-rotina de interrupção para INT0
ISR(INT0_vect) {
PORTB ^= (1 << LED); // Alterna o estado do LED
}
// Sub-rotina de interrupção para INT1
ISR(INT1_vect) {
PORTB ^= (1 << LED); // Alterna o estado do LED
}