#include <stdint.h> /* utilizamos o tipo uint8_t */
#define __AVR_ATmega2560__ /* programa para o microcontrolador ATmega2560 */
#include <avr/interrupt.h> /* usamos interrupções */
#include <avr/io.h> /* definições das entradas e saÃdas */
/**
* @brief Rotina de interrupção chamada quando TCNT0 é igual a OCR0A.
*/
ISR(TIMER0_COMPA_vect) {
PORTB &= ~(1 << PB7); // desligamos o LED em PB7
}
/**
* @brief Rotina de interrupção chamada quando TCNT0 é igual a OCR0A.
*/
ISR(TIMER0_COMPB_vect) {
PORTB |= (1 << PB7); // ligamos o LED em PB7
}
/**
* @brief configura o timer0 para contar os pulsos de T0 (PD7, terminal 38 da placa
* de desenvolvimento). Uma interrupção é gerada a cada 10 pulsos e outra após
* 15 pulsos. Na sub-rotina chamada a 10 pulsos de entrada, ligamos o LED em
* PB[7]. Na sub-rotina chamada a cada 15 pulsos o LED é desligado
*/
void configura_timer0(void) {
// fazemos PD7 = T0 a entrada do sinal de relógio
DDRD = DDRD & (~(1 << DDD7)); // fazemos PD7 = T0 uma saÃda
PORTD = PORTD | (1 << PORTD7); // usamos o resistor de pull-up interno
// configuramos o timer0 para contar os pulsos de T0 (PD7). A cada borda de descida em T0, o contador TCNT0 é
// incrementado.
TCCR0A = 0x02; // saÃas OC0A e OC0B como portas normais. COM0A[1:0]=00 COM0B[1:0]=00 WGM0[2:0]=010
TCCR0B = 0x06; // o sinal de relógio vem de T0. FOC0A = 0 FOC0B = 0 WGM0[2:0]=010 CS0[2:0] = 110
TIMSK0 = 0x06; // Interrupções quando TCNT0 retorna a 0. OCIE0B = 1 OCIE0A = 1 TOIE0 = 0
OCR0A = 14; // valor de TOP = 14. Chamamos ISR(TIMER0_COMPA_vect) a cada 15 pulsos em T0
OCR0B = 9; // Chamamos ISR(TIMER0_COMPB_vect) a cada 10 pulsos em T0
TCNT0 = 0x00; // zeramos o contador
sei(); // aceita globalmente as interrupções
}
/**
* @brief Faz o termina TERMINAL_LED uma saÃda.
*/
void configura_LED(void) {
DDRB = DDRB | (1 << PB7); // faz o terminal TERMINAL_LED uma saÃda
PORTB = PORTB & (~(1 << PB7)); // envia o valor 0 para o terminal TERMINAL_LED
}
/**
* @brief O procedimento principal. Aguarda as interrupções geradas na entrada
* PD7 = T0.
* @return int: O procedimento principal nunca retorna
*/
int main(void) {
// configura o sistema
configura_LED(); // configura a porta PB7 para acionar um LED
configura_timer0(); // configura o TC0 para gerar interrupções
while (1) // um laço infinito. aguarda as interrupções
;
return 0;
}