Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

reading frequency using pic16f877a

Status
Not open for further replies.
Hi all;
i want to measure the frequency of a sin wave passed through HEF4093BE NAND gate Schmitt trigger to be furnished and this frequency is feeded into pin RA2 of PIC16F877A; and from this pin i want to read the frequency. i made the following code for that purpose but instead of reading the frequency it is counting the numbers with a very high speed i think with the clock speed of my 4MHz crystal. plz analyze my code and tell me the mistake. (NOTE: i don't want to use counter pins).

Here are frequency related parts of my code to make it understandable for you.

Code:
void interrupt()
{
     if(PIR1.TMR1IF==1)
     {
        
        frq=1;

     }
}

void main()
{

ADCON1=0x06;   // adc reg initialization
INTCON=0xA0;  // for timer0  ; interrupt reg initilization

 TRISA = 0xFF;     // port A as input

      Lcd_Cmd(_LCD_CLEAR);                    // Clear display
      Lcd_Cmd(_LCD_CURSOR_OFF);
      Lcd_Cmd(_LCD_MOVE_CURSOR_RIGHT);
      Lcd_Out(1,1,CopyConst2Ram(msg,fv));   // Write text in first row
    
      
     T1CON.TMR1ON=0;
     PIR1.TMR1IF=0;
     TMR1L=0XEE;    // value loaded for 1 second delay.
     TMR1H=0X85;
              j==1;
              frq=0;
              while(j==1)
              {
                         while(G_freq==1)
                            {G++;}
                            
                                    IntToStr(G,string);
                                    Lcd_Out(2,2,string);
                                    Lcd_Out_CP("Hz");
                            
                         if(mains==P)
                         {j=0;}
                         
                         if(frq==1)
                         {
                             k++;
                             T1CON.TMR1ON=0;
                             PIR1.TMR1IF=0;
                             TMR1L=0XEE; // value loaded for 1 second delay.
                             TMR1H=0X85;
                                if(k=4)
                                  {
                                    IntToStr(G,string);
                                    Lcd_Out(2,2,string);
                                    Lcd_Out_CP("Hz");
                                    Delay_ms(1000);
                                    G=0;
                                    k=0;
                                   }
                             T1CON.TMR1ON=1;
                             frq=0;
                         }
              }
}
where
Code:
#define genr PORTA.F0
#define mains PORTA.F1
#define G_freq PORTA.F2

const char fv[] = "Frequency  Volts";
unsigned char frq=0;
unsigned int j=1,G=0,k=0;
 
if(k=4)
what the above statement is for?

And what is the error you are facing is it logical or compilation?
 
Last edited:
sorry i have modified it to

if(k==4)
It is for creating one second delay.

I am facing logical error. Compilation is OK.

i want to measure the frequency at pin RA2 of PIC16f877a.

the code with little modification is:

Code:
  while(j==1)
              {
                             if(G_freq==0)    // true at high pulse
                            {
                              G++;
                              while(G_freq==1);   // wait untill pulse is high
                            }
                            
                                //   IntToStr(G,string);
                                //   Lcd_Out(2,2,string);
                                //   Lcd_Out_CP("Hz");

                         if(mains==P)
                         {j=0;}
                         
                         if(frq==1)
                         {
                             k++;
                             T1CON.TMR1ON=0;
                             PIR1.TMR1IF=0;
                             TMR1L=0X00;
                             TMR1H=0X00;
                                if(k==5)
                                  {
                                      l2=~l2;
                                    IntToStr(G,string);
                                    Lcd_Out(2,2,string);
                                    Lcd_Out_CP("Hz");
                                   // Delay_ms(1000);
                                   // G=0;
                                    k=0;
                                   }
                             T1CON.TMR1ON=1;
                             frq=0;
                         }
                         l2=0;
}

where l2 is for another LED indicating the timer is runnig and creating 1sec delay .
 
Last edited:
void interrupt()
{
if(PIR1.TMR1IF==1)
{

frq=1;

}
}

when the interrupt will get executed when the timer overflow interrupt occurs..
And your timer is only running when the frq=1... the intial value of frq is 0....
And one more thing you have not cleared the timer interrupt flag also....
 
void interrupt()
{
if(PIR1.TMR1IF==1)
{

frq=1;

}
}

when the interrupt will get executed when the timer overflow interrupt occurs..
And your timer is only running when the frq=1... the intial value of frq is 0....
And one more thing you have not cleared the timer interrupt flag also....

1)the interrupt will get executed when timer is role over after each 1/4th of a second.

2)no; on execution of interrupt. it will just go and set frq and go back to the while routine and off the timer, display the value of G which is frequency, clear G and K and frq variables and turn the timer ON again.

3)i have cleared it in while routine.
 
Sorry Qaisar but that is a terrible (not accurate) way to get a 1 second gated period. There are many "PIC frequency meter" projects on the net, most with source code and Microchip appnotes on making a PIC16 frequency meter.

With a 4MHz xtal you have 1MHz timers, so to make 1 second you need to count exactly 1 million ticks. One easy way is to set the TMR2 PR2 to a period of 250 ticks;
PR2 = (250 - 1);

And then the TMR2 interrupt will occur exactly every 250 ticks. So 1 miilion ticks is 4000 interrupts exactly.
 
Sorry Qaisar I have not seen that you have already cleared the interrupt after execution.
And if it is having the static 0Hz display means may be your value of G is not changing...
 
Status
Not open for further replies.

Latest threads

Back
Top