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
}
}