PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Timer Programmierung



Dane
19.12.2005, 05:37
Morgen,

ich versuche momentan, die Timer-Programmierung zu verstehen. Ich komme aber damit nicht klar.
Wann wird die Zeit im untenstehenden Programm gestartet und wann springt er zur Sprungmarke Timer_irq:?

Wäre super, wenn mir das jemand erläutern könnte!

Mit der Forum-Suche bin ich auf folgendes Programm gestoßen:


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

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

'Hier wird der Timer und der Teiler festgelegt
Config Timer0 = Timer, Prescale = 64

'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 wird das Unterprogramm festgelegt, das
'in dem von ihnen eingestellten Intervall aufgerufen wird
On Timer0 Timer_irq

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


'Hier werden die Timer aktiviert
Enable Timer0
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:
Timer0 = 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

Return

MfG, Dane

Marco78
19.12.2005, 07:51
Die Zeit wird gestartet nachdem Enable Interrupts und Enable Timer0 ausgeführt wurde. Je nachdem, was als letzes kommt.

Wenn Timer_Irq: aufgerufen wird, kann ich dir so nicht sagen. Aber es ist dann, wie du es im Programm RNAvr eingestellt hast.
Also wenn du 1 Sekunde angegeben hast, wird die ISR (Timer_irq) jede Sekunde aufgerufen.

Dane
19.12.2005, 17:13
Ich hab dieses Programm gerade ausprobiert, bei mir leuchtet die LED dauernd.
BTW: Was ist RNAvr?

Es wäre super, wenn mir jemand ein Beispielprogramm schreiben könnte. Daraus lerne ich erfahrungsgemäß am meisten, zumindest wenn ich es verstehe ;).

Ich will folgendes realisieren:
In meinem Programm soll eine Zeit von 2min gestartet werden, wenn eine Variable= 1 ist (Signal zum PC ausschalten).
Wenn innerhalb dieser Zeit Pind.0=0 wird (Rückmeldung Rechner läuft), soll Portd.5=0 werden (Relais zum Trennen des PCs vom Netz).
Nach den 2 Minuten soll Portd.5=0 werden, unabhängig davon, ob der Rechner noch läuft. Das habe ich deswegen vor, wenn sich der Rechner beim runterfahren aufhängt, dass er nicht stundenlang weiterläuft.
Das Hauptprogramm zwischen DO und LOOP soll allerdings weiterlaufen.

Das würde mir echt weiterhelfen, wenn mir jemand diesen Programmteil schreiben und vielleicht etwas erläutern könnte.

Schon mal Danke!

MfG, Dane

Dane
19.12.2005, 17:16
Ich habe gerade festgestellt, dass das obere Programm läuft.
Die LED blinkt schon, allerdings mit 1,6 kHz. =D>
Habs gerade mit dem Oszi gemessen.

Dane

albundy
19.12.2005, 18:10
Hallo,

Du solltest für größere Zeiten Timer1 benutzen.


Config Timer1 = Timer, Prescale = 64
Const Startwert=7936
Load Timer1, Startwert



Timer1 zählt ohne Startwert bis 65535 und lößt dann einen Interrupt aus.
Bei deiner Quarzfrequenz von 3686400 Hz / Vorteiler 64 ergibt das 57600 Takte pro Sekunde.
Wenn der Timer mit einem Startwert von 7936 voreingestellt wird, zählt er von diesem Wert, bis 65535.
Ergibt 65535 - 7936 = 57599. Das heisst, jede Sekunde wird ein Interrupt ausgelößt.


IRQ_Timer1:
Load Timer1, Startwert 'Startwert wieder neu laden
Incr Zaehler 'Zaehler wird jede Sekunde erhöht
Return

Jetzt musst du nur noch in deinem Programm die Auswertung machen.
Wenn ich dich richtig verstanden habe etwa so ...


If Variable = 1 Then Zaehler = 0 'den Zaehler starten
If Zaehler < 120 AND Pind.0 = 0 then Portd.5 = 0 ' wenn noch keine 2 Minuten um sind und Pind.0 = 0 dann schalte Portd.5 auf 0

Dane
19.12.2005, 19:35
Erst mal Danke Albundy!

Ich habe deine Codes mal in dieses Programm eingefügt. Zum Ausprobieren nochmal vereinfacht. PD5 soll nach 5s eingeschaltet werden, nachdem das Startsignal gegeben wurde.
Allerdings geht das Programm nicht.
Was ist daran falsch?


$regfile = "m32def.dat"
$crystal = 3686400

Config Timer1 = Timer , Prescale = 64
Const Startwert = 7936 'zählt bis 65535
Load Timer1 , Startwert

Dim Zaehler As Byte , Startsignal As Bit
Config Pind.5 = Output

Do
If Startsignal = 1 Then Zaehler = 0 'den Zaehler starten
If Zaehler = 5 Then Portd.5 = 1 'nach 5s PD5 einschalten
Loop

Irq_timer1:
Load Timer1 , Startwert 'Startwert wieder neu laden
Incr Zaehler 'Zaehler wird jede Sekunde erhöht
Return

End

Warum wird eigentlich der Zähler gestartet, wenn er auf 0 gesetzt wird?

MfG, Dane

albundy
20.12.2005, 09:52
Hallo,


Allerdings geht das Programm nicht.
Was ist daran falsch?


du konfigurierst Timer1, aber aktivierst ihn nicht.
du gibst die Interrupts nicht frei.
du hast nicht definiert, welches Unterprogramm Timer1 anspringen soll.

sieh dir mal deinen 1. Code an... ](*,)


Warum wird eigentlich der Zähler gestartet, wenn er auf 0 gesetzt wird?

hab mich vielleicht falsch ausgedrückt.
Der Zähler wird nicht gestartet, sondern auf einen definierten Wert gesetzt. Man könnte die Variable "Zaehler" auch auf 120 setzen und herunter auf 0 zählen lassen.

Das sollte ja auch nur ein Beispiel sein und kein kompletter Code.