Hallo Teslanikola,
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,
und warum 216?
sonst hab ichs ja so wie du wolltest!!
Ich will nicht!
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...
Code:
Dim Frequenz as long
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.)
Also...
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
Wie bekommst Du nun die beiden Variablen "Freq_low_word" und "Freq_high_word" in die Variable Frequenz.
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
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
Und genau das kann Bascom in dem Du die Variablen so deklarierst.
Code:
Dim Frequenz as long
Dim Freq_low_word as word at Frequenz OVERLAY
Dim Freq_high_word as word at Frequenz+2 OVERLAY
Du hast nun 3 Variablen, die in Wirklichkeit aber nur eine einzige sind.
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
Code:
incr Freq_high_word
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.
Als Gerüst ergibt sich dann für Deinen Frequenzzähler...
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
Mach was draus!
Ich hab den Code nicht getestet, ich kann etwas ultra wichtiges vergessen haben, ich kann Fehler drin haben.
Ciao
Werner
Lesezeichen