MCO018703 2021 2 AULA11

De MediaWiki do Campus São José
Revisão de 09h45min de 18 de outubro de 2021 por Douglas (discussão | contribs) (Criou página com '=Timers e Interrupções= Temporização é fundamental quando se trabalha com circuitos microcontrolados, seja para um simples ''delay'' (tempo de espera) ou para geração...')
(dif) ← Edição anterior | Revisão atual (dif) | Versão posterior → (dif)
Ir para navegação Ir para pesquisar

Timers e Interrupções

Temporização é fundamental quando se trabalha com circuitos microcontrolados, seja para um simples delay (tempo de espera) ou para geração de sinais ou eventos periódicos. Todo microcontrolador tem pelo menos um periférico temporizador/contator. Esse periférico possui hardware dedicado para contagem de tempo e o seu correto uso, auxilia em uma programação mais eficiente para realização de diversos projetos.


Timers do ATmega328

O Atmega328, utilizado na placa Arduino UNO, possui 3 timers, sendo dois de 8 bits (TIMER0 e TIMER2) e um de 16 bits (TIMER1). Esses temporizadores são utilizados para diversas funcionalidades, tais como:

  • Temporização;
  • Contagem de eventos externos;
  • Geração de sinais PWM;
  • Interrupções periódicas;
  • Medida de intervalos de pulsos.


Cada temporizador possui características próprias e são utilizados conforme os recursos disponíveis. A biblioteca do Arduino abstrai o uso destes temporizadores em muitas de suas funções. Por exemplos, as funções delay(), millis(), micros(), tone(), analogWrite() utilizam recursos de timers para o funcionamento.


O TIMER1 é utilizado somente em algumas bibliotecas no Arduino específicas, podendo ser utilizado para outras finalidades sem causar muito impacto no funcionamento do restante das funções. [1]

Interrupções no Arduino

No Arduino, assim como em qualquer outro microcontrolador, pode-se utilizar interrupções para priorizar ou não tarefas e resolver problemas de tempo (timing). Existe dois tipos de interrupção no Arduino: a interrupção interna que permite interromper um código, caso o Arduino precise "rodar" o código inteiro sem ser interrompido; e a interrupção externa, dada pela portas digitais 2 e 3.


Interrupção Externa

O exemplo abaixo demonstra o uso da interrupção externa de forma simples e funcional. O exemplo adotado é o blink (pisca-pisca) com botão utilizando interrupção externa, a figura abaixo mostra a montagem, e, em seguida apresentamos o código fonte.

Fig33 MCO18703.png
Nota
O capacitor de 100nF serve como "delay" para o botão, já que a interrupção é muito rápida e precisa de um atraso para poder funcionar corretamente, e um resistor de 4,7k ohms como Pull-Up.


int pin = 13;
volatile int state = LOW;
volatile int state1 = LOW;

void setup()
{
   pinMode(pin, OUTPUT);
   attachInterrupt(0, blink, FALLING);  // chama a função blink quando o pino 2 (0) for pressionado.
}                                       // o pino vai de HIGH para LOW

void loop()
{
   digitalWrite(pin, state);

}

void blink()
{
   if(state==state1) {
      state = !state1;
   }
   else {
      state=state1; 
   }
}

Interrupção Interna

Os timers podem ser configurados para gerar uma interrupção quando o seu contador chegar ao valor máximo (timer overflow).

A configuração "manual" dos timers é bem trabalhosa pois exige a manipulação de vários registradores do microcontrolador, mas existem algumas bibliotecas que permitem fazer isso de forma simples. Vamos usar a biblioteca Timer1 e Timer3 está no [Arduino Playground].

O primeiro passo é baixar as bibliotecas e coloca-las na pasta hardware/libraries/ que está dentro da pasta do Arduino ou em sketchbook/libraries/. O local exato destes diretórios depende do sistema operacional (Linux, Mac ou Windows) e também da forma como a IDE do Arduino foi instalada.


Usando a biblioteca

A descrição completa do funcionamento da biblioteca está neste [link]. As principais funções da biblioteca são:

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, periodo)

Atribui uma função para ser chamada a cada interrupção gerada pelo timer. Se não for especificado um período, será utilizado o período definido na inicialização ou por setPeriod.

Testando a biblioteca

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.

Aqui está a versão traduzida do exemplo que está na página da biblioteca:

/*
* Timer1 library example
* August 2012 Translated by Tiago de França Queiroz
* June 2008 | jesse dot tane at gmail dot com
*/

#include "TimerOne.h"

void setup()
{
pinMode(13, OUTPUT);
Timer1.initialize(500000); // Inicializa o Timer1 e configura para um período de 0,5 segundos
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);
}

void loop()
{
// Seu código vai aqui...
}


Para usar os outros timers basta substituir o #include <TimerOne.h> por #include <TimerTree.h>, #include <TimerFour.h> ou #include <TimerFive.h> e no resto do código substitua Timer1 por Timer3, Timer4, ou Timer5.

Essas bibliotecas são úteis em várias situações, comoquando o loop principal do seu programa está bloqueado por algum motivo (esperando um botão ser pressionado, por exemplo) e você precisa atualizar um display, ou ler um sensor independentemente do loop principal, entre outras.

É importante lembrar que o tempo necessário para executar as funções que são chamadas na interrupção dos timers deve ser MENOR do que o tempo entre as interrupções!

Lembre-se que a versão que eu modifiquei a função de pwm (que eu não falei nesse post) está desativado.

Referências

[1] https://www.embarcados.com.br/timers-do-atmega328-no-arduino/

[2] http://labdegaragem.com/profiles/blogs/tutorial-executando-fun-es-em-intervalos-de-tempo-fixos-timers




Icone voltar.png Icone menu.png Icone prox.png