terça-feira, 8 de maio de 2012

Circuito PWM para LED

Nesta matéria apresento um circuito para fazer o controle do brilho de um LED por PWM utilizando um microcontrolador. A figura abaixo ilustra o circuito que deve ser montado:
Para você conseguir construir este projeto você já deve ter construído o seu próprio Gravador AVR. Se você ainda não tem um gravador de chip sugiro que consulte o artigo Gravador AVR para USB. Este projeto irá utilizar um modulador PWM (Pulse Width Modulator) para conseguir uma intensidade de brilho gradual em um LED. Será utilizado um microcontrolador AT90s2313 para fazer o controle de luminosidade.  Além disso, você poderá desenvolver este mesmo projeto se você já tiver um KIT recomendado pelo artigo  Gravador AVR para USB. Uma vez que o AT90s2313 é obsoleto, e provavelmente difícil de ser encontrado, você pode troca-lo pelo sucessor ATtiny2313 com algumas pequenas modificações na posição dos pinos. Isso pode ser feito consultando o datasheet do Attiny2313. Uma grande vantagem no uso deste microcontrolador mais moderno é que não é preciso utilizar um cristal ou qualquer outro oscilador externo. Este microcontrolador vem com um oscilador interno de 1MHz. Assim, você pode suprimir os componentes C1, C2 e Q1 do diagrama esquemático mostrado pela figura acima. Além disso, os componentes R1 e C3 associados com o circuito de RESET também podem ser omitidos (no caso do attiny2313) restando somente o capacitor de bypass C4, o resistor R2 e o LED.

Compile o seguinte programa e grave no microcontrolador utilizando o gravador AVR para USB.

 /*  
  * ----------------------------------------------------------------------------  
  *  
  * Demonstração de um programa AVR simples em C  
  * O brilho do LED é controlado por PWD. Depois de cada  
  * periodo do PWM , o valor do PWM eh incrementado ou  
  * decrementado.  
  *  
  */  
 #include <inttypes.h>  
 #include <avr/io.h>  
 #include <avr/interrupt.h>  
 #include <avr/sleep.h>  
 #include "iocompat.h"   
 enum { UP, DOWN };  
 ISR (TIMER1_OVF_vect)  
 {  
   static uint16_t pwm;    
   static uint8_t direction;  
   switch (direction)    
   {  
     case UP:  
       if (++pwm == TIMER1_TOP)  
         direction = DOWN;  
       break;  
     case DOWN:  
       if (--pwm == 0)  
         direction = UP;  
       break;  
   }  
   OCR = pwm;          
 }  
 void  
 ioinit (void)          
 {  
   /* Timer 1 is 10-bit PWM (8-bit PWM on some ATtinys). */  
   TCCR1A = TIMER1_PWM_INIT;  
   /*  
    * Start timer 1.  
    *  
    * NB: TCCR1A and TCCR1B could actually be the same register, so  
    * take care to not clobber it.  
    */  
   TCCR1B |= TIMER1_CLOCKSOURCE;  
   /*  
    * Run any device-dependent timer 1 setup hook if present.  
    */  
 #if defined(TIMER1_SETUP_HOOK)  
   TIMER1_SETUP_HOOK();  
 #endif  
   /* Set PWM value to 0. */  
   OCR = 0;  
   /* Enable OC1 as output. */  
   DDROC = _BV (OC1);  
   /* Enable timer 1 overflow interrupt. */  
   TIMSK = _BV (TOIE1);  
   sei ();  
 }  
 int  
 main (void)  
 {  
   ioinit ();  
   /* loop forever, the interrupts are doing the rest */  
   for (;;)          /* Note [7] */  
     sleep_mode();  
   return (0);  
 }  

Nenhum comentário:

Postar um comentário

Por favor, faça seu comentário aqui!