High Frequency Counter with a 10Mhz PIC

Discussion in 'Embedded Systems and Microcontrollers' started by adam555, Nov 1, 2014.

  1. adam555

    Thread Starter Active Member

    Aug 17, 2013
    858
    39
    Hi,

    I'm trying to make a Frequency Counter with a PIC running at 10 Mhz, but I can't get it to pass the 700 KHz. I found a couple of websites that claim to have achieved up to 80 Mhz with the same type of MCU, but they don't offer the source code to see how they've done it.

    I would appreciate any help, advice or suggestions; or if anyone could direct me towards or explain the technique that I need to use it would be great.

    In my code I'm already using interrupts and as few lines as possible; with Timer 0 tracking the time between the signal pulses through Timer 1.

    Thanks in advance for your help,

    Code (Text):
    1. void interrupt myISR() // Called on any interrupt
    2. {
    3.     //      TMRxIE Overflow Interrupt enable
    4.     //      TMRxIF Overflow Flag bit
    5.     if(INTCONbits.TMR0IE && INTCONbits.TMR0IF)
    6.     {
    7.         count+=256;
    8.         INTCONbits.TMR0IF = 0; // clear the flag
    9.     }
    10.  
    11.     if(PIE1bits.TMR1IE && PIR1bits.TMR1IF)
    12.     {
    13.         frequency=(count+TMR0)*4;
    14.         count=TMR0=0;
    15.  
    16.         PIR1bits.TMR1IF = 0; // clear the flag
    17.     }
    18. }
     
    Last edited: Nov 1, 2014
    KLillie likes this.
  2. atferrari

    AAC Fanatic!

    Jan 6, 2004
    2,644
    759
    Go to PIClist. There is a design there which is a classic.

    Search also something like "PIC" "MONDO". Hay muchos .
     
  3. Art

    Distinguished Member

    Sep 10, 2007
    785
    61
    You can prescale the signal coming in with decade counters, I don't see how it's possible to read a faster freq than the pic is running when you think about it.
     
  4. MrChips

    Moderator

    Oct 2, 2009
    12,410
    3,353
    You need to say which PIC. Does the PIC timer module have a direct pulse counting input?
     
  5. NorthGuy

    Active Member

    Jun 28, 2014
    602
    120
    Your code isn't important much because it only runs once per 256 pulses. Some of the timers might be run in 16-bit mode, or you can use pre-scaler.

    The counter is synchronous. I think it samples twice per instruction cycle - at 5MHz, so you should be able to get reasonable results up to 1.5-2MHz. But it can be only once, then your limit is 0.7-1MHz.

    80MHz is absolutely out of the reach unless external dividers are used.
     
  6. jjw

    Member

    Dec 24, 2013
    173
    31
    50Mhz frequency counter has been done with 4Mhz PIC16F84.
    Input to timer0, that has fast ~50Mhz prescaler.
    Microchip AN592
    http://f6csx.free.fr/PROJETS/Fmetre/AN592.pdf
     
  7. adam555

    Thread Starter Active Member

    Aug 17, 2013
    858
    39
    I'm using a PIC16F88 with the prescaler at 1:8; which is the maximum for Timer 1. I can't use the 1:256 from Timer 0 because I have its interrupt tracking the input pulses directly through the ToCKI pin.

    I'm also running the PIC at 8 Mhz, which is the maximum I can get from the internal clock, as I don't have a single extra I/O pin to free and attach a 20 Mhz crystal.
     
  8. NorthGuy

    Active Member

    Jun 28, 2014
    602
    120
    I was wrong. The built-in pre-scaler is asynchronous, so you can get to higher frequncies. However, data sheet for your PIC states that the shortest detectable period for Timer0 is 20 ns (assuming 50% duty cycle), which translates to 50MHz. If duty cycle is not 50%, then it's less than 50MHz.

    However, the timer's sampling rate is 4MHz if you run your PIC at 8MHz (2MIPS), so at the very best you can detect after-prescaler frequencies up to 2MHz (in practice it's about 1.2MHz or so). Multipled by 8 (1:8 prescaler), this gives you about 10MHz. To get full theoretical 50MHz you will need at least 1:64 prescaler.
     
  9. adam555

    Thread Starter Active Member

    Aug 17, 2013
    858
    39
    I'm looking for a way to change the input pulse to Timer 1 and use Timer 0 as the timer; since Timer 1 only has a 1:8 prescaler and Timer 0 can go up to 1:256. But this is proving more difficult than I thought, since I have all the I/O pins already allocated to some other function.

    I have some doubts whether or not increasing the prescaler will achieve better results. The reason I'm saying this is because if I change the prescaler down -tried 1:4 and 1:2 instead of 1:8- I don't see any difference; I still get up to 700Khz when in theory I should get worse results. The only noticeable change is a worse resolution at lower frequencies.

    What did improve the counter was increasing the clock from 4Mhz to 8Mhz. At the beginning with 4Mhz I could only read up to 400Khz; now with 8Mhz the top is around 750Khz.
     
  10. Art

    Distinguished Member

    Sep 10, 2007
    785
    61
    Nice :)
    I have an issue now where it would be nice to count faster than the pic is running.
    but it's to keep track of hardware PWM but I'm probably already out of timers.
     
  11. atferrari

    AAC Fanatic!

    Jan 6, 2004
    2,644
    759
    What precission does it ensure?
     
  12. takao21203

    Distinguished Member

    Apr 28, 2012
    3,577
    463
    some years ago I have done a counter with a 16F54- clocked with an IF transformer coils, so maybe 1MHz.

    Then I used 18.0 Mhz CXO as reference, and turned the screw until the display matched.

    Its easy, cheap and works with almost all PICs. Most PICs have an interrupt which you can use to detect overflow. Even easier. Some 18F PICs can run at 40 MHz, some 8bit PICs at 32, PIC 32 run at 50, 80, 100 or 200 MHz, but of course its a problem to route signals with more than 30 MHz.
     
  13. NorthGuy

    Active Member

    Jun 28, 2014
    602
    120
    If the pre-scaler is asynchronous then its operations should be independent of the CPU clock.

    What kind of signal do you get? Is it regular? What duty cycle?
     
  14. adam555

    Thread Starter Active Member

    Aug 17, 2013
    858
    39
    Just reached 2Mhz!!!

    I tried switching Timer0 and Timer1 (using the first as timer and the second as input for the signal), and on top of getting a really bad resolution at low frequencies, I was back again to the 400Khz barrier.

    However, when I mounted it back to the original configuration -with Timer0 for the signal input and Timer1 as timer- I misplaced a 100k resistor and used it in series between the signal and the T0CKI pin; which prevented me from passing 500Khz. Tried without resistor, as I didn't even remember what that resistor was even doing there, and same result. Then I remember that in the original design I used it as a pull-down resistor. So, I began trying with different resistors and found that with 10k I can get up to 2Mhz.

    From this point I'm not sure the signal will be clear enough; as I have it all on a breadboard and I always had problems when passing over 2Mhz (e.g. the amplitud begins to drop, the square wave begins to curve, and so on).

    I'm using the PDO output of the MAX038, which is a +5v 50% duty cycle square wave.
     
    Last edited: Nov 2, 2014
  15. takao21203

    Distinguished Member

    Apr 28, 2012
    3,577
    463
    Code (Text):
    1.  
    2. if(INTCONbits.TMR0IE && INTCONbits.TMR0IF)
    3. {
    4. count+=256;
    5. INTCONbits.TMR0IF = 0; // clear the flag
    6. }
    Code (Text):
    1. if(TMR0IF){count++;TMR0IF=0;}
    later

    Code (Text):
    1. if(count==0xff){count_2++;count=0;}
    2. if(count_2==0xff){count_3++;count_2=0;}
    you can increase resolution with changing the prescaler, but using other than 8 bit variables in the interrupt routine isnt adviseable. You dont need to check the IE bit, as IF is raised anyway; just no INT is caused.
     
  16. NorthGuy

    Active Member

    Jun 28, 2014
    602
    120
    Must be something circuit related - stray iductivity, capacitance, noise, that sort of thing. Stick them both next to each other.
     
  17. adam555

    Thread Starter Active Member

    Aug 17, 2013
    858
    39
    I think I found the problem...

    As you increase the frequency, the quality of the PDO output from the MAX038 drops. I took some pictures to explain it more accurately:

    This is a picture of the outputs at 100Khz and without drop down resistor. The top signal is from the regular output, and the one on the bottom is from the PDO. Notice how the falling edge begins to curve (it was meant to be a square wave exactly like the one on the top).

    WP_20141103_001.jpg

    And this one is at 1Mhz, also without drop down resistor. At this frequency it already looks more like a triangular wave than a square wave.

    WP_20141103_002.jpg

    However if I add a drop down resistor up to a minimum of 10k I can sort of stretch it as in this picture. The higher the resistor value the less effective.

    WP_20141103_003.jpg

    But if I go under 10k this is what I get. It won't reach 5v, so the PIC will not detect the signal.

    WP_20141103_004.jpg

    I can't use the normal output because that one is not a DC digital 5v, it's an AC 2v peak to peak. So I was wondering: is there anything I can do to improve the quality of the PDO square wave?

    Edit: I took those pictures with just the oscilloscope connected to the PDO.
     
    Last edited: Nov 3, 2014
  18. NorthGuy

    Active Member

    Jun 28, 2014
    602
    120
    You rise time is around 2us, and the fall time is even worse. Looks like you have some sort of capacitive load (parallel strips of breadboard?) or series inductance (long winding wires?).
     
  19. takao21203

    Distinguished Member

    Apr 28, 2012
    3,577
    463
    The statement breadboard rows and long wires can cause 2uS rise time is quite a stretch.

    You'd see some effects starting to kick in above 30 MHz.

    10 MHz - 100nS
    30 MHz - 33nS

    How about a schematic / picture of the whole circuit?
     
  20. NorthGuy

    Active Member

    Jun 28, 2014
    602
    120
    Yes, this is a long stretch :)

    You would need 100K resistor followed by two parallel breadoard strips (10pF) to damage transitions like that. Must be something else.
     
Loading...