Wenn deine Kiste nicht grade ne Magnetozündung hat (wo ich mir den Signalabgriff schwierig vorstelle), geht es im Prinzip so wie Jacko sagt.
Wenn das Ding ein Polrad hat, was ich annehme, sollte es am einfachsten mit einem Magnetfeldsensor machbar sein.
Das Teil läuft mit 5V und Angst wegen vagabundierender Hochspannung braucht man auch nur wenig haben, es sei denn man legt die Signalleitungen direkt neben das Zündkabel.
Zum Thema Codeschnipsel:
Zuerst die beiden Interruptroutinen zur Ermittlung der Drehzahlen:
Code:
/* Turn registers saving off */
#pragma savereg-
// External Interrupt 1 service routine Drehzahlmesser impulseingang
interrupt [EXT_INT1] void ext_int1_isr(void)
{
new_drimp=1;
#asm
PUSH r26
IN r26,SREG
PUSH r26
PUSH r27
;*** Erste Phase der Drehzahlermittlung mittels Timerabfrage = Periodendauermessung ***
IN r26,TCNT0 ;Aktuelle Zeit holen
LDS r27,(_li_oldtimer) ;Vorherigen Wert holen
STS (_li_oldtimer),r26 ;Vorheriger alten Wert überschreiben
SUB r26,r27 ;Unterschied berechnen
STS (_li_drwert),r26 ;Die berechnung als Wert abspeichern
LDS r26,(_li_timer+1) ;Das gleiche für die 2te Stelle _li_timer+1 ist der überlauf des TCNT0
LDS r27,(_li_oldtimer+1)
STS (_li_oldtimer+1),r26
SBC r26,r27
STS (_li_drwert+1),r26
LDS r26,(_li_timer+2) ;Das gleiche für die 3te Stelle
LDS r27,(_li_oldtimer+2)
STS (_li_oldtimer+2),r26
SBC r26,r27
STS (_li_drwert+2),r26
LDS r26,(_li_timer+3) ;Das gleiche für die 4te Stelle
LDS r27,(_li_oldtimer+3)
STS (_li_oldtimer+3),r26
SBC r26,r27
STS (_li_drwert+3),r26
;*** Zweite Phase der Drehzahlermittlung mittels Pulszählung ***
LDS r26,(_ui_intpulses)
INC r26
STS (_ui_intpulses),r26
BRNE ENDINT1
LDS r27,(_ui_intpulses+1)
INC r27
STS (_ui_intpulses+1),r27
ENDINT1:
POP r27
POP r26
OUT SREG,r26
POP r26
#endasm;
}
// Timer 0 overflow interrupt service routine Drehzahlmesser Pulsdauermessung
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
#asm
PUSH r26
IN r26,SREG
PUSH r26
LDS r26,(_li_timer+1)
INC r26
STS (_li_timer+1),r26
BRNE ENDINT0
LDS r26,(_li_timer+2)
INC r26
STS (_li_timer+2),r26
BRNE ENDINT0
LDS r26,(_li_timer+3)
INC r26
STS (_li_timer+3),r26
ENDINT0:
POP r26
OUT SREG,r26
POP r26
#endasm
}
/* re-enable register saving for the other interrupts */
#pragma savereg+
Nun der Teil der für die Sekundenzählung ( Torzeit ) und Mittelung der Drehzahlimpulse zuständig ist.
Code:
// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
/* 1 Sekunde */
ui_timer++;
if (new_drimp>0)
{
li_drmittel+=li_drwert; /* Aufaddierung für Drehzahlmittelwertbildung */
uc_stellen++; /* Aufaddierung der Stützstellen */
new_drimp=0; /* Neue Drehzahl Flag löschen*/
};
if (ui_timer>19)
{
ui_drpulses=ui_intpulses;
ui_intpulses=0;
ui_timer=0;
new_sec=1;
uc_overflow++;
}
}
Nun die Berechnung der Drehzahl
Code:
//Drehzahlermittlung
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 */
Und die dazugehörige Timer initialisierung
// 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;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x11;
Die Routine arbeitet mit beiden möglichen Messmethoden und schaltet ab 350 Impulsen pro Sekunde ( ~21000 U/min ) zwischen den beiden Berechnungsverfahren um.
Der Controller läuft mit einem externen 8MHz Quarz.
Lesezeichen