/**
@file interrupcoes_int.c
@author Giovani Baratto ([email protected])
*/
#include <stdint.h> /* usamos o tipo uint8_t */
#define __ATmega2560_ /* programa para o microcontrolador ATmega2560 */
#include <avr/io.h> /* definições das entradas e saÃdas */
#ifndef F_CPU /* se a frequência de clock da CPU não foi definida */
#define F_CPU 16000000UL /* definimos a frequência de clock igual a 16 MHz */
#endif
#include <avr/interrupt.h> /* usamos interrupções no programa */
#include <util/delay.h> /* usamos o procedimento _delay_ms(double) */
uint8_t permite_interrupcao_n;
/**
@brief Sub-rotina de interrupção para tratar as solicitações das interrupções
INT0. Esta sub-rotina complementa o estado de um LED conectado na porta PB0.
*/
ISR(INT0_vect) {
if (permite_interrupcao_n == 0) {
PORTB ^= (1 << PORTB0); // complementa o LED em PB0
permite_interrupcao_n = 10;
}
}
/**
@brief Configuramos o terminal PD0 para gerar interrupções.
PD0 (INT0): interrupção na borda de subida
*/
void interrupcoes_externas_int_configura(void) {
EICRA = 0x02; // ISC3[1:0]=00 ISC2[1:0]=00 ISC1[1:0]=00 ISC0[1:0]=10
EICRB = 0x00; // ISC7[1:0]=00 ISC6[1:0]=00 ISC5[1:0]=00 ISC4[1:0]=00
EIMSK = 0x01; // INT7=0 INT6=0 INT5=0 INT4=0 INT3=0 INT2=0 INT1=0 INT0=1
sei(); // habilita as interrupções globalmente
}
/**
@brief Configuramos as portas deste exemplo
PB[0] : saÃda. Ligamos um LEDs a este terminal (terminal 53 do Arduino)
PD[0] : Entrada com resistor de pull-up interno. Ligamos a este terminal (terminal 21) uma chave tipo push-buttom.
*/
void portas_configura(void) {
// PB0 é configurado como uma saÃda
DDRB |= (1 << DDB0);
// PD0 é configurado como entrada
DDRD &= ~(1 << DDD0);
// Usamos o resistor de pull-up interno de PD0
PORTD |= (1 << DDD0);
}
/**
@brief Procedimento princiapal. Configuramos as portas e as interrupções externas. Fazemos o LED em PB7 piscar.
@return int Este procedimento não retorna
*/
int main(void) {
portas_configura(); // configuras as portas
interrupcoes_externas_int_configura(); // configuramos o sistema para aceitar
permite_interrupcao_n = 0;
while (1) // este laço é continuamente executado
{
_delay_ms(1);
if (PIND & (1 << PIND0)) {
if (permite_interrupcao_n > 0) permite_interrupcao_n--;
} else {
permite_interrupcao_n = 10;
}
}
return 0;
}