was hastn fürn quarz???
Martin
(dieser Text steht hier wegen den 30 Zeichen min.)
Hallo, ich weiß es gibt hier schon viele Threads zu diesem Thema aber ich werd daraus irgendwie nicht schlau.
Ich habe einen Taster an einer Drehenden Achse, der jede Umdrehung einen Impuls gibt. Jetzt möchte ich eigentlich nur wissen wieviele Impulse es in einer bestimmten Zeit gibt. Die Impulse zähle ich mit einer Schleife, ohne Interrupts da die Drehzahl sehr gering ist. Nun bräuchte ich eine Sub Routine die immer nach einer bestimmten Zeit (jede Sekunde würde schon reichen) aufgerufen wird, die Umdrehungen speichert und wieder auf Null setzt. Aber wie mache ich das mit dem Timer?
Hab mit den Timern jetzt schon viel rumprobiert aber irgendwie funktioniert das bisher noch nicht...
Kann mir da bitte nochmal jemand helfen?
was hastn fürn quarz???
Martin
(dieser Text steht hier wegen den 30 Zeichen min.)
Linus Torvalds, Entwickler von LinuxIch will Microsoft wirklich nicht zerstören. Das wird nur ein gänzlich unbeabsichtigter Nebeneffekt sein.
Also um genau zu sein, brauchst du nur einen Timer, der jede Sekunde einen Interrupt auslöst, oder?
In der Interruptroutine wird dann der zuvor gespeicherte Wert bearbeitet, wie, dass ist dann deine Aufgabe. Hier mal ein wenig Code von mir:
Der Code ist schon getestet, da ich weder weiß, welchen Controller du verwendest, noch wie dein uC getaktet ist, überlasse ich dann die anpassung der Werte dir, oder du sagst mir halt, wie es aussieht.Code:$regfile = "m8def.dat" $crystal = 8000000 Dim Zaehlerstand As Byte '255 Werte in der Sec. sollte nicht überschritten werden, ansonsten eine Word-varaible verwenden oder so. Const Timervorgabe = 34286 '65536-31250 = 34286 Config Timer1 = Timer , Prescale = 256 On Timer1 Timer1_isr Timer1 = Timervorgabe Enable Timer1 Enable Interrupts Do 'Bestimmung von Zaehlerstand (deine Aufgabe ;-) ) Loop End Timer1_isr: Timer1 = Timervorgabe 'Hier passiert jetzt was mit deinem Zaehlerstand Zaehlerstand = 0 Return
MFG Moritz
Danke, genau das meinte ich RCO. Sorry das ich das vergessen hab ich benutzen einen Mega32 der mit 16Mhz getaktet ist.
Das Prescale bestimmt doch nach wievielen Takten der Timer ausgelöst werden soll, oder?
Den Code hab ich soweit verstanden bis auf diese Rechnung:
Const Timervorgabe = 34286 '65536-31250 = 34286
Die Timervorgabe legt den Startwert des Timers fest, 31250 mal würde der Timerinterrupt in einer Sekunde ausgelöst bei einem Prescale von 256, aber wo kommen die 65536 her?
Also: Wie müste das bei 16Mhz aussehen ?
$regfile = "m32def.dat"
$crystal = 16000000
Config Timer1 = Timer, Prescale = 256
On Timer1 Timer_irq
Const Timervorgabe = 3036
Enable Timer1
Enable Interrupts
Do
'Dein Part
Loop
Timer_irq:
Timer1 = Timervorgabe
Return
Linus Torvalds, Entwickler von LinuxIch will Microsoft wirklich nicht zerstören. Das wird nur ein gänzlich unbeabsichtigter Nebeneffekt sein.
Ja, also der Timer ist eingentlich ein Counter hört sich zwar blöd an, ist aber so, deshalb spricht man oft von "Timer/Counter".
Er zählt alle Takt/Prescaler +1, Timer1 ist also selber eine Variable, die immer erhöht wird. wenn Timer 1 voll ist, bzw. überläuft, dass heißt den Wert 2^16 erreicht (16-Bit Timer) löst er einen Interrupt aus. Unser Ziel ist es jetzt, dass der Timer immer genau jede Sekunde überläuft.
Wenn wir den Timer mit 34286 vorladen, bleiben 31250 Impulse des Prescalers, bis der Timer überläuft.
31250 entspricht in unserem Fall:
8000000 [Takt meines uCs] / 256 [Prescaler]
Also genau einer Sekunde.
Ziehen wir nun von dem Überlaufwert den Wert für eine Sekunde ab, läuft der Timer1 genau jede Sekunde über, dann sollten wir ihn natürlich möglichst schnell wieder beladen, damit keine Fehler entseht.
In deinem fall würde ich einen größeren Prescaler nehmen (1024) weil der uC dann etwas entlastet wird. (Ich habe 256 gewählt, weil ich mit 1024 auf eine Komma-Zahl kam)
Mit 16000000/1024 kommen wir auf 15625. Nun Muss Timervorgabe
2^16-15625 sein, also 49911.
Alles klar?
Müsste mit Timervorgabe 49911 und Prescaler 1024 bei 16 Mhz genau auf eine Sekunde kommen. Kannst ja mal eine Diode toggeln, um es zu prüfen.
Natürlich entstehen aufgrund von Quarzungenauigkeiten etc. immer Fehler, aber da es sich ja nciht um eine Langzeituhr handelt, sollte das kein Problem sein. Bei anderen sind schonmal auf einen Tag einige Sekunden Differenz entsatnden, kannste ja runterrechnen.
Noch fragen?
MFG Moritz
Vielen Dank für die erklärung. Hab wie du sagtest eine Led damit getriggered und es funktioniert Allerdings ist der Timer mit einem Anfangswert von 4991 ungefähr auf 3, 4 Sekunden eingestellt. 16 bit sind nämlich 2^17 und nich 2^16 . Also wär der richtige Startwert 115447, mit dem blinkt die Led jetzt im 1 Sekundentakt.
Könnte ich das dann auch mit Timer0 machen? Der Timer1 wird ja beim RN-Control Board für die Motorensteuerung benutzt und ich will die Drehzahl dieser Motoren messen.
Der Timer0 ist ja ein 8Bit Counter. 2^9 sind ja bloß 512 da würde ich auf einen Startwert von -15113 kommen, funktioniert aber leider nicht
Das ist mir neu, bis jetzt waren 16 Bit bei mir immer 65536!16 bit sind nämlich 2^17 und nich 2^16
Ein Bit hat ja auch nur 2^1 also 2 und nicht 2^2 also 4 Zustände.
Wie kommst du nun jetzt auf diesen Wert? Ich hab doch 49911 geschrieben.4991
Ja mit 4991 kommt man auf 3,1306 sec.ungefähr auf 3, 4 Sekunden eingestellt
Aber mit 49911 Meiner Meinung nach immer noch auf 1.
Schön, wenn es läuft, mir allerdings total unverständlich.
MFG Moritz
EDIT: könnte es sein, dass 4991 tatsächlich nicht nur ein Schreibfehler war?
Denn: wenn du sagst, das du 2^17 verwendet schreibst du ja in ein 17 nicht mehr in dieser Variable existierendes Bi und schreibst somit also nur 49911 in die Varaible. Was dann meinem Wert entsprechen würde
MFG Moritz
Hmmm, naja ka es ging jedenfalls lol. Die größte Zahl die man mit 16Bits darstellen kann ist doch 2^17 dachte ich? So haben wir das jedenfalls gelernt lmao. Das 16. Bit ist ja für 2^16, aber wenn man alle anderen Bits auchnoch setzt hat man ja insgesamt 2^17 (2^1+2^2+2^3+2^4....+2^16).
Weiß nich ob das damit zusammenhängt habs auch nur ausprobiert. Kann gut sein das ich mich verschrieben hatte, bin jetzt allerdings auf Timer2 umgestiegen der nur 8Bit hat also kann ich das jetzt leider nicht so schnell ausprobieren.
Frag mich allerdings immernoch wie man das nun mit einem 8Bit Timer macht. Ich fange jetzt bei 0 an, da er leider nicht im negativen anfangen kann lol. Da heißt er läuft 30,51 mal in der Sekunde über. Da das viel zu schnell wäre schalte ich die Lampe nur jedes 31. mal an bzw. aus damit ich wieder auf ~1 sek kommen. Aber irgendwie ist das ein bisschen aufwändig lol. Geht das auch irgendwie besser?
Lesezeichen