Frequency counter


Closed Thread
Results 1 to 5 of 5
  1. #1

    Question Frequency counter

    Hello,

    Has anyone played around with using a PIC as a frequency counter? I have the Analog/Digital part with the attenuator + divide by 1000 prescaler figured out. I want a usable range of 1kHz to 100MHz, in increments of 1kHz steps. I am using a serial 2 x 20 LCD.

    If I use COUNT for 1 sec

    low end 1kHz/1000 = 1 count per second
    high end 100,000,000 Hz/ 1000 = 100,000 counts per second

    I have not figured out how to scale and display the values such that I get for example a read out :
    10.001.000 Mhz or 10.111.000 Mhz

    Is there a better way of doing the above stated? Any info would be appreciated.

    Nick

  2. #2
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default

    Hi Nick,

    The Timer 0 module is capable of counting signals up to about 50-MHz in asynchronous counter mode so you could probably get away with a single "divide by 2" prescaler in front of the T0CKI input if you want to use that counter for a 100-MHz input signal. An input gate "on" time of 20-msecs would provide 100 Hz counter resolution. An input gate "on" time of 200-msecs would provide 10-Hz resolution. You would need 24 bits to hold the 0..1,000,000 input counts (20-msec gate/100-Hz resolution) or to hold the 0..10,000,000 input counts (200-msec gate/10-Hz resolution). You would pull the least significant 8 bits from the 1:256 Timer 0 prescaler, the middle 8 bits from the TMR0 register, and the most significant 8 bits from a TMR0 "overflow" variable. With a 50-MHz input to Timer 0 (100-MHz divided by 2) and using a 1:256 Timer 0 prescaler, you can expect a TMR0 register overflow approximately once every 1.31 msecs so you would want to check for TMR0 register overflow at least that often during input gate "on" time.

    Does that help? I've got assembler code for a Serial 12F683 50-MHz counter but I'm not sure that would be of any help to anyone here on the PBP forum.

    Happy Holidays!

    Cheerful regards, Mike

  3. #3


    Did you find this post helpful? Yes | No

    Default

    Hello Mike,

    Thanks for the reply, I think I need to think about your post. I haven't thought about using the PIC hardware, also I need to wrap my head around how to make sense of the 24bit payload. I will be asking questions soon..lol.

    Nick

  4. #4
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default

    Hi Nick,

    Using the PIC hardware instead of a "divide by 1000" external prescaler would allow for more frequent LCD updates. Would that be an advantage for your application?

    Here's one way I thought about implementing a frequency counter in a HLL (BoostC in this case). I might use periodic 1-msec timer 2 interrupts to check for TMR0 register overflow and gate the counter on or off every 200 msecs by toggling the T0CKI data direction pin. Timer 0 would alternate between counting for 200-msecs or being idle for 200-msecs.

    Extracting the 8-bit timer 0 prescaler value and adding it to the 24 bit result is tricky. After T0CKI has been set to an output (gate 'off') we pulse the timer 0 edge select bit (in option_reg) which bumps the prescaler and we decrement the CountL byte until the prescaler overflows into the TMR0 register.

    Maybe something like this;

    Code:
    ;
    ;  unsigned char msctr = 200;   //
    ;  unsigned char CountL = 0;    //
    ;  unsigned char CountH = 0;    //
    ;  unsigned char CountU = 0;    //
    ;  unsigned long result = 0;    //
    ;
    ;  void interrupt()             // 1-msec TMR2 interrupts
    ;  { pir1.TMR2IF = 0;           // clear TMR2 interrupt flag
    ;    msctr--;                   // decrement 200-msec timer
    ;    if(msctr == 0)             // if end of 200-msec interval
    ;    { trisio.0 ^= 1;           // toggle GP2/T0CKI direction
    ;      msctr = 200;             // reset 200-msec timer
    ;    }
    ;    if(intcon.T0IF)            // if TMR0 overflow
    ;    { CountU++;                // bump b23..b16 byte
    ;      intcon.T0IF = 0;         // clear the overflow flag
    ;    }                          //
    ;  }
    ;
    ;  void main()                  //
    ;  { init();                    // initialize
    ;    while(1)                   // main.loop
    ;    { while(trisio.2 == 1);    // while 200-msec gate "on"
    ;      CountH = tmr0;           // result b15..b8 bits
    ;      do                       // extract the prescaler bits
    ;      { option_reg.T0SE = 1;   // pulse TMR0 edge select bit
    ;        option_reg.T0SE = 0;   // to increment the prescaler
    ;        CountL--;              // adjust b7..b0 result bits
    ;      } while(tmr0 == CountH); // until overflow into TMR0
    ;      result = CountU * 65536; // build 24-bit result
    ;      result += CountH * 256;  //
    ;      result += CountL;        //
    ;      PutResult();             // put result on LCD
    ;      CountU = 0;              // prep for next count cycle
    ;      CountH = 0;              //
    ;      CountL = 0;              //
    ;      while(trisio.2 == 0);    // while 200-msec gate "off"
    ;    }                          //
    ;  }
    ;
    Last edited by Mike, K8LH; - 11th December 2010 at 14:08.

  5. #5
    Join Date
    Sep 2003
    Location
    INDIA
    Posts
    161


    Did you find this post helpful? Yes | No

    Default Re: Frequency counter

    Would it be very difficult to measure upto 40Mhz with reasonable accuracy using PBP and 16F628. Has anyone tried it. There are lots of design on the net using F84, but I would like to try it out in PBP.

    regards

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts