In this tutorial we will learn how to make digital frequency counter using PIC Micrcontroller. The frequency meter measure the frequency 3Hz up to 1KHz. Here I am use PIC16F877A Micrcontroller and Mikro C pro for PIC Compiler of code editing.

You can watch the video or read the written tutorial below.






PIC16F877A Micrcontroller has three Timer Module. In this project I am use Timer1 module. Timer1 module can be operate two mode.
 

  1. Timer Mode
  2. Counter Mode

In this project Timer1 module operate in counter mode. The counter count internal or external pulses.

Here  counter use internal pulse counter. The Timer1 module is 16-bit . it has two register pair(TMR1H : TMR1L).

 

 

Ther Timer1 module increment in internal clock pulse at pulse time of external signal.

 

The pulse timer is Ton. The Timer1 module increment on Ton Time of Pulse Generator signal. 

Calculate:
       
               Oscilator Frequency = 8MHz
               Internal clock Frequency = 8MHz / 4 = 2MHz
               Prescaler value = 1:8
               Timer1 value = (TMR1H : TMR1L)  = (TMR1H<<8) | (TMR1L)

               1second ,Timer1 count pulses =  ((8MHz / 4) / 8) /
                                                              = 250000

               1ms , Timer1 count pulses = 125000/1000
                                                          = 250

              assume,
                          Pulse Generator Frequency = 1KHz
                          T = 1ms
                           T = Ton + Toff,     Ton = Toff
                           Ton = (1 / 2)ms
                                 = 0.5ms

            Ther Timer1 count internal pulse at Ton time of Pulse Generator.
                          Ton = T / 2
             
              0.5ms, Timer1 count pulses = 250 / 2
                                                          = 125

             thence,
                         Timer Period of Pulse Generator signal = pulses / 125 ms







Circuit Diagram:

 

Project Code

// lcd module connections
sbit LCD_RS at RC0_bit;
sbit LCD_EN at RC1_bit;
sbit LCD_D4 at RC2_bit;
sbit LCD_D5 at RC3_bit;
sbit LCD_D6 at RC4_bit;
sbit LCD_D7 at RC5_bit;

sbit LCD_RS_Direction at TRISC0_bit;
sbit LCD_EN_Direction at TRISC1_bit;
sbit LCD_D4_Direction at TRISC2_bit;
sbit LCD_D5_Direction at TRISC3_bit;
sbit LCD_D6_Direction at TRISC4_bit;
sbit LCD_D7_Direction at TRISC5_bit;
// end lcd module connections
int pulse = 0;
int frequency = 0;
float timer;
char text[15];
void interrupt(){
     if(INTCON.RBIF ==1){
                    INTCON.RBIE = 0;  // Disable the port change interrupt
                    if(PORTB.F4==1){
                                    T1CON.TMR1ON = 1;
                                    }
                                 
                    if(PORTB.F4==0){
                                    T1CON.TMR1ON = 0;       // Stop timer1
                                    pulse = ((TMR1H<<8)|(TMR1L));
                                    TMR1H = 0;
                                    TMR1L = 0;
                                    }

                    }
     INTCON.RBIE = 1;      // Enable the port change interrupt
     INTCON.RBIF = 0;

     }
void main() {
     Lcd_Init();
     Lcd_Cmd(_LCD_CLEAR);
     Lcd_Cmd(_LCD_CURSOR_OFF);
     Lcd_Out(1,3,"Frequency");
     Lcd_Out(2,3,"Measurement");
     delay_ms(2000);
     Lcd_Cmd(_LCD_CLEAR);
     Lcd_Out(1,3,"Developed by");
     Lcd_Out(2,1,"MINA TECHNOLOGY");
     delay_ms(2000);
     Lcd_Cmd(_LCD_CLEAR);
     INTCON.RBIE = 1;
     TRISB = 0X10;
     PORTB = 0X00;
     INTCON.GIE = 1;            // Enable global interrupt
     INTCON.RBIF = 0;         // Clear the port change interrupt flag


     INTCON.RBIE = 1;         // Enable port change interrupt
     TMR1CS_bit  = 0;
     T1SYNC_bit = 1;
     T1CKPS0_bit = 1;
     T1CKPS1_bit = 1;
     TMR1ON_bit = 1;
     TMR1H = 0;
     TMR1L = 0;
     timer = 0;
     while(1){

              timer = pulse / 125.00;  // 125.0 is Timer1 count pulses at Ton time of input signal
              frequency = 1000/timer ;
              if(frequency>0){

                          intTostr(frequency,text);
                          text[6] = 0;
                          Lcd_Out(1,1,"frequency:");
                          Lcd_Out(2,1,text);
                          Lcd_Out(2,7,"Hz");
                          }
               else if(frequency<0){
                                    Lcd_Cmd(_LCD_CLEAR);
                                    }
              delay_ms(500);
              }

}

 

 

 

Download free source code

 

download