Ich möchte mir einen Frequenzzähler mit einem ATTINY2313 bauen und habe jetzt das Problem, eine genaue Sekunde als Meßzeit zu erzeugen. Da ich aber den Timer 0 als Counter brauche, kann ich mit ihm nicht die Meßzeit erzeugen. Der Timer 1 ist zu klein dafür. (4 Mhz Quarz). Sieht jemand eine andere Möglichkeit, die 1 Sekunde bzw. 100 Mikrosekunden genau zu erzeugen, denn Wait 1 in Bascom ist ungenau. Gedacht ist es so: (nur Pseudocode) -Timer 0 als Counter einstellen do -Timer-Interrupt erlauben -1 Sekunde warten -Interrupt verbieten loop Dann müßte ja im Timerregister die Anzahl der gezählten Impulse pro Sekunde enthalten sein und die kann ich ja dann ohne Mühe auf LCD ausgeben. Ich habe schon den Frequenzzähler von Bernhard auseinandergenommen, komme aber mit Assembler nicht zurecht. MfG Paul
> Der Timer 1 ist zu klein dafür...
Zu klein? Der hat 16 Bit, Timer 0 hat nur 8...
Weißt Du denn, in welchem Bereich die zu messenden Frequenzen liegen?
Wenn der Bereich größer ist, dann musst Du sowieso Zählerüberläufe mit
in die Überlegungen einbeziehen.
Der Prescaler des Timers kann bis auf 1024 eingestellt werden. Bei 4 Mhz und maximalem Prescaler kann der Zähler maximal ca 16,77 Sekunden lang laufen, bis er überläuft. Wenn du den Prescaler auf 256 einstellst und den Timer im CTC-Modus bis 15625 zählen läßt, bekommst du einen Interrupt, der genau einmal pro Sekunde ausgelöst wird.
Das war auch meine Idee. Aber da er ja keine Angaben über den Frequenzbereich macht, ist es ein bisschen schwierig, was konkretes zu sagen. Mit Timer 1 im CTC-Modus wie von Rolf beschrieben und Timer 0 als Periodenzähler sollte es im Prinzip gehen. Bei höheren Frequenzen als 255 Hz müssen dann die Überläufe von Timer 0 mitgezählt werden, was über den entsprechenden Interrupt aber auch kein Thema sein sollte.
Die MCs haben es sehr gerne, wenn sie auch mal etwas rechnen dürfen. Es spielt also überhaupt keine Rolle, ob die Torzeit nun 1s oder 789ms lang ist, man kann immer den Zählwert in Hz umrechnen. Selbst in float rechnet der AVR immer noch 1000-mal schneller, als bei Dir ein Lidschlag dauert. Peter
> Selbst in float rechnet der AVR immer noch 1000-mal schneller, als > bei Dir ein Lidschlag dauert. Sofern für die float-Bibliotheken noch genug Platz im Speicher ist, denn sonst rechnet er nähmlich gar nicht. Der Tiny2313 ist ja nicht gerade üppig mit Flash bestückt.
@Rolf Stimmt. Float ist zumindest beim WINAVR sehr groß, da sollte es schon ein ATMega48 sein. Peter
Ich habe Timer 0 und 1 aus Versehen im Text vertauscht. Außerdem wollte ich es so machen, daß ich bis 5Khz direkt zählen kann und dann über einen Portpin einen 10:1 Teiler (7490) einschalte, der dann wiederum bei f > 5Khz dem Prozessor wieder nur max. 5 Khz aufbürdet. Wenn ich Euch richtig verstanden habe, schlagt ihr vor, Timer 1 als Counter zu nehmen und Timer 0 als Geber für die Torzeit. Bloß- wie muß ich dann die beiden Timerinterrupts verknoten, damit nicht einer den anderen beeinflußt? Soviel ich weiß, gibt ein Interrupt im Interrupt "Mecker vom Meister"! :-) MfG Paul
@Rolf Ach so, das weiß ich, wie ich eine Sekunde erzeugen kann. (Hab ich in meiner Uhr genau so gemacht, wie Du beschreibst). Aber das Problem ist doch jetzt, daß der Timer durch die Sekundentakterzeugung belegt wäre. Ich brauche ihn aber als Counter, damit er die Impulse am Eingang zählt. Was ich brauche ist jetzt irgend etwas Anderes, was mir statt des Timers die Torzeit erzeugt. Wenn der Prozessor 2 16-Bit Timer hätte, dann könnte ich einen nehmen, der zählt und einen, der die Zählzeit des ersten festlegt. MfG Paul
Du kannst auch mit einem 8 Bit Timer eine beliebig lange Torzeit erzeugen. Selbst wenn du eine Stunde als Torzeit haben möchtest, ist das möglich. Prinzip: Du weist (oder hast dir ausgerechnet), dass von einem Timer-Overflow zum nächsten sagen wir mal 120 ms vergehen. Du möchtest eine Torzeit von, zum Beispiel, 4.2 Sekunden. D.h. du zählst in der Overflow-Routine mit (Variable hochzählen), wie oft der Interrupt bereits aufgetreten ist. Wenn vom Beginn der Torzeit an gerechnet, der Overflow Interrupt das 35-te mal auftritt, sind 4,2 Sekunden vergangen (4200 / 120 = 35)
@Karl-Heinz Das ist die Idee, die ich suchte. Ich werde mal mein Programm auf den "kleinen" Timer umbauen und mir so die Torzeit erzeugen. Mir fehlt jetzt nur der Zusammenhang, wie ich den "großen" Timer durch den kleinen starte und stoppe.Ich melde mich danach wieder. Ich habe mal mein Programm angehangen. Ich habe es für den Atmega8515 umgeschrieben, weil der gerade auf dem Testbord am LCD hängt.Im Moment versuche ich darin nur, die Torzeit mittels leerer Schleife empirisch zu erzielen. Noch eine andere Sache: Welcher Pin ist beim 8515 der Countereingang? Jedes Datenblatt sagt etwas Anderes?! MfG Paul
Hallo! So erzeuge ich ne Torzeit in C fuer ne Frequenzmessung void capture(unsigned int compare) { TCNT1H=0; // clear timer TCNT1L=0; OCR1H=(compare >> 8); OCR1L=compare; TIFR |= (1<<OCF1A); // clear overflov/compare flags TCCR1B=0x03; // write Prescaler loop_until_bit_is_set(TIFR, OCF1A); TIFR |= (1<<OCF1A); // clear overflov/compare flags TCCR1B=0; // stop timer } Das Programm AVRCalc (Google) hilft einem, den Prescaler zu bestimmen und den compare Wert. mfg, Bjoerm
$regfile = "2313def.dat" $crystal = 10000000 Config Timer1 = Counter , Edge = Falling , Prescale = 1 Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.2 , Rs = Portb.0 Config Lcd = 16 * 1 Initlcd Cursor Off Dim Timercounter As Word Dim Overflcounter As Word Dim Totalcounter As Long Dim T1 As Integer Dim T2 As Integer Dim M As Integer Dim Zeit As Long On Counter1 Uphigh Timercounter = 0 Totalcounter = 0 Zeit = 0 Enable Interrupts Enable Counter1 Cls Lcd " Frequen" Lowerline Lcd "zz" ; Chr(225) ; "hler " Waitms 500 Do Waitms 47.6 If Zeit = 21 Then Cls Timercounter = Counter1 Totalcounter = Overflcounter Shift Totalcounter , Left , 16 Totalcounter = Totalcounter + Timercounter Lcd Totalcounter Lowerline Lcd " Hz" Timercounter = 0 Totalcounter = 0 Zeit = 0 Counter1 = 0 Overflcounter = 0 End If Zeit = Zeit + 1 Loop Uphigh: Incr Overflcounter Return Das Ding steht bei mir auf dem Schreibtisch und läuft ganz gut. Hier wird ein Hardwarezähler verwendet und wenn der Zähler voll ist dann wird ein Overflowcounter ausgelöst und zählt die Überläufe. Über die Zeit "Waitms 47.6" kannst du Quarzungenauigkeiten ausbessern. hf Achja, 16 * 1 Display entspricht 2 mal 8 Zeichen aber in einer Zeile... ;-) Kann ich auch nix für....
Danke erst mal an alle "Mitwirkenden". Wenn man erst mal einen "Schubs" in die richtige Richtung bekommen hat... Jetzt habe ich es so gemacht, wie Karl-Heinz und Steffen vorschlugen. Ich habe die Sache komplizierter angesehen, als sie war. Jetzt werde ich bloß noch eine Auswertung der Zählfrequenz einbauen, um davon abhängig einen Vorteiler einzuschalten bzw. zu "überbrücken". MfG Paul
@Steffen So Wozu dienen die Variablen T1, T2 und M? Offenbar sind sie nicht benutzt. Welcher Pin ist der Zählereingang? (Müßte eigentlich PD6 sein, ist aber nicht definiert) Dafür müßte es oben wahrscheinlich CAPTURE EDGE heißen. Bis zu welcher Frequenz zählt die Schaltung? Ich nehme an, bis zur halben Taktfrequenz. (5 Mhz) MfG Paul
T1, T2 und M waren mal für irgendwelche Teiler vorgesehen, sind aber nicht benutzt. Zum Eingang: Du musst im Datenblatt mal gucken, auf welchem Pin Timer 1 liegt. Soweit ich weiß muss der dann auch nicht definiert werden. Die Frequenz habe ich nie voll ausprobiert, mein Frequenzgenerator liefert nur Frequenzen im kHz Bereich... Aber denke mal mit 5 MHz kommt das ganz gut hin, vll sogar mehr, da hier ja der Hardwarezähler verwendet wird.
Der Hardwarezähler muß aber auch das ganze sampeln :) Zitat DB: Each half period of the external clock applied must be longer than one system clock cycle to ensure correct sampling. The external clock must be guaranteed to have less than half the system clock frequency (fExtClk < fclk_I/O/2) given a 50/50% duty cycle. Since the edge detector uses sampling, the maximum frequency of an external clock it can detect is half the sampling frequency (Nyquist sampling theorem). However, due to variation of the system clock frequency and duty cycle caused by Oscillator source (crystal, resonator, and capacitors) tolerances, it is recommended that maximum frequency of an external clock source is less than fclk_I/O/2.5. [zitat ende] Also im besten Falle CPUCLK/2 und am besten CPU/2.5 oder geringer um sicher messen zu können :)
@Steffen Das wäre dann PD5. ....wolln mal sehen. @Läubi Mit den wenigen Englischkenntnissen, die ein alter Mann so hat, lese ich da heraus, daß die Eingangsfrequenz auch noch 50/50 Puls/Pause sein muß?! Da müsste ich ja noch ein extra Flipflop davor setzen, was mir dann allerdings die doppelte Zählfrequenz beschert. Sehe ich das richtig? Könnte man auch irgendwie den Analogeingang des Prozessors so "verbiegen", daß man den als Zählereingang benutzt? Dann könnte ich auch "Sinüsse" und "Dreiecke" messen, ohne das Signal vorzubehandeln. MfG Paul
Ne muß nicht, aber wenn 50/50 da ist, dann kann der AVR es schaffen die Halbe Frequenz mitzuzählen. Im Prinzip läufts so ab, bei jedem CLK "prüft" der AVR nach ob sich was an T0 (respektive T1) verändert hat, und zählt dann hoch. Alles auserhalb dieser Zeit wird ignoriert. Deshalb wenn das Signal zu schnell ist "übersieht" der AVR Taktflankenwechsel. Analogeingagn wird aber noch langsamer sein ;)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.