Hallo, ich programmiere meinen pic18 mit C und will da ein paar
while-schleifen, die ich eine bestimmte definierte Zeit (z.B. 5 sec)
ausführen möchte (also so lange die while loop wiederholen, bis die
bestimmte Zeit vergeht), einbauen. Wie kann ich das realisieren?
Kann man einen internen Zähler einbauen, der im Hintergrund hochzählt,
während die Schleife mehrmals wiederholt wird und bei der Zahl, die z.
B. 5 sec entspricht, einen "break" der Schleife ausführt? Oder ist es
eleganter die Dauer eines Schleifen-Durchganges vorher zu messen (bzw
simulieren) und daraus vor der while-Schleife die Anzahl N der
Schleifen-Durchgänge auszurechnen?
Ich habe nicht so viel Erfahrung mit der Programmierung von uC. Deswegen
bin ich gespannt auf eure Tipps! ;) Danke!
just_tanja schrieb:> ... B. 5 sec entspricht, einen "break" der Schleife ausführt? Oder ist es> eleganter ....
Weder, noch.
Man macht sinnvollerweise keines von beiden sondern ändert die
Programmstruktur so dass nicht auf das Zählereignis aktiv gewartet wird.
Die einzige Dauer-while Schleife ist die von der Hauptschleife in main.
Vor allen Dingen dann nicht, wenn von Zeiten wie 5 Sekunden die Rede
ist.
1
intmain()
2
{
3
...
4
5
while(1){
6
7
...
8
}
9
}
Eine Möglichkeit ist es zb. sich auszurechnen, zu welchem Zeitpunkt die
Anschaltung erfolgen soll, wenn es jetzt 18:02:05 ist und ein Gerät 5
Sekunden eingeschaltet sein soll. Der Zeitpunkt der Abschaltung ist dann
18:02:10. Und in der Hauptschleife prüft man dann ständig, ob dieser
Zeitpunkt erreicht (bzw. überschritten wurde). Man prüft das neben noch
vielen anderen Dingen, die genau nach dem gleichen Muster laufen: Im
Vordergrund steht immer die Frage: Ist ein bestimmtes Ereignis
eingetreten und wenn ja, dann führe eine zugehörige Aktion aus.
Zeitdauern lassen sich so immer in die Form 'Endzeitpunkt =
STartzeitpunkt + Wartezeit' umformen.
Und ja, der interen Zähler, das ist genau das, was man mit einem Timer
realisiert. Da steckt dann der Zeitgeber im Programm drinnen. Leider
programmiere ich keine PIC, daher kann ich dir nicht konkret sagen, wie
das bei einem PIC geht. Aber so wahnsinnig anders als bei einem AVR wird
das auch nicht sein.
Danke für die Antwort! Das mit dem Timer hört sich schon danach an, was
ich suche. Jetzt muss ich nur wissen, wie ich diesen ablesen kann bzw 5
sec damit messen kann))
Die Sache mit 'Endzeitpunkt = Startzeitpunkt + Wartezeit' wird, glaub
ich, schwierig, da ich gar nicht auf die Zeit zugreifen kann...
just_tanja schrieb:> Die Sache mit 'Endzeitpunkt = Startzeitpunkt + Wartezeit' wird, glaub> ich, schwierig, da ich gar nicht auf die Zeit zugreifen kann...
Doch, der Timer hat entsprechende Register welche sich auslesen lassen.
In einem der Register steht wie viele Runden er schon gedreht hat, das
lässt sich in eine Zeit umrechnen wenn man Prescaler und Zeitbasis
kennt.
just_tanja schrieb:> Danke für die Antwort! Das mit dem Timer hört sich schon danach an, was> ich suche. Jetzt muss ich nur wissen, wie ich diesen ablesen kann bzw 5> sec damit messen kann))>> Die Sache mit 'Endzeitpunkt = Startzeitpunkt + Wartezeit' wird, glaub> ich, schwierig, da ich gar nicht auf die Zeit zugreifen kann...
Das war auch nur symbolisch gemeint.
Kleb nicht zu sehr an konkreten Zeiten, wie du sie kennst.
Wenn du ein 'Gerät' hast, dass alle 1/10 Sekunde 'tick' macht, dann
musst du eben 50 Ticks abwarten, damit das 5 Sekunden entspricht.
Wenn dein Timer alle 1/1000 Sekunde um 1 weiter zählt und jetzt einen
Zählerstand von 4879 hat, dann muss man in der Schleife prüfen, ob der
Zählerstand von 9879 erreicht ist, damit dann 5 Sekunden vergangen sind.
Also: du wirst intern keine 'Zeit' in dem Sinne haben, wie du sie von
einer Uhr abliest. Aber du hast etwas regelmässiges, von dem du weißt in
welchen Zeitabständen es auftritt. Und das reicht dann schon. Der Rest
ist ein bischen Rechnerei.
Cool, danke Leute! Das grobe habe ich verstanden: ich muss in der
Schleife die Anzahl der Timer-Überläufe überprüfen & vorher muss ich ja
aber wissen, wie lange es bis zu einem Timer-Überlauf dauert und wie
viele Überläufe es vor der Schleife gab. "Der Rest ist ein bischen
Rechnerei.")) Oder?
Jetzt muss ich nur in dem pic18f Datenblatt gucken, wo ich die Sachen
auslesen kann bzw vorher aktivieren... Denn Begriffe wie "Prescaler" und
"Zeitbasis" sagen mir nichts=) noch nicht..
@LALELU: Ja, das habe ich mir schon gedacht. Ich finde nur kein gutes
Tutorial. Kennt jmd einen? Ich beschäftigte mich mit dem uC erst seit
paar Monaten, deswegen frage ich hier..
oder auch hier: http://sprut.de/electronic/pic/grund/timer/timer.htm
5 Sekunden sind für einen µC schon ziemlich lange.
Wenn du mit C programmierst, wirst du ja einen C-Compiler haben. Diese
bringen meist Funktionen mit, die du verwenden kannst, z.B. delay_ms();
Wenn du nun 5 Sekunden lang warten UND NICHTS TUN willst, dann baust du
das einfach ein: "delay_ms(5000);". Der Compiler macht dann nichts
anderes als ein paar schleifen zu berechnen (mit dem im Projekt
angegebenen Takt), die insgesammt 5 Sekunden brauchen. Kostet also
"Power" und ein paar Register im RAM für die Zähler.
Eleganter geht es mit den Timern, vorallem, weil man zwischenzeitlich
was machen kann.
Der Timer macht nichts anderes als mit einem gewissen Takt (siehe
Datenblatt) das TMR0-Register immer um eins zu erhöhen. Das läuft im
Hintergrund, weshalb man nebenbei auch andere Sachen machen kann (aber
nicht muss). Ist der Interrupt des Timers aktiviert, wird beim Überlauf,
also wenn das Register von 0xFF zu 0x00 wechselt, ein Interrupt
ausgelöst.
Ein Rechenbeispiel: Wenn dein PIC mit 8MHz Quarz läuft und der Prescaler
vom Timer hochgedreht ist (1:256), dann braucht der Timer für das
Inkrementieren des Registers 0,000128s also 128µs. In 5 Sekunden wird
also (5/0.000128=) 39062 mal inkrementiert. Anstatt man aber jetzt das
TMR0-Register dauernt auf >= 39062 überprüft, regelt man es so, dass
nach 5 Sekunden der Interrupt kommt. Also wird das TMR0 Register auf
(65535-39062=) 26473 gesetzt. Nun Läuft der Timer hoch und nach 5
Sekunden erreicht er 65535. Im nächsten Systemtakt wird der Interrupt
ausgelöst und man kann machen, was man will (z.B. eine Schleife beenden
oder eine Variable ändern).
LALELU schrieb:> Der soll ein Tutorial lesen oder ein Buch
Bei dem Namen bin ich mir nicht Sicher, obs wirklich ein ER ist.