Forum: Mikrocontroller und Digitale Elektronik PIC Zähler während der while loop


von just_tanja (Gast)


Lesenswert?

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!

von Karl H. (kbuchegg)


Lesenswert?

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
int main()
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.

von just_tanja (Gast)


Lesenswert?

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...

von troll (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von just_tanja (Gast)


Lesenswert?

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..

von LALELU (Gast)


Lesenswert?

Hört doch mal auf. Der soll ein Tutorial lesen oder ein Buch. Ist ja 
lächerlich.

von just_tanja (Gast)


Lesenswert?

@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..

von Stefan (Gast)


Lesenswert?


von just_tanja (Gast)


Lesenswert?


von Michael S. (rbs_phoenix)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.