Vous êtes sur la page 1sur 47

Timers no Arduino

Arduino / Timers / Interrupes

Prof. Ilton L Barbacena


IFPB Joo Pessoa / PB

Arduno
ATmega168/328-Arduino Pin Mapping

Ateno:
Os
pinos
analgicos
podem tambm
serem usados
como
digitais
(E/S).

2/42

Arduno
Conectores do arduno

Duemilinove

Uno
3/42

Arduno

4/42

Timers no Arduino

Gerando
manualmente:
void setup() {

PWM

pinMode(13, OUTPUT);
}
void loop() { // Aproximadamente 10% duty cycle @ 1KHz
digitalWrite(13, HIGH);
delayMicroseconds(100);
digitalWrite(13, LOW);
delayMicroseconds(900);
}

Esta tcnica tem a vantagem de que se pode


usar qualquer pino de sada digital. Alm disso,
voc tem o controle completo do ciclo de
trabalho e da frequncia.

Uso de PWM:
Controlar a intensidade da luz de
um LED;
Fornecer uma sada analgica,
decorrente do uso de um filtro na
sada do PWM, que ir fornecer
uma tenso analgica de 0 a
100%;
Gerar de sinais de udio;
Controlar
a
velocidade
de
motores DC;
Gerar
sinal
modulado,
por
exemplo para controlar um LED
infravermelho de um controle
remoto.
5/42

Timers no Arduino

Desvantagens
manualmente:

do

uso

do

PWM

Quaisquer interrupes ir afetar o tempo ou o


duty cycle, o que pode causar uma instabilidade
considervel, a menos que se desabilite todas as
interrupes.
O processador fica presa na execuo desta
rotina bsica;
Fica difcil determinar as constantes apropriadas
para um ciclo de trabalho e/ou freqncia, a
menos que voc conte cuidadosamente os ciclos,
ou ajuste os valores, enquanto observa um

6/42

O que um Timer?

Um temporizador um bloco de hardware embutido no controlador do arruno e em outros


uC. como um relgio, e pode ser utilizado para medir eventos de tempos.
O temporizador programado por alguns registradores especiais. Voc pode configurar o
prescaler para o timer, o modo de operao, e muitas outras coisas.
O controlador do arduino UNO o AVR Atmel ATmega168 ou ATmega328. Estes uCs
so compatveis pino e apenas diferem no tamanho da memria interna. Ambos tm 3
temporizadores, chamado timer0, timer1 e timer2. O Timer0 e timer2 so temporizador
de 8 bits, e o timer1 um temporizador de 16 bits.
A diferena mais importante entre temporizador de 8 bits e 16 bits a resoluo do
temporizador: 8bits significa 256 valores e 16bit significa 65.536 valores para maior
resoluo.

IFPB Engenharia Eltrica - Prof. Dr. Ilton Luiz Barbacena - 2011

7 / 40

O que um Timer?

O controlador para a srie arduino Mega o AVR Atmel ATmega1280 ou o


ATmega2560. Tambm idnticos diferenciando-se apenas no tamanho da memria.
Estes controladores tm 6 temporizadores. Temporizador de 0, e timer1 timer2 so
idnticos aos do ATmega168/328. O timer3, timer4 e timer5 so todos os
temporizadores de 16 bits, semelhante ao timer1.
Todos os temporizadores depende do relgio do sistema.
Normalmente, o relgio do sistema 16MHz, mas para o Arduino Pro, 3,3 V, 8MHz.
Portanto, tenha cuidado ao escrever suas prprias funes utilizando o temporizador.
O hardware do temporizador pode ser configurado usando alguns registradores
especiais da CPU. No firmware do arduino todos os temporizadores foram configurados
para uma frequncia de 1kHz e interrupes so geralmente habilitadas.

IFPB Engenharia Eltrica - Prof. Dr. Ilton Luiz Barbacena - 2011

8 / 40

Timers no arduno

Timer0
Timer0 um temporizador de 8 bits. Na plataforma arduino o timer0 est sendo utilizado para as
funes de tempo, como delay(), Millis() e micros(). Se houver alterao nos registradores do uC do
arduno, relativo a timer0, isso pode influenciar nas funes de temporizador. Ento, voc deve saber o
que est fazendo.

Timer1
Timer1 um temporizador de 16 bits. No mundo Arduino, a biblioteca Servo usa timer1 do Arduino Uno
e timer5 no Arduino Mega.

Timer2
Timer2 um temporizador de 8 bits como timer0. A funo Tone() usa timer2.

Timer3, Timer4, Timer5:


Temporizador 3,4,5 esto disponveis apenas em placas Arduino Mega. Estes temporizadores so
todos os temporizadores de 16 bits.

IFPB Engenharia Eltrica - Prof. Dr. Ilton Luiz Barbacena - 2011

9 / 40

Timers no Arduino

Uso frequente de interrupes no estouro


de timers:

Medindo um sinal de entrada em


intervalos
igualmente
espaados
(frequncia de amostragem constante);
Calculando o tempo entre dois eventos;
O envio de um sinal de uma freqncia
especfica;
Periodicamente, fazer a verificao de
entrada de dados seriais; etc

10/42

Timers no Arduino

Prescaler
O Uno tem trs temporizadores chamados timer0, timer1 e Timer2. Apenas o timer1
de 16bits.
Cada um dos temporizadores tem um contador que incrementado a cada instante
do relgio do timer;
A contagem interrompe quando o contador chegar a um valor especificado para a
comparao;
Uma vez que um contador atingiu este valor mximo, o contador zerado;
Ao escolher o valor mximo para a comparao pode-se controlar a freqncia de
interrupes do timer.
O primeiro parmetro a ser discutido a velocidade com que o temporizador
incrementa o contador. O relgio Arduino executado em 16MHz, esta a maior
velocidade que os temporizadores podem incrementar seus contadores.
Em 16MHz cada tique-taque do contador representa 1/16, 000.000 de um segundo
=~ 63ns:
Para uma contagem de 0 a 9
=> T = 10/16000000s
(timer speed (Hz)) = (Arduino clock speed (16MHz)) / prescaler
Para uma contagem de 0 a 99 => T = 100/16000000s;
Valor_registrador = (16 MHz) / (prescaler * tempo) ) 1
Para uma contagem de 0 a 255
=> T = 256/16000000s =~ 16uS / mximo
para timer0 e timer2;
Exemplo: tempo=1s / prescaler = 1024 => valor_registrador = 15624 => (apenas o timer1)
Para uma contagem de 0 a 65535 => T = 65536/16000000 = ~ 4 ms / mximo
para timer1 (16bits);

11/42

Timers no Arduino

Counter
Diagram

Unit

Block

count Increment or decrement TCNTn by 1.


direction
Selects
between
increment
and
decrement.
clear Clear TCNTn (set all bits to zero).
clkTn Timer/Counter clock, referred to as clkTn in the
following.
top Signalizes that TCNTn has reached maximum

O bit flag TOVn


setado de acordo
com o modo de
operao
em
WGMn2:0, podendo
ser
usado
para
gerar
uma
interrupo.
Modos de Operao:
Waveform
Generation
Mode
bits
(WGM):
Controla os vrios
modos
de
funcionamento dos
timers.
12/42

Timers no Arduino

Waveform Generation Mode bits (WGM) Timer0


(8 bits)
Modos:
Normal
PWM fase
Correta
PWM Fast
CTC
Desligado

13/42

Timers no Arduino

Waveform Generation Mode bits (WGM) Timer1


(16 bits)
Modos:

Normal
PWM fase Correta
PWM fase Correta 8bits
PWM fase Correta 9bits
PWM fase Correta
10bits
PWM fase e frequncia
Correta
PWM Fast
PWM Fast, 8 bits
PWM Fast, 9 bits
PWM Fast, 10 bits
CTC
14/42
Desligado

Timers no Arduino

Waveform Generation Mode bits (WGM) Timer2


(8 bits)
Modos:
Normal
PWM fase
Correta
PWM Fast
Desligado

15/42

Timers no Arduino

Timer/Counter
Timer1

Prescaler

16/42

Timers no Arduino

Timer/Counter
Timer2

Prescaler

17/42

8-bit Timer/Counter2 with PWM and Asynchronous


Operation

Timers no Arduino

O ATMEGA328 tem
3 timers e 6 sadas
PWM;
O Arduino usa o
Timer0,
8bits,
internamente para
as funes millis()
e delay();
Portanto, mudando
os
registradores
deste timer, pode
afetar o uso destas
funes;
A biblioteca de PWM
18/42
usa estas funes

Timers no Arduino

Cada temporizador tem 2 registradores para comparar


os valores de contagem com o valor limite ou
programado, e controlar a largura PWM;
Quando o registrador de contagem chega no valor
programado, a CPU avisada atravs de um bit flag,
que pode causar uma interrupo, se previamente
programada.
O Temporizador/Contador pode ser sincronizado
internamente, atravs do prescaler (AS2=0, default),
ou de forma assncrona com clock nos pinos TOSC
(TOSC1 e TOSC2 / AS2=1, neste caso).
A operao assncrona (externa/Tn) controlada pelo
Estado Assynchronous Register (RAEE).

19/42

Timers no Arduino

Cada um dos temporizadores tem um contador que


incrementado ou decrementado a cada pulso de
clock;
A interrupo do timer ocorre quando o contador
chegar a um valor especificado previamente no
registrador de comparao do timer (OCR2A
Output Compare Register A ou OCR2B Output
Compare Register B);
Neste momento o valor do contador zerado e inicia
novamente a nova contagem;
Ao escolher o valor para a comparao, o valor da
frequncia de clock, que sincroniza o incremento no
contador, pode-se controlar a frequncia de

20/42

Timers no Arduino

Cada um dos temporizadores tem um contador que


incrementado ou decrementado a cada pulso de
clock;
A interrupo do timer ocorre quando o contador
chegar a um valor especificado previamente no
registrador de comparao do timer (OCR2A
Output Compare Register A ou OCR2B Output
Compare Register B);
Neste momento o valor do contador zerado e inicia
novamente uma nova contagem;
Ao escolher o valor para a comparao e o valor da
frequncia de clock, que sincroniza o incremento no
contador, pode-se controlar a frequncia de

21/42

Timers no Arduino

Timer1 - Output Unit


(16 bits)

O contador de 16-bit formado por dois de 8-bit


TCNT1H e TCNT1L. O Registro TCNT1H s pode
ser acessada indiretamente pela CPU;
Quando a CPU faz um acesso ao local TCNT1H I,
usa o registro temporrio (TEMP).
O registo temporrio atualizado com o valor
TCNT1H quando o TCNT1L lido, e TCNT1H com o
valor do registrador temporrio, quando TCNT1L
est escrito. Isso permite que a CPU a ler ou
escrever todo o valor de 16 bits dentro um ciclo
de clock atravs do barramento de dados de 8
bits.
Dependendo do modo de operao utilizado, o
contador limpo, incrementado ou decrementado
em cada relgio temporizador (clkT1).
O clkT1 pode ser gerada a partir de uma fonte de
relgio externo ou interno, selecionado pelos bits
Relgio Select (CS12: 0). Quando no h fonte de
clock selecionado (CS12: 0 = 0) o cronmetro
parado.
22/42
No entanto, o valor TCNT1 pode ser acessada

Timers no Arduino

Timer2 - Output Compare Unit


(8 bits)
O comparador de 8 bits compara
continuamente TCNT2 com a sada do
Registrador (OCR2A ou OCR2B).
Sempre que TCNT2 for igual a OCR2A ou
OCR2B, o comparador seta o flag
correspondente (OCF2A ou OCF2B) para
avisar o timer e iniciar outra contagem;
Se a interrupo correspondente estiver
ativada, acionada a rotina de
atendimento a interrupo, onde o flag
automaticamente limpo;
Como alternativa, o flag pode ser limpo
por software, escrevendo 1 diretamente
no registrador correspondente;
O gerador de forma de onda utiliza o flag
para gerar uma sada OC2A ou OC2B, de
acordo com o modo de funcionamento
definido por WGM22:0 e COM2x1:0. 23/42

Timers no Arduino

Timer2 Modos de Operao


Normal Mode (WGM2x:0 = 0)
Neste modo, o sentido da contagem sempre incrementado, e tambm
no zera o contador ao atingir o valor mximo;
O contador reinicia ao atingir 0xFF (neste caso, TOP = 0xFF) indo para em
0x00;
Em operao normal, o flag de estouro do Timer / Contador (TOV2), ser
setado no mesmo ciclo de relgio do estouro e TCNT2 torna-se zero. O flag
TOV2, neste caso, se comporta como um nono bit;
Na rotina de atendimento a interrupo, automaticamente o flag TOV2
zerado;
A resoluo do temporizador pode ainda ser aumentada por software;
No h casos especiais a considerar no modo normal, e um novo valor do
contador pode ser escrita a qualquer hora;
A unidade de Comparao de sada pode ser usado para gerar
interrupes, em algum momento. Usar a sada para gerar formas de onda
no modo normal, no recomendado, uma vez que este vai ocupar muito

24/42

Timers no Arduino

Timer2 Modos de Operao


Fast PWM Mode (WGM22:0 = 3 ou
Usado para
7) gerar frequencias maiores para o PWM;

No modo de PWM rpido, o contador incrementado at que o valor do contador


atingir ao valor TOP, a o contador ento limpo no ciclo seguinte do relgio
temporizador.
O valor TCNT2 e o diagrama de temporizao esto ilustrads na figura a seguir;
O diagrama inclui sadas no invertida e invertida PWM;
As pequenas marcas vistas na linha horizontal na TCNT2 representam a comparao
entre OCR2x e TCNT2;
No modo de PWM rpido, a unidade de comparao permite a gerao de formas de
onda PWM no pino OC2x;
Definindo os bits COM2x1:0 para 2 ser produzido um PWM no invertida e uma sada
PWM invertido;
Definindo a COM2x1:0 para 3, TOP definido como 0xFF quando WGM2:0 = 3, e
quando MGM2:0 = 7 em OCR2A ;
O valor OC2x real s ser visvel no pino da porta se a direo de dados para o pino
da porta for definido como sada.
N = prescale = (1, 8, 32, 64, 128, 256, ou
25/42
A forma de onda PWM gerada
ajustando-se
o
Registrador
OC2x
equando
entre
1024)

Timers no Arduino

Timer2 Modos de Operao


Fast PWM Mode (WGM22:0 = 3 ou
7)

Os valores extremos para o Registrador OCR2A representam casos


especiais ao gerar um PWM de sada neste modo. Se o OCR2A =
BOTTOM, a sada ser um pico estreito para cada ciclo de clock
(MAX+1). Se OCR2A=MAX+1, resultar numa sada constante, alto ou
baixo, dependendo da polaridade da sada definido nos bits COM2A1: 0.

O flag de estouro do timer, TOV2, setado a cada


estouro de contagem (TOP). Se a estiver ativada, a
rotina de tratamento de interrupo pode ser
utilizada para atualizar o valor de comparao,
permitindo gerar o PWM no pino OC2x;
Definindo os bits COM2x1:0 = 2 ir produzir um PWM
no invertido, e uma sada PWM invertido pode ser
gerado, definindo a COM2x1:0 = 3;
O TOP definido como 0xFF, quando WGM2:0 = 3, e
quando em OCR2A, MGM2: 0 = 7;
O valor OC2x somente estar visvel no pino da
porta se a direo de dados para o pino da porta
estiver definida como sada.
A forma de onda PWM gerada no registrador OC2x
(1 ou 0), durante a comparao entre OCR2x e
TCNT2, e na transio lgica de durante os pulsos de
alto
para
baixo;;
A frequncia de PWM da sada pode ser calculada
pela seguinte equao:
N = prescale = (1, 8, 32, 64, 128,
256, ou 1024)

26/42

Timers no Arduino

Timer2 Modos de Operao


Clear Timer on Compare Match (CTC) Mode
(WGM22:0 = 2)
Neste modo, o registrador OCR2A usado para configurar a resoluo do
timer;
No modo CTC o contador zerado quando o timer atingir o valor do
contador (TCNT2) for igual ao valor no registrador OCR2A;
O OCR2A define o topo da contagem, portanto, a resoluo do timer;
Este modo permite maior controle na comparao e no frequncia do sinal
de sada;
1. Para gerar uma de forma de onda na sada no CTC
Este modo simplifica a operao commodo,
eventoa externo;
sada OC2A pode ser definido para
alternar o nvel lgico em cada partida
comparao definindo a comparar bits de modo
de sada para alternar o modo de (COM2A1: 0 =
1).
2. A frequncia da forma de onda definido pela
seguinte equao:
N = prescale ={1, 8, 32, 64, 128, 256,

27/42

Timers no Arduino

Timer2 Modos de Operao


Phase-Correct PWM (WGM22:0 = 1 ou 5)
Neste modo, o timer conta de 0 a 255 e, em seguida, de volta para 0.
Este modo baseia-se numa operao de dupla inclinao;
O TOP definido como 0xFF quando WGM2:0 = 3, e quando em OCR2A, MGM2:0 =
7;
A sada da comparao (OC2x) zerada enquanto o timer estiver com valores
acima do TOP de comparao e setado para valores abaixo, execeto na primeiro
ciclo, que inicia setada;
A operao de inclinao dupla tem menor freqncia de operao mxima de
operao que a de inclinao nica. No entanto, devido caracterstica simtrica
dos modos de dupla inclinao PWM, estes modos so preferidos para aplicaes
de controle do motores;
Neste modo o timer incrementado at o TOP e, ento, muda a direo de
contagem. O valor de TCNT2 ser igual ao TOP uma vez no ciclo do timer;
O flag TOV2 setado toda vez que o timer igualar ao valor BOTTOM (mais baixo);
Neste modo gerado um sinal PWM no pino OC2x, fazendo-se COM2x1:0=2,
28/42
produz o PWM invertido;

Timers no Arduino

Timer2 Modos de Operao


Phase-Correct PWM (WGM22:0 = 1 ou 5)
O valor OC2x somente ficar visvel no pino
da porta se a direo de dados para o pino
da porta for definida como sada;
A frequncia de PWM na sada pode ser
calculada pela seguinte equao:

N = prescale ={1, 8, 32, 64, 128, 256,


ou 1024}

29/42

Timers no Arduino

Registradores para TIMER2:


TCCR2A
Timer/Counter
Control Register A
TCCR2B
Timer/Counter
Control Register B
TCNT2
Timer/Counter
Register
OCR2A Output
Compare Register
A
OCR2B Output
Compare Register
B
30/42

Timers no Arduino

Registradores para TIMER2:

TIMSK2
Timer/Counter2
Interrupt Mask
Register
TIFR2
Timer/Counter2
Interrupt Flag
Register
ASSR
Asynchronous
Status Register
GTCCR General
Timer/Counter Control
Register
31/42

Timers no Arduino

Detalhes dos registradores para TIMER2:


TCCR2A

32/42

Timers no Arduino

Detalhes dos registradores para


TIMER2:

TCCR2A Timer/Counter Control Register A


TCCR2B Timer/Counter Control Register B
Bit 7 de TCCR2B FOC2A: Force Output Compare A
Ativo somente quando WGM configurar modo de no PWM / no gera interrupo / Sempre lido como 0;
Bit 6 de TCCR2B FOC2B: Force Output Compare A
Ativo somente quando WGM configurar modo de no PWM / no gera interrupo / Sempre lido como 0;
TCNT2 Timer/Counter Register
Contador do timer2 de 8 bits / Usado para comparar valores com o registrador OCR2x;
OCR2A Output Compare Register A
Registrador 8 bits com valor para comparar com TCNT2. O resultado pode gerar interrupo e gerar sinal no
pino OC2A;
OCR2B Output Compare Register B
Registrador 8 bits com valor para comparar com TCNT2. O resultado pode gerar interrupo e gerar sinal no
pino OC2B;
TIMSK2 Timer/Counter2 Interrupt Mask Register

Bit 2 OCIE2B: Timer/Counter2 Output Compare Match B Interrupt Enable

Se 1, habilita interrupo quando TCNT2 = OCR2B levando o flag OCF2B= 1, em TIFR2, e desviando o programa p/
atender a interrupo;
Bit 1 OCIE2A: Timer/Counter2 Output Compare Match A Interrupt Enable

Se 1, habilita interrupo quando TCNT2 = OCR2A levando o flag OCF2A= 1, em TIFR2, e desviando o programa p/
atender a interrupo;
Bit 0 TOIE2: Timer/Counter2 Overflow Interrupt Enable

Se 1, habilita interrupo quando ocorrer overflow no timer2 levando o flag TOV2=1, em TIFR2, e desviando o programa
p/ atender a interrupo;

TIFR2 Timer/Counter2 Interrupt Flag Register

Bit 2 OCF2B: Output Compare Flag 2 B

Se 1, indica houve uma interrupo decorrente de quando TCNT2 = OCR2B;

33/42

Timers no Arduino

Detalhes dos registradores para


TIMER2:

ASSR Asynchronous Status Register

Bit 7
Bit 6

Bit 5

Bit 4

Bit 3

Bit 2

Bit 1

Bit 0

Reserved
EXCLK: Enable External Clock Input
Se 1, clock assncrono (externo) selecionado para um clock de 32 KHz no pino TOSC1;
AS2: Asynchronous Timer/Counter2
Se 0, indica clock interno clkI/O e se 1, clock externo em TOSC1 ;
TCN2UB: Timer/Counter2 Update Busy
Se 0, indica que TCNT2 est pronto para atualizao;
OCR2AUB: Output Compare Register2 Update Busy
Se 0, indica que OCR2A est pronto para atualizao;
OCR2BUB: Output Compare Register2 Update Busy
Se 0, indica que OCR2B est pronto para atualizao;
TCR2AUB: Timer/Counter Control Register2 Update Busy
Se 0, indica que TCCR2A est pronto para atualizao;
TCR2BUB: Timer/Counter Control Register2 Update Busy
Se 0, indica que TCCR2B est pronto para atualizao;

Os mecanismos para a leitura TCNT2, OCR2A, OCR2B, TCCR2A e TCCR2B so diferentes. Ao ler TCNT2, o
valor atual lido. Ao ler OCR2A, OCR2B, CCR2A e TCCR2B o valor no registrador lido.

GTCCR General Timer/Counter Control Register

Bit 1 PSRASY: Prescaler Reset Timer/Counter2

Se 1, o prescaler resetado. No pode ser zerado por hardware, se TSM=1.

34/42

Timers no Arduino

Exemplo de gerao de PWM nos pinos 3 e 11 /


Fast PWM

WGM = 011 => Fast PWM em timer 2


COM2A = COM2B = 10 => PWM no invertido em A e B
CS = 100 => prescaler de 64
Registradores de comparao na sada sero 180 e 50, para PWM em A e B

Cdigo correspondente:
Sada A:
Fpwm_A = 16MHz / 64 / 256 = 976,56
Hz
duty_A = (180+1)/256 = 70,7%
Sada B:
Fpwm_B = 16MHz / 64 / 256 = 976,56
Hz
duty_B = (50+1)/256 = 19,9%

pinMode(3, OUTPUT);
pinMode(11, OUTPUT);

// pwm em A, duty 70,7%


// pwm em B, duty 19,9%

TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);


TCCR2B = _BV(CS22);
OCR2A = 180;
OCR2B = 50;

35/42

Timers no Arduino

Pinos de hardware relacionados aos timers do


ATMega328
Timer 0
input T0 pin 6 (D4)
output OC0A pin 12 (D6)
output OC0B pin 11 (D5)
Timer 1
input T1 pin 11 (D5)
output OC1A pin 15 (D9)
output OC1B pin 16 (D10)
Timer 2
output OC2A pin 17 (D11)
output OC2B pin 5 (D3)

36/42

Timers no Arduino

Count = contagem
ATMEGA328

com

os

prescalers

no

Count = frequency_from_table / target_frequency


Exemplo piscar um led a 50Hz :
Prescaler=1024 => Count = 15625 / 50 = 312,5 => somente timer1
Prescaler=256 => Count = 62500 / 50 = 1250 => timer1

37/42

Timers no Arduino

Exemplo de gerao de PWM nos pinos 3 e 11 /


Phase-Correct PWM

WGM = 001 => Phase-Correct PWM em timer 2


COM2A = COM2B = 10 => PWM no invertido em A e B
CS = 100 => prescaler de 64
Registradores de comparao na sada sero 180 e 50, para PWM em A e B

Cdigo correspondente:
Sada A:
Fpwm_A = 16 MHz / 64 / 255 / 2 = 490,196
Hz
duty_A = 180 / 255 = 70,6%
Sada B:
Fpwm_B = 16 MHz / 64 / 255 / 2 = 490.196
Hz
duty_B = 50 / 255 = 19.6 %

pinMode(3, OUTPUT);
pinMode(11, OUTPUT);

// pwm em A, duty 70,7%


// pwm em B, duty 19,9%

TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);


TCCR2B = _BV(CS22);
OCR2A = 180;
OCR2B = 50;

38/42

Timers no Arduino

Exemplo de gerao de PWM nos pinos 3 e 11 /

Fast

PWM com TOP = OCRA

WGM = 111 => Fast PWM com TOP = OCRA em timer 2


COM2A = 01=> OCR2A configurado para inverter a sada / COM2B = 10
CS = 100 => prescaler de 64
Registradores de comparao na sada (OCR2A e OCR2B) sero 180 e 50,
para PWM em A e B
Cdigo correspondente:

Sada A:
Fpwm_A = 16 MHz / 64 / (180+1) / 2 =
690,6 Hz
duty_A = 50%
Sada B:
Fpwm_B = 16 MHz / 64 / (180+1) = 1381,2
Hz
duty_B = 50 / 255 = 19,6 %

pinMode(3, OUTPUT);
pinMode(11, OUTPUT);

// pwm em A, duty 50 %
// pwm em B, duty 19,6%

TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);


TCCR2B = _BV(WGM22) | _BV(CS22);
OCR2A = 180;
OCR2B = 50;

39/42

Timers no Arduino

Exemplo de gerao de PWM nos pinos 3 e 11 /

phase-

correct PWM com TOP = OCRA

WGM = 101 => phase-correct PWM com TOP = OCRA em timer 2


COM2A = 01=> OCR2A
CS = 100 => prescaler de 64
Registradores de comparao na sada (OCR2A e OCR2B) sero 180 e 50,
para PWM em A e B
Cdigo correspondente:

Sada A:
Fpwm_A = 16 MHz / 64 / 180 / 2 / 2 = 347,2
Hz
duty_A = 50%
Sada B:
Fpwm_B = 16 MHz / 64 / 180 / 2 = 694,4 Hz
duty_B = 50 / 180 = 27,8 %

pinMode(3, OUTPUT);
pinMode(11, OUTPUT);
TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM20);
TCCR2B = _BV(WGM22) | _BV(CS22);
OCR2A = 180;
OCR2B = 50;

40/42

Timers no Arduino

Exemplo: Contador de 1ms / Timer2 / contagem


simples
/*

/*
* author: Sebastian Wallin
http://popdevelop.com/2010/04/mastering-timer-interrupts-on-the-arduino/
*/
unsigned int tcnt2;
int x= 0;
void setup() {
pinMode(2, OUTPUT); // 2 como saida
TIMSK2 &= ~(1<<TOIE2); // desabilita interrupo do timer overflow
// timer2 em modo normal (pura contagem, sem PWM) - WGM = 000
TCCR2A &= ~((1<<WGM21) | (1<<WGM20)); // clear bits
TCCR2B &= ~(1<<WGM22);
// clear bits
/* clock interno */
ASSR &= ~(1<<AS2);
/* desabilita interrupo decorrente de comparao*/
TIMSK2 &= ~(1<<OCIE2A);
// configura o prescaler do clock da CPU = 128 => 101
TCCR2B |= (1<<CS22) | (1<<CS20); // Set bits
TCCR2B &= ~(1<<CS21);
// Clear bit

* (CPU frequency) / (prescaler value) = 16MHz/128=125000 Hz => 8us.


* 1ms => tempo de contagem
* 1ms / 8us = 125 => contagens a ser realizada
* TCNT2 = MAX(uint8) + 1 - 125 = 255+1-125=131;
*/
tcnt2 = 131;
TCNT2 = tcnt2;
// para o primeiro ciclo
TIMSK2 |= (1<<TOIE2); // habilita interrupo do timer overflow
}
ISR(TIMER2_OVF_vect) {
TCNT2 = tcnt2; // recarrega o valor de contagem
digitalWrite(2, x== 0 ? HIGH : LOW);
x= ~x;
}
void loop() {

// loop infinito

}
41/42

Timers no Arduino

Exemplo: Contador de 1s / Timer1 / CTC


/******************************************************
Programa: pisca led com timer1 / modo CTC / 1s
Auto: Ilton L Barbacena
Data: Jan / 2012
Plataforma: Arduino Uno / adapatado de AVR
Fonte:
https://sites.google.com/site/qeewiki/books/avr-guide/timers-on-the-atmega328

Serial.begin(9600);
while(!Serial) {};

Timer1 / Modo 4 / CTC => WGM = 0100 (wgm13=0, wgm12=1, wgm11=0, wgm10=0)
clock = 16MHz / prescaler=1024 => CS = 101 (cs12=1, cs11=0, cs10=1)
valor = (16MHz / (prescaler * tempo) )-1
valor = (16MHz / (1024*1)) - 1
valor = 15624 = 0x3D08
OCR1A = 0x3D08
*******************************************************/
int toggle0=0;
// usado para inverter led
ISR(TIMER1_COMPA_vect)
{
//timer1 interrupt

OCR1A = 15624;
TCCR1B |= (1 << WGM12); // Mode 4, CTC on OCR1A
TIMSK1 |= (1 << OCIE1A); //Set interrupt on compare match
TCCR1B |= (1 << CS12) | (1 << CS10); // prescaler = 1024

toggle0 = ~toggle0;
digitalWrite(13,toggle0);

cli(); //stop interrupts


TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
TCNT1 = 0; //initialize counter value to 0

sei(); //allow interrupts


Serial.println("Programa: Timer1 / 1s");
Serial.println(" IFPB: Campus J Pessoa ");
Serial.println(" Prof.: Ilton L Barbacena");
Serial.print(" OCR1A = ");
Serial.print(OCR1A, HEX);
Serial.print(" TIMKSI = ");
Serial.print(TCCR1B, HEX);
Serial.print(" TCCR1B = ");
Serial.println(TCCR1B, HEX);
Serial.println(" ");

// inverte bit na saida 13

void setup(){
pinMode(13, OUTPUT);
digitalWrite(13,toggle0); // inverte bit na saida 13

}
loop() { }

//end setup
42/42

Timers no Arduino

Exemplo: Resultado do contador de 1s / Timer1 / CTC =>


AVR

43/42

Timers no Arduino

Exemplo: Gerao 3 formas de onda com timer0, timer1 e timer2


/******************************************************
Programa: pisca led com timer1 / modo CTC / 1s
Auto: Ilton L Barbacena
Data: Nov / 2012
Plataforma: Arduino Uno / adapatdo de AVR
Fonte:
https://sites.google.com/site/qeewiki/books/avr-guide/timers-on-the-atmega328
http://www.instructables.com/id/Arduino-Timer-Interrupts/?ALLSTEPS

//timer0 will interrupt at 2kHz


//timer1 will interrupt at 1Hz
//timer2 will interrupt at 8kHz
****************************************************/
boolean toggle0 = 0;
boolean toggle1 = 0;
boolean toggle2 = 0;
void setup()
{
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(13, OUTPUT);

//set timer0 interrupt at 2kHz


TCCR0A = 0; // set entire TCCR2A register to 0
TCCR0B = 0; // same for TCCR2B
TCNT0 = 0; //initialize counter value to 0
OCR0A = 124;// = (16*10^6)/(2000*64)-1 // set 2khz increments
TCCR0A |= (1 << WGM01);
// turn on CTC mode
TCCR0B |= (1 << CS11) | (1 << CS10); // 64 prescaler
TIMSK0 |= (1 << OCIE0A); // enable timer compare interrupt
//set timer1 interrupt at 1Hz
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;//initialize counter value to 0
OCR1A = 15624;// = (16*10^6)/(1*1024)-1 // set 1hz increments
TCCR1A |= (1 << WGM12);
// turn on CTC mode
TCCR1B |= (1 << CS12) | (1 << CS10); // 1024 prescaler
TIMSK1 |= (1 << OCIE1A);
// enable timer compare interrupt
//set timer2 interrupt at 8kHz
TCCR2A = 0;// set entire TCCR2A register to 0
TCCR2B = 0;// same for TCCR2B
TCNT2 = 0;//initialize counter value to 0
OCR2A = 249;// = (16*10^6)/(8000*8)-1 // 8khz increments
TCCR2A |= (1 << WGM21);
// turn on CTC mode
TCCR2B |= (1 << CS11);
// Set CS11 bit for 8 prescaler
TIMSK2 |= (1 << OCIE2A);
// enable timer compare interrupt

cli(); //stop interrupts

ISR(TIMER0_COMPA_vect)
{
//timer0 2kHz
// 2kHz/2 = 1kHz
toggle0 = ~toggle0;
digitalWrite(8,toggle0); // inverte bit na saida 8
}
ISR(TIMER1_COMPA_vect)
{
//timer1 1Hz
// 1Hz/2 = 0,5Hz
toggle1 = ~toggle1;
digitalWrite(13,toggle1); // inverte bit na saida 8
}
ISR(TIMER2_COMPA_vect)
{
//timer1 8kHz
// 8kHz/2 = 4kHz
toggle2 = ~toggle2;
digitalWrite(9,toggle2); // inverte bit na saida 8
}
void loop(){ }

sei(); //allow interrupts


}

//end setup
44/42

Timers no Arduino

Exemplo: Gerao 3 formas de onda com timer0, timer1 e timer2

45/42

Timers no Arduino

Fontes de Consultas:
1.

http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM

2.

http://www.instructables.com/id/Arduino-Timer-Interrupts/?ALLSTEPS

3.

http://www.gammon.com.au/forum/?id=11504

4.

https://sites.google.com/site/qeewiki/books/avr-guide/timers-on-the-atmega328

5.

http://www.cs.washington.edu/education/courses/csep567/10wi/lectures/lectures.html

6.

http://popdevelop.com/2010/04/mastering-timer-interrupts-on-the-arduino/

7.

http://stackoverflow.com/questions/12904637/arduino-duemilanove-pwm-and-timer

8.

http://electronics.stackexchange.com/questions/40279/multiplexing-two-7-segment-displays-ghosting-issues

9.

http://timer-scheduler.googlecode.com/svn-history/r30/trunk/examples/timerInterrupt_Match/timerInterrupt_Match.pde

10. http://forum.processing.org/topic/converting-from-arduino-to-processing
11. http://www.jeremyblum.com/2010/09/05/driving-5-speakers-simultaneously-with-an-arduino/
12. http://books.google.com.br/books?id=R7DKeahnY4C&pg=PA343&lpg=PA343&dq=arduino+WGM22+OCIE2A&source=bl&ots=M3-cCaQVFZ&sig=pa2I12ZWT3WGnymR
f2KYLXiGUKE&hl=pt-BR&sa=X&ei=cwfoUKH9Coq09QSb0oHYDA&ved=0CFMQ6AEwAzgU
13. http://www.4shared.com/office/jE7Zvx9E/arduino_internals.html
14. http://bennthomsen.wordpress.com/embedded-design/peripherals/timers/
15. http://www.gammon.com.au/forum/?id=11504

46/42

Timers no Arduino
Arduino / Timers / Interrupes

Prof. Ilton L Barbacena


IFPB Joo Pessoa / PB

Vous aimerez peut-être aussi