Frequency Counter Library

Now the library also works for leonardo

#include "FreqCounter.h"

volatile unsigned long FreqCounter::f_freq;

volatile unsigned char FreqCounter::f_ready;
volatile unsigned char FreqCounter::f_mlt;
volatile unsigned int FreqCounter::f_tics;
volatile unsigned int FreqCounter::f_period;
volatile unsigned int FreqCounter::f_comp;

void FreqCounter::start(int ms) {

#if defined (__AVR_ATmega32U4__)

    f_period=ms/2;
    f_ready=0;                  // reset period measure flag
    f_tics=0;                   // reset interrupt counter
  
  
    if (f_comp ==0) f_comp=1;  // 0 is not allowed in del us
	
    // hardware counter setup ( refer atmega32u4)
    TCCR1A=0;                  // reset timer/counter1 control register A
    TCCR1B=0;              	   // reset timer/counter1 control register A
    TCNT1=0;           		   // counter value = 0
	
    // set timer/counter1 hardware as counter , counts events on pin T1 ( arduino leonardo pin 12)
    // normal mode, wgm10 .. wgm13 = 0
    
    TCCR1B |=  (1<<CS10) ;//CLOCK ESTERNO su fronte di salita
    TCCR1B |=  (1<<CS11) ;
    TCCR1B |=  (1<<CS12) ;
    
    // timer0 setup / usato per la generazione del tempo di lettura
    TCCR0A=0;
    TCCR0B=0;
    
    // timer3 presaler set to 256 / timer3 clock = 16Mhz / 256 = 62.500 Hz
    TCCR0B = (1<<CS02); 

    //setta il timer0 to CTC(Clear Timer on Compare)  Mode with OCR3A is top counter value (arrivato a OCR3A si resetta)
	    TCCR0A = (1<<WGM01);  // CTC mode, normal (no Output compare)
	    GTCCR |= (1<<PSRASY);  // reset prescaler (undocumented bit in mega32u4?)
	    TCCR0B = (1<<CS02);  // timer0 on clk/256 == 16MHZ / 256 = 62500hz..
	    OCR0A = 124;  // 125 counts of 62500 Hz before an output compare interrupt...

	    TCNT1 = 0;
	    TCNT0 = 0;

	    TIMSK0 = (1<<OCIE0A);
    #endif
		
}
//******************************************************************
//  Timer3 Interrupt Service is invoked by hardware Timer3 every 1ms = 1000 Hz
//  16Mhz/256/124 = 500 Hz (corretto con il dimezzamento del period)
//  here the gatetime generation for freq. measurement takes place: 
//

ISR(TIMER0_COMPA_vect) {
										// multiple 2ms = gate time = 100 ms
if (FreqCounter::f_tics >= FreqCounter::f_period) {         	
                            			// end of gate time, measurement ready

   										// GateCalibration Value, set to zero error with reference frequency counter
    //  delayMicroseconds(FreqCounter::f_comp); // 0.01=1/ 0.1=12 / 1=120 sec 
    delayMicroseconds(FreqCounter::f_comp);
    TCCR1B = TCCR1B & ~7;   			// Gate Off  / Counter T1 stopped 
    TIMSK0 &= ~(1<<OCIE0A);    			// disable Timer3 Interrupt(timer del gate)
    //TIMSK0 |=(1<<TOIE0);     			// enable Timer0 again // millis and delay
    FreqCounter::f_ready=1;             // set global flag for end count period
    
                                        // calculate now frequeny value
    FreqCounter::f_freq=0x10000 * FreqCounter::f_mlt;  // mult #overflows by 65636
    FreqCounter::f_freq += TCNT1;      	// add counter1 value
    FreqCounter::f_mlt=0;
    
    }
    FreqCounter::f_tics++;            	// count number of interrupt events
    if (TIFR1 & 1) {          			// if Timer/Counter 1 overflow flag
    FreqCounter::f_mlt++;               // count number of Counter1 overflows
    TIFR1 =(1<<TOV1);        			// clear Timer/Counter 1 overflow flag
    }
    
}