5Volt-Junkie
07.03.2011, 17:49
Hallo,
ich habe folgendes vor:
Ich möchte mit einem ATmega8, die Zeit zwischen zwei Impulsen messen.
Um die Impulse zu generieren, benutze ich zwei Taster, die jeweils an INT0 und INT1 angeschlossen sind.
Quasi: Taster1 drücken => Stoppuhr starten => Taster2 drücken => Zeit stoppen und auf dem Display ausgeben. Ich würde gerne die Zeit auf die Mikrosekunde genau messen können :) Aber erst mal, mache ich das mit 10µs-Interrupt.
Warum so eine genaue Messung?
Die beiden Taster werden später durch Lichtschranken ersetzt und 6 Zoll von einander befestigt, um die Schussgeschwindigkeit einer Paint zu messen, die bis zu 100 m/s schnell fliegen kann oder auch bis zu 50 m/s langsam sen kann. :)
Statt Timer-Overflow benutze ich CTC-Modus, weil mir OVF hatte ich irgendwie Probleme.
Das aktuelle Programm habe ich mit einer Stopp-Uhr getestet und bei 10 Skeunden, bekomme ich auf dem LCD, eine Sekunde zu viel. :(
Kann mir da vielleicht jemand helfen?
Werde sehr dankbar sein. ;)
$regfile = "m8def.dat"
$crystal = 16000000
'================================================= ==============================
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
Initlcd
Cursor Off Noblink
Cls
'Interrupt-Pins konfigurieren===================================== =================================
On Int0 Timerstart 'Start-Taster an INT0
On Int1 Timerstopp 'Stop-Taster an INT1
Ddrd = &B00000000 'PortD als Eingang
Portd = &B11111111 'Pull-Ups von Int0 und Int1 einschalten
Mcucr = &B00001010 'Interrupt bei H/L-Flanke
Gicr = &B11000000 'Interrupts INT0 und INT1 einschalten
Sreg.7 = 1 'Interrupts freigeben
'================================================= ==============================
'Timer-Konfiguration===================================== =======================
Config Timer1 = Timer , Prescale = 8 , Clear Timer = 1 'Timer1 konfigurieren
Stop Timer1
'Comparewert auf 16000 setzen
On Compare1a Zaehle 'Interruptroutine für den Compare-Modus aktivieren
Enable Compare1a 'Compare-Modus aktivieren
Enable Interrupts 'Interrupts aktivieren
'================================================= ==============================
Dim Mikrosek As Long 'Mikrosek als Word
Dim Milisek As Single 'Milisekunden als Single, optional
Dim Sekunden As Single 'Milisekunden als Single
Mikrosek = 0
Milisek = 0
Sekunden = 0
'================================================= ==============================
Do
Loop
End
'Interrupt-Routine fuer INT0============================================== =====================
Timerstart:
Enable Interrupts 'Interrups einschalten
Compare1a = 10 'Compare-Wert
Enable Compare1a 'CTC einschalten
Mikrosek = 0 'Mikrosekunden auf 0 setzen
Start Timer1 'TIMER1 starten
Return 'Interrupt-Routine -Timerstart- verlassen
'Interrupt-Routine fuer INT1============================================== =====================
Timerstopp:
Disable Interrupts 'Interrupts ausschalten
Disable Compare1a 'Compare-Modus AUS
Stop Timer1 'TIMER1 anhalten
Sekunden = Mikrosek / 100000 'Mikrosekunden in Sekunden umrechnen
'Ausgabe auf dem LCD
Cls
Locate 2 , 1
Lcd "Sek "
Lcd Sekunden
Locate 1 , 1
Lcd "mikro "
Lcd Mikrosek
Waitms 3000
'Werte wieder auf 0 Setzen
'Milisek = 0
Mikrosek = 0
Sekunden = 0 'Interrupt-Routine -Timerstopp- verlassen
Return
'Interrupt-Routine bei Erreichen des Compare-Wertes
Zaehle:
Incr Mikrosek 'Mikrosekunden um 1 erhoehen
Return
ich habe folgendes vor:
Ich möchte mit einem ATmega8, die Zeit zwischen zwei Impulsen messen.
Um die Impulse zu generieren, benutze ich zwei Taster, die jeweils an INT0 und INT1 angeschlossen sind.
Quasi: Taster1 drücken => Stoppuhr starten => Taster2 drücken => Zeit stoppen und auf dem Display ausgeben. Ich würde gerne die Zeit auf die Mikrosekunde genau messen können :) Aber erst mal, mache ich das mit 10µs-Interrupt.
Warum so eine genaue Messung?
Die beiden Taster werden später durch Lichtschranken ersetzt und 6 Zoll von einander befestigt, um die Schussgeschwindigkeit einer Paint zu messen, die bis zu 100 m/s schnell fliegen kann oder auch bis zu 50 m/s langsam sen kann. :)
Statt Timer-Overflow benutze ich CTC-Modus, weil mir OVF hatte ich irgendwie Probleme.
Das aktuelle Programm habe ich mit einer Stopp-Uhr getestet und bei 10 Skeunden, bekomme ich auf dem LCD, eine Sekunde zu viel. :(
Kann mir da vielleicht jemand helfen?
Werde sehr dankbar sein. ;)
$regfile = "m8def.dat"
$crystal = 16000000
'================================================= ==============================
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
Initlcd
Cursor Off Noblink
Cls
'Interrupt-Pins konfigurieren===================================== =================================
On Int0 Timerstart 'Start-Taster an INT0
On Int1 Timerstopp 'Stop-Taster an INT1
Ddrd = &B00000000 'PortD als Eingang
Portd = &B11111111 'Pull-Ups von Int0 und Int1 einschalten
Mcucr = &B00001010 'Interrupt bei H/L-Flanke
Gicr = &B11000000 'Interrupts INT0 und INT1 einschalten
Sreg.7 = 1 'Interrupts freigeben
'================================================= ==============================
'Timer-Konfiguration===================================== =======================
Config Timer1 = Timer , Prescale = 8 , Clear Timer = 1 'Timer1 konfigurieren
Stop Timer1
'Comparewert auf 16000 setzen
On Compare1a Zaehle 'Interruptroutine für den Compare-Modus aktivieren
Enable Compare1a 'Compare-Modus aktivieren
Enable Interrupts 'Interrupts aktivieren
'================================================= ==============================
Dim Mikrosek As Long 'Mikrosek als Word
Dim Milisek As Single 'Milisekunden als Single, optional
Dim Sekunden As Single 'Milisekunden als Single
Mikrosek = 0
Milisek = 0
Sekunden = 0
'================================================= ==============================
Do
Loop
End
'Interrupt-Routine fuer INT0============================================== =====================
Timerstart:
Enable Interrupts 'Interrups einschalten
Compare1a = 10 'Compare-Wert
Enable Compare1a 'CTC einschalten
Mikrosek = 0 'Mikrosekunden auf 0 setzen
Start Timer1 'TIMER1 starten
Return 'Interrupt-Routine -Timerstart- verlassen
'Interrupt-Routine fuer INT1============================================== =====================
Timerstopp:
Disable Interrupts 'Interrupts ausschalten
Disable Compare1a 'Compare-Modus AUS
Stop Timer1 'TIMER1 anhalten
Sekunden = Mikrosek / 100000 'Mikrosekunden in Sekunden umrechnen
'Ausgabe auf dem LCD
Cls
Locate 2 , 1
Lcd "Sek "
Lcd Sekunden
Locate 1 , 1
Lcd "mikro "
Lcd Mikrosek
Waitms 3000
'Werte wieder auf 0 Setzen
'Milisek = 0
Mikrosek = 0
Sekunden = 0 'Interrupt-Routine -Timerstopp- verlassen
Return
'Interrupt-Routine bei Erreichen des Compare-Wertes
Zaehle:
Incr Mikrosek 'Mikrosekunden um 1 erhoehen
Return