
Passo 1 de 9
Um contador que funciona em hardware
Reconheça o Timer1 como contador de hardware independente do loop e prepare o uso responsável dos temporizadores do Uno R3.
Trilha de aprendizado · Nível 10 · Tutorial 5
Configurar o Timer1 do Uno R3 próprio para produzir intervalos calculados e consultar seus eventos no loop, sem alterar a base de tempo de millis.
Um contador que funciona em hardware
Reconheça o Timer1 como contador de hardware independente do loop e prepare o uso responsável dos temporizadores do Uno R3. 2 min
Como o CTC forma um intervalo
Entenda como a sequência de contagem do modo CTC determina o intervalo entre comparações. 2 min
Escolha o prescaler e calcule OCR1A
Selecione um prescaler que faça o intervalo caber no contador e confira o valor realmente representado. 4 min
Traduza o cálculo em campos de registradores
3 min
Consulte e limpe a flag sem esperar
Consulte OCF1A no loop e limpe-a corretamente por escrita direta, sem transformar o evento em uma espera bloqueante. 3 min
Inicialize antes de liberar o clock
Prepare o Timer1 em um estado conhecido e só libere seu clock depois de definir todos os parâmetros, preservando o Timer0. 3 min
Dois eventos formam um ciclo do LED
Relacione cada comparação atendida à alternância do LED e preveja o ciclo completo da saída. 2 min
Teste o intervalo no seu Uno R3
Grave e observe um sketch completo que alterna o LED integrado por consulta não bloqueante da flag de comparação do Timer1. 4 min
Aplique um novo intervalo e confira o resultado
Aplique a configuração de 250 ms com prescaler 64, confira o ciclo do LED e valide as condições de uso seguro do Timer1. 3 min

Passo 1 de 9
Reconheça o Timer1 como contador de hardware independente do loop e prepare o uso responsável dos temporizadores do Uno R3.
Nesta prática, a referência é o Arduino Uno R3 com ATmega328P, cujo clock nominal é de 16 MHz. Não transfira automaticamente estes valores, registradores ou comportamentos para Uno R4, ESP32 ou outras placas.
O Timer1 é um periférico de hardware com um contador de 16 bits. Ele pode assumir valores de 0 a 65535. Depois de configurado, seu contador recebe pulsos de clock e avança sem depender de o processador estar executando rapidamente ou lentamente as instruções do loop().
Assim, o loop() continua disponível para ler entradas, atualizar estados e comandar saídas enquanto o Timer1 conta em paralelo no hardware.

O prescaler divide o clock antes de ele chegar ao Timer1. A contagem ocorre em hardware, independentemente das tarefas executadas no loop.
O prescaler é o divisor aplicado ao clock antes da contagem. Se o divisor reduz a frequência entregue ao Timer1, cada avanço do contador leva mais tempo. Nos próximos passos, você escolherá esse divisor e definirá o limite de contagem para formar intervalos calculados.
Por enquanto, retenha o fluxo: clock de 16 MHz → prescaler → contador Timer1. O processador não precisa executar uma instrução para cada incremento do contador.
Dica
Enquanto Timer1 conta, o loop() não deve ficar esperando a contagem terminar. A ideia será consultar eventos do temporizador e retornar logo às demais tarefas — uma organização compatível com a temporização não bloqueante já estudada com millis().
O Uno R3 possui mais de um temporizador. Nesta prática, preserve o Timer0: o núcleo Arduino o utiliza para serviços temporais, incluindo millis(). Portanto, não vamos alterar a configuração do Timer0.
Também trate o Timer1 como recurso exclusivo deste exemplo. Reconfigurá-lo muda o funcionamento de tudo que depende dele. Entre os recursos que podem ser afetados estão analogWrite() nos pinos 9 e 10 e bibliotecas que usam Timer1.
Antes de usar esta técnica em um projeto, verifique quem já controla cada temporizador.

Uma mesma configuração do Timer1 não deve ser disputada por funções, bibliotecas ou saídas que esperam outro modo de operação.
Atenção
Evite alterar registradores de um temporizador apenas para “testar”. Uma mudança aparentemente local pode interromper millis(), alterar uma saída ou causar falha em uma biblioteca que já dependia daquele periférico.
Um sketch usa analogWrite(9, 128) para controlar uma saída e também pretende reconfigurar o Timer1 para esta prática. Qual conclusão é correta?

Passo 2 de 9
Entenda como a sequência de contagem do modo CTC determina o intervalo entre comparações.
No modo CTC (Clear Timer on Compare), o Timer1 conta de 0 até o valor guardado em OCR1A. Quando a contagem alcança esse limite, ocorre a comparação do canal A e o contador retorna a 0 por hardware para começar outro ciclo.
O loop() não precisa mandar esse retorno acontecer. Ele pode continuar executando outras instruções enquanto o contador avança conforme seu clock dividido pelo prescaler.

OCR1A estabelece o limite da contagem; o hardware faz o reinício após a comparação.
Considere o exemplo visual com OCR1A = 4. A sequência é:
0 → 1 → 2 → 3 → 4 → 0 → ...
Embora 4 seja o valor máximo contado, há cinco valores no ciclo: 0, 1, 2, 3 e 4. Portanto, o ciclo ocupa OCR1A + 1 passos do clock do contador.
A comparação acontece quando o contador chega a 4. O passo seguinte já inicia a nova contagem em 0.
Exemplo
Se o clock que chega ao contador tiver período de 16 µs e OCR1A = 4, cada ciclo terá 5 passos:
T = 5 × 16 µs = 80 µs
Não use apenas OCR1A para contar os passos: isso excluiria indevidamente o valor zero.
O intervalo entre duas comparações consecutivas é:
T = N × (OCR1A + 1) / f_clock
Em que:
O termo N / f_clock fornece a duração de um passo do contador. Ao multiplicá-la pela quantidade de passos, obtemos o intervalo completo.
Exemplo
Para um exemplo hipotético com prescaler N = 8 e OCR1A = 999:
999 + 1 = 1000;8 / 16 000 000 s = 0,5 µs;1000 × 0,5 µs = 500 µs.O próximo step mostrará como escolher valores que atendam a um intervalo desejado e caibam no contador.
Em CTC, se OCR1A = 6, quantos passos do clock do contador ocorrem entre comparações consecutivas?

Passo 3 de 9
Selecione um prescaler que faça o intervalo caber no contador e confira o valor realmente representado.
O Timer1 recebe o clock nominal de 16 MHz do Uno R3, mas o prescaler o divide antes da contagem. Assim, cada incremento do contador demora:
passo = N / 16 MHz
Como o contador e OCR1A têm 16 bits, o maior valor de OCR1A é 65535. Um ciclo CTC pode, portanto, ter no máximo 65536 passos. Escolha um divisor que faça o intervalo desejado caber nessa faixa.
Valores calculados para o clock nominal de 16 MHz e o maior ciclo possível, com OCR1A = 65535.
| Prescaler N | Duração de 1 passo | Maior intervalo CTC |
|---|---|---|
| 1 | 0,0625 µs | 4,096 ms |
| 8 | 0,5 µs | 32,768 ms |
| 64 | 4 µs | 262,144 ms |
| 256 | 16 µs | 1,048576 s |
| 1024 | 64 µs | 4,194304 s |

O prescaler não altera o clock da placa: ele determina apenas a frequência que chega ao contador do Timer1.
Partindo da fórmula já vista, isole OCR1A:
OCR1A = T × f_clock / N − 1
Use T em segundos, f_clock = 16 000 000 Hz e N como o prescaler. O resultado deve ficar entre 0 e 65535. Depois, substitua o valor escolhido na fórmula do intervalo para conferir o valor nominal obtido.
Não escolha o divisor pelos bits de configuração agora; aqui ele é apenas um número da tabela.
Exemplo
Requisito: comparação a cada 500 ms = 0,5 s.
Com N = 64:
OCR1A = 0,5 × 16 000 000 / 64 − 1
OCR1A = 124999
Esse valor ultrapassa 65535. Embora o passo de 4 µs pareça pequeno, essa opção não comporta 500 ms em um ciclo CTC.
Exemplo
Com N = 256:
OCR1A = 0,5 × 16 000 000 / 256 − 1
OCR1A = 31249
O valor cabe na faixa. Conferindo:
T = 256 × (31249 + 1) / 16 000 000
T = 0,5 s = 500 ms
Logo, N = 256 e OCR1A = 31249 produzem, nominalmente, uma comparação a cada 500 ms.
Nem todo requisito gera OCR1A inteiro. Suponha que o divisor esteja fixado em N = 1024 e o intervalo desejado seja 123 ms.
OCR1A = 0,123 × 16 000 000 / 1024 − 1
OCR1A = 1920,875
OCR1A só aceita inteiros. Arredondando para 1921, recalcule o intervalo real; não anuncie 123 ms como se fosse um valor exato.
Exemplo
Com OCR1A = 1921:
T_efetivo = 1024 × (1921 + 1) / 16 000 000
T_efetivo = 0,123008 s = 123,008 ms
O erro em relação ao requisito é +0,008 ms, ou +8 µs. O requisito desejado, o valor representável e o intervalo efetivo são grandezas diferentes.
Se outro arredondamento for escolhido, faça a mesma conferência e compare o erro.
Dica
Para um intervalo, primeiro verifique se o OCR1A calculado cabe de 0 a 65535. Se não couber, tente um prescaler maior. Se não for inteiro, escolha um inteiro próximo e calcule novamente o intervalo efetivo.
Você precisa de comparações a cada 250 ms, com prescaler N = 64. Qual valor inteiro de OCR1A configura esse intervalo nominal?
OCR1A = ____
Para o caso de 500 ms, qual afirmação está correta?

Passo 4 de 9
No ATmega328P do Uno R3, o Timer1 é controlado por registradores com papéis diferentes:
Para o caso de 500 ms já calculado, OCR1A = 31249. Ele define o limite; não escolhe sozinho nem o modo CTC nem o prescaler.

TCCR1A e TCCR1B configuram o funcionamento; TCNT1 e OCR1A representam valores do contador e da comparação.
O modo CTC usado aqui é o modo 4. Seus bits de seleção devem formar WGM13:0 = 0100:
Com essa combinação, OCR1A é o topo da contagem. Os campos COM1A1:0 e COM1B1:0, localizados em TCCR1A, permanecem em zero. Assim, os pinos de saída de comparação ficam desconectados: a comparação acontece internamente, mas não comanda um pino automaticamente.
Os campos necessários para esta prática
| Campo | Registrador | Função nesta prática |
|---|---|---|
| COM1A1:0 | TCCR1A | Manter em 00: saída A desconectada |
| COM1B1:0 | TCCR1A | Manter em 00: saída B desconectada |
| WGM11:0 | TCCR1A | Manter em 00 para o modo 4 |
| WGM13 | TCCR1B | Manter em 0 para o modo 4 |
| WGM12 | TCCR1B | Colocar em 1: seleciona CTC 4 |
| CS12:0 | TCCR1B | Escolher clock ou parar o contador |
O campo CS12:0 define o clock que chega ao contador. O padrão 000 para o Timer1; os demais padrões internos úteis são:
No caso-base, N = 256, portanto CS12:0 = 100. Isso significa CS12 ativo e CS11, CS10 zerados. A escolha do divisor fica em TCCR1B, junto de WGM12.
Considere estas atribuições como a tradução dos campos para o caso-base. Elas mostram quais bits representam CTC 4, prescaler 256 e saídas desconectadas; a ordem completa e segura de inicialização será tratada no próximo passo.
Complete as três lacunas sem alterar os demais termos.
Preencha os campos de TCCR1A e TCCR1B para CTC 4 com prescaler 256.
TCCR1A = ;
TCCR1B = _BV() | _BV();
Passo 5 de 9
Consulte OCF1A no loop e limpe-a corretamente por escrita direta, sem transformar o evento em uma espera bloqueante.
Quando a contagem do Timer1 alcança OCR1A, o hardware ativa a flag OCF1A no registrador TIFR1. Ela indica que existe uma comparação do canal A pendente de reconhecimento pelo programa.
A flag é persistente: depois de ficar em 1, continua em 1 até que o programa a limpe. Portanto, o loop() pode consultá-la sem ficar esperando. Se ela ainda estiver em 0, o fluxo simplesmente segue para as outras tarefas.

O Timer1 gera o evento em hardware; o loop apenas verifica se há uma pendência.
A consulta usa uma máscara, como nas leituras de bits já estudadas. O operador & verifica se OCF1A está ativo. Quando a condição é verdadeira, execute uma ação curta e limpe a pendência.
A limpeza de flags em TIFR1 tem uma regra especial: escrever 1 limpa o bit correspondente. Use atribuição direta da máscara. Escrever 0 não limpa nada.
Trecho para usar dentro de loop(). A consulta não bloqueia: se ainda não houve comparação, o programa continua após o if.
if (TIFR1 & _BV(OCF1A)) {
// Atenda rapidamente a comparação pendente.
TIFR1 = _BV(OCF1A); // Escrever 1 limpa OCF1A.
}
// Outras tarefas do loop continuam aqui.Atenção
Evite TIFR1 |= _BV(OCF1A);. Essa forma lê todas as flags que já estão em 1 e depois escreve esses 1s de volta; como 1 significa “limpar”, outras flags pendentes poderiam ser apagadas junto.
Para reconhecer somente OCF1A, escreva diretamente TIFR1 = _BV(OCF1A);.
Complete o trecho que consulta uma comparação pendente do canal A e limpa somente essa flag.
if ( & _BV()) {
// ação curta para a comparação
= _BV();
}Uma flag não é um contador. Imagine que OCF1A esteja em 0, ocorram duas comparações antes da próxima consulta e o loop então leia TIFR1.
O que o programa consegue saber nesse instante?
Após duas comparações sem limpeza entre elas, qual informação OCF1A fornece ao loop?
Dica
Planeje o loop() para retornar logo à consulta. Se uma tarefa demora demais, várias comparações podem ocorrer enquanto OCF1A já está em 1; depois da limpeza, essas ocorrências anteriores não poderão ser recuperadas individualmente.

Passo 6 de 9
Prepare o Timer1 em um estado conhecido e só libere seu clock depois de definir todos os parâmetros, preservando o Timer0.
A configuração deve começar com o Timer1 parado. Assim, nenhum pulso avança o contador enquanto você define o modo, o limite e o estado inicial.
Não suponha que o Timer1 esteja no estado desejado por causa do núcleo Arduino ou de outro trecho do programa. Nesta prática, ele é um recurso exclusivo: estabeleça explicitamente uma condição conhecida em setup().
O Timer0 não participa desta configuração. Não escreva nos registradores dele: é assim que millis() continua funcionando normalmente.

Preparar primeiro e liberar o clock por último evita uma contagem iniciada com parâmetros parciais.
Dica
Mantenha também as interrupções específicas do Timer1 desabilitadas nesta prática:
TIMSK1 = 0;
Isso não muda a habilitação global de interrupções. Apenas garante que nenhum evento do Timer1 será atendido por interrupção; aqui, o programa reconhecerá a comparação consultando TIFR1 no loop().
O atendimento por interrupção será assunto do próximo tutorial.
Com o clock parado, configure as saídas de comparação desconectadas, zere a contagem e carregue o limite calculado. Para o caso de 500 ms já calculado, use OCR1A = 31249.
Uma flag OCF1A poderia ter ficado pendente antes da sua configuração. Limpe-a escrevendo 1 na máscara correspondente, por atribuição direta. Só então selecione CTC e o prescaler 256 em TCCR1B.
Trecho para colocar em setup(). O LED e o loop serão completados mais adiante.
#include <avr/io.h>
void setup() {
TIMSK1 = 0; // prática por consulta
TCCR1A = 0; // COM1A/COM1B desconectados; WGM11:10 = 0
TCCR1B = 0; // clock parado; WGM13:12 = 0
TCNT1 = 0; // contagem inicial conhecida
OCR1A = 31249; // 500 ms com prescaler 256
TIFR1 = _BV(OCF1A); // escreve 1 para limpar pendência
TCCR1B = _BV(WGM12) | _BV(CS12); // CTC 4 e prescaler 256
}
void loop() {
// consulta de OCF1A virá aqui
}Exemplo
A última atribuição reúne dois campos já conhecidos: WGM12 seleciona o modo CTC 4 quando os demais bits WGM estão em zero; CS12 corresponde ao padrão 100, que seleciona o prescaler 256.
Depois dessa linha, o hardware começa a contar. Por isso ela deve vir depois de TCNT1, OCR1A e da limpeza da flag.
Atenção
Coloque as operações na ordem apropriada para iniciar o Timer1 em CTC por consulta. Considere que o contador está parado antes do primeiro item.
Ordene da primeira à última operação.
Escreva pelo menos 120 caracteres (0/120).
Agora organize a sequência concreta.
Organize as operações da primeira para a última.
A inicialização pertence a setup(), que é executado uma vez. Não a repita em loop().
Se loop() escrever repetidamente TCNT1 = 0, a contagem recomeçará antes de alcançar OCR1A. Se repetir a limpeza da flag, pode apagar uma comparação antes de atendê-la. E reescrever a configuração do temporizador sem necessidade torna o comportamento mais difícil de prever.
No loop(), a tarefa será apenas consultar a flag, atender o evento quando ela estiver presente e limpá-la corretamente.
Por que TCNT1 = 0 não deve ser repetido a cada passagem por loop()?

Passo 7 de 9
Relacione cada comparação atendida à alternância do LED e preveja o ciclo completo da saída.
A cada comparação do Timer1 que o loop() encontra e atende, o programa alterna o LED integrado: se estava desligado, liga; se estava ligado, desliga.
Portanto, uma comparação muda um estado, mas um ciclo completo do LED precisa de duas comparações: uma para ir de desligado para ligado e outra para voltar a desligado.

Duas comparações atendidas formam um ciclo completo: um trecho ligado e um trecho desligado.
Se o Timer1 gera comparações a cada intervalo T_comparação e todas são atendidas, o período nominal do LED é:
T_LED = 2 × T_comparação
A frequência do LED vem do período completo:
f_LED = 1 / T_LED
Não confunda a frequência das comparações com a frequência de piscar do LED: como são necessários dois eventos por ciclo, o LED completa ciclos à metade da frequência das comparações.
Exemplo
Com comparações a cada 500 ms:
As comparações do hardware seguem o valor calculado com o clock nominal de 16 MHz. Já a mudança no LED acontece quando o loop() consulta a flag e a atende. Se o loop() demora, a mudança pode ocorrer depois da comparação. Se mais de uma comparação ocorrer antes da limpeza, a flag continua representando apenas uma pendência; ela não informa quantas ocorreram.
O Timer1 gera uma comparação a cada 500 ms, e o loop() atende cada uma delas sem demora relevante. Qual é o período completo e a frequência aproximada do LED alternado a cada comparação?
Período e frequência do LED:

Passo 8 de 9
Grave e observe um sketch completo que alterna o LED integrado por consulta não bloqueante da flag de comparação do Timer1.
Agora você vai reunir a configuração já estudada em um único sketch para o Uno R3 com ATmega328P. O Timer1 gerará uma comparação a cada 500 ms; o loop() consultará a flag sem ficar parado esperando.
O LED integrado é o D13, correspondente a PB5. Ele começa apagado. Cada comparação reconhecida alterna esse pino; portanto, dois eventos formam um ciclo completo: aproximadamente 1 s.

A comparação ocorre a cada 500 ms; o período completo nominal do LED é aproximadamente 1 s.
Crie um sketch na IDE Arduino local, substitua seu conteúdo por este código, selecione a placa e a porta do seu Uno R3 e grave-o pela conexão USB. Não conecte componentes externos nesta prática.
O programa não usa bibliotecas adicionais. Ele preserva o Timer0: não escreve em registradores desse temporizador e, portanto, não altera a base usada por millis().
#include <avr/io.h>
void setup() {
DDRB |= _BV(DDB5); // LED integrado: PB5 / D13
PORTB &= ~_BV(PORTB5); // começa apagado
TCCR1A = 0; // saídas desconectadas; WGM11:0 = 0
TCCR1B = 0; // Timer1 parado
TIMSK1 = 0; // sem interrupções do Timer1
TCNT1 = 0;
OCR1A = 31249;
TIFR1 = _BV(OCF1A); // limpa pendência escrevendo 1
TCCR1B = _BV(WGM12) | _BV(CS12);
}
void loop() {
if (TIFR1 & _BV(OCF1A)) {
TIFR1 = _BV(OCF1A); // reconhece e limpa a comparação
PINB = _BV(PINB5); // alterna o LED
}
// Outras tarefas curtas podem ser atendidas aqui.
}LED integrado (D13): alterna aproximadamente a cada 500 ms. Ciclo completo esperado: aproximadamente 1 s.
A IDE não exibirá uma saída textual para este sketch. A saída a conferir é visual: o LED integrado deve ficar aproximadamente 500 ms apagado, 500 ms aceso e repetir esse ciclo em cerca de 1 s. A observação visual não é uma medição de precisão.
Antes de gravar, complete mentalmente ou no exercício o trecho central que ficará dentro de loop(). Ele deve atender rapidamente uma comparação pendente, sem espera ativa.
if ( & _BV()) {
= _BV();
= _BV();
}Após gravar, observe o LED integrado por alguns ciclos. O comportamento esperado é cerca de meio segundo em cada estado e um ciclo completo próximo de 1 s.
Faça também uma leitura rápida do sketch: não há delay(), laço de espera, escrita em Timer0 nem outro uso do Timer1. O if apenas atende a flag quando ela está presente; quando não está, o fluxo prossegue imediatamente para as demais tarefas.
Atenção
Se o LED integrado não estiver visível no seu modelo ou se você não puder gravar a placa agora, analise o código e faça a previsão, mas não trate essa análise como uma observação física.
Descreva sua verificação. O LED alternou aproximadamente a cada 500 ms, formando um ciclo próximo de 1 s? Cite uma evidência no código de que o loop() não fica bloqueado e uma condição que precisa continuar verdadeira para este sketch funcionar como previsto.
Escreva pelo menos 80 caracteres (0/80).

Passo 9 de 9
Aplique a configuração de 250 ms com prescaler 64, confira o ciclo do LED e valide as condições de uso seguro do Timer1.
Novo requisito: produza uma comparação a cada 250 ms com o prescaler fixado em N = 64.
Com o clock nominal de 16 MHz do Uno R3:
OCR1A = T × f_clock / N − 1
OCR1A = 0,250 × 16.000.000 / 64 − 1 = 62.499
Portanto, OCR1A = 62499. Cada ciclo do contador tem 62.500 passos. Como o LED alterna a cada comparação reconhecida, ele permanece aproximadamente 250 ms em cada estado. O ciclo completo do LED é nominalmente 500 ms.

Com N = 64 e OCR1A = 62499, a comparação é nominalmente a cada 250 ms. Duas comparações formam um ciclo de 500 ms do LED.
Complete os valores que liberam o Timer1 em CTC com comparação de 250 ms.
// Trechos finais da configuração em setup()
OCR1A = ;
TIFR1 = _BV(OCF1A); // descarta uma pendência anterior
TCCR1B = _BV(WGM12) | _BV() | _BV();Adapte o sketch de 500 ms da prática anterior: mantenha a estrutura, a consulta de OCF1A e o controle do LED integrado. Altere somente OCR1A e a seleção do prescaler no final de setup(). Grave este sketch no seu Uno R3 por USB e observe o LED integrado; não conecte componentes externos.
#include <avr/io.h>
void setup() {
DDRB |= _BV(DDB5); // LED integrado: PB5 / D13
PORTB &= ~_BV(PORTB5); // começa apagado
TCCR1A = 0; // saídas desconectadas; WGM11:0 = 0
TCCR1B = 0; // Timer1 parado
TIMSK1 = 0; // sem interrupções do Timer1
TCNT1 = 0;
OCR1A = 62499;
TIFR1 = _BV(OCF1A); // limpa pendência escrevendo 1
TCCR1B = _BV(WGM12) | _BV(CS11) | _BV(CS10);
}
void loop() {
if (TIFR1 & _BV(OCF1A)) {
TIFR1 = _BV(OCF1A); // reconhece e limpa a comparação
PINB = _BV(PINB5); // alterna o LED
}
// Outras tarefas curtas podem ser atendidas aqui.
}LED integrado alternando aproximadamente a cada 250 ms: - cerca de 250 ms aceso - cerca de 250 ms apagado - ciclo completo próximo de 500 ms
A observação visual não é uma medição de precisão. O instante exato de cada alternância também depende de quando o loop consulta a flag.
Qual situação invalida a prática tal como está escrita?
Após gravar, descreva o que observou e faça a previsão com base no código: qual deve ser o tempo aproximado de um ciclo completo do LED? Indique também uma condição do programa que evita perder comparações e uma situação em que este sketch não deve ser combinado com outro código.
Escreva pelo menos 80 caracteres (0/80).
Resumo
Parabéns! Você concluiu: Intervalos com o Timer1 em modo CTC
Milhares de cursos online em vídeo, ebooks e áudiobooks.
Para testar seus conhecimentos no decorrer dos cursos online
Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail
Baixe nosso aplicativo pelo QR Code ou pelos links abaixo:.
+ de 10 milhões
de alunos
Certificado grátis e
válido em todo o Brasil
60 mil exercícios
gratuitos
4,8/5 classificação
nas lojas de apps
Cursos gratuitos em
vídeo, ebooks e audiobooks