Geht das Programm jetzt so oder gibts noch was zu verändern, ach werner würde mich interessieren wie du das mit den Überläufen gemacht hättest
Gruß teslanikola
OK OK , du bist wie mein lieblings Opa, der hat auch immer das letzte Wort, aber ich muss dir rechtgeben, dein letztes Wort ist berechtigt.
Geht das Programm jetzt so oder gibts noch was zu verändern, ach werner würde mich interessieren wie du das mit den Überläufen gemacht hättest
Gruß teslanikola
Hallo Jungspund
es gibt noch viel zu tun, packen wir es später an. Sorry im Moment werde ich hier auf der Arbeit reichlich beansprucht.Geht das Programm jetzt so oder gibts noch was zu verändern,
hab ich doch schon geschrieben...ach werner würde mich interessieren wie du das mit den Überläufen gemacht hättest
1s Torzeit = 10E6 Prozessortakte bei 10MHz Quarz.
10E6 sind 38.147 Überläufe des Timer0 (8bit) bei Prescale = 1024
Also, entweder...
man vergisst 0.147 Überlaüfe und misst nur während 38*256*1024 = 9.961.147 Prozessor-Takten == 0,9961s
In dem Fall startet man den Timer bei "0" und zählt bis zum 38ten Überlauf
oder...
man setzt den Timer auf (256-0.147*256 = 219) vor und zält bis zum 39ten Überlauf.
In dem Fall ergibt sich die Torzeit zu 38*256*1024+ 1*(256-219)*1024 = 9.999.360 Prozessor-Takten == 0,9999360s
Ciao,
Werner
Aha, hab ja au die 2. gememacht Zähle doch bis zu 38, müsste 39 sein, und starte den timer bei 126, müsste 216 sein, sonnst hab ichs ja so wie du wolltest!!
Hallo Teslanikola,
und warum 216?Aha, hab ja au die 2. gememacht Zähle doch bis zu 38, müsste 39 sein, und starte den timer bei 126, müsste 216 sein,
Ich will nicht!sonst hab ichs ja so wie du wolltest!!
Ich meine höchstens etwas ist sinnvoller/besser!
Wenn Du etwas anders machst und erklären kannst warum Du es anders machst, ich wäre der zufriedenste Mensch auf Erden weil Du dann nicht nur abkupferst sondern angefangen hast mitzudenken.
Aber wenden wir uns der Variablen Var2 und der Verknüpfung von Var2 mit dem Wert Timer1 zur Frequenz zu.
Du willst Frequenzen bis zu 1-2 MHz messen. Deine Variable "Freq" muß daher so groß sein, das Zählerstände >= 1-2 Millionen reinpassen.
Mit 16bit = 2 Byte kannst Du bis 2^16 - 1 = 65535 zählen. Das reicht nicht.
Mit 24bit = 3 Byte kommst Du bis über 16.7 Millionen, reicht, aber einen 24bit Datentyp kennt Bascom nicht.
Bleibt der 4Byte Variablentyp, auch bekannt als "long". Die sind zwar viel zu groß, aber kleinere haben wir nunmal nicht. Die Arbeit sowas in Bascom von Hand zu managen machen wir uns auch nicht.
Also...
Dann brauchen wir noch eine Variable für den Wert von Timer1 und eine Variable zum zählen der Überläufe. Timer1 ist 16 bit breit entsprechend muß die Variable für den Zählerstand vom Datentyp Word damit der Zählestand da rein passt. Für die Überläufe reicht eine Byte-Variable, wir nehmen trotzdem ein Word. (Einziger Grund ist, daß ich hoffe das was jetzt kommt ist dann leichter zu verstehen. Es geht auch mit 'ner Byte-Variablen.)Code:Dim Frequenz as long
Also...
Wie bekommst Du nun die beiden Variablen "Freq_low_word" und "Freq_high_word" in die Variable Frequenz.Code:Dim Freq_low_word as Word ' Speicher für den Wert von Timer1 Dim Freq_high_word as Word 'Zähler für die Überläufe. "as Byte" geht ausch
Du erinnerst Dich, Frequenz = Anz_Überläufe "+" Timerwert1
("+" == aneinandergehängt)
Das erste was einfällt, man multipliziert Freq_high_word mit 2^16 und addiert dann Freq_low_word. So hast Du es vor ein paar Versionen auch schon gemacht. (Nun gut, Du meitest zwar * 256 würde reichen, aber bis Du das selbst gefunden hast bin ich wirklich Opa geworden.)
Es geht aber pfiffiger.
Die Variable "Frequenz" belegt im Speicher genau 4 Bytes. Wenn wir nun die Variablen Freq_low_word und Freq_high_word genau auf die gleichen Speicherstellen legen, dann haben wir ohne jede Rechnung genau das was wir wollen.
also
Und genau das kann Bascom in dem Du die Variablen so deklarierst.Code:Variable Variable Variable Frequenz Freq_low Freq_high 1.Byte = 1.Byte 2.Byte = 2.Byte 3.Byte = 1.Byte 4.Byte = 2.Byte
Du hast nun 3 Variablen, die in Wirklichkeit aber nur eine einzige sind.Code:Dim Frequenz as long Dim Freq_low_word as word at Frequenz OVERLAY Dim Freq_high_word as word at Frequenz+2 OVERLAY
Sie belegen im Speicher nur die 4 Bytes, die auch die Variable "Frequenz" belegt. Mit Freq_low_byte sprichst Du die Bytes 1+2 der Frequenz-Variablen an und mit Freq_high_byte die Bytes 3+4.
Wenn Du jetzt in der Interrupt Routine den Befehl
ausführst, wird "Freq_high_word" um eins erhöht und (weil "Freq_high_word" auf der 3.+4. Speicherstelle der Variablen "Frequenz" liegt) wird "Frequenz" quasi nebenbei um 2^16 erhöht.Code:incr Freq_high_word
Als Gerüst ergibt sich dann für Deinen Frequenzzähler...
Mach was draus!Code:' ## Bascom settings $regfile = ... $crystal = ... $baud = ... [...] ' ## Definitionen const Preset_Timer0 = 219 const OvF_Timer0 = 39 [...] Dim Torzeit as Byte Dim Frequenz as long Dim Freq_low_word as word at Frequenz OVERLAY Dim Freq_high_word as word at Frequenz+2 OVERLAY [...] ' ## Initialisierung On Timer0 ... On Timer1 ... enable ... enable ... enable ... Timer0 = Preset_Timer0 ' ## Hauptschleife Do ' ## Messzeit abgelaufen? if Torzeit = OvF_Timer0 Then Freq_low_word = Timer1 ' ## Ausgabe [hier: Ausgabe der Variablen "Frequenz"] ' ## Messung neu initialisieren Torzeit = 0 Freq_low_word = 0 'braucht nicht drin sein, da der Wert oben mit "=" zugewiesen wird Freq_high_word = 0 Timer0 = Preset_Timer0 Timer1 = 0 Start Timer0 Start Timer1 end if ' ## hier kannst Du noch beliebige ander Sachen machen. ' Achtung, sobald Du oben die Messung neu initialisierst, wird der Wert in ' der Variablen Frequenz wieder verändert. ' Wenn Du den Wert hier noch brauchst, z.B. für eine Ausgabe über die ' Serielle Schnittstelle, dann mußt Du ihn vorher in eine andere Variable ' sichern. loop ' ## Schlußbemerkung: ' Wenn ich den Code so wie er hier steht 1:1 in Deinem Programm ' wiederfinde, dann hau ich ihn Dir eine halbe Stunde lang um die Ohren. ' (Falls wir uns irgendwann mal persönlich begenen sollten.) ' Nimm ihn als Vorlage, versuch ihn zu verstehen und programmier dann ' Deinen eigenen! Der Code den Du schon mühsam selbst geschrieben hast ' ist dazu eine gute Grundlage. Den Rest, besonders die Funktion der ' OVERLAY Option düfte hiermit soweit klar sein, daß Du es auch selber ' kannst. Wenn nicht, dann FRAGE! End ' ## Interrupt Timer0 Überlauf Timer0_Ueberlauf_int: incr Torzeit if Torzeit = OVF_Timer0 Then Stop Timer1 Stop Timer0 end if return ' ## Interrupt Timer1 Überlauf Timer1_Ueberlauf_int: incr Freq_high_word Return
Ich hab den Code nicht getestet, ich kann etwas ultra wichtiges vergessen haben, ich kann Fehler drin haben.
Ciao
Werner
Danke , war nenn toller code, aber warum hast du alles geändert , war meins den so sch***. ich glaube, ich hab jetzt verstanden Worum es Kommentare im Quellcode gibt! Damit andere auch verstehen was ich meine. Zugegeben dein Code ist echt kompliziert, geht das echt nicht einfacher?
Code:## Definitionen const Preset_Timer0 = 219 const OvF_Timer0 = 39 [...] Dim Torzeit as Byte Dim Frequenz as long Dim Freq_low_word as word at Frequenz OVERLAY Dim Freq_high_word as word at Frequenz+2 OVERLAY [...] ' ## Initialisierung On Timer0 ... On Timer1 ... enable ... enable ... enable ... Timer0 = Preset_Timer0 ' ## Hauptschleife Do ' ## Messzeit abgelaufen? if Torzeit = OvF_Timer0 Then Freq_low_word = Timer1 ' ## Ausgabe [hier: Ausgabe der Variablen "Frequenz"] ' ## Messung neu initialisieren Torzeit = 0 Freq_low_word = 0 'braucht nicht drin sein, da der Wert oben mit "=" zugewiesen wird Freq_high_word = 0 Timer0 = Preset_Timer0 Timer1 = 0 Start Timer0 Start Timer1 end if ' ## hier kannst Du noch beliebige ander Sachen machen. ' Achtung, sobald Du oben die Messung neu initialisierst, wird der Wert in ' der Variablen Frequenz wieder verändert. ' Wenn Du den Wert hier noch brauchst, z.B. für eine Ausgabe über die ' Serielle Schnittstelle, dann musst Du ihn vorher in eine andere Variable ' sichern. loop ' ## Schlußbemerkung: ' Wenn ich den Code so wie er hier steht 1:1 in Deinem Programm ' wiederfinde, dann hau ich ihn Dir eine halbe Stunde lang um die Ohren. ' (Falls wir uns irgendwann mal persönlich begenen sollten.) ' Nimm ihn als Vorlage, versuch ihn zu verstehen und programmier dann ' Deinen eigenen! Der Code den Du schon mühsam selbst geschrieben hast ' ist dazu eine gute Grundlage. Den Rest, besonders die Funktion der ' OVERLAY Option düfte hiermit soweit klar sein, daß Du es auch selber ' kannst. Wenn nicht, dann FRAGE! End ' ## Interrupt Timer0 Überlauf Timer0_Ueberlauf_int: incr Torzeit if Torzeit = OVF_Timer0 Then Stop Timer1 Stop Timer0 end if return ' ## Interrupt Timer1 Überlauf Timer1_Ueberlauf_int: incr Freq_high_word ReturnWürde dich nie so dermasen beleidigen!!!!!!!!!Wenn ich den Code so wie er hier steht 1:1 in Deinem Programm
' wiederfinde, dann hau ich ihn Dir eine halbe Stunde lang um die Ohren.
' (Falls wir uns irgendwann mal persönlich begenen sollten.)
Hier mein Code MIT Kommentar:
Hatte doch noch ein paar Fehlerchen korrigiert!Code:$regfile = "2313def.dat" Dim Var1 As Byte Dim Var2 As Long Dim Freq As Long Config Portb = Output Config Portd = Output Enable Interrupts Enable Timer0 Enable Timer1 Config Timer0 = Timer , Prescale = 1024 Config Timer1 = Counter , Edge = Rising Config Pinb.5 = Input Portb.5 = 0 On Timer0 Test1 ' Springe zu Test1 wenn Timer0 "voll" On Timer1 Test2 ' Springe zu Test2 wenn Timer1 "voll" Timer0 = 216 ' Constante zum erzeugen einer "Exacten" Sek. Timer1 = 0 Start Timer0 Start Timer1 'Auf die Pins, Fertig, Messen! Do ' Anzeige Schlaufe Loop Test1: ' Wenn Timer0 (Gatetimer) voll, dann Var1 + 1 Incr Var1 If Var1 = 39 Then 'Wenn Timer0 39 überlief (1 Sek) dann: Freq = Timer1 ' Lese Timer1 aus ( Counter ) Freq = Freq + Var2 ' Addiere Timer1 und Anzahl der überlaufe von Timer1*256 Var1 = 0 Var2 = 0 Stop Timer0 ' Starte Messung erneut Stop Timer1 Timer0 = 126 Timer1 = 0 Start Timer0 Start Timer1 Return End If Return Test2: ' Wenn counter (Timer1) überlauft, dann addiere 65536 Var2 = Var2 + 65536 Return
Jetzt versteht man meinen Code besser.
Gruß teslanikola
Hallo Teslanikola,
ich hab doch fast nix verändert.toller code, aber warum hast du alles geändert , war meins den so sch***.
Ich hab andere Variablenbezeichnungen verwendet, weil ich bei Var1,Var2, Test1, Test2 immer durcheinander komme welche nun welche ist. Ich konnte ja nicht ahnen, das Du dein Programm rund um das Beispiel herum schreibst, das eigentlich nur die Timerinterrupts erklären sollte.
Ansonsten sind nur Sachen drin, über die schon gesprochen wurde.
Das mit dem Overlay ist oben erklärt, Dein Goto ist durch eine If-abfrage im Hauptprogramm ersetzt und das mit den Überläufen ist auch so drin wie von Dir bereits verwendet (bis auf die 216 und die 38 )
Auch wenns anders aussieht, schau nochmal genau hin, Du dürftest nichts finden, daß Du nicht kennst und das nicht in diesem Thread besprochen wurde.
Stimmt, ich hätte einige Kommentare einfügen sollen. Ich hab aber ehrlich nicht damit gerechnet, daß Du noch Schwierigkeiten damit haben könntest.ich glaube, ich hab jetzt verstanden Worum es Kommentare im Quellcode gibt! Damit andere auch verstehen was ich meine.
Das der Code komplizierter ist als Deiner würde ich rundweg abstreiten, aber der selbstgeschriebene Code erscheint immer einfacher.Zugegeben dein Code ist echt kompliziert, geht das echt nicht einfacher?
Aber bitte nimm Dir 'ne Stunde Zeit, guck ihn Dir nochmal genau an und Du wirst feststellen, es haben sich die Variablennamen geändert und sonst nix was nicht vorher erklärt wurde.
Das einzige was vielleicht ein bisschen komplizierter ist als in Deinem Code, ist die Sache mit dem Overlay. Es vereinfacht aber extrem viel, nicht nur hier, sondern bei fast allen Programmen die man schreibt.
Setz Dich mal hin und schreib ein kleines Testprogramm, in dem Du nur das mit dem Overlay ausprobiert. Vieleicht verstehst Du es dann.
Ciao,
Werner
Hallo Tesnikola,
hast Du das interesse am Frequenzzähler verloren oder grübelst Du noch über dem Code?
Ciao,
Werner
sorry hatte wenig Zeit, immer diese Arbeiten in der Schule. Brenne heute mal den Code ins Flash und mache mak nen kl. Test.
servus, irgendwas geht nicht, wenn der Timer0 oder timer1 voll ist, springt der nicht zu Test1 oder 2 ( in der Sim )
Lesezeichen