As stated in my comment, your code is kind of fine. Id mostly works, but it looses a few microseconds on each iteration. If you are looking at multi-kHz frequencies, you probably want to avoid loosing microseconds. The solution is simple: never reset the counter. I changed you ISR as follows:
uint16_t previous_counter;
void pin_ISR(){
uint16_t counter = TCNT1;
f = 2000000/(counter - previous_counter);
previous_counter = counter;
}
and now it gives the correct frequency... on average. There are some variations though, dues mostly to delays caused by other interrupts.
Edit: If you want to avoid the fluctuations caused by other interrupts, your best bet is probably to use the input capture feature of Timer 1.
- 45.1k
- 4
- 42
- 81