47
Timers no Arduino Arduino / Timers / Interrupções Prof. Ilton L Barbacena IFPB – João Pessoa / PB

Timers Interrupcoes Arduino

Embed Size (px)

Citation preview

Page 1: Timers Interrupcoes Arduino

Timers no Arduino

Arduino / Timers / Interrupções

Prof. Ilton L BarbacenaIFPB – João Pessoa / PB

Page 2: Timers Interrupcoes Arduino

Arduíno• ATmega168/328-Arduino Pin Mapping

2/42

Atenção:

Os pinos analógicos podem também serem usados como digitais (E/S).

Page 3: Timers Interrupcoes Arduino

Arduíno• Conectores do arduíno

3/42Uno

Duemilinove

Page 4: Timers Interrupcoes Arduino

Arduíno

4/42

Page 5: Timers Interrupcoes Arduino

Timers no Arduino

5/42

• Gerando PWM manualmente:

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

}

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

}

Uso de PWM:

• Controlar a intensidade da luz de um LED;

• Fornecer uma saída analógica, decorrente do uso de um filtro na saída do PWM, que irá fornecer uma tensão analógica 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.Esta técnica tem a vantagem de que se pode usar qualquer

pino de saída digital. Além disso, você tem o controle completo do ciclo de trabalho e da frequência.

Page 6: Timers Interrupcoes Arduino

Timers no Arduino

6/42

• Desvantagens do uso do PWM manualmente:

• Quaisquer interrupções irá afetar o tempo ou o duty cycle, o que pode causar uma instabilidade considerável, a menos que se desabilite todas as interrupções.

• O processador fica presa na execução desta rotina básica;• Fica difícil determinar as constantes apropriadas para um

ciclo de trabalho e/ou freqüência, a menos que você conte cuidadosamente os ciclos, ou ajuste os valores, enquanto observa um osciloscópio.

Page 7: Timers Interrupcoes Arduino

O que é um Timer?

IFPB – Engenharia Elétrica - Prof. Dr. Ilton Luiz Barbacena - 2011 7 / 40

• Um temporizador é um bloco de hardware embutido no controlador do arruíno e em outros uC. É como um relógio, 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 operação, e muitas outras coisas.

• O controlador do arduino UNO é o AVR Atmel ATmega168 ou ATmega328. Estes uCs são compatíveis pino e apenas diferem no tamanho da memória interna. Ambos têm 3 temporizadores, chamado timer0, timer1 e timer2. O Timer0 e timer2 são temporizador de 8 bits, e o timer1 é um temporizador de 16 bits.

• A diferença mais importante entre temporizador de 8 bits e 16 bits é a resolução do temporizador: 8bits significa 256 valores e 16bit significa 65.536 valores para maior resolução.

Page 8: Timers Interrupcoes Arduino

O que é um Timer?

IFPB – Engenharia Elétrica - Prof. Dr. Ilton Luiz Barbacena - 2011 8 / 40

• O controlador para a série arduino Mega é o AVR Atmel ATmega1280 ou o ATmega2560. Também idênticos diferenciando-se apenas no tamanho da memória. Estes controladores têm 6 temporizadores. Temporizador de 0, e timer1 timer2 são idênticos aos do ATmega168/328. O timer3, timer4 e timer5 são todos os temporizadores de 16 bits, semelhante ao timer1.

• Todos os temporizadores depende do relógio do sistema. • Normalmente, o relógio do sistema é 16MHz, mas para o Arduino Pro, 3,3 V, é 8MHz.

Portanto, tenha cuidado ao escrever suas próprias funções 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 frequência de 1kHz e interrupções são geralmente habilitadas.

Page 9: Timers Interrupcoes Arduino

Timers no arduíno

IFPB – Engenharia Elétrica - Prof. Dr. Ilton Luiz Barbacena - 2011 9 / 40

• Timer0• Timer0 é um temporizador de 8 bits. Na plataforma arduino o timer0 está sendo utilizado para as

funções de tempo, como delay(), Millis() e micros(). Se houver alteração nos registradores do uC do arduíno, relativo a timer0, isso pode influenciar nas funções de temporizador. Então, 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 função Tone() usa timer2.

• Timer3, Timer4, Timer5:• Temporizador 3,4,5 estão disponíveis apenas em placas Arduino Mega. Estes temporizadores são

todos os temporizadores de 16 bits.

Page 10: Timers Interrupcoes Arduino

Timers no Arduino

10/42

• Uso frequente de interrupções no estouro de timers:

• Medindo um sinal de entrada em intervalos igualmente espaçados (frequência de amostragem constante);

• Calculando o tempo entre dois eventos;• O envio de um sinal de uma freqüência específica;• Periodicamente, fazer a verificação de entrada de

dados seriais; etc

Page 11: Timers Interrupcoes Arduino

Timers no Arduino

11/42

• Prescaler• O Uno tem três temporizadores chamados timer0, timer1 e Timer2. Apenas o timer1 é de 16bits.• Cada um dos temporizadores tem um contador que é incrementado a cada instante do relógio do timer;• A contagem interrompe quando o contador chegar a um valor especificado para a comparação;• Uma vez que um contador atingiu este valor máximo, o contador é zerado;• Ao escolher o valor máximo para a comparação pode-se controlar a freqüência de interrupções do timer.• O primeiro parâmetro a ser discutido é a velocidade com que o temporizador incrementa o contador. O

relógio 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• Para uma contagem de 0 a 99 => T = 100/16000000s;• Para uma contagem de 0 a 255 => T = 256/16000000s =~ 16uS / máximo para timer0 e timer2;• Para uma contagem de 0 a 65535 => T = 65536/16000000 = ~ 4 ms / máximo para timer1 (16bits);

• Prescaler => Aumenta o tempo de contagem. Todos os timers pode selecionar prescaler de 1, 8, 64, 256 e 1024;

(timer speed (Hz)) = (Arduino clock speed (16MHz)) / prescalerValor_registrador = (16 MHz) / (prescaler * tempo) ) – 1

Exemplo: tempo=1s / prescaler = 1024 => valor_registrador = 15624 => (apenas o timer1)

Page 12: Timers Interrupcoes Arduino

Timers no Arduino

12/42

• Counter Unit Block Diagram

• 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 value.• bottom Signalizes that TCNTn has reached minimum value (zero).

O bit flag TOVn é setado de acordo com o modo de operação em WGMn2:0, podendo ser usado para gerar uma interrupção.

Modos de Operação:

Waveform Generation Mode bits (WGM): Controla os vários modos de funcionamento dos timers.

Page 13: Timers Interrupcoes Arduino

Timers no Arduino

13/42

• Waveform Generation Mode bits (WGM) – Timer0 (8 bits)

Modos:

• Normal• PWM – fase Correta• PWM – Fast• CTC• Desligado

Page 14: Timers Interrupcoes Arduino

Timers no Arduino

14/42

• 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 frequência Correta• PWM – Fast• PWM – Fast, 8 bits• PWM – Fast, 9 bits• PWM – Fast, 10 bits• CTC• Desligado

Page 15: Timers Interrupcoes Arduino

Timers no Arduino

15/42

• Waveform Generation Mode bits (WGM) – Timer2 (8 bits)

Modos:

• Normal• PWM – fase Correta• PWM – Fast• Desligado

Page 16: Timers Interrupcoes Arduino

Timers no Arduino

16/42

• Timer/Counter Prescaler – Timer1

Page 17: Timers Interrupcoes Arduino

Timers no Arduino

17/42

• Timer/Counter Prescaler – Timer2

Page 18: Timers Interrupcoes Arduino

Timers no Arduino

18/42

8-bi

t Tim

er/C

ount

er2

with

PW

M a

nd A

sync

hron

ous O

pera

tion

• O ATMEGA328 tem 3 timers e 6 saídas PWM;

• O Arduino usa o Timer0, 8bits, internamente para as funções millis() e delay();

• Portanto, mudando os registradores deste timer, pode afetar o uso destas funções;

• A biblioteca de PWM usa estas funções internamente:

analogWrite(pin, duty_cycle)

Page 19: Timers Interrupcoes Arduino

Timers no Arduino

19/42

• 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 através de um bit flag, que pode causar uma interrupção, se previamente programada.

• O Temporizador/Contador pode ser sincronizado internamente, através do prescaler (AS2=0, default), ou de forma assíncrona com clock nos pinos TOSC (TOSC1 e TOSC2 / AS2=1, neste caso).

• A operação assíncrona (externa/Tn) é controlada pelo Estado Assynchronous Register (RAEE).

Page 20: Timers Interrupcoes Arduino

Timers no Arduino

20/42

• Cada um dos temporizadores tem um contador que é incrementado ou decrementado a cada pulso de clock;

• A interrupção do timer ocorre quando o contador chegar a um valor especificado previamente no registrador de comparação 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 comparação, o valor da frequência de clock, que sincroniza o incremento no contador, pode-se controlar a frequência de interrupções do timer, quando habilitada.

Page 21: Timers Interrupcoes Arduino

Timers no Arduino

21/42

• Cada um dos temporizadores tem um contador que é incrementado ou decrementado a cada pulso de clock;

• A interrupção do timer ocorre quando o contador chegar a um valor especificado previamente no registrador de comparação 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 comparação e o valor da frequência de clock, que sincroniza o incremento no contador, pode-se controlar a frequência de interrupções do timer, quando habilitada.

Page 22: Timers Interrupcoes Arduino

Timers no Arduino

22/42

• 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 temporário (TEMP).

• O registo temporário é atualizado com o valor TCNT1H quando o TCNT1L é lido, e TCNT1H com o valor do registrador temporário, quando TCNT1L está escrito. Isso permite que a CPU a ler ou escrever todo o valor de 16 bits dentro um ciclo de clock através do barramento de dados de 8 bits.

• Dependendo do modo de operação utilizado, o contador é limpo, incrementado ou decrementado em cada relógio temporizador (clkT1).

• O clkT1 pode ser gerada a partir de uma fonte de relógio externo ou interno, selecionado pelos bits Relógio Select (CS12: 0). Quando não há fonte de clock é selecionado (CS12: 0 = 0) o cronômetro é parado.

• No entanto, o valor TCNT1 pode ser acessada pela CPU, independentemente de clkT1 está presente ou não.

Page 23: Timers Interrupcoes Arduino

Timers no Arduino

23/42

• Timer2 - Output Compare Unit (8 bits)

• O comparador de 8 bits compara continuamente TCNT2 com a saída 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 interrupção correspondente estiver ativada, é acionada a rotina de atendimento a interrupção, 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 saída OC2A ou OC2B, de acordo com o modo de funcionamento definido por WGM22:0 e COM2x1:0.

Page 24: Timers Interrupcoes Arduino

Timers no Arduino

24/42

• Timer2 – Modos de Operação• Normal Mode (WGM2x:0 = 0)

• Neste modo, o sentido da contagem é sempre incrementado, e também não zera o contador ao atingir o valor máximo;

• O contador reinicia ao atingir 0xFF (neste caso, TOP = 0xFF) indo para em 0x00; • Em operação normal, o flag de estouro do Timer / Contador (TOV2), será setado no mesmo

ciclo de relógio do estouro e TCNT2 torna-se zero. O flag TOV2, neste caso, se comporta como um nono bit;

• Na rotina de atendimento a interrupção, automaticamente o flag TOV2 é zerado;• A resolução do temporizador pode ainda ser aumentada por software;• Não há casos especiais a considerar no modo normal, e um novo valor do contador pode ser

escrita a qualquer hora;• A unidade de Comparação de saída pode ser usado para gerar interrupções, em algum

momento. Usar a saída para gerar formas de onda no modo normal, não é recomendado, uma vez que este vai ocupar muito do tempo de CPU.

Page 25: Timers Interrupcoes Arduino

Timers no Arduino

25/42

• Timer2 – Modos de Operação• Fast PWM Mode (WGM22:0 = 3 ou 7)

• Usado para gerar frequencias maiores para o PWM;• No modo de PWM rápido, o contador é incrementado até que o valor do contador atingir ao valor TOP, aí o

contador é então limpo no ciclo seguinte do relógio temporizador.• O valor TCNT2 e o diagrama de temporização estão ilustrads na figura a seguir;• O diagrama inclui saídas não invertida e invertida PWM;• As pequenas marcas vistas na linha horizontal na TCNT2 representam a comparação entre OCR2x e TCNT2;• No modo de PWM rápido, a unidade de comparação permite a geração de formas de onda PWM no pino

OC2x;• Definindo os bits COM2x1:0 para 2 será produzido um PWM não invertida e uma saída 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á visível no pino da porta se a direção de dados para o pino da porta for definido

como saída. • A forma de onda PWM é gerada ajustando-se o Registrador OC2x equando entre OCR2x for igual a TCNT2;• A frequência de saída de PWM pode ser calculada pela seguinte equação:

N = prescale = (1, 8, 32, 64, 128, 256, ou 1024)

Page 26: Timers Interrupcoes Arduino

Timers no Arduino

26/42

• Timer2 – Modos de Operação• Fast PWM Mode (WGM22:0 = 3 ou 7)

N = prescale = (1, 8, 32, 64, 128, 256, ou 1024)

• O flag de estouro do timer, TOV2, é setado a cada estouro de contagem (TOP). Se a estiver ativada, a rotina de tratamento de interrupção pode ser utilizada para atualizar o valor de comparação, permitindo gerar o PWM no pino OC2x;

• Definindo os bits COM2x1:0 = 2 irá produzir um PWM não invertido, e uma saída 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á visível no pino da porta se a direção de dados para o pino da porta estiver definida como saída.

• A forma de onda PWM é gerada no registrador OC2x (1 ou 0), durante a comparação entre OCR2x e TCNT2, e na transição lógica de durante os pulsos de alto para baixo;;A frequência de PWM da saída pode ser calculada pela seguinte equação:

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

Page 27: Timers Interrupcoes Arduino

Timers no Arduino

27/42

• Timer2 – Modos de Operação• Clear Timer on Compare Match (CTC) Mode (WGM22:0 = 2)

• Neste modo, o registrador OCR2A é usado para configurar a resolução 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 resolução do timer;• Este modo permite maior controle na comparação e no frequência do sinal de saída;• Este modo simplifica a operação com evento externo;

1. Para gerar uma de forma de onda na saída no CTC modo, a saída OC2A pode ser definido para alternar o nível lógico em cada partida comparação definindo a comparar bits de modo de saída para alternar o modo de (COM2A1: 0 = 1).

2. A frequência da forma de onda é definido pela seguinte equação:

N = prescale ={1, 8, 32, 64, 128, 256, ou 1024}

Page 28: Timers Interrupcoes Arduino

Timers no Arduino

28/42

• Timer2 – Modos de Operação• 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 operação de dupla inclinação;• O TOP é definido como 0xFF quando WGM2:0 = 3, e quando em OCR2A, MGM2:0 = 7;• A saída da comparação (OC2x) é zerada enquanto o timer estiver com valores acima do TOP de

comparação e setado para valores abaixo, execeto na primeiro ciclo, que inicia setada;• A operação de inclinação dupla tem menor freqüência de operação máxima de operação que a de

inclinação única. No entanto, devido à característica simétrica dos modos de dupla inclinação PWM, estes modos são preferidos para aplicações de controle do motores;

• Neste modo o timer é incrementado até o TOP e, então, muda a direção 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, produz o PWM invertido;• Um PWM invertido pode ser gerado fazendo-se COM2x1:0=3;• O TOP é definido como 0xFF quando WGM2:0 = 3, e em OCR2A, MGM2:0 = 7;

Page 29: Timers Interrupcoes Arduino

Timers no Arduino

29/42

• Timer2 – Modos de Operação• Phase-Correct PWM (WGM22:0 = 1 ou 5)

O valor OC2x somente ficará visível no pino da porta se a direção de dados para o pino da porta for definida como saída;A frequência de PWM na saída pode ser calculada pela seguinte equação:

N = prescale ={1, 8, 32, 64, 128, 256, ou 1024}

Page 30: Timers Interrupcoes Arduino

Timers no Arduino

30/42

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

Registradores para TIMER2:

Page 31: Timers Interrupcoes Arduino

Timers no Arduino

31/42

TIMSK2 – Timer/Counter2 Interrupt Mask Register

TIFR2 – Timer/Counter2 Interrupt Flag Register

ASSR – Asynchronous Status Register

GTCCR – General Timer/Counter Control Register

Registradores para TIMER2:

Page 32: Timers Interrupcoes Arduino

Timers no Arduino

32/42

Detalhes dos registradores para TIMER2: TCCR2A

Page 33: Timers Interrupcoes Arduino

Timers no Arduino

33/42

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 não PWM / não gera interrupção / Sempre lido como 0;

• Bit 6 de TCCR2B – FOC2B: Force Output Compare A• Ativo somente quando WGM configurar modo de não PWM / não gera interrupção / 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 interrupção e gerar sinal no pino OC2A;

• OCR2B – Output Compare Register B• Registrador 8 bits com valor para comparar com TCNT2. O resultado pode gerar interrupção 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 interrupção quando TCNT2 = OCR2B levando o flag OCF2B= 1, em TIFR2, e desviando o programa p/ atender a interrupção;• Bit 1 – OCIE2A: Timer/Counter2 Output Compare Match A Interrupt Enable

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

• Se 1, habilita interrupção quando ocorrer overflow no timer2 levando o flag TOV2=1, em TIFR2, e desviando o programa p/ atender a interrupção;• TIFR2 – Timer/Counter2 Interrupt Flag Register

• Bit 2 – OCF2B: Output Compare Flag 2 B• Se 1, indica houve uma interrupção decorrente de quando TCNT2 = OCR2B;

• Bit 1 – OCF2A: Output Compare Flag 2 A• Se 1, indica houve uma interrupção decorrente de quando TCNT2 = OCR2A;

• Bit 0 – TOV2: Timer/Counter2 Overflow Flag• Se 1, indica que houve uma interrupção decorrente do estouro de timer2;

Page 34: Timers Interrupcoes Arduino

Timers no Arduino

34/42

Detalhes dos registradores para TIMER2:

• ASSR – Asynchronous Status Register• Bit 7 – Reserved• Bit 6 – EXCLK: Enable External Clock Input

• Se 1, clock assíncrono (externo) é selecionado para um clock de 32 KHz no pino TOSC1;• Bit 5 – AS2: Asynchronous Timer/Counter2

• Se 0, indica clock interno clkI/O e se 1, clock externo em TOSC1 ;• Bit 4 – TCN2UB: Timer/Counter2 Update Busy

• Se 0, indica que TCNT2 está pronto para atualização;• Bit 3 – OCR2AUB: Output Compare Register2 Update Busy

• Se 0, indica que OCR2A está pronto para atualização;• Bit 2 – OCR2BUB: Output Compare Register2 Update Busy

• Se 0, indica que OCR2B está pronto para atualização;• Bit 1 – TCR2AUB: Timer/Counter Control Register2 Update Busy

• Se 0, indica que TCCR2A está pronto para atualização;• Bit 0 – TCR2BUB: Timer/Counter Control Register2 Update Busy

• Se 0, indica que TCCR2B está pronto para atualização;

Os mecanismos para a leitura TCNT2, OCR2A, OCR2B, TCCR2A e TCCR2B são 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. Não pode ser zerado por hardware, se TSM=1.

Page 35: Timers Interrupcoes Arduino

Timers no Arduino

35/42

• Exemplo de geração de PWM nos pinos 3 e 11 / Fast PWM

• WGM = 011 => Fast PWM em timer 2• COM2A = COM2B = 10 => PWM não invertido em A e B• CS = 100 => prescaler de 64• Registradores de comparação na saída serão 180 e 50, para PWM em A e B

Saída A: Fpwm_A = 16MHz / 64 / 256 = 976,56 Hz

duty_A = (180+1)/256 = 70,7%

Saída B:Fpwm_B = 16MHz / 64 / 256 = 976,56 Hz duty_B = (50+1)/256 = 19,9%

pinMode(3, OUTPUT); // pwm em A, duty 70,7%pinMode(11, OUTPUT); // pwm em B, duty 19,9%

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

OCR2A = 180; OCR2B = 50;

Código correspondente:

Page 36: Timers Interrupcoes Arduino

Timers no Arduino

36/42

• 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)

Page 37: Timers Interrupcoes Arduino

Timers no Arduino

37/42

• Count = contagem com os prescalers no ATMEGA328

Count = frequency_from_table / target_frequency Exemplo piscar um led a 50Hz :

Prescaler=1024 => Count = 15625 / 50 = 312,5 => somente timer1Prescaler=256 => Count = 62500 / 50 = 1250 => timer1

Page 38: Timers Interrupcoes Arduino

Timers no Arduino

38/42

Exemplo de geração de PWM nos pinos 3 e 11 / Phase-Correct PWM

• WGM = 001 => Phase-Correct PWM em timer 2• COM2A = COM2B = 10 => PWM não invertido em A e B• CS = 100 => prescaler de 64• Registradores de comparação na saída serão 180 e 50, para PWM em A e B

Saída A: Fpwm_A = 16 MHz / 64 / 255 / 2 = 490,196 Hz

duty_A = 180 / 255 = 70,6%

Saída B:Fpwm_B = 16 MHz / 64 / 255 / 2 = 490.196 Hz duty_B = 50 / 255 = 19.6 %

pinMode(3, OUTPUT); // pwm em A, duty 70,7%pinMode(11, OUTPUT); // pwm em B, duty 19,9%

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

OCR2A = 180; OCR2B = 50;

Código correspondente:

Page 39: Timers Interrupcoes Arduino

Timers no Arduino

39/42

Exemplo de geração 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 saída / COM2B = 10 • CS = 100 => prescaler de 64• Registradores de comparação na saída (OCR2A e OCR2B) serão 180 e 50, para PWM em A e B

Saída A: Fpwm_A = 16 MHz / 64 / (180+1) / 2 = 690,6 Hz

duty_A = 50%

Saída B:Fpwm_B = 16 MHz / 64 / (180+1) = 1381,2 Hz duty_B = 50 / 255 = 19,6 %

pinMode(3, OUTPUT); // pwm em A, duty 50 %pinMode(11, OUTPUT); // pwm em B, duty 19,6%

TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);TCCR2B = _BV(WGM22) | _BV(CS22);

OCR2A = 180;OCR2B = 50;

Código correspondente:

Page 40: Timers Interrupcoes Arduino

Timers no Arduino

40/42

Exemplo de geração 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 comparação na saída (OCR2A e OCR2B) serão 180 e 50, para PWM em A e B

Saída A: Fpwm_A = 16 MHz / 64 / 180 / 2 / 2 = 347,2 Hz

duty_A = 50%

Saída 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;

Código correspondente:

Page 41: Timers Interrupcoes Arduino

Timers no Arduino

41/42

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 interrupção 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 interrupção decorrente de comparação*/ 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 interrupção do timer overflow

} ISR(TIMER2_OVF_vect) {

TCNT2 = tcnt2; // recarrega o valor de contagemdigitalWrite(2, x== 0 ? HIGH : LOW);

x= ~x; } void loop() { // loop infinito

}

Page 42: Timers Interrupcoes Arduino

Timers no Arduino

42/42

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 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 ledISR(TIMER1_COMPA_vect){ //timer1 interrupt

toggle0 = ~toggle0; digitalWrite(13,toggle0); // inverte bit na saida 13}

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

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

cli(); //stop interrupts TCCR1A = 0; // set entire TCCR1A register to 0 TCCR1B = 0; // same for TCCR1B TCNT1 = 0; //initialize counter value to 0 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 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(" "); } //end setup

loop() { }

Page 43: Timers Interrupcoes Arduino

Timers no Arduino

43/42

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

Page 44: Timers Interrupcoes Arduino

Timers no Arduino

44/42

Exemplo: Geração 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);

cli(); //stop interrupts

//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 sei(); //allow interrupts

} //end setup

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(){ }

Page 45: Timers Interrupcoes Arduino

Timers no Arduino

45/42

Exemplo: Geração 3 formas de onda com timer0, timer1 e timer2

Page 46: Timers Interrupcoes Arduino

Timers no Arduino

46/42

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=pa2I12ZWT3WGnymRf2KYLXiGUKE&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

Page 47: Timers Interrupcoes Arduino

Timers no Arduino

Arduino / Timers / Interrupções

Prof. Ilton L BarbacenaIFPB – João Pessoa / PB