Forum: Mikrocontroller und Digitale Elektronik Delay Funktion ohne _delay_ms(). Wie umsetzten?


von Jan H. (jan_h865)


Lesenswert?

Guten Tag,
Ich hätte da mal ne Frage und zwar habe ich bis, jetzt immer mit der 
_delay_ms(time) Funktionen gearbeitet. Nun habe ich aber am RESET Pin 
des Atmega328p ein Drucktaster angeschlossen. Das Problem ist da 2 LED 
immer blinken und die _delay_ms Funktion dafür nutzen. Reagiert der 
Taster nur wenn man drückt wenn die LED aus ist.
Beim Arduino gibt es die millis() Methode. Aber ich weis nicht wie ich 
sie im Atmel Studio umsetzten soll.

Kann mir da einer helfen?

Lg Jan Hampel

von Dussel (Gast)


Lesenswert?

Jan H. schrieb:
> Beim Arduino
Das Signalwort Arduino im Zusammenhang mit so einer Frage…

Vielleicht hilft das weiter: 
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer

von Jan H. (jan_h865)


Lesenswert?

Dussel schrieb:
> Jan H. schrieb:
>> Beim Arduino
> Das Signalwort Arduino im Zusammenhang mit so einer Frage…
>
> Vielleicht hilft das weiter:
> http://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer

Ah, ich brauche also ein Overflow Interrupt. Aber die LED Blinken zum 
beispiel alle 250 ms. Wie berechne ich das dann? Bzw. erzählt ja bis 256 
hoch(wenn ich das richtig verstanden habe) Und löst dann das Interrupt 
aus.

Wenn ich ein Takt von 16 Mhz habe und ein Prescaler von 64 verwende. Und 
dazu noch ein 8 Bit Timer. Dann müsst das Interrupt jede. 1,024 ms 
ausgelöst werden

16000000  64  256 Hz = 976,5625

1 / 976,5625 = 0,001024 = 1,024 ms?

Dann könnte man doch ein Integer(uint8_t = 8 Bit müssten 255 gewesen 
sein) hoch zählen lassen und diesen jede 1,024 ms denn Integer um 1 
erhöhen dann müsste ja nach 250 Overflows der Integer 250 haben. Und 
dann könnte man ja mit einer If Abfrage abfragen ob der Wert >= 250 ist. 
Und dann die LED mit einer XOR Anschalten und dann denn Integer wieder 
auf 0 setzten und wieder hoch zählen, lassen. Dann müsste die LED danach 
doch wieder aus gehen oder?

Ist meine Theorie so richtig?

von Dussel (Gast)


Lesenswert?

Ja, so ist das Grundprinzip.

Wenn man nur bis 244 zählt, kommt man sogar bis auf 50 µs an die 250 ms 
ran.

Es gibt vielen AVR auch noch einen 16-Bit-Timer bei dem man den 
Zählerstand zum Auslösen des Interupts beliebig festlegen kann. Das wäre 
auch eine Möglichkeit, halte ich aber hier für unnötig aufwendig.

von Sascha (Gast)


Lesenswert?

Overflow Interrupt geht prinzipbedingt nur bis TOP, das ist 255 bei nem 
8bit und 65535 bei nem 16 bit timer.

Will man möglichst genau auf 250ms kommen, muss man den TOP-Wert selbst 
festlegen.

Steht im Datenblatt, Stichworte CTC Modus, OCR1A, WGM Bits.

von Wolfgang (Gast)


Lesenswert?

Sascha schrieb:
> Will man möglichst genau auf 250ms kommen, muss man den TOP-Wert selbst
> festlegen.

... und wenn dann der Taster alle 10ms abgefragt werden soll, braucht 
man wieder einen Timer?

Spätestens nach der dritten blinkenden LED werden dann die Timer knapp. 
:-(

Besser ist es, sich einen Basistakt festzulegen (z.B. 10ms) und dann für 
jede Aktion festzulegen nach wieviel Basistakt-Interrupts die 
stattfinden soll, z.B. bei jedem Takt den Taster prüfen oder bei jedem 
25. Takt die LED umschalten.

von Stefan F. (Gast)


Lesenswert?

Timer ist schon mal ein gute Stichwort. Als nächstes befasse dich mit 
Zustandsautomaten.

von Sascha (Gast)


Lesenswert?

Wolfgang schrieb:
> Sascha schrieb:
>> Will man möglichst genau auf 250ms kommen, muss man den TOP-Wert selbst
>> festlegen.
>
> ... und wenn dann der Taster alle 10ms abgefragt werden soll, braucht
> man wieder einen Timer?
>
> Spätestens nach der dritten blinkenden LED werden dann die Timer knapp.
> :-(
>
> Besser ist es, sich einen Basistakt festzulegen (z.B. 10ms) und dann für
> jede Aktion festzulegen nach wieviel Basistakt-Interrupts die
> stattfinden soll, z.B. bei jedem Takt den Taster prüfen oder bei jedem
> 25. Takt die LED umschalten.

Das stimmt, aber man kann ja auch beliebig viele Taster in einer 
Timer-Routine abfragen.

Noch besser: Flags für die main() setzen oder Funktionen zur Ausführung 
per void* Array vormerken. Letzteres dann am besten nicht ohne Debugger.

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.