PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Timer geht vor



sebastian.heyn
06.12.2004, 11:41
Hallo,
habe eine Uhr erstmal zum testen programmiert. WAS HABE ICH FALSCH GEMACHT? Die Zeit geht zu schnell. Muss man "probieren", bis die uhr genau genug läuft? das prog. soll später auf nem Mega8 laufen...



$regfile = "m128def.dat"
$crystal = 16000000
$baud = 9600

Config Timer1 = Timer , Prescale = 1024

Dim Sekunde As Byte
Dim Minute As Byte
Dim Stunde As Byte
On Timer1 Timer1int
Load Timer1 , 15625
Enable Interrupts
Enable Timer1
Start Timer1

'HAUPTPROGRAMM
Stunde = 10 'uhrzeit stellen :-)
Minute = 29

Do
Waitms 100
Loop
End


Timer1int:
Load Timer1 , 15625 '1ne Sekunde
Sekunde = Sekunde + 1
If Sekunde = 60 Then
Sekunde = 0
Minute = Minute + 1
If Minute = 60 Then
Minute = 0
Stunde = Stunde + 1
If Stunde = 24 Then Stunde = 0
End If
End If
Print Chr(12)
Print Stunde ; ":" ; Minute ; ":" ; Sekunde
Return

Michael
06.12.2004, 11:58
Hallo sebastian.heyn,
dadurch, daß dein Timer1 ja überläuft, und dadurch den Interrupt auslöst, mußt du den errechneten (15625) vom maximalen Timerwert (65535) abziehen.
Dein Timer muß im Interrupt also mit 65535-15625 = 49911 geladen werden. Dann sollte der Sekundenwert auch stimmen.
Gruß, Michael

sebastian.heyn
06.12.2004, 12:42
MMHH,
so läufts zu langsam.. Gibts noch ne andre oder evtl bessere möglichkeit nen interrupt auszulösen?

x-ryder
06.12.2004, 13:16
ich hab mal nachgeguckt und festgestellt das dein reloadwert falsch ist...

reloadwert bei prescaler 256 = 3036

also timervorgabe=3036 NICHT 65536 - 3036

Martin

sebastian.heyn
06.12.2004, 13:21
lach mich bitte nicht aus, aber auf welcher berechnungsgrundlage beruht das? Ich dachte ich muss clock also 1600000 (hoffe ich habe alle nullen) / prescalewert rechnen? Oder hab ich was nicht verstanden? (wie öfters mal) O:)

sebastian.heyn
06.12.2004, 13:25
habe mir gerade die software aus dem forum gezogen DANKE NOCHMAL AN FRANK FÜRS BEREITSTELLEN.

mal schauen wies damit läuft!

x-ryder
06.12.2004, 13:27
HAHA......... neeeeeeeeiiiiiiiiiiiin ich lach nicht :cheesy:

keine angst ich kanns im prinzip auch nicht so gut ich habs jetzt mit rnAVR gemacht das geht ganz gutt damit!

muss ich auch immer nachgucken falls ich grad keinen rechner mit rnAVR dabei hab

Martin

Michael
07.12.2004, 00:49
Hallo sebastian.heyn,
jetzt hab ich extra mal ein Atmega8-Board aufgebaut, um das zu testen.
den Befehl:
Load Timer1 , 15625 '1ne Sekunde
hatte ich bisher nicht genutzt.
Bei mir läuft es damit auch zu schnell :(
Ich habe also den Befehl durch:
Timer1 = 49911
ersetzt und siehe da, die Zeit läuft richtig, ts, ts. Genau eine Sekunde pro Interrupt.
Gruß, Michael

07.12.2004, 08:10
So gehts in jedem Fall, hier ist der komplette Code den das Tool rnAVR generiert hat:



'################################################# #############
' Timer Beispiel für das universelle Controllerboard
' rn-control mit mega 16 oder mega 32
' Ausführliche Infos zum Controller Board findet man
' unter www.robotikhardware.de als auch im
' www.roboternetz.de
'
' Dieses ruft einen Timer Interrupt in ihrer gewählten Frequenz auf.
' Bei jedem Interrupt wird der Zustand der LED einmal umgeschaltet, dadurch
' blinkt die LED genau in der halben Frequenz
' Der generierte Code kann direkt in den Bascom-Compiler kopiert
' und kompiliert werden. Natürlich läßt sich der Code auch in
' bestehende Programme integrieren

' Autor: CodeGenerator rnAvr vom roboternetz.de
' Weitere Beispiele und Beschreibung der Hardware
' unter http://www.Roboternetz.de oder robotikhardware.de
' Eigene Programmbeispiele sind im Roboternetz gerne willkommen!
'################################################# #############



'wenn mega 32, dann ändern in $regfile = "m32def.dat"
$regfile = "m16def.dat"

'Quarzfrequenz, entsprechend ihren Angaben
'der passende Quarz muss in die Fassung gesteckt werden
$crystal = 16000000

'nur notwendig wenn rs232 benutzt werden soll
$baud = 9600

'Hier wird der Timer und der Teiler festgelegt
Config Timer1 = Timer, Prescale = 256

'Der Port mit der dritten LED auf RN-Control wird als Ausgang programmiert
Config Pinc.2 = Output
'Hier geben wir der Definition einen schöneren Namen
Led3 Alias Portc.2

'Hier definieren wir den rn-control Piepser als Ausgang
Config Pind.7 = Output
'Hier geben wir der Definition einen schöneren Namen
Piepser Alias Portd.7

'Hier wird das Unterprogramm festgelegt, das
'in dem von ihnen eingestellten Intervall aufgerufen wird
On Timer1 Timer_irq

'Diese Vorgabe wurde berechnet um die genaue Intervallfrequenz zu erreichen
Const Timervorgabe = 3036


'Hier werden die Timer aktiviert
Enable Timer1
Enable Interrupts

'Hier ist die Programmhauptschleife
Do
'Hier könnte Ihr Hauptprogramm stehen
Loop



'Dies ist der Programmteil, der in dem von ihnen gewählten
'Intervall aufgerufen wird
Timer_irq:
Timer1 = Timervorgabe

'Hier könnte nun ihre beliebige IRQ-Routine stehen
'Dabei sollte man darauf achten das diese nicht mehr Zeit
'benötigt, als das Intervall zuläßt

'Der Zustand der LED wir umgekehrt, wodurch sich blinken in der halben Frequenz ergibt
'Hohe Frequenzen sind natürlich nicht mehr sichtbar
Toggle Led3
'Der Zustand des Piepsers wird umgekehrt, wodurch sich ein Ton in der halben Frequenz ergibt
Toggle Piepser

Return



Das Tool geht auch bei Mega128 und anderen AVR-Controllern

sebastian.heyn
07.12.2004, 09:29
Ja habe meinen Code gestern auch angepasst (laut dem Beispiel in rnAVR) scheint echt zu passen. wollte heute früh gucken aber da hatter der controller irgendwie nen reset bekommtn, warscheinlich über das ISP kabel beim hochfahren des rechner (wie dumm). gestern lief sie noch nach 5 stunden recht genau soweit ich erkennen konnte.

RCO
07.12.2004, 11:42
Im Grunde ist das aber das genauso wie Michael meinte, nur nen anderer Prescaler, wundert mich, dass es jetzt läuft. Nur der Timer wird eigentlich anders beladen, allerdings läuft die erste Sekunde in Gasts Code zu langsam, da der Timer noch nciht beladen ist. Der Timer startet doch bei 0, oder.

@ xryder (erster Post): Natürlich, die Zahl 3036 kommt ja wie folgt zu Stande:

16000000/256=62500

Eine Sekunde ist also 62500 Steps lang
Allerdings hat der Timer (16 Bit) ja 65536, also

65536-62500 = 3036!

Damit der Timer pünktlich zur Sekunde überläuft muss er mit 3036 neu beladen werden. Allerdings hier meine Frage, wenn der Timer doch erst in der Interruptroutine neu beladen wird, dann wird ja die Zeit, die vom Sprung zur Routine bis zum neu beladen vergeht, immer auf die Sekunde gerechenet. Stimmt das so?

MFG Moritz

Marco78
31.03.2005, 23:33
Damit der Timer pünktlich zur Sekunde überläuft muss er mit 3036 neu beladen werden. Allerdings hier meine Frage, wenn der Timer doch erst in der Interruptroutine neu beladen wird, dann wird ja die Zeit, die vom Sprung zur Routine bis zum neu beladen vergeht, immer auf die Sekunde gerechenet. Stimmt das so?
Ja, aber das sind ja nur wenige Takte. Behaupten wir mal, ein Takt für den Sprung und 1 Takte um den Timer wieder zu laden.
Wenn man die ungenauigkeit des Quarz bedenkt, sind die 2 Takte bei über.
Dann geht's aber weiter. Ein Interrupt verhält sich ja ähnlich wie ein GOSUB. Es muss noch gespeichert werden, wo das Programm gerade steht um an der Stelle nach Return (oder Reti) weiterzumachen.
(2 Takte glaube ich)
Das schlimmst kommt aber noch. Das speicher aller Register. (jeweils 2 Takte!)
So sind mal gut und gerne 60 Takte abgelaufen, bis der Timer mit x (3036) wieder aufgeladen wird.
Nach meinem Verständnis wirkt sich das aber nur auf Prescaler=1 aus. Weil ja nur da jeder Takt ein Schritt näher zum Overflow bedeutet. Bei Teiler = 256 müssen ja erstmal 256 Takte abgelaufen sein, damit der Timer um 1 erhöht.

Marco78
01.04.2005, 13:20
Kann es sein, das hier grade jemand was geschrieben hat und es wieder gelöscht hat???
Jeder, der hier schonmal ein Text verfasst hat, oder das Thema beobachtet, bekommt idr eine Emailbenachrichtigung.
Wenn jetzt, so wie es wohl der Fall war, jemand was schreibt und den Beitrag löscht, geht der Link in der Benachrichtigung ins leere!
Und wenn mal wirklich jemand hier eine Anmerkung schreiben möchte, gibt es dann keine neuen Emails mehr, es sei denn, man lässt sich wieder welche schicken.
Das ist aber nicht Sinn der Erfindung.

Also, am besten der Beitrag bearbeiten und den Text einfach löschen, damit haben es alle anderen leichter!