Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PINGUINO32 High accuracy 80MHz frequency meter
01-01-2013, 10:12 PM,
#1
PINGUINO32 High accuracy 80MHz frequency meter
Hi


Starting from the sample code available here I wrote a simple frequency meter program using the wonderful PINGUINO32-MICRO board.

Using TMR4 as base time (1 second) and TMR1 as pulse counter I got a precise 80MHz frequency meter with a few lines of code.
The biggest problem encountered, as explained here, is with TMRx=0 operation which introduce big counting errors, to avoid problems I removed all these operations.

In this sample program TMR1 and TMR4 have the same 80MHz peripheral clock source, in this manner the oscillator drift error is 0 and the measured error is due only to program delays.
This max error is about +-2 count on 80.000.000 pulse count, about +-0.025ppm.

To transform the program in a real frequency meter is only necessary decomment the line //T1CONSET=0x8002; in init_timer1 function, at this point the pin P31 (Conn1.1) becomes the input clock of TMR1.






Code:
/*-----------------------------------------------------
Author:  Manzini Moreno
Date: 01/01/2013
Description:
Easy frequency meter which measure Peripheral clock fixed at 80MHz with Pinguino32
For measure external clock on P31 (Conn1.1) pin use T1CONSET=0x8002; instead of T1CONSET=0x8000; in init_timer1 function
Max internal error about +- 2 count +- 0,025ppm

01/01/2013 Ver. 1 Rev. 0 c. Moreno Manzini ( moreno at mediacom dot it )

Licence Creative Commons 3.0 http://creativecommons.org/licenses/by-sa/3.0/
  
Interrupt routines inspired to http://blog.pinguino.cc/?p=225

-----------------------------------------------------*/


#include <interrupt.c>




#define NumSample100mS 10 //1Sec total




unsigned int CounterO=0;
unsigned int VCounterRes=0;
unsigned int TmpCounterRes=0;
unsigned int VCounterO=0;
unsigned int TmpCounterO=0;
unsigned int CtnPulse100mS=0;
unsigned int PrevRes=0;
unsigned int ActRes=0;

DWORD   Frequency;



// Put the ISR_wrapper in the good place
void ISR_wrapper_vector_4(void) __attribute__ ((section (".vector_4")));

// ISR_wrapper will call the Tmr1Interrupt()
void ISR_wrapper_vector_4(void) { Tmr1Interrupt(); }

// TMR1 Overflow Interrupt Function
void Tmr1Interrupt(void) __attribute__ ((interrupt));



// Put the ISR_wrapper in the good place
void ISR_wrapper_vector_16(void) __attribute__ ((section (".vector_16")));

// ISR_wrapper will call the Tmr1Interrupt()
void ISR_wrapper_vector_16(void) { Tmr4Interrupt(); }

// TMR1 Overflow Interrupt Function
void Tmr4Interrupt(void) __attribute__ ((interrupt));




// TMR1 Overflow Interrupt Function
void Tmr1Interrupt(void)
{
if (IFS0bits.T1IF)        // Timer Interrupt flag
    {
     IFS0CLR=0x10;        // Clear the timer interrupt flag
     CounterO++;           // increment the CounterO
    }
}



// TMR1 Init Function
void init_timer1(void)
{
IntConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);    // interrupt mode (interrupt.c)
T1CON=0;             // reset timer 1 configuration
TMR1=0;                 // reset timer 1 Counter register (VERY DANGEROUS OPERATION USE ONLY AT INIT TIME)
PR1=0x0FFFF;          // define the preload register
IPC1SET=0x7;          // select interrupt priority and sub-priority
IFS0CLR=0x10;        // clear interrupt flag
IEC0SET=0x10;        // enable timer 1 interrupt
T1CONSET=0x8000;    // start timer 1 and set prescaler to 1 internal clock
// decomment to measure external clock on P31 (Conn1.1) I/O pin
//T1CONSET=0x8002;    // start timer 1 and set prescaler to 1 external clock
}



// TMR4 Overflow Interrupt Function
void Tmr4Interrupt(void)
{
TmpCounterRes = TMR1;
TmpCounterO = CounterO;
if (IFS0bits.T4IF)        // Timer Interrupt flag
    {
     IFS0CLR=0x10000;        // Clear the timer interrupt flag
     CtnPulse100mS++;        // increment the CounterO
   if (CtnPulse100mS >= NumSample100mS)
    {
     VCounterRes = TmpCounterRes;
     PrevRes = ActRes;
     ActRes = TmpCounterRes;
     VCounterO = TmpCounterO;
     CounterO = 0;
     CtnPulse100mS = 0;
      }
  }
}



// TMR4 Init Function
void init_timer4(void)
{
IntConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);    // interrupt mode (interrupt.c)
T4CON=0;                    // reset timer 4 configuration
TMR4=0;                        // reset timer 4 Counter register (VERY DANGEROUS OPERATION USE ONLY AT INIT TIME)
PR4=31250-1;                 // define the preload register
IPC4SET=0x7;                 // select interrupt priority and sub-priority
IFS0CLR=0x10000;            // clear interrupt flag
IEC0SET=0x10000;            // enable timer 4 interrupt
T4CONSET=0x8070;          // start timer 4 and set prescaler to 256
}



void setup()
{
System.setCpuFrequency(80000000); // should be 80 MHz
System.setPeripheralFrequency(80000000); // should be 80 MHz

init_timer1();
init_timer4();
}



void loop()
{
Frequency = VCounterO;
Frequency *= 65536;
Frequency += VCounterRes;
Frequency -= PrevRes;
CDC.printf("Freq= %u Hz , OvF= %d , Cnt= %d , Res= %d\n\r",Frequency,VCounterO,VCounterRes,PrevRes);    
delay(1000);
}


Happy new year!!!!

Bye Bye, Moreno
Reply
21-05-2013, 06:57 AM,
#2
RE: PINGUINO32 High accuracy 80MHz frequency meter
(01-01-2013, 10:12 PM)moreno Wrote: Hi, Moreno,
Thank you very much for the code, that I was looking for a long time!
It could be compiled with IDE x.4 without any problems. And the program works fine, the PINGUINO Micro will be embedded into an older 145 Mc transceiver (homemade), with a prescaler.
I let the frequency show with a character- LCD (2 lines).
Thanks from Wolfgang Kiefer (DH1AKF)
Reply
21-05-2013, 01:13 PM,
#3
RE: PINGUINO32 High accuracy 80MHz frequency meter
Hi

I'm happy that you enjoyed my program.


Bye Bye, Moreno
Reply
27-05-2013, 06:57 AM, (This post was last modified: 27-05-2013, 07:05 AM by ted051.)
#4
Video  RE: PINGUINO32 High accuracy 80MHz frequency meter
Hi all,
my Pinguino now counts 140 MHz without prescaler. The testsignal comes from a SI570 chip, is formed by an emitter- stage (2SC3355) and goes to IDE-pin 31 (T1CK). The 100- Hz digit is stable in this configuration.
With shorter connections I hope to get 146 MHz.
Best regards, Wolfgang


Attached Files Thumbnail(s)
   
Reply
27-05-2013, 09:09 AM,
#5
RE: PINGUINO32 High accuracy 80MHz frequency meter
What's the xtal frequency tolerance?

John
Reply
27-05-2013, 10:17 AM,
#6
RE: PINGUINO32 High accuracy 80MHz frequency meter
It's a non specified, no name quartz. I measured 79,9951 instead of 80 MHz, that means -61 ppm. With a correction factor you can get more precious results...
Reply
27-05-2013, 01:41 PM,
#7
RE: PINGUINO32 High accuracy 80MHz frequency meter
Only if you have a very accurate frequency measuring device. And if yu have then it's slightly odd to want the one on here!

I also wonder what the effect of varied temperature is on the xtal.

Overall, this strikes me as a good but not especially accurate way to measure frequency.

John
Reply
27-05-2013, 04:42 PM, (This post was last modified: 27-05-2013, 06:14 PM by moreno.)
#8
RE: PINGUINO32 High accuracy 80MHz frequency meter
Hi

If you need more accuracy is very easy replace the quartz with a TCXO like this http://it.rs-online.com/web/p/oscillator.../6758770P/ with a 2,5ppm stability on a wide range of temperature.
You reach the top with OCXO like this http://it.rs-online.com/web/p/oscillatori/7293331/ with 0,2ppm stability but is very expensive and require a divider by 5 to obtain 8MHz.


For normal use, the accuracy of the standard quartz in more than sufficient.


I do not know exactly the frequency limits of the counter, 80MHz is the minimum, normally is around 2 time the frequency clock, about 160MHz.
If you have the possibility, make some test to see which are the real limit of the counter frequency.


Bye Bye, Moreno
Reply
12-06-2013, 10:06 PM, (This post was last modified: 12-06-2013, 10:08 PM by ted051.)
#9
RE: PINGUINO32 High accuracy 80MHz frequency meter
    Hi all,
with a new design, away from simple breadboard to a board with hole grid and soldered wires, the Pinguino Micro reached 148 MHz with constant 100 Hz jitter. Important is the good rectangle input signal, and short wires too.
Higher frequencies up to 160 MHz could also be measured, but with a loss of accuracy.
Reply
13-06-2013, 08:17 AM, (This post was last modified: 13-06-2013, 08:42 AM by moreno.)
#10
RE: PINGUINO32 High accuracy 80MHz frequency meter
Hi

WOW!!!! 148MHz is about the double of the frequency clock, Microchip produce great microprocessors.

P.S. With the latest release of PINGUINO32 was introduced the use of MIPS which reduce the code size.
This forces to restructure the interrupt definitions, more info here


Bye Bye, Moreno
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)