frequency counter for Atmega2560

Hi, Nick Gammon

thanks for quick reply

I am using Amega2560 - seeeduino,the code is yours: the code is working perfectly,when I tested, the problem is jumping over one number.
here is the code:

// Timer and Counter example for Mega2560
// Author: Nick Gammon
// Date: 24th April 2012

// input on pin D47 (T5)

// these are checked for in the main program
volatile unsigned long timerCounts;
volatile boolean counterReady;

// internal to counting routine
unsigned long overflowCount;
unsigned int timerTicks;
unsigned int timerPeriod;

void startCounting (unsigned int ms) 
  {

  counterReady = false;         // time not up yet
  timerPeriod = ms;             // how many 1 mS counts to do
  timerTicks = 0;               // reset interrupt counter
  overflowCount = 0;            // no overflows yet

  // reset Timer 2 and Timer 5
  TCCR2A = 0;
  TCCR2B = 0;
  TCCR5A = 0;             
  TCCR5B = 0;  

  // Timer 5 - counts events on pin D47
  TIMSK5 = _BV (TOIE1);   // interrupt on Timer 5 overflow

  // Timer 2 - gives us our 1 mS counting interval
  // 16 MHz clock (62.5 nS per tick) - prescaled by 128
  //  counter increments every 8 uS. 
  // So we count 125 of them, giving exactly 1000 uS (1 mS)
  TCCR2A = _BV (WGM21) ;   // CTC mode
  OCR2A  = 124;            // count up to 125  (zero relative!!!!)

  // Timer 2 - interrupt on match (ie. every 1 mS)
  TIMSK2 = _BV (OCIE2A);   // enable Timer2 Interrupt

  TCNT2 = 0;     
  TCNT5 = 0;      // Both counters to zero

  // Reset prescalers
  GTCCR = _BV (PSRASY);        // reset prescaler now
  // start Timer 2
  TCCR2B =  _BV (CS20) | _BV (CS22) ;  // prescaler of 128
  // start Timer 5
  // External clock source on T4 pin (D47). Clock on rising edge.
  TCCR5B =  _BV (CS50) | _BV (CS51) | _BV (CS52);

}  // end of startCounting

ISR (TIMER5_OVF_vect)
{
  ++overflowCount;               // count number of Counter1 overflows  
}  // end of TIMER5_OVF_vect


//******************************************************************
//  Timer2 Interrupt Service is invoked by hardware Timer 2 every 1ms = 1000 Hz
//  16Mhz / 128 / 125 = 1000 Hz

ISR (TIMER2_COMPA_vect) 
{
  // grab counter value before it changes any more
  unsigned int timer5CounterValue;
  timer5CounterValue = TCNT5;  // see datasheet, (accessing 16-bit registers)

  // see if we have reached timing period
  if (++timerTicks < timerPeriod) 
    return;  // not yet

  // if just missed an overflow
  if (TIFR5 & TOV5)
    overflowCount++;

  // end of gate time, measurement ready

  TCCR5A = 0;    // stop timer 5
  TCCR5B = 0;    

  TCCR2A = 0;    // stop timer 2
  TCCR2B = 0;    

  TIMSK2 = 0;    // disable Timer2 Interrupt
  TIMSK5 = 0;    // disable Timer5 Interrupt

  // calculate total count
  timerCounts = (overflowCount << 16) + timer5CounterValue;  // each overflow is 65536 more
  counterReady = true;              // set global flag for end count period
}  // end of TIMER2_COMPA_vect


void setup () {
  Serial.begin(115200);       
  Serial.println("Frequency Counter");
} // end of setup



void loop () {

  // stop Timer 0 interrupts from throwing the count out
  byte oldTCCR0A = TCCR0A;
  byte oldTCCR0B = TCCR0B;
  TCCR0A = 0;    // stop timer 0
  TCCR0B = 0;    
  
  startCounting (500);  // how many mS to count for

  while (!counterReady) 
     { }  // loop until count over

  // adjust counts by counting interval to give frequency in Hz
  float frq = (timerCounts *  1000.0) / timerPeriod;

  // restart timer 0
  TCCR0A = oldTCCR0A;
  TCCR0B = oldTCCR0B;

  Serial.print ("Frequency: ");
  Serial.println ((unsigned long) frq);
  
  // let serial stuff finish
  delay(200);

}   // end of loop

what I have to modify this code so it can count .. 1,2, 3, 4, 5, 6, 7, 8, instead of 1 , 3, 5, 7, 9 or 2, 4, 6, 8, 10 using signal generator.

thanks