Вы находитесь на странице: 1из 59

PWM

Prof. Ilton L Barbacena


2012.2
PWM
Modulao de Largura de pulso, ou PWM, uma tcnica para obter sinais
analgicos utilizando sinais digitais. Um conversor Digital-Analgico barato;
O controle digital usado para criar uma onda retangular, formado por um
sinal alternado entre ligado e desligado. Este padro on-off pode simular
tenses analgicas entre 5 Volts e 0 volts, alterando a poro de tempo que o
sinal esteja alto em comparao com o tempo em que o sinal esteja baixo.
A durao do "tempo" chamado de largura de impulso. Para obter diferentes
valores analgicos, muda-se a largura de pulso. Se repetir este padro on-off
com rapidez suficiente, com um LED por exemplo, o resultado obter o
controle da luminosidade do LED;
Esta durao do tempo ou perodo o inverso da frequncia de PWM.
2/59
PWM
A tcnica de PWM consiste em manipularmos a razo cclica de um sinal, o
duty cycle, afim de transportar informao ou controlar a potncia de algum
outro circuito.
Com isso, teremos um sinal digital que oscila entre 0v e 5v com determinada
frequncia (o Arduino trabalha com um padro prximo a 500Hz).
O duty cycle a razo do tempo em que o sinal permanece em 5v sobre o
tempo total de oscilao, como est ilustrado abaixo:
3/59
PWM Pulse Width Modulation
Com PWM pode-se obter uma tenso analgica a partir de
um sinal digital (DAC), com utilizao de filtros na sada;
4 /59
PWM
A tenso mdia diretamente proporcional ao duty cycle ou
ciclo ativo.
5 /59
Onde:
V(t) = Vpulsos para 0<= t
<=tp
V(t) = 0 para tp < t
<= T
A tenso mdia ser:
PWM
Para se obter um conversor digital analgico a partir de
um pino digital, basta implementar um sinal PWM e
adicionar em sua sada um filtro passa baixa com
frequncia de corte menor que a prpria frequncia do
PWM.

Supor um filtro RC, onde f
corte
= 1 / (2*pi*R*C);

Neste caso, deve-se adotar sempre o seguinte:


6 /59
Quando no necessria obter uma tenso mdia contnua, a
implementao do filtro descartada;
No caso de resistores de aquecimento ou motores DC o filtro
dispensvel, uma vez que estes componentes j atuam como
filtros, desde que a frequncia do PWM no seja muito baixa.
PWM - DAC
7 /59
PWM com filtro RC
8 /59
1 Escolhe p/ gerar pulsos 2- Tenso de pico (5V)
3 duty = 10% 4 freq. Do PWM
Etapas:
PWM com filtro RC
9 /59
Duty = 10% Duty = 70%
Veja alguns exemplos em:
http://ww1.microchip.com/downloads/en/AppNotes/00655a.pdf
http://aquaticus.info/pwm-sine-wave
http://www.wpi.edu/Pubs/E-project/Available/E-project-042711-
190851/unrestricted/PWM_Techniques_final.pdf
PWM com filtro RC
10 /59
Veja o resultado da simulao com um sinal PWM aplicado em utilizando
um filtro RC com 2 estgios, para gerao de um sinal senoidal.
Filtro RC com 2 polos
Sinal de entrada pwm
de 19kHz e duty de
70%
PWM com filtro LC
11 /59
Veja o resultado da simulao com um sinal PWM aplicado em
utilizando um filtro LC com 2 estgios, para gerao de um sinal
senoidal.
Em no havendo necessidade de obter tenso mdia contnua, utiliza-
se o PWM sem filtros (aquecimento e acionamento de motores), desde
que a frequncia do PWM no seja muito baixa.
Filtro LC com 2 polos
Sinal de entrada pwm
de 19kHz e duty de
80%
PWM gerado com 555
12/59
x1
X2
X2
X1
R3
1k
Q1
BD136
+88.8
M1
D1
1N4148
BAT1
12V
A
B
C
D
SW1
SW-DPDT
HH duplo
C3
100n
SW1 Controla o sentido de rotao
RV1 Controla a velocidade (PWM)
Controle de Velocidade de motor DC (PWM)
Prof Ilton Barbacena IFPB - Maio - 2012
42%
RV1
47k
R1
1k
R
4
DC
7
Q
3
G
N
D
1
V
C
C
8
TR
2
TH
6
CV
5
U1
555
C1
0.01u
C2
0.1u
D2
1N4148
D3
1N4148
Volts
rpm
Componentes fora da PCI:
- Potencimetro
- Chave reversora (H-H dupla)
- Fonte de alimentao
- Motor DC (12V)
Nota: Usar conectores KRE para ligaes da PCI aos componentes fora da PCI (chassis)
PWM trivial com Arduino
Esta tcnica tem a vantagem de que se pode usar qualquer pino de sada digital.
Alm disso, tem-se o controle completo do ciclo de trabalho e da frequncia.
Uma grande desvantagem que quaisquer interrupes ir afetar o tempo, o
que pode causar instabilidade considervel a menos que voc se desabilite
todas as interrupes.
Nesta fonte de PWM difcil determinar as constantes apropriadas para um
ciclo de trabalho particular e frequncia, a menos que voc queira contar os
ciclos cuidadosamente, enquanto observa no osciloscpio.
13/59
void setup()
{
pinMode(13, OUTPUT);
}
void loop()
{
digitalWrite(13, HIGH);
delayMicroseconds(100); // aproximadamente 10% duty cycle @ 1KHz
digitalWrite(13, LOW);
delayMicroseconds(1000 - 100);
}
PWM trivial com filtro no Arduino
14/59
Implementao do exemplo anterior
PWM com uso de analogWrite() no Arduino
PWM no arduno fcil de utilizar, com a funo: analogWrite(pin, dutyCycle),
onde dutyCycle is um valor de 0 a 255, e o pin uma das sadas analgicas
(pinos 3, 5, 6, 9, 10, ou 11).
A funo analogWrite fornece uma interface simples, mas no fornece qualquer
controle sobre frequncia. (Note-se que, apesar do nome da funo, a sada
um sinal digital, muitas vezes referenciada como uma onda quadrada.)
Provavelmente 59% dos leitores pode parar aqui, e usar apenas analogWrite
para PWM, mas h outras opes que oferecem mais flexibilidade.
15/59
#define ledPin 5 // Pinos de pwm: 3, 5, 6, 9, 10, e 11
#define analogPin A3 // Leitura de potenciometro, tensao analogica

int val = 0, val1=0, val2=1;

void setup()
{

pinMode(ledPin, OUTPUT); // sada do PWM

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

Serial.println("IFPB - Prof. Ilton");
Serial.println("PWM com analogWrite()");
Serial.println("Plataforma Arduino ");
Serial.println("Jan / 2013");
Serial.println(" ");
delay(4000);

}


void loop()
{
val = analogRead(analogPin); // Le ADC: 0 ... 1023

val1= val/4; // mximo 255

if (val != val2) // se houver mudancas
{
analogWrite(ledPin, val1); // gerar PWM em ledPin

Serial.print("ADC = ");
Serial.print(val, DEC);
Serial.print(" duty = ");
Serial.print(100*val1/256, DEC);
Serial.println("% ");
}

val2 = val;
}

// val varia de 0 a 1023
// val1 varia de 0 a 255
PWM com uso de analogWrite() no Arduino
16/59
Implementao do exemplo anterior
PWM com uso de registradores no Arduno
O microcontrolador ATMEGA328, do arduno UNO, possui 3 temporizadores que podem controlar
at 6 sadas PWM diretamente, obtendo-se mais controle, do que a funo analogWrite()
proporciona. A tabela abaixo resume os timers existentes na linha arduno:
17/59
timer bits Canal
Pino no
UNO (CI)
Pino no
MEGA
timer0 8 A 6(12) 13
timer0 8 B 5(11) 4
timer1 16 A 9 (15) 11
timer1 16 B 10(16) 12
timer2 8 A 11 (17) 10
timer2 8 B 3(5) 9
timer3 16 A - 5
timer3 16 B - 2
timer3 16 C - 3
timer4 16 A - 6
timer4 16 B - 7
timer4 16 C - 8
timer5 16 A - 44
timer5 16 B - 45
timer5 16 C - 46
No reset, o bootloader do
Arduno configura os timers
para uso em PWM pela
funo analogWrite ();
Os timers so configurados
para o modo phase-
correct 8-bit e com o
relgio preescaleado por 64.
No entanto, o timer0
configurado para o modo
fast PWM, para uso das
funes millis() / micros().

PWM com uso de registradores no Arduno
18/59
Pinos do ATMEGA328 em vermelho relacionados a PWM
Timer output Arduino output Chip pin Pin name
OC0A 6 12 PD6
OC0B 5 11 PD5
OC1A 9 15 PB1
OC1B 10 16 PB2
OC2A 11 17 PB3
OC2B 3 5 PD3
PWM com uso de registradores no Arduno
Timers no arduino:

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. Na plataforma Arduno, a biblioteca
Servo usa timer1 do Arduno Uno e timer5 no Arduno 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.
19/59
PWM com uso de registradores no Arduno
O controlador do arduino UNO o AVR Atmel ATmega168 ou
ATmega328. Estes uCs so compatveis pino a 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.
Um timer 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.
A diferena mais importante entre temporizador de 8 bits e 16 bits a
resoluo do temporizador: 8bits significa 256 valores e 16bit significa
65536 valores para maior resoluo.
O temporizador programado por alguns registradores especiais. Pode-
se configurar o prescaler para o timer, o modo de operao, e muitas
outras coisas.
20/59
PWM com uso de registradores no Arduno
Os temporizadores tambm podem gerar interrupes no overflow (final
de contagem) como tambm, comparar valores de registradores, quando
usados em CCR (capture e Compare);
O controlador para a srie arduino Mega o AVR Atmel ATmega1280 ou
o ATmega2560. Este semelhante ao ATmega328 do UNO
diferenciando-se apenas no tamanho da memria. Estes controladores
tm 6 temporizadores. O timer0, timer1 e 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, deve-se ter cuidado ao escrever funes
utilizando os timers.
O hardware do temporizador pode ser configurado usando alguns
registradores especiais da CPU. No firmware do arduno todos os
temporizadores foram configurados para uma frequncia de 1kHz e
interrupes so geralmente habilitadas.

21/59
PWM com uso de registradores no Arduno
22/59
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 final (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 considerado a velocidade com que o temporizador incrementa o contador.
Como o clock do Arduino de 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 (tempo p/ fazer a contagem)
Para uma contagem de 0 a 99 => T = 100/16000000s;
Para uma contagem de 0 a 255 => T = 256/16000000s =~ 16uS / mx para timer0 e timer2;
Para uma contagem de 0 a 65535 => T = 65536/16000000 = ~ 4 ms / mximo para timer1 (16bits);
Prescaler => Aumenta o tempo de contagem. Todos os timers pode selecionar o prescaler de 1, 8, 64, 256 e
1024;
Prescaler nos Timers:
F
timer
(Hz) = (F
clock
) / prescaler

Valor_registrador = (16 MHz) / (prescaler * tempo) ) 1

Exemplo: tempo=1s / prescaler = 1024 => valor_do registrador = 15624 => (apenas o timer1)
Timers no Arduino
23/42
Diagrama de blocos dos TImers
count Incrementa e decrement TCNTn por 1;
direction Seleciona incremento ou decremento;
clear limpa TCNTn;
clkTn clock do timer
top indica que TCNTn atingiu valor mximo;
bottom indica que TCNTn atingiu valor mnimo (0)
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:

Os bits WGM (Waveform
Generation Mode)
controlam os vrios modos
de funcionamento dos
timers.
Timers no Arduino
24/42
Waveform Generation Mode bits (WGM) Timer0 (8 bits)
Modos:

Normal
PWM - Phase
Correct
PWM Fast
CTC
Desligado
Timers no Arduino
25/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 frequncia
Correta
PWM Fast
PWM Fast, 8 bits
PWM Fast, 9 bits
PWM Fast, 10 bits
CTC
Desligado
Timers no Arduino
26/42
Waveform Generation Mode bits (WGM) Timer2 (8 bits)
Modos:

Normal
PWM Phase Correct
Fast PWM
CTC
Timers no Arduino
27/42
Timer/Counter Prescaler Timer1
Timers no Arduino
28/42
Timer/Counter Prescaler Timer2
Timers no Arduino
29/42
8
-
b
i
t

T
i
m
e
r
/
C
o
u
n
t
e
r
2

w
i
t
h

P
W
M

a
n
d

A
s
y
n
c
h
r
o
n
o
u
s

O
p
e
r
a
t
i
o
n

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
usa estas funes
internamente:
analogWrite(pin, duty_cycle)
Timer0 => Pinos de sada: PD6 (6) e PD5(5)
Timer1 => Pinos de sada: PB1(9) e PB2(10)
Timer2 => Pinos de sada: PB3(11) e PD3(3)
Timers no Arduino
30/42

Cada temporizador tem 2 registradores para comparar os
valores de contagem com o valor limite ou programado (0xFF
ou OCRnA), 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).
Timers no Arduino
31/42

Cada um dos timers tem um contador que incrementado ou
decrementado a cada pulso de clock;
A interrupo do timer ocorre quando o contador atingir 0xFF ou
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;
A frequncia PWM gerada pode ser controlado de 2 modos: (b)
frequncia de PWM, usando o prescaler; (b) limite superior do
contador (0xFF ou OCRnA);
Ao escolher o valor para a comparao, junto com o valor da
frequncia de clock (usando o prescaler), que sincroniza o
incremento no contador, pode-se controlar a frequncia de
interrupes do timer, quando habilitada, bem como, a gerao do
PWM.
Timers no Arduino
32/42
Timer1 - Output Unit (16 bits)
O contador de 16-bit formado por dois registradores
de 8-bit: TCNT1H e TCNT1L. O Registro TCNT1H s
pode ser acessada indiretamente pela CPU;
Quando a CPU precisa acessar 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 escreve em TCNT1L.
Isso permite 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 a
cada relgio temporizador (clkT1).
O sinal 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) e o cronmetro
parado.
No entanto, o valor TCNT1 pode ser acessada pela
CPU, independentemente de clkT1 est presente ou
no.
Timers no Arduino
33/42
Timer2 - Output Compare Unit (8 bits)
O comparador de 8 bits que 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 reiniciar a 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 PWM gerado utiliza o flag para gerar uma
sada OC2A ou OC2B, de acordo com o
modo de funcionamento definido por
WGM22:0 e COM2x1:0.
Pinos de sada: 3 (OC2B) e 11 (OC2A)
Timers no Arduino
34/42
Modos de operao do Timer2 (8 bits)
Modo Normal
O timer conta normalmente at o MAX, 0xFF, quando reinicia a contagem, setando flag de
interrupo (TOP = MAX);
No gera PWM automtico, podendo ser gerado na rotina de interrupo;
Modo Clear Timer on Compare Match (CTC)
O timer conta normalmente at atingir o limite o TOP de contagem:OCR2A ou OCR2B, quando
reinicia a contagem, setando flag de interrupo;
No gera PWM automtico, podendo ser gerado na rotina de interrupo;
Modo: Fast PWM
Um modo de gerao automtica de PWM nos pinos 11 e/ou 3, onde ocorre o incremento do
MIN ao TOP (neste caso, MIN=0);
Modo: Phase Corrected PWM
Um modo de gerao automtica de PWM nos pinos 3 e/ou 11, onde o contador incrementa de
MIN at o TOP e, em seguida, decrementa at o valor mnimo (0).
Melhor opo para acionamento de certas cargas, como motores.
Modo: Phase and Frequency Corrected PWM
Diferencia-se do anterior apenas no momento em que o registrador OCRnx atualizado com o
novo buffer. Como o nome sugere, a vantagem do Phase and Frequency correct PWM ser mais
apropriado para alterar a frequncia do PWM, por estar os sinais PWM em fase.
Para qualquer um dos modos, existem 3 bits no registrador TCCR2B, que alteram o
prescaler ou o relgio do contador. Valores do prescaler: 1, 8, 32, 64, 128, 256 e 1024.
Timers no Arduino
35/42
Fast PWM no Timer2
O timer conta at OCR2x, e nesse momento atualiza o pino OC2x (se o liga ou desliga
depende da configurao dos bits COM1x0 e COM1x1).
Depois continua a contar at TOP, e nesse momento volta ao BOTTOM e atualiza o pino OC2x,
alterando o seu estado;

Pino OC2A duty de 66,66%
Pino OC2B duty de 33,66%
Timers no Arduino
36/42
Phase Corrected PWM no Timer2
O timer conta at OCR2x, e nesse momento atualiza o pino OC2x (se o liga ou desliga
depende da configurao dos bits COM1x0 e COM1x1).
Depois decrementa at chegar ao BOTTOM (0). Ao passar por OCR2x atualiza o pino OC2x,
alterando o seu estado;

Timers no Arduino
37/42
Timer2 Modos de Operao
Fast PWM Mode (WGM22:0 = 3 ou 7)
Usado para 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 PWM no invertida e invertida;
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.
A forma de onda PWM gerada ajustando-se o Registrador OC2x equando entre OCR2x for
igual a TCNT2;
A frequncia de sada de PWM pode ser calculada pela seguinte equao:
N = prescaler = (1, 8, 32, 64, 128, 256, ou 1024)
Timers no Arduino
38/42
Timer2 Modos de Operao
Fast PWM Mode (WGM22:0 = 3 ou 7)
N = prescale = (1, 8, 32, 64, 128, 256, ou 1024)

Duty = (OCR2A *N * 256 / clk
I/O
)
O flag de estouro do timer, TOV2, setado a cada
estouro de contagem (TOP). Se a interrupo 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:

Neste modo o timer conta de 0 a 255. A sada liga quando o timer 0, e desliga
quando o valor do timer corresponder ao valor do registrador OCR2A. Quanto
maior o valor da sada de comparao, maior o ciclo de servio (duty).
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.
Timers no Arduino
39/42
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;
Este modo simplifica a operao com evento externo;
1. Para gerar uma de forma de onda na
sada no CTC modo, a 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 = prescaler ={1, 8, 32, 64, 128, 256, ou 1024}
Timers no Arduino
40/42
Timer2 Modos de Operao
Phase-Correct PWM (WGM22:0 = 1 ou 5)
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 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, 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;
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;
Timers no Arduino
41/42
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}
Timers no Arduino
42/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:
Timers no Arduino
43/42
TIMSK2 Timer/Counter2
Interrupt Mask Register
TIFR2 Timer/Counter2
Interrupt Flag Register
ASSR Asynchronous
Status Register
GTCCRGeneral Timer/Counter
Control Register
Registradores para TIMER2:
Timers no Arduino
44/42
Detalhes dos registradores para TIMER2: TCCR2A
Timers no Arduino
45/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 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;
Bit 1 OCF2A: Output Compare Flag 2 A
Se 1, indica houve uma interrupo decorrente de quando TCNT2 = OCR2A;
Bit 0 TOV2: Timer/Counter2 Overflow Flag
Se 1, indica que houve uma interrupo decorrente do estouro de timer2;
Timers no Arduino
46/42
Detalhes dos registradores para TIMER2:
ASSR Asynchronous Status Register
Bit 7 Reserved
Bit 6 EXCLK: Enable External Clock Input
Se 1, clock assncrono (externo) selecionado para um clock de 32 KHz no pino TOSC1;
Bit 5 AS2: Asynchronous Timer/Counter2
Se 0, indica clock interno clk
I/O
e se 1, clock externo em TOSC1 ;
Bit 4 TCN2UB: Timer/Counter2 Update Busy
Se 0, indica que TCNT2 est pronto para atualizao;
Bit 3 OCR2AUB: Output Compare Register2 Update Busy
Se 0, indica que OCR2A est pronto para atualizao;
Bit 2 OCR2BUB: Output Compare Register2 Update Busy
Se 0, indica que OCR2B est pronto para atualizao;
Bit 1 TCR2AUB: Timer/Counter Control Register2 Update Busy
Se 0, indica que TCCR2A est pronto para atualizao;
Bit 0 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.


PWM com uso de registradores no Arduno
47/59
#define TOGGLE_PIN 13
#define pot A3

int ler=0, ler1=2, ler3;

void setup() {

// Setup Timer2 overflow to fire every 8ms (125Hz)
// period [sec] = (1 / f_clock [sec]) * prescale * (255-count)
// (1/16000000) * 1024 * (255-130) = .008 sec
Serial.begin(9600);
while(!Serial) {};

TCCR2B = 0x00; // Disable Timer2 while we set it up

TCNT2 = 130; // Reset Timer Count (255-130) = execute ev 125-th T/C clock
TIFR2 = 0x00; // Timer2 INT Flag Reg: Clear Timer Overflow Flag
TIMSK2 = 0x01; // Timer2 INT Reg: Timer2 Overflow Interrupt Enable
TCCR2A = 0x00; // Timer2 Control Reg A: Wave Gen Mode normal
TCCR2B = 0x07; // Timer2 Control Reg B: Timer Prescaler set to 1024

Serial.println("IFPB - Prof. Ilton");
Serial.println("PWM com Timer2 Normal");
Serial.println("Plataforma Arduino ");
Serial.println("Jan / 2013");
Serial.println(" ");
delay(2000);
}
void loop(){

ler = analogRead(pot); // ler potenciometro
ler3 = map(ler, 0, 1023, 0, 255);

if (ler != ler1)
{
Serial.print("ler = ");
Serial.print(ler, DEC);
Serial.print(" ler3 = ");
Serial.println(ler3, DEC);
}

ler1=ler;


}

ISR(TIMER2_OVF_vect) {
static unsigned int led_state = 0; // LED state

led_state = !led_state; // toggles the LED state

digitalWrite(TOGGLE_PIN, led_state);

//TCNT2 = 130; // 8mS
TCNT2 = ler3;
TIFR2 = 0x00; // timer2 int flag reg: clear overflow flag
};
Neste exemplo temos o uso do estouro de timer2, para gerar um pwm de duty de 50%
PWM com uso de registradores no Arduno
48/59
PWM normal com uso de registradores do timer2
Gerao do PWM descrito no exemplo anterior, onde observa-se que
mesmo mudando o valor do estouro de contagem, o duty fica em 50%
PWM com uso de registradores no Arduno
49/59
#define pwm1 3 // OC2B
#define pwm2 11 // OC2A
#define pot A3
int ler=0, ler1=2, ler3;

void setup()
{
// Setup Timer2 overflow to fire every 8ms (125Hz)
// period [sec] = (1 / f_clock [sec]) * prescale * (255-count)
// (1/16000000) * 1024 * (255-130) = .008 sec
Serial.begin(9600);
while(!Serial) {};

pinMode(pwm1, OUTPUT);
pinMode(pwm2, OUTPUT);
pinMode(pot, INPUT);

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

// COM2A=10 => Fast pwm no pino OC2A (no invertido)
// COM2B=11 => Fast pwm no pino OC2B (invertido)
// WGM=7 => Fast PWM com MAX em OCR2A

TCCR2B = _BV(CS22); // CS22=1 => prescaler 64 para timer2
OCR2A = 180;
OCR2B = 50;
Serial.println("IFPB - Prof. Ilton");
Serial.println("PWM Fast - timer2");
Serial.println("Plataforma Arduino ");
Serial.println("Jan / 2013");
Serial.println(" ");
delay(2000);
}
void loop()
{

ler = analogRead(pot); // ler potenciometro
ler3 = map(ler, 0, 1023, 0, 255);

OCR2A = ler3;
OCR2B = 256-ler3;

if (ler != ler1) // mostra mudancas
{
Serial.print("ler3 = ");
Serial.print(ler3, DEC);
Serial.print(" ORR2A = ");
Serial.print(ler3, DEC);
Serial.print(" OCR2B = ");
Serial.println(256-ler3, DEC);

}

ler1=ler;
delay(100);


}
Exemplo: Fast PWM em timer2
PWM com uso de registradores no Arduno
50/59
Gerao do PWM descrito no exemplo anterior, com o duty varivel
PWM com uso de registradores no Arduno
51/59
Driver para Motor DC ou servo: L293D
Fonte: http://www.societyofrobots.com/member_tutorials/node/164

Controla 2 motores DC de
forma independente;
Para cada motor possvel
controlar o sentido de
rotao e a velocidade com
um sinal de PWM;
Limitado a at 1,2 A / 12V
por motor DC.

PWM com uso de registradores no Arduno
52/59
Driver para Motor DC: SN754410
http://www.sparkfun.com/datasheets/IC/SN754410.pdf
PWM com uso de registradores no Arduno
53/59
Funcionamento dos drivers L293D ou SN754410
Caractersticas:
Controlam at 2 motores DC ou servos
Para cada motor: (a) controle de sentido de rotao; (b) Controle de velocidade; (c ) Alimentao independente;
PWM com uso de registradores no Arduno
54/59
Funcionamento dos drivers L293D ou SN754410
#define pwm1 3 // OC2B
#define pwm2 11 // OC2A
#define pot A3 // controla velocidade (PWM)
#define led1 4 // pino do led que sinaliza qdo botao acionado
#define in1 A0 // controla sentido rotao do motor

int ler=0, ler1=2, ler3;
boolean inv1=0, inv=0, ss=0; //

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

pinMode(pwm1, OUTPUT);
pinMode(pwm2, OUTPUT);
pinMode(pot, INPUT);
pinMode(led1, OUTPUT); // pisca led qdo muda o sentido
pinMode(in1, OUTPUT); // muda o sentido de rotacao
attachInterrupt(0, muda_sentido, RISING); // interrupo no botao

TCCR2A = _BV(COM2A1)| _BV(COM2B1) | _BV(COM2B0)
| _BV(WGM22) | _BV(WGM21)| _BV(WGM20);
// COM2A=10 => Fast pwm no pino OC2A (no invertido)
// COM2B=11 => Fast pwm no pino OC2B (invertido)
// WGM=7 => Fast PWM com MAX em OCR2A

TCCR2B = _BV(CS22); // CS22=1 => prescaler 64 para timer2
OCR2A = 180; OCR2B = 50;
Serial.println("IFPB - Prof. Ilton");
Serial.println("PWM Fast - L293D");
Serial.println("Plataforma Arduino ");
Serial.println("Jan / 2013"); Serial.println(" "); ss=1;
delay(500);
} // setup
void loop(){
ler = analogRead(pot); // ler potenciometro
ler3 = map(ler, 0, 1023, 0, 255);
OCR2B = ler3;
OCR2A = 256-ler3;

if (ler != ler1)
{
Serial.print("ler3 = "); Serial.print(ler3, DEC);
Serial.print(" INV= ");
if (inv) Serial.println(" 1"); else Serial.println(" 0");
}
ler1=ler;
delay(100);
} // loop

void muda_sentido()
{
inv1 = ~inv1;
inv = ~inv; // liga motor

digitalWrite(led1, inv1); // inverte led
digitalWrite(in1, inv); // inverte sentido
if (ss)
{
Serial.print(" INV= ");
if (inv)
Serial.println(" 1");
else
Serial.println(" 0");
}
}

Uso do driver L293 p/ motor DC
55/59
Usando o driver L293D (O CI L293DD possui 4 drivers):
Para controlar os motores, utiliza-se os pinos 2 e 7 para motor 1 e os pinos 10 e 15 para motor 2.
Os pinos de ligao aos motores so os pinos 3 e 6 para um dos motores e 11 e 14 para o outro. Os aterramentos so
os pinos 4 e 13 e 5 e 12 para os motores 1 e 2;
Os pinos 1 e 9 habilitam os canais; para utilizar 1 motor sinalize 1 ou 9. Para utilizar 2 motores, sinalize ambos. Para tal,
basta liga-los 5v;
O pino 16 a alimentao do circuito lgico, onde que deve ser conectada a 5v;
O pino 8 a entrada de energia para alimentao dos motores. Essa entrada suporta at 36v, ou seja, podemos
tranquilamente alimentar 2 motores de impressora;
Uso do driver L293 p/ motor DC
56/59
Usando o driver L293D:
Ligando e mudando o sentido de rotao do motor DC com L293D
Uso do driver L293 p/ motor DC
57/59
const int L293_ENA2 = 8; // D8
const int L293_INP3 = 9; // D9
const int L293_INP4 = 10; // D10
#define led1 4 // pino do led que sinaliza qdo botao acionado

int inv=0, ss=0;
boolean inv1=0;

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

pinMode (L293_ENA2, OUTPUT);
pinMode (L293_INP3, OUTPUT);
pinMode (L293_INP4, OUTPUT);
pinMode (led1, OUTPUT);
attachInterrupt(0, muda_sentido, RISING);

digitalWrite (L293_ENA2, LOW);
digitalWrite (L293_INP3, LOW);
digitalWrite (L293_INP4, LOW);

Serial.println("IFPB - Prof. Ilton");
Serial.println("L293D sem PWM");
Serial.println("Plataforma Arduino ");
Serial.println("Jan / 2013 - inv=1");
Serial.println(" ");
ss=1;

digitalWrite (L293_ENA2, HIGH);
digitalWrite (L293_ENA2, LOW);
digitalWrite (L293_INP4, HIGH);
digitalWrite (L293_INP3, LOW);
digitalWrite (L293_ENA2, HIGH);
delay(1000);
}

void loop () { }
void muda_sentido()
{
inv1 = ~inv1;
digitalWrite(led1, inv1); // inverte led

switch(inv)
{
case 0: // esquerda
digitalWrite (L293_ENA2, LOW);
digitalWrite (L293_INP4, LOW);
digitalWrite (L293_INP3, HIGH);
digitalWrite (L293_ENA2, HIGH);
break;

case 1: // direita
digitalWrite (L293_ENA2, LOW);
digitalWrite (L293_INP4, HIGH);
digitalWrite (L293_INP3, LOW);
digitalWrite (L293_ENA2, HIGH);
break;
case 2: // parado
digitalWrite (L293_ENA2, LOW);
digitalWrite (L293_INP3, LOW);
digitalWrite (L293_INP4, LOW);
digitalWrite (L293_ENA2, LOW);
break;

}

if (ss)
{
Serial.print(" INV= ");
Serial.println(inv, DEC);
}
inv++;
if (inv >= 3) inv=0;
}
PWM no ARDUINO
Fontes de Consulta:

http://arduino.cc/en/Tutorial/PWM
http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM
http://www.eletronica.org/arq_apostilas/apostila_pwm.pdf
http://jaktek.com/wp-content/uploads/2011/12/HC-SR04.pdf
http://www.instructables.com/id/Easy-ultrasonic-4-pin-sensor-monitoring-hc-sr04/
http://playground.arduino.cc/Main/PWMallPins
http://www.fiz-ix.com/2012/01/how-to-configure-arduino-timer-2-registers-to-drive-an-ultrasonic-transducer-
with-a-square-wave/
http://blipbox.org/blog/2011/05/23/arduino-squarewave-generation/
https://sites.google.com/site/qeewiki/books/avr-guide/pwm-on-the-atmega328
http://lusorobotica.com/index.php?topic=2838.120
http://www.mythic-beasts.com/~markt/ATmega-timers.html
http://www.societyofrobots.com/member_tutorials/book/export/html/228
http://electronics.stackexchange.com/questions/26363/how-do-i-create-a-timer-interrupt-with-arduino
http://bluepichu.wordpress.com/2012/07/16/fast-pwm-with-arduino-fast/
http://www.cursodearduino.com.br/apostila/apostila-rev4.pdf
http://www.societyofrobots.com/member_tutorials/node/159
http://labdegaragem.com/profiles/blogs/tutorial-motor-de-passo-parte-3-circuitos-de-acionamento
http://itp.nyu.edu/physcomp/Labs/DCMotorControl
http://web.ics.purdue.edu/~fwinkler/616/sn754410_Arduino.pdf
http://www.tigoe.net/pcomp/code/circuits/motors/stepper-motors/
http://www.societyofrobots.com/member_tutorials/node/228
http://www.logicaprogrammabile.it/shift-register-arduino-74595/
http://www.righto.com/2009/07/secrets-of-arduino-pwm.html
58/59
Obrigado


iltonlb@gmail.com

Вам также может понравиться