Forum: Mikrocontroller und Digitale Elektronik Timerwert im Lauf anzeigen


von soundmachine (Gast)


Lesenswert?

Hallo liebe Mikrocontrollergemeinde,

ich habe ein kleines Problem bei meinem aktuellen µC Projekt und hoffe 
ihr könnt mir helfen.

Zu meinem Status. Ich habe bisher mit Mikrocontrollern ein paar LED RGB 
Ansteuerungen sowei eine Wellenpaketsteuerung realisiert und habe mich 
nun an ein neues Projekt gewagt.
In diesem Projekt geht es um mehrere Ultraschallsensoren, die bei 
Auftreten verschiedener Eingangszustände (diese können sich alle 5s aber 
auch bis zu alle 30-40 min ändern) sollen verschiedene Ausgänge für 10ms 
ein EIN-Signal erhalten. Da ich nicht alle 10ms einen Timerinterrupt 
auslösen will in dem ich dann die meiste Zeit doch nichts mache suche 
ich nach alternativen Realisierungsmöglichkeiten. Meine Idee:

Den TIMER0 verwenden und diesen imme rim Hintergrund bis zum Überlauf 
durchlaufen lassen. Dann, nicht in der ISR, sondern in Hauptptogramm bei 
Auftreten der entsprechenden Eingangszustände den Zählerstand des 
Registers abrufen und solange den Ausgangs schalten, bis der Zähler 
einen 10ms höheren Wert hat? (Vorteiler etc. natürlich mit berechnet).

Frage: Ist der lesende Zugriff auf das Timerregister im Hauptptogramm 
möglich oder ist dies nur in der ISR schreibend möglich um den Timer 
vorzuladen?
Gibt es sond irgendwelche Sachen die ich bei dieser Idee nicht 
berücksichtigt habe?

Für eure konstruktiven Meinungen/Hilfen bin ich sehr dankbar

von Falk B. (falk)


Lesenswert?

@  soundmachine (Gast)

>ein EIN-Signal erhalten. Da ich nicht alle 10ms einen Timerinterrupt
>auslösen will in dem ich dann die meiste Zeit doch nichts mache

Warum nicht? Ist im Normalfall kein Problem, es sei denn mam will/muss 
Strom sparen und einen Sleep Mode verwenden.

Im einfachsten Fall tut es ein _delay_ms(10), ist nicht das Schönste, 
geht aber.

>Den TIMER0 verwenden und diesen imme rim Hintergrund bis zum Überlauf
>durchlaufen lassen. Dann, nicht in der ISR, sondern in Hauptptogramm bei
>Auftreten der entsprechenden Eingangszustände den Zählerstand des
>Registers abrufen und solange den Ausgangs schalten, bis der Zähler
>einen 10ms höheren Wert hat? (Vorteiler etc. natürlich mit berechnet).

Das ist das Gleiche wie _delay_ms(10). Die CPU wartet "aktiv".

>Frage: Ist der lesende Zugriff auf das Timerregister im Hauptptogramm
>möglich

Sicher.

> oder ist dies nur in der ISR schreibend möglich um den Timer
>vorzuladen?

Nein.

>Gibt es sond irgendwelche Sachen die ich bei dieser Idee nicht
>berücksichtigt habe?

Keine Ahnung. Wenn während er 10ms sowiso nix weiter zu tun ist für die 
CPU, kann man das so machen. Anderenfalls sollte man den Timer immer 
laufen lassen und nur die ISR per Bit im TIMSK Register ein und aus 
schalten. In dem speziellen Fall der 10ms setzt man dann noch den Timer 
auf Null und hat damit sofort eine 10ms Wartezeit, währendessen die CPU 
weiterarbeiten kann.

MFG
Falk

von Thomas E. (thomase)


Lesenswert?

soundmachine schrieb:
> Da ich nicht alle 10ms einen Timerinterrupt
>
> auslösen will in dem ich dann die meiste Zeit doch nichts mache

Was spricht denn dagegen?

Wenn er sowieso nichts macht, dann kann er auch das machen.
Das Auslesen des Timerregisters geht natürlich. Aber das ist doch viel 
aufwendiger.

mfg.

von Dennis (Gast)


Lesenswert?

Also ich weiß zwar nicht, welchen Controller du verwendest, aber beim 
MSP ist es so, dass du klar jederzeit das Register Auslesen kannst, 
davon für sehr genaue Timing-Geschichten aber abgeraten wird, da dies 
die Inkrementierung stört. Aber es hört dich bei dir nicht nach einer 
ultra-exakten Sache an.

von Tobias Hagemeier (Gast)


Lesenswert?

Ohne die Information, mit welchem µC du arbeitest, wird dir wohl leider 
niemand helfen können. TIMER0 lässt zwar einige Rückschlüsse zu, aber 
trotzdem kann niemand hellsehen ;-)

von soundmachine (Gast)


Lesenswert?

Hi, vielen dabk schonmal für die Antworten,

während der 10ms muss ich sonst eigentlich erst mal nichts machen, aber 
in der restlichen zeit hat er sehr viel mit Datebloggen, rechnet mit 
floats etc zu tun, so dass ich ihn nicht alle 10ms in eine ISR schicken 
wollte, statdessen würde iche infach eine if anweisung machen in der das 
Eingangsbite als Bedingung gilt und erst dann sowas wie lese Timerwert 
und setzt den Ausgangs auf high, irgendwo anders im Hauptprogramm dann 
sowas wie, wenn der Timerwert 10 höher ist wie den Auslesewert, dann 
schalte den Ausgang aus (Überlauf muss man natürlich irgendwie 
mitberücksichtigen).
Dann kann er während der 10 ms wenigstens noch was andres machen.

@Falk, deine beschriebene Methode, den Interrupt für die restlichen 
Zeiträume zu sperren hört sich am elegantesten an. Könntest du das etwas 
detaillierter Ausführen?
Würde das bedeuten, einfach ein cli() an den Anfang des Programms und 
ein sei() in eine if Anweisung wenn die Eingangsport stimmen und dann 
dort gleich den Ausgang einschalten und den Timer entsprechend vorladen 
und in der ISR den Ausgang auschalten? ahbe ich das so richtig 
verstanden?

Vielen dabks chonmal...Ihr seid super

von soundmachine (Gast)


Lesenswert?

Nachtarg....Ich verwende einen Atmega 32

von Falk B. (falk)


Lesenswert?

@soundmachine (Gast)

>Zeiträume zu sperren hört sich am elegantesten an. Könntest du das etwas
>detaillierter Ausführen?

Habe ich das nicht?

>Würde das bedeuten, einfach ein cli() an den Anfang des Programms und
>ein sei() in eine if Anweisung wenn die Eingangsport stimmen

Nein. Davon schrieb ich auch nicht. Der Timerinterrupt wird per 
zugehörigem Bit iM TIMSK-Register ein und aus geschaltet.

> und dann
>dort gleich den Ausgang einschalten

ja.

> und den Timer entsprechend vorladen

Vergiss doch mal dieses dämliche Vorladen! Im Jahr 2010 gibt es den CTC 
Modus.

>und in der ISR den Ausgang auschalten?

ja.

> ahbe ich das so richtig verstanden?

Nur die Hälfte.

von soundmachine (Gast)


Lesenswert?

Hi, habe grad nochmal im Tutorial hier nachgeblättert. Also TIMSK zum 
Einschalten/Aktivieren/Freigeben der ISR im Hauptprogramm verwenden und 
zum Abschalten der Interruptfreigabe in der ISR selbst. Im Hauptprgramm 
den Ausgang einschalten und den Timer auf = setzen und dann den 
Comparemode ISR verwenden für die 10ms und dort den Ausgang wieder 
Ausschalten.
So richtig?

Wunderbar, hatte an den bedingten Aufruf, bzw. an das Zu- und Abschalten 
des Interrupts garnichtmehr gedacht.

Vielen dank schonmal und einen schönen Abend

von Falk B. (falk)


Lesenswert?

@  soundmachine (Gast)

>So richtig?

Ja.

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.