Você está na página 1de 13

Sistemas Embarcados

TEMPORIZADORES

Luis Claudio
O que são temporizadores?
● Um timer nada mais é do que um contador que é incrementado a cada intervalo de
tempo (podendo ser configurado).
● Funcionam como um relógio que pode ser usado para contar o tempo, medir a
duração de certos eventos, entre outras aplicações, tais como:
– Temporização
– Contagem de eventos externos
– Geração de sinais PWM
– Interrupções periódicas
– Medida de intervalos de pulsos

● O Arduino UNO vem equipado com um microcontrolador Atmega328. Esse


microcontroladore possi os timers: timer0, timer1 e timer2.
● Timer0 e timer2 são contadores de 8bits, ou seja, contam de 0 a 255, e o timer1 é um
contador de 16bits, conta de 0 a 65535.
Interrupções do Atmega328
● Timer0
– O timer0 é utilizado pelo Arduino para funções como delay(), millis() e
micros(). Então não se deve utilizar esse timer para evitar comprometer essa
funções.

● Timer1
– No Arduino UNO esse é o timer utilizado pela biblioteca de controle de servos.
Caso você não esteja utilizando a biblioteca de controle de servos, esse timer
está livre para ser utilizado para outros propósitos.

● Timer2
– Esse timer é utilizado pela função tone(). Então se você não precisar da função
tone() esse timer está livre para outras aplicações.
Usando os timers
● Os timers podem ser configurados para gerar uma interrupção quando
o seu contador chegar ao valor máximo (timer overflow).
– Interrupções
● No Arduino (e nos microcontroladores de forma geral) o programa é executado
sequencialmente, linha após linha, instrução após instrução. Uma interrupção é um
evento externo que interrompe a execução do programa e chama uma função para
tratar a interrupção, após o fim dessa função a execução normal do programa é
retomada de onde parou.
– Ao atingirem o valor máximo da contagem (overflow), os timers geram uma
interrupção e chamam uma função específica.
– Como a frequência de trabalho pode ser muito alta é comum os MCUs
implementarem circuitos divisores de frequência, denominado “prescalers”.
Prescaler

Circuito TTL 7490 Prescaler


Mais informações:
https://www.youtube.com/watch?v=b-7rUfDG_D8
Prescaler
Utilizando o TIMER1 no Arduino
● Neste exemplo, é mostrado como piscar o LED no pino 13, da placa Arduino
UNO, em intervalos de 1 segundo e utilizando interrupção por estouro timer:
Utilizando o TIMER1 no Arduino de
forma “manual” (registradores)
#define ledPin 13

void setup()
{
pinMode(ledPin, OUTPUT);

// Configuração do timer1
TCCR1A = 0; //confira timer para operação normal pinos OC1A e OC1B desconectados
TCCR1B = 0; //limpa registrador
TCCR1B |= (1<<CS10)|(1 << CS12); // configura prescaler para 1024: CS12 = 1 e CS10 = 1

TCNT1 = 0xC2F7; // incia timer com valor para que estouro ocorra em 1 segundo
// 65536-(16MHz/1024/1Hz) = 49911 = 0xC2F7

TIMSK1 |= (1 << TOIE1); // habilita a interrupção do TIMER1


}

void loop()
{
//loop principal. a manipulação do led é feita na ISR
}

ISR(TIMER1_OVF_vect) //interrupção do TIMER1


{
TCNT1 = 0xC2F7; // Renicia TIMER
digitalWrite(ledPin, digitalRead(ledPin) ^ 1); //inverte estado do led
}
Utilizando o TIMER1 no Arduino de
forma “manual” (registradores)
● O controle do modo de operação do TIMER1 é feito nos registradores TCCR1A e TCCR1B e
TIMSK.

● Nesse exemplo o timer foi configurado para modo normal, com pinos OC1A e OC1B
desconectados (TCCR1A = 0).

● Foi selecionado o prescaler para 1024 através do registrador TCCR1B.

● Para que o timer estoure a cada segundo é necessário iniciar seu valor com a diferença entre o seu
valor máximo (65536) e o período desejado.

● O período é calculado levando em consideração a frequência do oscilador e o prescaler selecionado,


além da frequência de interrupção desejada.

● Por fim foi habilitada a interrupção de estouro do TIMER1 através do bit T0IE1 do registrador
TIMSK1. A inversão do LED é feita na rotina de interrupção, note que é necessário recarregar o
timer para a correta contagem.

Prescaler é um dispositivo eletrônico que reduz uma frequência por um fator pre-determinado.
Por exemplo, converte um sinal de 1 MHz em um sinal de 100kHz (gradua a frequência por
um fator de 10). Em microcontroladores é a parte que divide a frequência de oscilação do
clock.
Registradores de configuração
● Timers no Arduino Mega
– O Arduino Mega vem equipado com o ATmega2560. Ele possui 6 timers: timer0,
timer1, timer2, timer3, timer4, timer5. Os timers 0, 1 e 2 são idênticos aos do
ATmega328, e os timers 3, 4 e 5 são ambos de 16bits.
– Timer3 e Timer4:
● Esses timers só estão presentes no Arduino Mega e eles só serão utilizados pela
biblioteca do Arduino caso vocês esteja utilizando mais de 24 servos. De 25 a
36 servos o timer3 será utilizado e de 37 a 48 servos o timer4 será utilizado.
– Timer5:
● No Arduino Mega esse é o timer padrão para o controle de servos, ou seja, se
você estiver utilizando de 1 a 12 servos, apenas esse timer será utilizado pela
biblioteca.

Referências:
https://www.embarcados.com.br/timers-do-atmega328-no-arduino/
http://maxembedded.com/2011/07/avr-timers-ctc-mode/
Utilizando o TIMER1 no Arduino
usando a “biblioteca” TimerOne
● Baixa a biblioteca no link http://arduino.cc/playground/Code/Timer1
● Instale a biblioteca na IDE do Arduino
● Use as funções:
– initialize(periodo)
● Esse método deve ser chamado antes de qualquer outro método, pois ele é responsável pelas
configurações iniciais. Você pode opcionalmente informar o intervalo (em microsegundos) no
qual a interrupção deve ser gerada. O menor tempo aceito é 1 micro-segundo e o tempo
máximo é de 8.388.480 micro-segundos, ou seja, aproximadamente 8,3 segundos. Caos não
seja informado nenhum valor, será atribuído o valor padrão de 1.000.000 micro-segundos (1
segudo). Quando usado o timer1 o analogWrite() nos pinos 9 e 10 do Arduino param de
funcionar.

– setPeriod(periodo)
● Modifica o período da interrupção.

– attachInterrupt(funcao)
● Atribui uma função para ser chamada a cada interrupção gerada pelo timer.
Utilizando o TIMER1 no Arduino
usando a “biblioteca” TimerOne
● Para testar essa biblioteca não é necessário nenhum hardware
adicional, basta usarmos o LED conectado ao pino 13 da placa do
Arduino e escrever um novo blink.

#include "TimerOne.h"

void setup()
{
pinMode(13, OUTPUT);
Timer1.initialize(500000); // Inicializa o Timer1 e config para um período de 0.5s
Timer1.attachInterrupt(callback); // Configura a função callback() como a função para
// ser chamada a cada interrupção do Timer1
}

void callback()
{
digitalWrite(13, digitalRead(13) ^ 1); // Operação XOR bit a bit
}

void loop()
{
// Seu código vai aqui...
}
Concorrência usando Timer
#define ledPin 13
int contador = 0;

void setup() {
pinMode(ledPin, OUTPUT);
TCCR1A = 0;
TCCR1B = 0;
TCCR1B |= (1<<CS10)|(1 << CS12);
TCNT1 = 0xC2F7;
TIMSK1 |= (1 << TOIE1);
Serial.begin(9600);
}

void loop() {
Serial.print("Contador: ");
Esta tarefa será executada em concorrência com a
Serial.println(contador); interrupção do timer. A cada estouro do contador, a
contador++; cpu executa o tratador da interrupção e retorna do
if (contador==256) contador = 0; último ponto de parada na função loop.
}

ISR(TIMER1_OVF_vect) {
TCNT1 = 0xC2F7;
digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
}

Você também pode gostar