// Tiago Pitol Mroginski 202020163
/* 2. (3,5 pontos, 30 min.) Use o circuito anterior, com o dip switch conectado as portas
PB2 a PB0. O temporizador/contador TC0 gera interrupções a cada 1,3 ms. Use as
interrupções deste contador para fazer um led piscar na frequência de 1 Hz (Não
use delay_ms()). A cada mudança em pelo menos uma das entradas (PB2, PB1 e
PB0), transmita pela USART0 o valor de cada entrada, uma vez. Transmita a 9600
Baud, quadros no formato 8N1.
OCR0A = time*Fsis/N -1
OCR0A = TOP
N = geralmete 256 = prescaler
Time = requerido pelo professor
Fsis - 16MHz frequencia do atmega2560
*/
#define __AVR_ATmega2560__
#define F_CPU 16000000UL
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "usart.h" // chama a biblioteca serial pro codigo principal
// Variáveis globais para controle
volatile uint8_t led = 0; // Estado do LED
volatile uint16_t timer_contagem = 0; // Contador para o tempo do LED (1 Hz)
uint8_t final_led = 0xFF; // Último estado do DIP switch
// Função para configurar pinos de entrada e saída
void configura_pinos()
{
DDRB &= ~(1 << DDB2) & ~(1 << DDB1) & ~(1 << DDB0); // Configura como entrada
PORTB |= (1 << PORTB2) | (1 << PORTB1) | (1 << PORTB0); // Ativa resistor de pull-up
DDRB |= (1 << DDB7); // Configura PB7 como saída para o LED
PORTB &= ~(1 << PORTB7);
}
// Função para inicializar o temporizador TC0 para gerar interrupções a cada 1,3 ms
void inicializa_timer()
{
// Configura o temporizador em modo CTC
TCCR0A = (1 << WGM01);
// Define o prescaler para 256
TCCR0B = (1 << CS02);
OCR0A = 81; // valor de TOP
// Habilita interrupção por comparação no temporizador TC0
TIMSK0 = (1 << OCIE0A);
}
// Função de interrupção para o temporizador TC0
ISR(TIMER0_COMPA_vect)
{
// Incrementa o contador do tempo do LED
timer_contagem++;
// Verifica se o contador atingiu 1 Hz = 1 s / 1,3 ms ≈ 769
if (timer_contagem >= 769)
{
led = !led; // Alterna o estado do LED
if (led)
PORTB |= (1 << PORTB7); // Liga o LED
else
PORTB &= ~(1 << PORTB7); // Desliga o LED
timer_contagem = 0; // Reseta o contador
}
uint8_t estado = PINB & 0x07; // Lê os bits PB2, PB1, PB0
// Verifica se houve mudança em pelo menos uma das entradas
if (estado != final_led)
{
// Atualiza o estado do DIP switch
final_led = estado;
// Transmite o valor atual das entradas pela USART0
USART0_transmite_string_RAM("Entradas: ");
USART0_transmite(( estado & (1 << 2)) ? '0' : '1');
USART0_transmite(( estado & (1 << 1)) ? '0' : '1');
USART0_transmite(( estado & (1 << 0)) ? '0' : '1');
USART0_transmite('\r');
USART0_transmite('\n');
}
}
int main()
{
configura_pinos(); // Configura os pinos de entrada e saída
USART0_configura(); // Configura a USART0
inicializa_timer(); // Inicializa o temporizador TC0
sei(); // Habilita interrupções globais
while (1)
{
// Loop infinito
}
return 0;
}