I've done this at my telemetry transmitter ( Telemetrie Sender ).
Look here:
**broken link removed**
Sourcecode:
**broken link removed**
I've done this with with INT1 Interrupt routine there and not in the ICP.
The rotation relevant parts are:
//Count Pulses to avoid overflow
// External Interrupt 1 service routine Drehzahlmesser impulseingang
interrupt [EXT_INT1] void ext_int1_isr(void)
//Count Up the Overflow Counters of Timer 0
// Timer 0 overflow interrupt service routine Drehzahlmesser Pulsdauermessung
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
That Part middles the Values over one second:
// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
This Part Calculates the rpm with entire values on 8MHz Controller clock:
Code:
if (ui_drpulses<3) /* Drehzahlen unter 120 U/min werden ignoriert */
{
li_drehzahl=0;
}
else
{
if (ui_drpulses<350) /* Entscheidung welches Drehzahlermittlungsverfahren angewendet wird bei 21000 U/min*/
{
li_drmittel=li_drmittel/uc_stellen; /* Mittelwert der Drehzahlmessungen errechnen */
li_drehzahl=7500000/(li_drmittel*uc_blatt); /* Periodendauermessung */
}
else
{
li_drehzahl=ui_drpulses; /* Pulszählung in Torzeit ( 1Sekunde )*/
li_drehzahl=(li_drehzahl*60)/uc_blatt;
}
}
ui_drpulses=0; /* Pulszählung zurücksetzen */
li_drmittel=0; /* Mittelwertbildner zurücksetzen */
uc_stellen=0; /* Stützstellenzähler zurücksetzen */
That are the Settings for Initialisation:
Code:
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
TCCR0=0x03;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
// CTC Mode : On
TCCR1A=0x00;
TCCR1B=0x0A;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0xC3;
OCR1AL=0x4F;
OCR1BH=0x00;
OCR1BL=0x00;
...
// External Interrupt(s) initialization
// INT0: Off
// INT0 Mode: Falling Edge
// INT1: On
// INT1 Mode: Falling Edge
GICR|=0x80;
MCUCR=0x0A;
GIFR=0xC0;
That routine works only at >120rpm. You should correct the parameters for your application.