Trilha de aprendizado · Nível 10 · Tutorial 6

Interrupções de comparação do Timer1

Atender eventos do Timer1 com uma rotina curta de interrupção, enquanto o fluxo principal mantém outra atividade de sinalização no Uno R3 próprio.

  • Nível: Intermediário
  • Duração: 20 min
  • 7 passos
Interrupções de comparação do Timer1

O que você vai percorrer

  1. Do evento de comparação à retomada do programa Entenda a sequência entre uma comparação do Timer1, o atendimento por interrupção e a retomada do programa. 2 min
  2. A flag, a máscara e o vetor corretos Associe a comparação A do Timer1 à flag, à máscara e ao vetor corretos, distinguindo a ocorrência do evento de sua autorização para atendimento. 3 min
  3. Uma ISR que apenas alterna o LED Defina uma ISR curta para a comparação A do Timer1, alternando o LED integrado sem espera nem variáveis compartilhadas. 3 min
  4. Habilitar a interrupção somente ao final Prepare o Timer1 e a saída antes de permitir que a ISR de comparação A seja atendida. 3 min
  5. Por que a rotina precisa terminar rápido Reconheça por que uma ISR precisa ser mínima e quais operações devem permanecer no fluxo principal. 2 min
  6. Duas sinalizações no seu Uno R3 Prática local no Uno R3: uma ISR curta alterna D13 enquanto o loop mantém a sinalização não bloqueante em D7. 5 min
  7. Aplicação final: mudar o loop sem mudar a ISR Ajuste a atividade não bloqueante de D7 sem tocar na ISR e confirme a separação de responsabilidades. 3 min

O que você vai aprender

  • Explicar a sequência entre evento, atendimento da ISR e retomada do programa.
  • Associar o evento de comparação ao vetor e à máscara corretos.
  • Implementar uma ISR curta para alternar o LED integrado sem espera.
  • Reconhecer operações que atrasariam outros atendimentos se fossem colocadas na ISR.

Antes de começar

  • Controle de GPIOs por registradores no ATmega328P
  • Intervalos com o Timer1 em modo CTC

Passo 1 de 7

Do evento de comparação à retomada do programa

Entenda a sequência entre uma comparação do Timer1, o atendimento por interrupção e a retomada do programa.

Um desvio temporário

Da consulta ao atendimento

No tutorial anterior, o loop consultava a flag de comparação do Timer1 e decidia o que fazer. Agora a comparação pode solicitar um atendimento automático: uma interrupção.

Quando o evento é aceito para atendimento, o processador desvia temporariamente do ponto atual do programa para uma rotina curta chamada ISR (Interrupt Service Routine, ou rotina de serviço de interrupção). Ao terminar essa rotina, ele retorna ao fluxo principal exatamente para continuar o trabalho interrompido.

Diagrama de linha do tempo: o processador sai brevemente do fluxo principal, executa uma rotina curta e volta ao ponto interrompido.

A interrupção é um desvio temporário; o fluxo principal não é apagado nem reiniciado.

O que acontece no processador

Evento não é atendimento

A comparação do Timer1 é um evento de hardware: ela acontece quando o contador alcança o valor configurado, independentemente da instrução que o programa está executando naquele instante.

O atendimento pela ISR vem depois. Entre o evento e o começo da rotina pode haver um pequeno atraso, pois o processador conclui a instrução em andamento antes de desviar. Portanto, evento de comparação e primeira instrução da ISR não são necessariamente o mesmo instante.

Exemplo

Pense em uma única pessoa alternando entre duas tarefas. Ela estava seguindo o fluxo principal, recebe um chamado do hardware, faz rapidamente o atendimento e volta à tarefa anterior. Ela não executa as duas tarefas ao mesmo tempo.

O Timer1 continua sendo um periférico de hardware; a ISR é código do processador executado por um breve intervalo.

Verifique a linha do tempo

Sequência de execução

Organize a sequência típica após uma comparação do Timer1.

Coloque os acontecimentos na ordem correta.

  1. O Timer1 atinge o valor de comparação e ocorre o evento.
  2. O processador retorna ao fluxo principal interrompido.
  3. A ISR executa sua ação curta.
  4. O processador interrompe temporariamente o fluxo principal e entra na ISR.

Consolide

Ideia central

Nesta etapa, guarde este modelo mental:

  • O Timer1 produz uma comparação.
  • O processador pode desviar para atendê-la por uma ISR.
  • Enquanto a ISR executa, o trecho principal fica suspenso.
  • Ao final, a execução principal é retomada.

Nos próximos passos, você verá quais condições permitem esse atendimento e qual rotina corresponde especificamente à comparação A do Timer1.

Resumo

Resumo

  • A comparação do Timer1 é um evento de hardware.
  • Uma ISR é um desvio temporário do fluxo principal.
  • O evento pode ocorrer antes de o processador iniciar a ISR.
  • Processador, ISR e loop não executam simultaneamente neste modelo.

Passo 2 de 7

A flag, a máscara e o vetor corretos

Associe a comparação A do Timer1 à flag, à máscara e ao vetor corretos, distinguindo a ocorrência do evento de sua autorização para atendimento.

Evento não é atendimento automático

Duas condições para atender o evento

No step anterior, a comparação do Timer1 foi apresentada como um evento que pode desviar temporariamente o processador para uma ISR. Para esse desvio ocorrer, não basta a comparação acontecer: duas permissões precisam estar ativas.

  • Habilitação global de interrupções: permite que o processador aceite interrupções em geral.
  • Máscara específica do evento: permite o atendimento daquela fonte, neste caso a comparação A do Timer1.

No núcleo Arduino AVR do Uno R3, a habilitação global já está ativa antes de setup() começar. Mesmo assim, a máscara específica do Timer1 continua desabilitada até o seu programa ativá-la.

O caminho até o atendimento

Diagrama mostrando o evento de comparação A passando pela flag e pelas permissões global e específica antes de chegar à rotina de interrupção.

A comparação pode ocorrer sempre que o Timer1 estiver configurado e em funcionamento; o atendimento exige as permissões global e específica.

Flag, máscara e vetor

Os três elementos da comparação A

Para a comparação do canal A do Timer1, use esta associação no ATmega328P:

  • OCF1A, em TIFR1: flag que indica que ocorreu a comparação A.
  • OCIE1A, em TIMSK1: máscara que autoriza o atendimento por interrupção desse evento.
  • TIMER1_COMPA_vect: vetor que identifica a rotina destinada à comparação A.

A flag responde “o evento aconteceu?”. A máscara responde “este evento pode interromper?”. O vetor responde “qual rotina será executada?”.

Os nomes parecidos ajudam a lembrar a relação: OCF1A é a flag, OCIE1A é a habilitação da interrupção e COMPA identifica o canal A no vetor.

Função de cada símbolo

Referência rápida dos símbolos envolvidos na interrupção de comparação A do Timer1.

Associação específica do canal A do Timer1.
ElementoLocalFunção
OCF1ATIFR1Indica comparação A ocorrida
OCIE1ATIMSK1Permite atendimento da comparação A
TIMER1_COMPA_vectVetor de interrupçãoIdentifica a rotina de atendimento
Habilitação globalEstado do processadorPermite aceitar interrupções em geral

Verifique a associação

Identifique a permissão específica

Considere o Timer1 funcionando e ocorrendo uma comparação A. Qual elemento precisa estar habilitado especificamente para que esse evento possa chamar sua rotina de interrupção?

Escreva pelo menos 5 caracteres (0/5).

Explique a associação

Associe cada elemento ao seu papel na comparação A do Timer1.

Escreva pelo menos 30 caracteres (0/30).

Máscara não bloqueia o hardware

Máscara desabilitada

Se OCIE1A estiver desabilitado, a comparação A deixa de acontecer?

Teste seu entendimento

Com a máscara OCIE1A desabilitada, uma comparação A do Timer1 não ocorre e OCF1A nunca é ativada.

Habilite a máscara correta

Complete a instrução que habilita apenas a máscara da comparação A do Timer1, preservando os demais bits do registrador.

cpp
 |= _BV();

Passo 3 de 7

Uma ISR que apenas alterna o LED

Defina uma ISR curta para a comparação A do Timer1, alternando o LED integrado sem espera nem variáveis compartilhadas.

Associar a rotina ao evento

A função chamada pelo hardware

A rotina não é chamada pelo seu código

No exemplo anterior, loop() consultava a flag de comparação. Agora, quando a comparação A for atendida, o processador desvia temporariamente para uma rotina de serviço de interrupção (ISR).

A macro ISR(...), disponível em avr/interrupt.h, associa o corpo da rotina diretamente ao vetor TIMER1_COMPA_vect. Portanto, a ISR fica fora de setup() e de loop() e não deve ser chamada como uma função comum.

Nesta aplicação, ela terá uma única responsabilidade: alternar o LED integrado, ligado a PB5 (D13).

Desvio breve para a ISR

Diagrama mostrando o fluxo principal interrompido brevemente por uma ISR que alterna o LED de PB5 e depois retorna ao fluxo principal.

A ISR é um desvio curto: uma ação no LED e retorno ao ponto em que o programa foi interrompido.

Corpo mínimo e responsabilidade única

Uma ação, sem espera

Código mínimo da ISR

Inclua os cabeçalhos para os nomes dos registradores, bits e vetores AVR. A declaração ISR(TIMER1_COMPA_vect) define a rotina que o hardware executará no atendimento da comparação A.

A escrita de 1 no bit PB5 de PINB alterna o bit correspondente de PORTB; como PB5 será preparado como saída, isso alterna o LED integrado. Não use delay(), laços de espera ou operações longas aqui.

Também não há variável da aplicação acessada tanto por ISR quanto por loop() neste exemplo. Essa troca de dados exige cuidados próprios e será tratada no próximo tutorial.

Definição da ISR

cpp
#include <avr/io.h>
#include <avr/interrupt.h>

ISR(TIMER1_COMPA_vect) {
  PINB = _BV(PB5);
}

Dica

O que a rotina não faz

Quando o ATmega328P aceita este vetor, o hardware limpa automaticamente a flag OCF1A. Assim, esta ISR não deve escrever em TIFR1 para limpar essa flag.

Antes que o atendimento possa ser habilitado, PB5 precisa estar configurado como saída. A sequência completa — incluindo preparar PB5, configurar o Timer1, limpar uma pendência e só então habilitar a máscara — vem no próximo step.

Prática: preencher a rotina

Monte a ISR curta

Complete a definição mínima da ISR. Ela deve incluir o cabeçalho de interrupções, atender a comparação A e alternar apenas PB5.

cpp
#include <avr/io.h>


ISR() {
   = ;
}

Verificação rápida

Escolha a ação essencial

Qual corpo é adequado para a ISR TIMER1_COMPA_vect desta aplicação?

Passo 4 de 7

Habilitar a interrupção somente ao final

Prepare o Timer1 e a saída antes de permitir que a ISR de comparação A seja atendida.

A sequência evita atendimento prematuro

Preparar antes de permitir

A ISR já foi definida; agora importa quando ela pode começar a executar. Durante a inicialização, mantenha o Timer1 parado e sua interrupção de comparação A desabilitada. Assim, o periférico continua reservado à aplicação, mas nenhum atendimento ocorre enquanto registradores e pinos ainda estão sendo preparados.

A ordem segura é: preparar o LED e o Timer1 em CTC, limpar uma possível pendência, iniciar o clock do temporizador e, por último, permitir o atendimento com OCIE1A.

Sequência de partida segura

Diagrama de fluxo no qual a configuração do GPIO e do Timer1 ocorre antes da limpeza da flag, da partida do clock e da habilitação final da interrupção.

A máscara de interrupção é habilitada somente depois que a saída e o temporizador estão prontos.

Configurar, limpar, partir e habilitar

Configuração conhecida, sem partida antecipada

Use a configuração de referência já calculada: clock de 16 MHz, prescaler de 256 e OCR1A = 31249. Em CTC, ela produz uma comparação A a cada 500 ms.

TCCR1A e TCCR1B começam em zero: as saídas de comparação ficam desconectadas e não há clock para o Timer1. A configuração WGM12 seleciona CTC; CS12 inicia o clock com prescaler 256. Como COM1A e COM1B permanecem em zero, o Timer1 não assume o controle de pinos de saída.

Inicialização ordenada no setup

Sketch mínimo para observar a ordem de inicialização. A ISR pode ficar acima ou abaixo de setup(), mas não é chamada diretamente.

cpp
#include <avr/io.h>
#include <avr/interrupt.h>

ISR(TIMER1_COMPA_vect) {
  PINB = _BV(PB5);
}

void setup() {
  DDRB |= _BV(DDB5);              // D13 como saída

  TIMSK1 = 0;
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 31249;
  TCCR1B |= _BV(WGM12);           // CTC
  TIFR1 = _BV(OCF1A);             // limpa pendência
  TCCR1B |= _BV(CS12);            // prescaler 256
  TIMSK1 |= _BV(OCIE1A);          // habilita por último
}

void loop() {
}
Saída esperada
O LED integrado D13 muda de estado aproximadamente a cada 500 ms.
Um ciclo completo de acender e apagar dura cerca de 1 s.

A percepção visual pode variar com a iluminação, mas a mudança de estado do LED integrado deve ocorrer aproximadamente duas vezes por segundo.

Evite uma ISR no meio da preparação

Por que limpar antes da máscara

Uma comparação pode ter ocorrido antes ou durante a preparação. Nesse caso, OCF1A pode estar pendente. Ao escrever 1 nesse bit de TIFR1, a pendência é descartada antes de permitir o atendimento.

Se OCIE1A fosse habilitado cedo demais, com a flag pendente e as interrupções globais já ativas no núcleo Arduino, a ISR poderia iniciar no meio da configuração. Ela poderia alternar PB5 antes de PB5 ser saída ou antes de o Timer1 estar na condição planejada.

Iniciar o clock antes da máscara é seguro: uma comparação futura apenas deixa a flag pendente até que a máscara seja habilitada.

Dica

Regra de organização

A máscara não deve ser a primeira permissão da sequência. Ela só libera o atendimento quando GPIO, modo CTC, contador e comparação já têm estados conhecidos.

Pratique a ordem e as máscaras

Planeje a sequência

Organize as ações na sequência segura. Considere que preparar o Timer1 inclui zerar TCNT1, carregar OCR1A = 31249 e selecionar CTC sem ainda escolher o clock.

Ordem segura de inicialização

Coloque as ações na ordem correta de inicialização.

  1. Selecionar o clock do Timer1 com prescaler 256
  2. Limpar uma eventual pendência de OCF1A em TIFR1
  3. Preparar PB5 como saída e configurar o Timer1 em CTC
  4. Desabilitar a máscara do Timer1 e manter o temporizador parado
  5. Habilitar OCIE1A em TIMSK1

Habilitar no momento certo

Agora complete as duas ações finais: primeiro o clock com prescaler 256 e depois a máscara da comparação A.

Clock e máscara finais

Preencha as máscaras das duas ações finais.

cpp
// GPIO, CTC, contador, OCR1A e TIFR1 já foram preparados
TCCR1B |= ;
TIMSK1 |= ;

Passo 5 de 7

Por que a rotina precisa terminar rápido

Reconheça por que uma ISR precisa ser mínima e quais operações devem permanecer no fluxo principal.

O custo de permanecer na ISR

Um atendimento adia os demais

Em uma ISR normal do AVR, o processador atende a rotina e só depois retorna ao ponto em que interrompeu o programa. Enquanto ela executa, as interrupções ficam globalmente desabilitadas nesta aplicação: não há aninhamento.

Um evento de hardware ainda pode acontecer nesse intervalo e sua flag pode ficar pendente, mas o atendimento correspondente espera a ISR atual terminar. Portanto, interrupção não cria execução simultânea: ela apenas troca temporariamente qual trecho o único processador está executando.

Eventos podem esperar

Linha do tempo que compara uma ISR curta, seguida de retorno rápido ao loop, com uma ISR longa durante a qual eventos do Timer0 e de outros periféricos aguardam atendimento.

O hardware pode registrar eventos durante a ISR, mas seus atendimentos ficam adiados até o retorno.

Curto aqui, trabalho maior no loop

O que cabe na ISR

A ISR de comparação A deste tutorial tem uma responsabilidade deliberadamente pequena: alternar PB5, ligado ao LED integrado. Essa escrita direta é adequada porque termina rapidamente e não depende de espera.

Decida pelo tempo de execução e pela responsabilidade da ação.
Ação propostaLugar adequadoMotivo
`PINB = _BV(PB5);`ISREscrita curta para alternar D13
`delay(100);`Fora da ISRDepende de serviços temporais afetados na ISR
Laço esperando uma condiçãoFora da ISRPode prolongar o bloqueio sem limite previsível
Cálculo ou processamento demoradoFora da ISRProlonga a suspensão do firmware
Atualizar D7 por `millis()`loopDepende da base temporal do Timer0

Atenção

Regra prática

Evite delay(), laços de espera e processamento demorado no corpo da ISR. No Arduino AVR, delay() depende de serviços temporais ligados ao Timer0. Durante uma ISR normal, os atendimentos estão desabilitados; por isso, delay() não é uma espera confiável nesse contexto e pode manter a rotina presa de modo inválido ou imprevisível.

Uma ISR longa também adia o atendimento do Timer0 e, consequentemente, a atualização da base usada por millis(). Mantenha a ação mínima na ISR. Uma tarefa maior deve ficar no fluxo principal; a comunicação segura entre ISR e loop() será abordada no próximo tutorial.

Prática: encontre a espera

Exemplo

Analise uma espera sem limite

Considere esta proposta para a ISR de comparação do Timer1:

ISR(TIMER1_COMPA_vect) {
  PINB = _BV(PB5);

  while (entradaAindaNaoEstaPronta()) {
    // espera por uma condição externa
  }
}

A escrita em PINB é curta. O problema é o laço: não há garantia de quando a condição ficará pronta. Enquanto ele continua, a ISR não retorna ao loop() e outros vetores aguardam atendimento.

Verifique seu raciocínio

Qual alternativa explica corretamente por que essa ISR é inadequada?

Síntese e previsão

Essencial deste step

Uma ISR não acelera uma tarefa longa nem a executa em paralelo ao loop(). Ela interrompe o fluxo principal, executa uma ação curta e retorna.

Para esta aplicação, a rotina deve apenas alternar PB5. Esperas, laços que aguardam algo e operações demoradas ficam fora dela. Assim, o loop() continua responsável por suas atividades, e os demais atendimentos não ficam bloqueados por uma ISR extensa.

Explique com suas palavras

Você decidiu colocar uma espera ou um processamento de cerca de 200 ms dentro da ISR para deixar o LED visível. O que pode acontecer com o loop() e com atendimentos dependentes do Timer0 enquanto essa ISR ainda está ativa?

Escreva pelo menos 80 caracteres (0/80).

Passo 6 de 7

Duas sinalizações no seu Uno R3

Prática local no Uno R3: uma ISR curta alterna D13 enquanto o loop mantém a sinalização não bloqueante em D7.

1. Prepare a montagem local

Monte as duas saídas

Monte a segunda sinalização com a placa desenergizada: conecte D7 → resistor de 1 kΩ → ânodo do LED; conecte o cátodo (terminal mais curto ou lado achatado) ao GND. Depois, alimente o Uno R3 somente pelo cabo USB de dados conectado ao computador.

O LED integrado em D13 não precisa de montagem externa. Nesta prática, ele será alternado pela ISR do Timer1; o LED externo em D7 será controlado exclusivamente pelo loop() usando millis().

Ligação do LED externo

Diagrama mostrando D7 ligado a um resistor de 1 kΩ, ao ânodo de um LED externo e, pelo cátodo, ao GND; o LED integrado em D13 também está destacado.

D7 aciona o LED externo; D13 corresponde ao LED integrado do Uno R3.

Atenção

Alimentação e revisão

Não conecte fonte externa a VIN nem ao pino de 5 V durante esta prática. Confira a polaridade do LED antes de ligar o USB: um LED invertido normalmente não acende, mas a montagem deve sempre ser revisada com a placa sem alimentação.

2. Use o sketch completo

Grave uma aplicação com responsabilidades separadas

Copie o sketch completo para a IDE Arduino, selecione Arduino Uno e a porta correta, depois grave na sua placa. Não acrescente bibliotecas que usem o Timer1.

A ISR só escreve em PINB para alternar PB5/D13. O loop() mantém seu próprio estado e sua própria marca de tempo para D7. Não há consulta a OCF1A no loop() e não há variável compartilhada entre os dois fluxos.

Sinalização por Timer1 e millis

Sketch completo para o Uno R3

cpp
#include <avr/io.h>
#include <avr/interrupt.h>

ISR(TIMER1_COMPA_vect) {
  PINB = _BV(PB5);  // alterna somente o LED integrado (D13)
}

void setup() {
  DDRB |= _BV(DDB5);              // D13 como saída
  DDRD |= _BV(DDD7);              // D7 como saída
  PORTD &= ~_BV(PORTD7);

  TIMSK1 = 0;
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 31249;
  TCCR1B |= _BV(WGM12);           // CTC
  TIFR1 = _BV(OCF1A);             // limpa pendência
  TCCR1B |= _BV(CS12);            // prescaler 256
  TIMSK1 |= _BV(OCIE1A);          // habilita por último
}

void loop() {
  static unsigned long ultimoD7 = 0;
  static bool d7Ligado = false;
  unsigned long agora = millis();

  if (agora - ultimoD7 >= 200) {
    ultimoD7 = agora;
    d7Ligado = !d7Ligado;

    if (d7Ligado) {
      PORTD |= _BV(PORTD7);
    } else {
      PORTD &= ~_BV(PORTD7);
    }
  }
}
Saída esperada
D13 muda de estado a cada cerca de 500 ms.
D13 completa um ciclo em cerca de 1 s.
D7 muda de estado a cada cerca de 200 ms.
D7 completa um ciclo em cerca de 400 ms.

O resultado é físico: observe os LEDs na placa após gravar o sketch. As cadências são aproximadas e podem variar ligeiramente.

3. Confirme o vetor usado pela ISR

Verifique a associação vetor → ISR

Complete o nome do vetor que liga a ISR ao evento de comparação A do Timer1. A rotina não é chamada pelo loop(); o hardware a atende quando a comparação habilitada ocorre.

Vetor da comparação A

Preencha a lacuna com o vetor correto.

cpp
#include <avr/interrupt.h>

ISR() {
  PINB = _BV(PB5);
}

4. Verifique o resultado no hardware

Observe as duas cadências

Após gravar o sketch, observe os dois LEDs por alguns segundos. O LED integrado D13 deve mudar de estado a cada comparação, aproximadamente a cada 500 ms; por isso, seu ciclo completo fica perto de 1 s. O LED externo em D7 muda de estado aproximadamente a cada 200 ms, com ciclo completo perto de 400 ms.

As duas cadências não significam que o processador executa ISR e loop() simultaneamente: a ISR é breve, termina e o processador retoma o loop().

Registre sua observação

Relate o que você observou na sua placa: qual LED pareceu mais rápido e qual trecho do programa controla cada um? Se algo não funcionou, descreva o comportamento observado e a ligação que você conferiu.

Escreva pelo menos 80 caracteres (0/80).

Passo 7 de 7

Aplicação final: mudar o loop sem mudar a ISR

Ajuste a atividade não bloqueante de D7 sem tocar na ISR e confirme a separação de responsabilidades.

Síntese da integração

Duas responsabilidades separadas

A cadeia desta aplicação é: a comparação A do Timer1 ocorre, OCF1A indica o evento, a máscara OCIE1A e as interrupções globais permitem o atendimento, e o vetor TIMER1_COMPA_vect leva à ISR. A rotina alterna somente D13 e termina; então o processador retoma o ponto em que o loop() foi interrompido.

Isso não é execução simultânea: é uma troca rápida e temporária de fluxo. Como D7 é controlado apenas pelo loop(), sua cadência pode mudar sem alterar a ISR nem a configuração do Timer1.

Fluxos que se encontram só no processador

Diagrama mostra o Timer1 desviando brevemente a execução para alternar D13, enquanto o loop controla D7 antes e depois desse atendimento.

A ISR atende D13 por um instante; o loop retoma e continua responsável por D7.

Prática final no Uno R3

Altere apenas a atividade do loop

Na IDE Arduino do seu computador, abra o sketch da prática anterior. Altere somente o intervalo usado pelo loop() para alternar D7: de 200 ms para 800 ms.

Não modifique OCR1A, os registradores do Timer1, TIMSK1 nem o corpo da ISR. Mantenha a verificação temporal não bloqueante: ela precisa continuar usando a comparação de tempo decorrido, sem delay().

Grave o sketch no seu Uno R3. O LED externo em D7 deve completar um ciclo em aproximadamente 1,6 s, pois alterna a cada 800 ms. O LED integrado em D13 continua alternando a cada 500 ms, com ciclo aproximado de 1 s.

Complete a integração

Complete as duas partes que preservam a separação da aplicação: o intervalo de D7 e a máscara que habilita a comparação A do Timer1.

Intervalo e máscara

Preencha apenas os elementos que já foram estudados.

cpp
const unsigned long intervaloD7 = ;

// Depois de configurar o Timer1 e limpar uma pendência:
TIMSK1 = ;

Validação e conclusão

Observe e justifique

Após observar a placa, registre sua previsão confirmada: como ficaram as duas sinalizações? Em seguida, explique por que colocar delay(800) dentro da ISR seria inadequado.

Escreva pelo menos 80 caracteres (0/80).

Resumo

Fechamento

Critérios que você validou

  • A comparação A gera a indicação OCF1A; a máscara OCIE1A habilita seu atendimento pelo vetor TIMER1_COMPA_vect.
  • A saída e o Timer1 são preparados antes de habilitar a máscara de interrupção.
  • A ISR é curta: alterna D13 sem espera e retorna ao fluxo interrompido.
  • O loop controla D7 com temporização não bloqueante e sem alterar recursos do Timer1.
  • Mudar a cadência de D7 não muda a cadência de D13 quando as responsabilidades permanecem separadas.
  • No próximo tutorial, você verá como tratar dados compartilhados entre ISR e loop com segurança.

Tutorial concluído

Parabéns! Você concluiu: Interrupções de comparação do Timer1

Competência alcançada: configurar e usar uma interrupção de comparação do Timer1 sem bloquear as demais atividades do firmware.

Baixe o Aplicativo agora para ter acesso a + de 5000 cursos gratuitos, exercícios, certificado e muito conteúdo sem pagar nada!

  • Cursos online 100% gratuitos do início ao fim

    Milhares de cursos online em vídeo, ebooks e áudiobooks.

  • Mais de 60 mil exercícios gratuitos

    Para testar seus conhecimentos no decorrer dos cursos online

  • Certificado Digital gratuito válido em todo o Brasil

    Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail

Aplicativo Cursa na tela de ebook, na tela de curso em vídeo e na tela de exercícios do curso, mais o certificado de conclusão de curso