Das ist schonmal schlecht, da Taster prellen.Um die Impulse zu generieren, benutze ich zwei Taster, die jeweils an INT0 und INT1 angeschlossen sind.
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.
Code:$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
Das ist schonmal schlecht, da Taster prellen.Um die Impulse zu generieren, benutze ich zwei Taster, die jeweils an INT0 und INT1 angeschlossen sind.
deswegen deaktiviere ich die Interrupts nach ihrem Auslösen.
Ok, übersehen.
Hier kann man das gut rauslesen: http://www.rn-wissen.de/index.php/Be...mit_RN-Control
öööhm, was genau kann man da rauslesen?
Wenn ich das richtig verstanden habe, geht das mit CTC genauer als mit Timer-Ovf, oder war die Aussage falsch?
Hallo Sheff,
ich verstehe nicht so ganz, wie Du auf den Zähltakt von 10µs kommst und warum Du nur 1s Unterschied beim Stoppen hast.
Im Programm steht $crystal=16000000 und im CONFIG TIMER ein PRESCALER von 8. Damit zählt der TCNT mit 2Mhz. Mit dem Compare1a von 10 errechnet sich die Interruptfrequenz mit: 2Mhz / (1 + 10) = 181818,18... Hz. Das sind 5,5µs Periodendauer.
Bei dem Stoppuhrvergleich über 10s erhälts Du in der Variablen Mikrosek also den Wert von 1818181 , den Du für die Sekundenanzeige durch 100000 teilst - ergibt also 18,18s.
Läuft der µC vielleicht nur mit 8MHz? 8MHz / (8 * (1 + 10)) = 90909,09...Hz - das käme mit ca 11µs näher an deinen angepeilten Wert. In 10s enthält Variable Mikrosek = 909090 -> 909090 / 100000 = 9,09s -> Danach müßte Dir das LCD zuwenig ausgeben oder eben 8s zuviel.
Ich hoffe, daß ich selbst selbst den Timer richtig verstanden habe
Gruß
Searcher
Hoffentlich liegt das Ziel auch am Weg
..................................................................Der Weg zu einigen meiner Konstruktionen
Hallo Searcher,
Ich habe nochmal die Zeit gemessen. Genauer zu sein, ist es eine Sekunde bei 15 Sekunden.
Die Timer/Compare-Einstellungen habe ich auf dieser seite berechnet: http://www.bunbury.de/technik/berech...berechnung.htm
Hallo!
Also das man Compare1A Enablen & Disablen kann, ist mir neu. Ist meinem bescheiden Wissen nach
nur ein Bascom Name für das Compareregister.
1 Sekunde hat meines Wissens 1Million µs.
MfG
Rone
Hi,
ich habe oft gesehen, dass Compare1A mit En-/Disable ein-und ausschalten kann.
Eine Sekunde hat 1Mio. µs - ist richtig.
Ich werde das ganze nochmal mit TimerOVF versuchen und den Preloader anpassen, sodass diese 10 Sekunden auch 10s dauern.
Hallo,
im Mega8 Datenblatt (Atmel doc2486) gibt es auf Seite 111 unter Figur 49 eine Formel zur Berechnung der Ausgangsfrequenz des OC Pins wenn er toggelt. Danach rechnet auch http://www.bunbury.de/technik/berech...berechnung.htm , Zitat: "...welche Comparewerte (CTC-Modus mit Toggle Pin)..."; meiner Meinung nach allerdings mit einem kleinen Fehler.
Du brauchst jedoch nicht die Ausgangsfrequenzfrequenz des OC Pins sondern die Frequenz des Auftretens des Interrupts.
Formel im Datenblatt für Ausgangsfrequenz: Focn = fclk / 2 * N * (1+OCRn)
Die Interruptfrequenz ist doppelt so hoch: Fint = fclk / N * (1+OCRn)
Focn - Ausgangsfrequenz am Pin
fclk - Systemclock (zB 16Mhz oder 8MHz)
2 - Devisor wg. toggle
N - Prescaler
OCRn - Compare Value
Fint - Interruptfrequenz
gewünschte Peridendauer 10µs entspricht Fint von 100000Hz
Formel nach OCRn umgestellt: OCRn = (fclk / N * Fint) - 1
Damit ist muß für 10µs der Compare1a (OCRn) = 19 für Systemtakt 16MHz sein und 9 für 8MHz
Die "1", die da noch subtrahiert wird, kommt wohl daher daß wenn der Timer (TCNT) auf Null steht, einen clk braucht um auf Eins zu kommen. Zwei clks um auf Zwei zu kommen...zehn clks um auf Deinen Comparewert 10 zu kommen - Interrupt wird ausgelöst - ABER nun braucht er einen weiteren clk um wieder auf Null zu kommen!
Hab jetzt nur versucht, den Timer wie ich ihn verstanden habe zu erklären. Alles ohne Gewähr und kann auch nicht sagen ob Dein Programm sonst OK ist, da ich mit ATtiny45 bastele. Weitere Abweichungen müßte man nochmal unter die Lupe nehmen, wenn das mit dem Timer klar ist.
Gruß
Searcher
Hoffentlich liegt das Ziel auch am Weg
..................................................................Der Weg zu einigen meiner Konstruktionen
Lesezeichen