Montando uma fonte chaveada variavel com o pic.

Aviso: não tente fazer este projeto se você não tiver conhecimentos suficientes para isto, não me responsabilizo por qualquer dano causado pela inexperiência por parte do leitor.Este projeto é somente para fins didáticos não sendo recomendado para uso comercial.


Para montar uma fonte chaveada é preciso entender como é a lógica de funcionamento em fontes chaveadas (fontes ATX para PC por exemplo) comerciais que segue os passos abaixo:

•Ao ser ligada a rede elétrica é alimentado o circuito primário da fonte (alta tensão), observe que a maioria das fontes tem 3 transformadores de ferrite :

1.Transformador de partida (geralmente na fôrma EE-19C).

2.Transformador de pulsos (geralmente na fôrma EE-16, é de costume ficar entre o transformador principal e o de partida).

3.Transformador principal ( geralmente na fôrma ERL-35, é o maior dos três), veja a figura abaixo.
 
 
  Figura1 - transformador na fôrma ERL-35.

•O transformador de partida é acionado por um circuito oscilador, gerando no seu secundário 5V que alimenta o CI(circuito integrado) controlador de pwm (tl494 ou um outro que desempenhe a função parecida, veja na figura 2, o diagrama interno deste CI), este CI tem duas saídas pwm defasadas em 180°, que é aplicada a transistores(também chamados de drives) no lado sencundário fazendo o chaveamento do transformador de pulso, e com isso chaveando a base de dois transistores (ou mosfets) que estão no lado primário da fonte, e estes por sua vez fazem o chaveamento da tensão no transformador principal gerando no secundário(deste) as tensões de 12V,-12V,5V,-5V e 3.3V.



 Figura 2 – Diagrama interno do tl494

•É importante lembrar que o CI controlador de pwm é responsável por verificar a tensão e corrente de saída, pois caso a tensão esteja abaixo ou acima do valor ajustado pelo fabricante este CI deve aumentar ou diminuir a largura de pulso gerada(duty cycle), além de desligar a fonte caso seja detectado sobrecorrente.

•Com certeza a maior vantagem de uma fonte chaveada está no fato dela ser menor que as fontes convencionais (devido à alta freqüência de funcionamento e o tipo do material do núcleo (ferrite)) e ter uma melhor relação de transferência de energia (de 70 a 90%).

Primeiramente para trabalhar com estes transformadores é preciso saber qual sua freqüência de trabalho (ressonância) e sua potência (vem na caixa da fonte neste caso), então usei um gerador de funções para encontrar a freqüência de trabalho do transformador com o núcleo na fôrma ERL-35(transformador principal) que é facilmente encontrado em sucatas ou fonte de computador que não estão sendo utilizadas (dificilmente este transformador queima em fontes chaveadas comum.), esta freqüência estava entre 100 e 125 Khz (onda senoidal), mas nos teste com onda quadrada o comportamento é outro e devido a isto fiz alguns testes e um valor que julguei ideal tanto para o microcontrolador (precisão no numero de passos de incremento da largura de pulso) quanto para o transformador foi a freqüência de 40Khz .

O circuito que montei é o seguinte:

 Figura 3 – fonte chaveada microcontrolada com tensão variável.

O objetivo deste projeto era:

Fonte chaveada com saída ajustável digital de 0 a 30V, e reprogramável.

•Entrada 110/220V.

•Capacidade de corrente de até 7A (em 12V).

•Pequeno porte.


•Baixo custo.

O resultado obtido foi:

•Fonte chaveada com saída ajustável digital de 8 a 25 V, e reprogramável.


•Entrada 110/220V automática.


•Capacidade de corrente de no Máximo 2A.

•Pequeno porte (ficou a metade do tamanho de uma fonte ATX de PC).

•Baixo custo (componentes retirados de sucata).

Entendendo o projeto

O circuito do primário após passar pelo filtro de EMI(filtro de interferência eletromagnética )e dividido em dois estágio circuito de alimentação e interface do microcontrolador que irá gerar o sinal de pwm e o outro composto pelo mosfet e transformador.No primeiro estágio a tensão percorre o resitor de 47K e o capacitor de 680nF (em paralelo ao resistor de 1M) e chega ao diodo zener de 5V, o diodo 1N4007 dá passagem da tensão no semiciclo positivo e o capacitor de 2200uF/25V(pode ser de 1000uF/25V também ) funciona como um filtro estabilizando a tensão de saída que em seguida é entregue ao microcontrolador (pic 16F628A). Ligado ao microcontrolador tem dois leds que indicam quando o sinal pwm está sendo incrementado ou decrementado, dois botões que permitem aumentar ou diminuir a tensão de saída, existem ainda dois optoacopladores que recebem o sinal para controle de tensão da fonte (sinal emitido pelo microcontrolador (12F675) que está no secundário), e por fim o pino_9 do microcontrolador envia o sinal pwm a base do mosfet que irá chavear o transformador, o diodo na base do mosfet evita que uma tensão acima de 5V retorne ao pino do microcontrolador. A função do led em paralelo ao capacito de 220uF/400V e descarregar o capacitor quando a fonte for desligada.

No secundário do transformador principal após a tensão ser retificada parte vai a saída da fonte e parte alimenta o segundo microcontrolador(12F675) que tem a função de monitorar a tensão de saída e mandar que o controlador pwm aumente ou diminua a largura de pulso e ainda um botão que permite programar o valor de saída.

Entendendo o funcionamento

Ao ligar a fonte o microcontrolador do primário vai aumentando a largura de pulso até que a tensão do secundário atinja 5V (mediante um pulso recebido do microcontrolador que está no secundário) ou chegue ao limite Máximo programado no microcontrolador 12F675 (pois o secundário pode estar em curto). Quando houver os 5V no secundário o microcontrolador espera um tempo para verificar se o botão ‘programar’ está pressionado(para evitar que ruidos dispare uma operaçao de escrita sobrepondo o valor gravado)caso a resposta seja afirmativa ele entra em modo de gravação do valor da tensão de saída (que pode ser ajustada nos dois botões do circuito do primário, botão ‘mais’ e ‘menos’), caso o botão não seja pressionado no inicio do funcionamento do microcontrolador que está no secundário a fonte irá elevar a tensão até o valor programado.

Quando for usar a fonte pela primeira vez você deve pressionar o botão de programação e quando a tensão chegar a 8V, você deve tirar o dedo do botão, depois disto desligue a fonte e ligue novamente ela deverá retornar aos 8V, para alterar o valor programado repita este processo.Na figura 4 é apresentado a fonte funcionando com o valor de 12V programado.


               Figura4 - prototipo final da fonte chaveada microcontrolada.

           Para que se interessar eu envio o desenho do esquemático + placa de circuito impresso + código fonte dos dois microcontroladores que controlam a fonte  espero ter ajudado a quem queira montar uma fonte chaveada por puro hobby ou mesmo intender como funciona uma fonte chaveada.
           Devido a vários e-mails que tenho recebido resolvi postar aqui o código fonte dessa fonte(tando do lado secundário quanto do lado primário ) e vou colocar uma imagem em jpg ampliado do esquemático no final do post .Vale lembrar que este projeto está parado e não pretendo finalizar devido ao fato das fontes chaveadas no mercado serem bem mais baratas.

Código fonte do lado primário :

// ****************************************************************************************************************************************************
//                                                               
//
//  Data:      22/06/2009
//  atualizado 25/06/2009
//  atualizado 24/07/2009
//  Autores:   Aguivone
//  Descrição: controlador da fonte chaveada
//
// **************************************************************************************************************************************************** 
#include <16F628A.h> 
#FUSES NOWDT, HS, PUT, NOPROTECT,BROWNOUT, NOMCLR, NOLVP, NOCPD 
#locate tx_reg=          0x19
#locate rx_reg=          0x1A
#use delay(clock=20M)
long valor=5;

void main() 
{ 
   Set_tris_b(0);
   output_low(PIN_B0);//led vermelho
   output_low(PIN_B1);//led verde 
   output_low(PIN_B2);//gravar  
   output_low(PIN_B3);//pwm 
   setup_timer_2(T2_DIV_BY_1,250, 1); // (postcaler do timer/ pr2/prescaler) 
   setup_ccp1(CCP_PWM); 
   valor=1;
   set_pwm1_duty(valor); //duty=pwm/Tpwm
    output_high(PIN_B0);
    delay_ms(1000);
    output_low(PIN_B0);//led
  while(input(pin_B4))
   {
    valor++;
    set_pwm1_duty(valor); //duty=pwm/Tpwm
    delay_ms(80); //tempo de subida de tensão  
   while(valor>900)//sobrecorrente
   {
    set_pwm1_duty(1); //duty=pwm/Tpwm
    output_high(PIN_B0);
    delay_ms(500);
    output_low(PIN_B0);//led
    output_high(PIN_B1);
    delay_ms(500);
    output_low(PIN_B1);//led
    } 
    }
   for(;;)// o numero de passos aqui é 1000
     {

                if((!input(pin_B4))&&(valor>2))//optoacoplador que manda baixar tensão
                  {
                  output_high(PIN_B0);//led
                  valor--;
                  set_pwm1_duty(valor); //duty=pwm/Tpwm
                  output_low(PIN_B0);//led
                  } 
                if((!input(pin_B5))&&(valor<=900))//optoacoplador que manda aumentar tensão
                  {
                  output_high(PIN_B1);//led
                  valor++;
                  set_pwm1_duty(valor); //duty=pwm/Tpwm
                  output_low(PIN_B1);//led
                  } 

            if((!input(pin_B6))&&(valor>2))//botao que no modo de programação reduz tensão
             {
               delay_ms(100);
               if(!input(pin_B6))
               {
               output_high(PIN_B0);//led
               valor--;
               set_pwm1_duty(valor); //duty=pwm/Tpwm
               delay_ms(300);
               output_low(PIN_B0);//led
               }
              } 
             if((!input(pin_B7))&&(valor<=950))//botao que no modo de programação aumenta tensão
             {
               delay_ms(100);
               if(!input(pin_B7))
               {
               output_high(PIN_B1);//led
               valor++;
               set_pwm1_duty(valor); //duty=pwm/Tpwm
               delay_ms(300);
               output_low(PIN_B1);//led
               }
              } 
   while(valor>900)//sobrecorrente
   {
    set_pwm1_duty(1); //duty=pwm/Tpwm
    output_high(PIN_B0);
    delay_ms(500);
    output_low(PIN_B0);//led
    output_high(PIN_B1);
    delay_ms(500);
    output_low(PIN_B1);//led
    }

     }
}

 //numero de passo = (Fosc/(Fpwm*4*prescaler))-1 nesse caso é 100
 
/* 
//clock de 4mhz 
#define PWM_250HZ_CLK4         setup_timer_2(T2_DIV_BY_16, 250, 1) //
#define PWM_500HZ_CLK4         setup_timer_2(T2_DIV_BY_16, 125, 1) //
#define PWM_1KHZ_CLK4          setup_timer_2(T2_DIV_BY_4, 250, 1)  //
#define PWM_1K25HZ_CLK4        setup_timer_2(T2_DIV_BY_16, 50, 1)  //
#define PWM_2KHZ_CLK4          setup_timer_2(T2_DIV_BY_4, 125, 1)  //
#define PWM_2K5HZ_CLK4         setup_timer_2(T2_DIV_BY_4, 100, 1)  //
#define PWM_4KHZ_CLK4          setup_timer_2(T2_DIV_BY_1, 250, 1)  //
#define PWM_5KHZ_CLK4          setup_timer_2(T2_DIV_BY_1, 200, 1)  //
#define PWM_8KHZ_CLK4          setup_timer_2(T2_DIV_BY_1, 125, 1)  //
#define PWM_10KHZ_CLK4         setup_timer_2(T2_DIV_BY_1, 100, 1)  //
#define PWM_20KHZ_CLK4         setup_timer_2(T2_DIV_BY_1,  50, 1)  //
#define PWM_25KHZ_CLK4         setup_timer_2(T2_DIV_BY_1,  40, 1)  //
#define PWM_100KHZ_CLK4        setup_timer_2(T2_DIV_BY_1, 10, 1)   //
//clock de 8mhz 
#define PWM_500HZ_CLK8         setup_timer_2(T2_DIV_BY_16, 250, 1) //
#define PWM_1KHZ_CLK8          setup_timer_2(T2_DIV_BY_16, 125, 1) //
#define PWM_2KHZ_CLK8          setup_timer_2(T2_DIV_BY_4, 250, 1)  //
#define PWM_2K5HZ_CLK8         setup_timer_2(T2_DIV_BY_16, 50, 1)  //
#define PWM_4KHZ_CLK8          setup_timer_2(T2_DIV_BY_4, 125, 1)  //
#define PWM_5KHZ_CLK8          setup_timer_2(T2_DIV_BY_4, 100, 1)  //
#define PWM_8KHZ_CLK8          setup_timer_2(T2_DIV_BY_1, 250, 1)  //
#define PWM_10KHZ_CLK8         setup_timer_2(T2_DIV_BY_1, 200, 1)  //
#define PWM_16KHZ_CLK8         setup_timer_2(T2_DIV_BY_1, 125, 1)  //
#define PWM_20KHZ_CLK8         setup_timer_2(T2_DIV_BY_1, 100, 1)  //
#define PWM_40KHZ_CLK8         setup_timer_2(T2_DIV_BY_1,  50, 1)  //
#define PWM_50KHZ_CLK8         setup_timer_2(T2_DIV_BY_1,  40, 1)  //
#define PWM_200KHZ_CLK8        setup_timer_2(T2_DIV_BY_1, 10, 1)   //
//clock de 16mhz 
#define PWM_1KHZ_CLK16         setup_timer_2(T2_DIV_BY_16, 250, 1) //
#define PWM_2KHZ_CLK16         setup_timer_2(T2_DIV_BY_16, 125, 1) //
#define PWM_4KHZ_CLK16         setup_timer_2(T2_DIV_BY_4, 250, 1)  //
#define PWM_5KHZ_CLK16         setup_timer_2(T2_DIV_BY_16, 50, 1)  //
#define PWM_8KHZ_CLK16         setup_timer_2(T2_DIV_BY_4, 125, 1)  //
#define PWM_10KHZ_CLK16        setup_timer_2(T2_DIV_BY_4, 100, 1)  //
#define PWM_16KHZ_CLK16        setup_timer_2(T2_DIV_BY_1, 250, 1)  //
#define PWM_20KHZ_CLK16        setup_timer_2(T2_DIV_BY_1, 200, 1)  //
#define PWM_32KHZ_CLK16        setup_timer_2(T2_DIV_BY_1, 125, 1)  //
#define PWM_40KHZ_CLK16        setup_timer_2(T2_DIV_BY_1, 100, 1)  //
#define PWM_80KHZ_CLK16        setup_timer_2(T2_DIV_BY_1,  50, 1)  //
#define PWM_100KHZ_CLK16       setup_timer_2(T2_DIV_BY_1,  40, 1)  //
#define PWM_400KHZ_CLK16       setup_timer_2(T2_DIV_BY_1, 10, 1)   //

*/

Código fonte do lado secundário:

// *********************************************
// regulador da fonte chaveada secundario
// criado em 26/06/09
// atualizado 16/07/09
// atualizado 24/07/09
/*
autor: aguivone

a função deste microcontrolador e mandar subir ou descer a tensão de acordo com o valor gravado ma memoria 
*/

#include <12f675.h>
#device ADC=10
#use delay(clock=4M)
#fuses XT,nowdt,CPD,put,brownout,nomclr,PROTECT
#rom 0x3ff = { 0x34b4 }
void main()
{
   long valor,gravado;
   int  conta,conta2;
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_adc_ports(pin_A0);
   set_adc_channel(0);
   conta=read_eeprom(8);
   delay_us(3);
   conta2=read_eeprom(9);
   delay_us(3);
   gravado=250*conta2;    //recuperação  de dados long da memoria
   gravado=conta+gravado;    
   while(true)
    {
        if(!input(pin_A3))// manda gravar
        {
             delay_ms(10);
             if(!input(pin_A3))
             {
             delay_ms(100);
             if(!input(pin_A3))
             {
             output_low(pin_a1);
             output_low(pin_a2);
             while(!input(pin_A3));
             delay_ms(200);
             while(!input(pin_A3));
             gravado = read_adc();
             delay_us(5);
             conta=0;
             conta2=0; 
             while(gravado>0)  //gravação na memoria
             {
              gravado--;
              conta++;
                if(conta==250)
                 {
                  conta2++;
                  conta=0;
                 }
              }
          write_eeprom(8,conta);
          delay_us(5);
          write_eeprom(9,conta2);
          delay_us(5);
          gravado=250*conta2;
          gravado=conta+gravado;
           }
           }
           else
           {
              valor = read_adc();
              delay_us(2);
              if(valor>(gravado+2))//2 - tolerancia
               {
                        output_low(pin_a2);
                        output_high(pin_a1);
                        delay_us(5);
                        output_low(pin_a1);
                        output_low(pin_a2);
               }
             else
              {
                   if(valor<(gravado-2))//tolerancia
                    {
                        output_low(pin_a1);
                        output_high(pin_a2);
                        delay_us(5);
                        output_low(pin_a1);
                        output_low(pin_a2);
                     }
                   if((valor<(gravado+2))&&(valor>(gravado-2)))
                    {
                        output_low(pin_a1);
                        output_low(pin_a2);
                     } 
           } 
            }
         }
         else
         {
              valor = read_adc();
              delay_us(2);
              if(valor>(gravado+5))//5 - tolerancia
               {
                        output_low(pin_a2);
                        output_high(pin_a1);
                        delay_us(5);
                        output_low(pin_a1);
                        output_low(pin_a2);
               }
             else
              {
                   if(valor<(gravado-5))//5)//tolerancia
                    {
                        output_low(pin_a1);
                        output_high(pin_a2);
                        delay_us(5);
                        output_low(pin_a1);
                        output_low(pin_a2);
                     }
                   if((valor<(gravado+5))&&(valor>(gravado-5)))
                    {
                        output_low(pin_a1);
                        output_low(pin_a2);
                     } 
           } 
       }
   }
}


Imagem do esquemático: