quinta-feira, 31 de janeiro de 2019

PWM de 20KHZ com o PIC 12F683 - Saída variável de 0 a 10V.


          Olá pessoal que acompanha o blog! depois de um bom tempo sem nenhum post, temos mais um projeto realizado por nosso colaborador Renato Lôbo, que nos traz um circuito que controla a saída por meio do uso da modulação PWM.
           O funcionamento se baseia na leitura da tensão que vem do potenciômetro(que neste caso varia de 0 a 5V) e então o microcontrolador irá gerar um sinal de pwm na frequência de 20Khz  e com largura de pulso proporcional a entrada(ou seja para  0 a 5V temos 0 a 10V) veja Figura 1, O filtro passa baixas  na saída(R3 e C2) faz com que o sinal de onda quadrada se aproxime do sinal analógico, dando uma "suavizada" no contorno do sinal  que tera um ganho de potencia por meio do transistor BC337.

Figura 1 - sinal gerado pelo microcontrolador.

 O código fonte.

Paste your////////////////////////////////////////////////////////////////////////////////
//              Projeto: PWM de 20Khz                                         //
//                 Nome: Renato Lôbo Rodrigues                                //
//                 Data: 27/01/19                                             //
//                Email: lobosoft@oi.com.br                                   //
////////////////////////////////////////////////////////////////////////////////
#include <12F683.h>
#use delay (clock = 8Mhz)
//Configure os fusíveis em acordo com o pic selecionado
#fuses NOWDT
#fuses PUT
#fuses NOBROWNOUT
#fuses NOMCLR
#fuses INTRC_IO
#fuses PROTECT

//Estes registros encontra-se nas funções especiais de cada modelo de pic.
#bit tris_bot1 = 0x85.0 //direção do pino A0
#bit bot1      = 0x05.0 //pino A0

#bit tris_bot2 = 0x85.1 //direção do pino A1
#bit bot2      = 0x05.1 //pino A1

#bit tris_pwm = 0x85.2 //direção do pino A2
#bit p_pwm    = 0x05.2 //pino A2

#bit tris_led = 0x85.5 //direção do pino A5
#bit led      = 0x05.5 //pino A5

#bit tris_adc = 0x85.4 //direção do pino A4
#bit adc      = 0x05.4 //pino A5

//Registro dos comparadores
#byte CMCON0            = 0x19          //Controle dos comparadores

//Registros do ADC
#byte ADCON0            = 0x1F          //Controle do ADC
#bit  ADCON0_GO_DONE    = ADCON0.1      //Status de conversão
#byte ANSEL             = 0x9F          //Selecioa os pinos Analógicos
#byte ADRESH            = 0x1E          //endereço do byte mais significativo
#byte ADRESL            = 0x9E          //endereço do byte menos significativo


//Registros de interrupção
#byte INTCON            = 0x0B          //Controle de interrupção
#bit  INTCON_GIE        = INTCON.7      //Registro geral
//#bit  INTCON_PEIE       = INTCON.6    //Interrupção de periferico

//Registros de PULL_UP
#byte OPTION_REG        = 0x81          //Registros de Opção 
#bit  OPT_REG_GPPU      = OPTION_REG.7  //habilitar ou desabilitar os Pull_up dos pinos 
#byte WPU               = 0x95          //Configurar os pinos que vão ser habilitados

//Registros do CCP1
#byte CCP1CON           = 0x15          //Registro do CCP1
//#bit  CCP1CON_DC1B1     = CCP1CON.5     //Bit 1 para byte menos significativo
//#bit  CCP1CON_DC1B0     = CCP1CON.4     //Bit 0 para byte menos significativo
#byte CCPR1L            = 0x13          //Byte mais significativo

//Registros do Timer2 para PWM
#byte T2CON             = 0x12          //Controle do timer 2
#byte PR2               = 0x92          //periodo do PWM


int16 pwm = 0;

//______________________________________________________________________________
//Rotina principal
void main()
{
   int1  st1         = false;    //status do botão
   int1  st2         = false;    //status do botão
   int   toc         = false;    //inicia regulando no potenciometro
   int16 valor_adc   = 0;        //inicia com zero 
   
   tris_bot1         = 1;        //pino A0 como entrada
   tris_bot2         = 1;        //pino A1 como entrada
   tris_adc          = 1;        //pino A4 entrada analogica
   tris_pwm          = 0;        //pino A2 do pwm como saída
   pwm               = 0;        //inicia o pwm com zero
   tris_led          = 0;        //pino A5 do led como saída
   led               = 0;        //led apagado
   
   OPT_REG_GPPU   = 0;  //zero = habilita os pull-up 
   WPU            = 3;  //00000011 liga pul-up dos pinos A0 e A1
                        //||||||||_Pino A0
                        //|||||||_Pino A1
                        //||||||_Pino A2
                        //|||||_Não usado, pino A3 não tem Pull_up interno
                        //||||_Pino A4 
                        //|||_Pino A5
                        //||_dois bit não usado

   CMCON0     = 7;      //000000111 Comparadores Desligados
                        //|||||||||_Tres bits "um" desliga todos os comparador
                        //||||||_Não usado para esse caso
   
   ADCON0     = 141;    //10001101 Controle do ADC
                        //||||||||_liga ou desliga o ADC
                        //|||||||_Status de conversão, zero terminou a conversão 
                        //||||||_Tres bits para determminar o canal usado 
                        //|||_Não implementado
                        //||_VDD
                        //|_Formatado a direita
                        
   ANSEL       = 88;    //10001000  frequência de atualização e pino A4 como ADC
                        //||||||||_Quatro bit seta o pinos analogicos
                        //||||_Tres bits seta a frequencia de conversão
                        //|_Não usado

   INTCON_GIE  = 1;     //Habilita Registro Geral
   
   CCP1CON     = 12;    //00001100 Habilita o modo PWM 
                        //||||||||_Quatro bits define o uso do PWM do CCP1
                        //||||_Dois bit do Duty
                        //||_Não usado
                        
   CCPR1L      = 0;     //Byte mais significativo
 
   T2CON       = 4;     //00000100
                        //||||||||_2 bit prescaler do time 2 = 1
                        //||||||_ bit liga o timer2
                        //|||||_Quatro bit do Postscaler = 1
                        //|_não usado
                        
   PR2         = 49;    //49 calculado para PWM com frequência de 20 Khz


   //Setando o Duty
   //CCPR1L = pwm>>2;   //DUTY(;
   //CCP1CON = (pwm <<4) | 12;

   while(true)     //laço infinito
   {
      ADCON0_GO_DONE = 1;
      while(ADCON0_GO_DONE)//Espera até terminar a conversão analogica para digital  
      valor_adc = ((int16)ADRESH<<8)|(ADRESL); //Formatado a direita
      
      if(!toc) pwm =  valor_adc/5.0895;   //1023/201

      CCPR1L = pwm>>2;                    //Duty
      //CCP1CON = (pwm<<4) | 12;      //dois bits do Duty    
      CCP1CON = (pwm<<4) | 12;
      
      if ( bot1)   st1=false;
      if (!bot1 && st1==false)
      {
           st1=true;
           led = 1 ; //Acende o led1
           if(pwm>=10) pwm=pwm-10;
           if(pwm<=10)pwm=0;
           CCPR1L = pwm>>2;               //Duty
           CCP1CON = (pwm <<4) | 12; //dois bits do Duty            
           toc = true;
           delay_ms(10);
           led = 0 ;
      }
      if ( bot2)   st2=false;
      if (!bot2 && st2==false)
      {
           st2=true;
           led = 1 ; //Acende o led1
           if(pwm<191) pwm=pwm+10;
           if(pwm>=191)pwm=201;
           CCPR1L = pwm>>2;               //Duty
           CCP1CON = (pwm<<4) | 12; //dois bits do Duty          
           delay_ms(10);
           led = 0 ;
      }
      if(!bot1 && !bot2) toc = false;
   }
} text here.

Esquemático do projeto:


PCB - do protótipo.
              O protótipo final ficou conforme a figura a seguir:


Obrigado e até a próxima!

Um comentário :

olá,digite aqui seu comentário!