Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] frequency counter using pic16f877a

Status
Not open for further replies.

Qaisar Azeemi

Full Member level 5
Joined
Feb 11, 2011
Messages
315
Helped
16
Reputation
32
Reaction score
15
Trophy points
1,298
Location
Peshawar, Pakistan, Pakistan
Activity points
3,829
HI;
i want to count the pulses using pic16f877a. the pulses are being fed into pin RA4. i want to use timer interrupt for that so that other functions performed by the mico should not disturbed. the frequency is displayed on the LCD Screen.
kindly help me with Mikro C code.

thanking you in anticipation.
 

thank you very much to all for your kind replies. acctually i want to understand the programming. what happend when a pulse of frequency signal reaches at T0CK1 pin of the pic16f877a. will it cause an interrupt??? so should i define interrupt for that? kindly help me with Mikro C code.
 

Several Frequency Counter designs use some variation of this method to 'gate' off the the input to the RTCC (T0CKI) pin and then 'pump' the RTCC (T0CKI) pin to retrieve the counts in the 256:1 prescaler.
Another method for retrieving the 8-bit prescaler value doesn't require any additional PIC pins other than the T0CKI input pin. *This method gates off the input to the T0CKI pin by simply switching the pin from an input to an output then pumps the prescaler until it overflows into the TMR0 register by toggling the TMR0 edge select bit.

https://www.edaboard.com/threads/194212/

In this application, the PIC 16F84A operated as a frequency
counter which can read frequencies from 10 Hz to 30 MHz. It
is used the method of measuring the 24-bits (3-bytes) counter
value from the prescaler, TMR0 (timer 0 module) and some
other registers, such as Option Register. The basic hardware
for the measurement circuit is depicted in Fig. 2. It consists of
the frequency input at TMR0 or TOCKI (pin3 in a PIC
16F84A). This pin is connected to RA3 and the input
frequency is connected to TOCKI through a 470Ÿ resistor.
TMR0 is configured to measured the input frequency, at
RA4 of the PIC 16F84A. The input frequency is “gated” for a
precise duration of time. Before starting this precise “gate”,
TMR0 is cleared and the RA3 pin is configured as an input.
The precise “gate” is implemented in software as an accurate
delay. A 24-bit value of the input frequency is now saved in
TMR0, Registers and 8-bit prescaler. By concatenating the
calculated value and the original value from TMR0 (256-N),
the 24-bit value for the frequency is determined.
 

Attachments

  • Implementation_of_Digital_Frequency_Counter.pdf
    408.2 KB · Views: 122

please check my Mikro c code. it is not woking:

Code:
//Timer 0 will count and Timer 1 will measure 1 second time using interrupts ; mikro=16f877a
// OUTPUTS

#define led PORTB.F2 // simple blinking led to show the system is working

sbit LCD_RS at RD5_bit;
sbit LCD_EN at RD4_bit;
sbit LCD_D4 at RC4_bit;
sbit LCD_D5 at RC5_bit;
sbit LCD_D6 at RC6_bit;
sbit LCD_D7 at RC7_bit;

sbit LCD_RS_Direction at TRISD5_bit;
sbit LCD_EN_Direction at TRISD4_bit;
sbit LCD_D4_Direction at TRISC4_bit;
sbit LCD_D5_Direction at TRISC5_bit;
sbit LCD_D6_Direction at TRISC6_bit;
sbit LCD_D7_Direction at TRISC7_bit;
//=======End LCD Connections=============================================
unsigned int x=0,frq=0, cnt=0;

void interrupt()
{
     if(PIR1.TMR1IF)
     {
       T1CON.TMR1ON=0;  //stop
       TMR1L=0XEE;     // <------------- reload the timer
       TMR1H=0X85;


        if(cnt>=4)
        {
           led=~led;
	   frq=1;
           cnt=0;
           x=tmr0;
	   tmr0=0;
        }



        //frq=1;
       PIR1.TMR1IF=0;  // <------------- clear the timer interrupt flag
     }



}

void main()
{
        OPTION_REG=0xA0;  // for timer 0; NO presscaller; counter mode at T0CKI
	T1CON=0X60;  // 1:8 prescallar, timer off
	ADCON1=0x07;   // adc reg initialization  ; changes port a to digital I/O
	INTCON=0x80;       // globle interrupt enabled
	TMR1L=0xEE;
	TMR1H=0x85;
	T1CON.TMR1ON=1; // timer on
	PIR1.TMR1IF=0;
	TRISA.f4=1;// making ra4 as input


        x=0;
	frq=0;
  lcd_init();
  Lcd_Cmd(_LCD_CLEAR);                    // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);
  Lcd_Cmd(_LCD_MOVE_CURSOR_RIGHT);      //*/

   Lcd_Out(1,1,"Frequency");
	 while(1)
	{
	  if(frq==1)
	  {
	    Lcd_Out(2,2,X);
	    Lcd_Out_CP("Hz");
	    frq=0;
	   }
	}

}
 

please see my code again i am stuck in a new issue now. acctually i wana measure the frequency of input power sine wave which is 50hz here in south of asia. i am counting the pulses using timer 0 at t0cki input, these pulses increment tmr0 register which is after every one second due to interrupt of timer 1 is made 0 to take counts for next pass ... it should count 50 to display but instead it counts 12... here is the code..

Code:
//Timer 0 will count and Timer 1 will measure 1 second time using interrupts ; mikro=16f877a
// OUTPUTS

#define led PORTB.F2

sbit LCD_RS at RD5_bit;
sbit LCD_EN at RD4_bit;
sbit LCD_D4 at RC4_bit;
sbit LCD_D5 at RC5_bit;
sbit LCD_D6 at RC6_bit;
sbit LCD_D7 at RC7_bit;

sbit LCD_RS_Direction at TRISD5_bit;
sbit LCD_EN_Direction at TRISD4_bit;
sbit LCD_D4_Direction at TRISC4_bit;
sbit LCD_D5_Direction at TRISC5_bit;
sbit LCD_D6_Direction at TRISC6_bit;
sbit LCD_D7_Direction at TRISC7_bit;
//=======End LCD Connections=============================================
unsigned int frq=0, cnt=0;
unsigned short G=0;
unsigned char op[12];

void interrupt()
{
     if(PIR1.TMR1IF)
     {
       T1CON.TMR1ON=0;  //stop
       TMR1L=0XEE;     // <------------- reload the timer
       TMR1H=0X85;
         cnt++;

        if(cnt>=4)
        {
           led=~led;
	   frq=1;
           cnt=0;
           G=tmr0;
	   tmr0=0;
        }



        //frq=1;
       PIR1.TMR1IF=0;  // <------------- clear the timer interrupt flag
       T1CON.TMR1ON=1;
     }



}

void main()
{
        OPTION_REG=0xA0;  // for timer 0; NO presscaller; counter mode at T0CKI
	T1CON=0X60;  // 1:8 prescallar, timer off
	ADCON1=0x07;  // adc reg initialization  ; changes port a to digital I/O
	INTCON=0xc0;       // globle & prephral interrupt enabled
	TMR1L=0xEE;
	TMR1H=0x85;
	PIR1.TMR1IF=0;
	PIE1.TMR1IE=1;
	T1CON.TMR1ON=1; // timer on

	TRISA.f4=1;// making ra4 as input
        TRISB.f2 = 0;  //o/p
        
        cnt=0;
        G=0;
	frq=0;
  lcd_init();
  Lcd_Cmd(_LCD_CLEAR);                    // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);
  Lcd_Cmd(_LCD_MOVE_CURSOR_RIGHT);      //*/

   Lcd_Out(1,1,"Frequency");
	 while(1)
	{
	  if(frq==1)
	  { 
	   shortToStr(G,op);
           Lcd_Out(2,2,op);
	   Lcd_Out_CP("Hz");
	   frq=0;
	   }
	}

}
 

Did you converted input from sinewave to sqarewave digital level in hardware?
 

Did you use this circuit? http://embedded-lab.com/blog/wp-content/uploads/2011/03/FrequencyPreamp.jpg

This is causing the problem.

Code:
void interrupt()
{
     if(PIR1.TMR1IF)
     {
       T1CON.TMR1ON=0;  //stop
       TMR1L=0XEE;     // <------------- reload the timer
       TMR1H=0X85;
         cnt++;

        if(cnt>=4)
        {
           led=~led;
	   frq=1;
           cnt=0;
           G=tmr0;
	   tmr0=0;
        }



        //frq=1;
       PIR1.TMR1IF=0;  // <------------- clear the timer interrupt flag
       T1CON.TMR1ON=1;
     }



}

Your timer will we OFF when you are doing this
Code:
  if(cnt>=4)
        {
           led=~led;
	   frq=1;
           cnt=0;
           G=tmr0;
	   tmr0=0;
        }

You have to give input to RC0/T1OSO/T1CKI pin 15 and not to pin T0CKI (Timer0) because you are using Timer1.
Your T1CON settings are wrong.
 
Last edited:

You have to use i2c or spi external eeprom like 24LC or 25LC series eeprom and use i2c or spi library and write the code.

Thanks you for your response unfortunately my program is very long it is not fitting in the memory of my pic and this is the first time I am gonna using external EEPROM in ccs;can you plz sample for me
 

I don't know CCS and I don't know whether you can store program in external memory and run the PIC from accessing ext. memory. Data can be stored in external memory. Choose a PIC with more memory.
 

push buton in ccs c compiler and PIC16F877A (for loop and if conditional statements)

hello every body can somebody help me to use the push button below:

see the codes;I am reading the frequency on pic T1CKI and then from that frequency and arrays created I display numbers 7.1%,7.2%,7.3%.............basing on the frequency read;I come out by displaying those percantage but I want them to be displayed after using a push button on pin_c4 of PIC16F877A can you plz help me to handle the issue;I am using to simulate in proteus but nothing comes out.
See the codes:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <16F877A.h>
#DEVICE ADC=10
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include "lcd.c"
#define ARRAY_SIZE 7
 
 
int search,i,vals,found;
float value1,value;
float l;
  
 const float k[]={100,121,125,156,256,350,352};
 const float j[]={410,420.5,450.6,485.2,600.5,854.6,905.8};
 
  int main(void)
{
   set_tris_c(0xff);
 set_tris_b(0x00);
 
  while(1)
 {
 lcd_init();
 delay_us(200);  
 
      set_timer1(0);   
      setup_timer_1(t1_external | T1_DIV_BY_1);
      delay_ms(1000);         
      setup_timer_1(T1_DISABLED);
      value=get_timer1();  
      
     value1=value;
if(input(PIN_C4)!=1)
 {
   for ( i =0,found=-1;i <ARRAY_SIZE ; i++)
   
   if((value1<= j[i])&&(k[i]<=value1))
    
     {  
      
      l=(0.1*i)+7.0;
printf(lcd_putc,"\f%2.1d", i);
 delay_ms(3500);
 printf(lcd_putc,"\f%2.1f", l);
 printf(lcd_putc,"\%%");
 delay_ms(3500);
      
 
 }  
}
}



Help me plz those if are not working.
 
Last edited by a moderator:


Hello Tahmid,can you plz help me to understand why on your blog of SPWM generation for
TBL_POINTER_SHIFT = TBL_POINTER_NEW >>8;with that value of shifting less than 8 the simulation shows error even in implementation the signal are not very nice like the one you posted on your blog??
 

Hello Tahmid,can you plz help me to understand why on your blog of SPWM generation for
TBL_POINTER_SHIFT = TBL_POINTER_NEW >>8;with that value of shifting less than 8 the simulation shows error even in implementation the signal are not very nice like the one you posted on your blog??

All that is explained in this tutorial:

Demystifying The Use of Table Pointer in SPWM - Application in Sine Wave Inverter
https://tahmidmc.blogspot.com/2013/02/demystifying-use-of-table-pointer-in.html

Hope this helps.
Tahmid.
 

All that is explained in this tutorial:

Demystifying The Use of Table Pointer in SPWM - Application in Sine Wave Inverter
https://tahmidmc.blogspot.com/2013/02/demystifying-use-of-table-pointer-in.html

Hope this helps.
Tahmid.

I read it but now I have a problem I want to control the H_Bridge with 20KHz but its generation I decided imossible because I am not coming to get but the calculations I did I refered to your blog and I think that I am right with;can you plz help me to get that value of 20KHz?
Also the signal of C and D on your circuit me I am getting the difference to it can you help me to know where the error is.(when I generate other signals not 20KHz I am getting a signal different to what you posted).

Help plz.
 

I read it but now I have a problem I want to control the H_Bridge with 20KHz but its generation I decided imossible because I am not coming to get but the calculations I did I refered to your blog and I think that I am right with;can you plz help me to get that value of 20KHz?
Also the signal of C and D on your circuit me I am getting the difference to it can you help me to know where the error is.(when I generate other signals not 20KHz I am getting a signal different to what you posted).

Help plz.

To adjust the frequency, you need to adjust the value of PR2. What is the clock frequency at which you are running the PIC?

What difference do you get? Can you post a screenshot or image of the waveform?
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top