Fork me on GitHub

Microcontrolandos

O Blog está passando por uma fase de mudanças. Todos os posts estão sendo atualizados, códigos, links e imagens estão sendo arrumados. Conteúdos novos ainda estão por vir.

Frequencimetro com PIC16F628A

Share:

Frequencímetro com PIC16F628A



Um outro projeto de frequencímetro, mas este utiliza o modo de captura do módulo CCP. Esse é o melhor método para se medir frequência. Através desse método, você programador consegue fazer a leitura do tempo de nível alto e/ou baixo com uma alta precisão, e com isso conseguir medir a frequência.

Nesse projeto, é feito a leitura do período e do duty cycle do sinal, e é calculado a frequência.

DOWNLOAD:
Projeto: Frequencimetro.zip

CóDIGO-FONTE:
/*
  *Projeto: Frequencimetro
  *MCU: PIC16F628A
  *Clock: INTOSC 4MHz
  *Descrição: Atraves do modulo CCP, faz a leitura do periodo, duty cycle e
              frequencia de um sinal.
  *Compilador: MikroC PRO PIC
  *Autor: Tiago H. Melo
*/

//Configuração dos pinos
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D7 at RB2_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D4 at RB6_bit;

// Configuração da direção dos pinos
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D7_Direction at TRISB2_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB6_bit;

char conta[16], *res;
bit capturaOK;
unsigned long t1, t2, duty;
unsigned long Periodo, Frequencia, DutyCycle;
char pulso = 0,cnt=0;

void interrupt()
{
    if(PIR1.CCP1IF == 1)
    {
    if(pulso == 0)
    {
     t1 = (CCPR1H << 8) + CCPR1L;//captura o tempo1(dutyCycle e periodo)
     pulso = 1;
     CCP1CON.F0 = ~CCP1CON.F0; //a proxima captura é por borda de descida
    }
    else if(pulso == 1)
    {
     duty = (CCPR1H << 8) + CCPR1L;//captura o fim do dutyCycle
     pulso = 2;
     CCP1CON.F0 = ~CCP1CON.F0; //a proxima captura é por borda de subida
    }
    else if(pulso == 2)
    {
     t2 = (CCPR1H << 8) + CCPR1L;//captura o tempo2(fim do periodo)
     TMR1H=0;TMR1L=0;
     pulso = 0;
     capturaOK = 1;
     cnt++;
    }
    
    PIR1.CCP1IF = 0;
    }
}

void main()
{
    //configura o timer1
    T1CON = 0B00000001; //prescaler 1:1, clock interno
    TMR1H=0;
    TMR1L=0;
    
    //configura o CCP
    CCP1CON = 0b00000101;//modo captura por borda de subida
    TRISB.F3 = 1;
    
    PIE1.CCP1IE = 1;//habilita interrupção do modulo CCP
    INTCON.GIE = 1; //habilita interrupcao global
    INTCON.PEIE = 1;//habilita interrupcao dos perfericos

    //Inicializa o LCD
    Lcd_Init();
    Lcd_Cmd(_LCD_CLEAR);
    Lcd_Cmd(_LCD_CURSOR_OFF);
    


while(1)
{
   if(capturaOK && cnt > 100)
   {
    CCP1IE_Bit = 0; //desabilita a interrupcao do CCP
    Periodo = (t2 - t1); //Periodo em us
    longtostr(Periodo, conta);
    res = LTrim(conta); //remove o espaço a esquerda
    lcd_out(1,1,"P: ");
    lcd_out_CP(res);
    lcd_out_CP("us ");
    
    DutyCycle = (duty - t1);//DutyCicle em us
    longtostr(DutyCycle, conta);
    res = LTrim(conta);
    lcd_out_CP("DC: ");
    lcd_out_CP(res);
    lcd_out_CP("us  ");

    Frequencia = 1000000/ Periodo;
    longtostr(Frequencia, conta);
    res = LTrim(conta);
    lcd_out(2,1,"F: ");
    lcd_out_CP(res);
    lcd_out_CP("Hz");

    capturaOK = 0;
    cnt=0;
    CCP1IE_Bit = 1; //habilita a interrupcao do CCP
   }
}
}



50 comentários:

  1. boa noite Thiago este Frequencímetro se eu quiser medir a frequencia da rede elétrica é so liga o pino 9 na rede

    ResponderExcluir
    Respostas
    1. Se você fizer isso, vai queimar seu microcontrolador.
      Você deve converter a onda senoidal da rede em uma onda quadrada equivalente de 5V. Veja nesse site o equema do circuito. Alimente este circuito com 5V. Mas antes voce deve reduzir a tensao da rede, antes de ligar no circuito.

      Excluir
  2. Frequências a partir de 30 Hz pra baixo não funciona...

    ResponderExcluir
    Respostas
    1. Posso te ajudar a medir até 1Hz com algumas modificações de código que uso em um projeto, se quiser me dá um toque.

      Excluir
    2. Olá Viтөя_βөѕѕ, poderia compartilhar como fez para medir outras frequencias também com este frequencímetro?
      A alteração que realizou também consegue medir acima de 10Khz, que parece ser o limite deste?
      Obrigado.

      Excluir
    3. Claro Fabio, como posso enviar o código? Para frequencias maiores que 10KHz é necessário um divisor, posso te enviar um projeto com tais modificações

      Excluir
    4. Caso não for lhe incomodar, e seja permitido informar emails neste espaço: fami171 no hotmail.
      Obrigado Vitor

      Excluir
    5. Fabio, tentei adicionar divisores de frequencia porém o circuito perde a habilidade de medir o duty da onda, posso te enviar o codigo para medir até 1Hz?

      Excluir
    6. Olá Vitor,
      Pode sim, claro...
      Apesar que eu encontrei um codigo bastante interessante também, e parece funcionar bem... caso queria ve-lo, a titulo de curiosidade: moty22.co.uk/lcd_counter.php

      Obrigado.

      Excluir
    7. Ola Vitor, me passe o código para ler frequência de 1 a 20 Hz

      Excluir
    8. Olá Vitor...vc poderia me passar este código que lê frequencias baixas? Preciso fazer um afinador de guitarra. Se puder me envie: douglasnigri@gmail.com

      Muito Obrigado.

      Excluir
    9. Faz muito tempo que escrevi o código, eu perdi o original mas tenho gravado na memória(cérebro) vou reescrever e te mando.

      Excluir
  3. Thiago como faço para abrir o projeto e ver o desenho da placa?

    ResponderExcluir
  4. como faço na programação para em vez de usar um lcd, usar apenas dois display de 7 segmentos?

    ResponderExcluir
  5. Boa tarde eu gostaria medir 220v 50 a 60 hz e gostaria de acionar um rele quando a frequencia passar de 55 hz, e quando dimunuir desligar o rele , teria como fazer isso neste projeto? Obrigado

    ResponderExcluir
  6. ola boa tarde, nao consigo compilar. da erro, algem pode mim ajudar?

    ResponderExcluir
  7. Também não consigo compilar 78 324 Undeclared identifier 'LTrim' in expression

    ResponderExcluir
    Respostas
    1. tem que habilitar a biblioteca Conversions do MikroC PRO PIC 6.x

      Excluir
    2. Já habilitei,mas verifiquei no help da versão que estou usando o Mikroc Pro v1.65 só existem as opções

      Library Routines


      ByteToStr
      ShortToStr
      WordToStr
      IntToStr
      LongToStr
      LongWordToStr
      FloatToStr

      alguma alternativa?

      Excluir
  8. Tiago,
    Pretendo utilizar o módulo CCP para ler duas frequências diferentes (CCP1 e CCP2) e estou com dificuldades. Pelo que entendi os dois usam como base de tempo o TIMER1 e isto esta me complicando um pouco. Tem como vc dar uma ajuda aí?

    ResponderExcluir
  9. Primeiramente parabéns pelo blog e conteúdo... que é excelente!

    É possível realizar o mesmo mas em um PIC 12F629?
    Sem o display, é claro, devido a quantidade menor de pinos.
    Eu gostaria de apenas verificar se a frequência é maior que X, ligar um LED em um pino, por isso a escolha por um PIC menor e mais barato, visto que utilizarei apenas 2 pinos do PIC.

    Eu tentei alterar as informações do PIC no mikroC, mas parece que o 12F629 não possui os modulos CCP, é isso mesmo? Não é possível utilizá-lo?

    Obrigado.

    ResponderExcluir
    Respostas
    1. Olá, muito obrigado!
      Para este projeto optei por utilizar o modulo CCP, mas voce pode utilizar apenas o timer1 para contar o numero de pulsos e calcular a frequencia, assim poderá utilizar o PIC12F629.

      Excluir
  10. amigo e seu eu mudar o CCP1CON = 0b00000110. = prescaler 1:4, oq mudaria a mais no codigo ?

    ResponderExcluir
  11. Amigo preciso medir frequencias de 1 a 150hz e duty de 1a100% bem rapido achei esse projeto lento demais.

    ResponderExcluir
    Respostas
    1. Mude a linha "if(capturaOK && cnt > 100)" para um numero menor que 100, e acrescente esta linha :"cnt = 97; //Usa 3 clocks para primeira medição, útil para baixas freq." logo após a linha "Lcd_Cmd(_LCD_CURSOR_OFF);". Isso deu certo para mim

      Excluir
    2. Fora o citado acima vc tb pode substituir as 3 ultimas linhas por esse código:

      capturaOK = 0;
      if(Frequencia <= 10)
      cnt = 96;
      else if(Frequencia <= 100)
      cnt = 60;
      else
      cnt = 0;
      CCP1IE_Bit = 1;

      Excluir
  12. Tiago H. Melo, fiz um upgrade no código e virtualizei o timer para 32bits gerando uma medição melhor para baixas frequências e mostra o duty em %. Gostaria de compartilhar com a galera, teria como criar um outro post com o código?

    ResponderExcluir
    Respostas
    1. Opa, seria bem legal. Envie-me por email.

      Muito obrigado por estar respondendo os comentários.
      Abraços,

      Excluir
    2. Ola, compartilhe comigo este seu upgrade para ler baixas frequencia.
      sergiocarvalho_ol@hotmail.com

      Excluir
    3. por favor eu também gostaria deste código lucasdanili@yahoo.com.br

      Excluir
    4. Thiago, já faz bastante tempo que te enviei um convite do Google+ mas não consigo achar seu endereço de e-mail. Aos que vão pedindo estou enviando.

      Excluir
  13. Meu irmao tiago mande para meu email o arquivos atulizado que vc cita arquivo c e o hex doumingueira@gmail.com desde ja muito obrigado que Deus abençoe

    ResponderExcluir
  14. boa noite alguem pode dizer qual a frequencia minima e maxima?

    ResponderExcluir
    Respostas
    1. pelo que vi do projeto, a frequência mínima é 30 Hz e a máxima 10kHz. Isso porque utilizando o o modo de captura, você ganha precisão, mas precisa trabalhar em sincronismo com o PIC cujo o Clock máximo é de 4MHz. É possível medir frequências de até 50MHz utilizando o TMR1 em modo assíncrono. No meu site eu explico como fazer. www.dnail.org

      Excluir
  15. Oi amigo, tinha como modificar pra medir frequencia dentro de um limite entre 70 a 120khz, vai ser pra usar como detector de metais, onde a frequencia varia de acordo com o metal proximo a bobina osciladora.

    ResponderExcluir
  16. Viтөя_βөѕѕ™ Por favor envie o código para ler baixas Frequências pra mim testar email:carlosb.firmeware@hotmail.com

    ResponderExcluir
    Respostas
    1. Blz Viтөя_βөѕѕ™,muito obrigado mesmo testei hoje no Proteus show de bola fico feliz de ter amigos aqui obrigado mesmo jhow

      Excluir
  17. Tiago boa noite ! tudo bem ?
    Gostaria de saber se é possível implementar dois frequencímetros no mesmo microcontrolador, ou mesmo alterar esse código para essa finalidade.

    Att

    ResponderExcluir
  18. Boa noite Viтөя_βөѕѕ™ e Thiago
    Testei na pratica em baixas Frequências ficou legal será que seria possível a frequencia aparecer em tempo real porque ele demora um minuto mais ou menos para
    aparecer no lcd vou tenta mudar no código alguma coisa mas gostei Pois funciona
    mesmo.

    ResponderExcluir