WatbBascom nicht diese Sprache, die pro Zeile nur 1 Berechnung konnte.
Seit wann kann man in Bascom bei der Parameterübergabe rechnen?
Brauchst du da nicht eine Zwischenvariable?
löter schrieb:> Mach keine Berechnung in den Klammern von FIX> Mach alle Variablen SINGLE
Guter Tipp, im Simulator läuft es damit.
Mein Vorschlag wäre Dword zu benutzen, wenn der Wertebereich ausreicht.
Läuft schneller und macht keine Rundungsfehler.
$regfile = "M8def.dat"
$hwstack = 128
$swstack = 128
$framesize = 64
$crystal = 3686400
Dim Ms As Single
Dim A As Single
Dim Rechnenval As Single
Dim Wert As Single
Dim Merke As Single
Wert = 1000
Ms = 3526
If Ms >= Wert Then
Merke = Ms / Wert
A = Fix(merke)
Rechnenval = Frac(merke)
End If
Print "Merke=" ; Merke
Print "A=" ; A
Print "Rechnenval=" ; Rechnenval
'*******************************************
' Vorschlag:
Dim _ms As Dword
Dim _a As Dword
Dim _rechnenval As Dword
Dim _wert As Dword
_wert = 1000
_ms = 3526
If _ms >= _wert Then
_a = _ms / _wert
_rechnenval = _ms Mod _wert
End If
Print
Print "_A=" ; _a
Print "_Rechnenval=" ; _rechnenval
End
Hallo,
vielen Dank für die Infos.
Was soll mein Programm machen?
Ich gebe an, in wieviel ms die Led an und dann wieder ausgeschaltet
werden soll.
Hierzu rechne ich natürlich alles um, aber es macht eben nicht das was
es soll.
Normalerweise müsste nach 6452 ms, also 6,452 sek die led bzw. aus
gehen.
Wenn ich es in den atmega8 übernehme, dann leuchtet die led in 1 Sekund
extrem oft.
Hier mein bisheriger Programmiercode:
<pre>
$regfile = "M8def.dat"
$crystal = 1000000
$hwstack = 100
$swstack = 100
$framesize = 100
'Timer0 konfigurieren
'1000000 (Systemtakt) / 1 (Prescaler) = 1000000 (Counts)
Config Timer0 = Timer , Prescale = 1
'Timer0 Overflow Interrupt
'Dieser Interrupt wird beim Überlauf (255 nach 0) ausgelöst
'1000000 (Counts) / 256 (8-Bit Timer) = 3906,25 (Interrupts die Sekunde)
On Timer0 On_timer0_overflow
Enable Timer0
Enable Interrupts
Config Portb = Output
Dim A As Long
Dim B As Long
Dim Ende As Single
Dim Aa As Integer
Dim Ueberlaeufe As Double
Dim Onems As Double
Dim Anzahlms As Long
Dim Rechnen(4) As Double
Dim Rechne(2) As Long
Ueberlaeufe = 3906.25
Anzahlms = 6452
Onems = Ueberlaeufe / 1000
'3,90625
Rechnen(1) = Onems * Anzahlms
'25203,125
'Wieviele Überläufe, wichtig für Variabele a
Rechnen(2) = Rechnen(1) / Ueberlaeufe
'6,452
Rechne(1) = Fix(rechnen(2))
'6
Rechnen(3) = Frac(rechnen(2))
'0,452
Rechnen(4) = Rechnen(3) * Ueberlaeufe
'1765,625
Rechne(2) = Abs(rechnen(4))
'1766
A = 0
Aa = 0
B = 0
Do
Portb.0 = 1
Do
Loop Until Aa = Rechne(1)
A = 0
Aa = 0
B = 0
ende = 0
Portb.0 = 0
Do
Loop Until Aa = Rechne(1)
A = 0
Aa = 0
B = 0
ende = 0
Loop
End
On_timer0_overflow:
A = A + 1
If Aa = Rechne(1) Then
B = B + 1
If B = Rechne(2) Then
Ende = 1
End If
End If
If A = 3906 Then
Aa = Aa + 1
A = 0
End If
Return
</pre>
Ich habe jetzt folgenden Bereich so gelassen:
<pre>
Do
Loop Until Aa = Rechne(1)
</pre>
und nicht so:
<pre>
Do
Loop Until Aa = Rechne(1) and ende = 1
</pre>
Da es anscheinend schon bei rechne(1) das Problem liegt.
Es finden also 3906.25 Timerüberläufe in 1 Sekunde statt.
Um es dann dementsprechend besser zu rechnen, da gibt es einen externen
Quarz für, aber ich weiss nicht mehr dem Quarz seine MHZ Zahl.
Dann ist der Timerüberlaufwert eine Ganzzahl, ohne Nachkommastelle
andy_help schrieb:> 3906,25 (Interrupts die Sekunde)
Warum so ein krummer Wert?
Wenn man mit Zeitwerten arbeiten will, nimmt man einen Interrupt im
ms-Abstand; d.h. 1000 Interrupts pro Sekunde. Dann kann man sich die
ganze Umrechnerei sparen.
Marvin schrieb:> andy_help schrieb:>> 3906,25 (Interrupts die Sekunde)>> Warum so ein krummer Wert?> Wenn man mit Zeitwerten arbeiten will, nimmt man einen Interrupt im> ms-Abstand; d.h. 1000 Interrupts pro Sekunde. Dann kann man sich die> ganze Umrechnerei sparen.
Prescaler Werte:
1 , 8 , 64, 256,1024
1 MHZ sind 1000000HZ.
1000000 / 1 = 1000000 /256 =3906,25
1000000 / 8 =125000/256 =488,28125
1000000 / 64 = 15625/256 =61,03515625
1000000 /256 =3906,25/256 =15,2587890625
1000000 / 1024 = 976,5625/256 =3,81469726562
Wenn ich 1 MHZ habe, diesen durch den Prescaler u. dem Timerwert teile,
erhalte ich immer einen Wert mit Nachkommastelle.
Es gibt aber einen externen Quarz, bei dem durch die Teilung dann Werte
ohne Nachkommastelle entstehen, aber mir fällt der entsprechende externe
Taktgeber für den Atmega nicht mehr ein
andy_help schrieb:> Es gibt aber einen externen Quarz, bei dem durch die Teilung dann Werte> ohne Nachkommastelle entstehen, aber mir fällt der entsprechende externe> Taktgeber für den Atmega nicht mehr ein
Dann nimm einen Quarz mit 1,024MHz. Da kommst Du auch auf "richtige"
Zahlen.
Oder: Du läßt im Interrupt den Timer immer wieder mit einem Wert
vorladen, so daß er nicht seinen vollen Umfang zählen muß und erzeugst
auf diese Weise
gut benutzbare Zeiten.
Hm...ok, aber warum rechnet das Programm nicht so wie es soll?
double -> für Nachkommastellen
Fix -> Entfernt die Nachkommastellen
frac -> Nur die Nackommastellen
freebasic Beispiel:
dim wert as double
dim a as integer
dim b as double
wert = 2562.1345351
a = fix(wert)
b =frac(wert)
print wert
print a
print b
Ergibt folgende Ausgabe:
2562.1345351
2562
0.1345350999999937