Programando AVR na IDE e placa Arduino - PWM
Nas duas primeiras postagens sobre AVR mostrei configurações de portas e timer trabalhando no modo CTC, nesta postagem mostrarei o timer trabalhando como PWM (Pulse-width modulation). O PWM é amplamente usado em micro controladores para controle de motores, lampadas, temperatura e inúmeros dispositivos.
O trabalho do PWM como o próprio nome diz é controlar a largura de pulso, com isso a porta passará a ter um controle de potência. Na figura abaixo por exemplo, para a saída da porta em 5V a primeira linha entregaria 2.5V a segunda 3.75V e a terceira 1.25V
Lembrando que no PWM do ATMega 328P já existe as portas padrões para se trabalhar, para o Timer 0 vamos trabalhar na porta Arduino 6 que equivale ao PD6 (OC0A). Existe dois modos de trabalho em PWM para o Timer 0, que são Fast PWM e Phase Correct PWM Mode. As diferenças são que no Fast PWM quando o contator TCNT0 inicia a contagem, a porta é colocada em nível alto até chegar ao valor setado em OCR0A, neste momento a porta vai para nível baixo e permanece até o contador TCNT0 chegar em 255 e voltar a 0, onde inicia novamente o processo. No modo Phase Correct PWM Mode o contador TCNT0 não volta a 0 quando chega em 255 e sim decrementa esse valor até 0. Nas páginas 108 e 110 do datasheet tem detalhado esses modos com gráficos para melhor entendimento.
Para o exemplo vamos precisar de um hardware adicional além do Arduino Uno, um led e resistor conforme abaixo:
O código de exemplo será este:
int main(void) { DDRD |= (1 << DDD6); // PD6 (Arduino Pin 6) TCCR0A |= (1 << COM0A1) | // Seta na comparação (1 << WGM01) | (1 << WGM00); // Modo Fast PWM TCCR0B |= (1 << CS01) | (1 << CS00); // Prescaler 64 OCR0A = 125; // Valor baixo largura de pulso pequena // Valor alto largura de pulso grande while (1) {} //Loop infinito return 0; }
int main(void) { DDRB |= (1 << DDB1); // PB1 (Arduino Pin 9) TCCR1A = 0; // Inicia o registrador com valores em 0 TCCR1B = 0; // Inicia o registrador com valores em 0
TCCR1A |= (1 << COM1A1) | // Seta na comparação (1 << WGM11); // Fast PWM (Modo 14) TCCR1B |= (1 << CS10) | (1 << CS11) | // Prescaler 64 (1 << WGM13) | (1 << WGM12); // Fast PWM (Modo 14) ICR1 = 250 ; // 16000000 / (64*250) = 1000hz OCR1A = 125; while (1) {} // Loop infinito return 0; }
Comentários
Postar um comentário