Forum: Mikrocontroller und Digitale Elektronik Atmega8 und C - Eine Frage zur Programmgestaltung


von Moritz (Gast)


Lesenswert?

Hallo,

hoffe ihr habt nicht so schlechtes Wetter wie ich in Berlin ;)

Jedenfalls hat mich das schlechte Wetter dazu veranlasst mal wieder 
etwas mit µC zu basteln. Jedoch habe ich eine Frage, die ich mir schon 
länger stelle und bisher immer programmiertechnisch irgendwie umgangen 
habe.

Folgendes fiktives Szenario:
- Atmega8 und eine in C Programmierte Uhr, die über den internen Timer 
läuft und einfach hochgezählt wird
- es ist also notwendig, dass der Atmega8 andauernd zählt, also etwas zu 
tun hat so etwas wie sleep 1 sek und erhöhe dann Sekunden-Zahl auf dem 
Display um eine Einheit
- wie bekommt man es denn programmiertechnisch am besten hin, wenn man 
nun auf einen Tastendruck reagieren will? Läuft das dann über 
Interrupts? Oder muss ich in der while-Hauptschleife bei jedem Durchlauf 
prüfen, ob die Taste gedrückt wird?

Wie gestaltet man denn so etwas am besten? Insbesondere lässt man doch 
sicher nicht bei einer Uhr den Atmega immer 1sek. in sleep oder?

von Wolfgang (Gast)


Lesenswert?

Moritz schrieb:
> Wie gestaltet man denn so etwas am besten?

Mit einem Timer.
Beitrag "Die genaue Sekunde / RTC"

von Stefan (Gast)


Lesenswert?

sleep 1sek ist kein geigneter Ansatz, da du nicht wiesst, wie lange die 
anderen Aktionen zwischen den Sekunden dauern. Die Uhr würde ungenau 
laufen. Benutze einen Timer-Interrupt, um die Zeit zu messen. Ob Du auch 
die Anzeige als Interrupt-Routine umsetzt, bleibt deinen persönlichen 
Vorlieben überlassen. Es spielt ja keine Rolle, ob die Anzeige in einem 
exakten Zeitraster aufgefrischt wird, solande die angezeigte Zeit 
stimmt.

von Coder (Gast)


Lesenswert?

Wenn man den Sleep-Mode verwenden möchte, würde man sich bei diesem 
Szenario fiktiv das Kapitel über die Sleep-Modes durchlesen.

von Moritz (Gast)


Lesenswert?

Danke für die Hinweise.

Und wie reagiert man dann auf einen Tasterdruck? Auch über einen 
Interrupt?

von Oliver J. (skriptkiddy)


Lesenswert?

Moritz schrieb:
> es ist also notwendig, dass der Atmega8 andauernd zählt, also etwas zu
> tun hat so etwas wie sleep 1 sek und erhöhe dann Sekunden-Zahl auf dem
> Display um eine Einheit
Zu unpräzise, die Uhr wird mit Delays als Zeitbasis nie genau gehen.


> Oder muss ich in der while-Hauptschleife bei jedem Durchlauf
> prüfen, ob die Taste gedrückt wird?
Ist die am häufigsten gewählte Lösung. Denke aber an die Entprellung.


> Und wie reagiert man dann auf einen Tasterdruck? Auch über einen
> Interrupt?
Wozu das denn? Das macht man am einfachsten so:
1
if (Taste_gedueckt()) {
2
  mach_was();
3
}
Oliver

von Der Hase (Gast)


Lesenswert?

Oliver J. schrieb:
> Wozu das denn? Das macht man am einfachsten so:
> if (Taste_gedueckt()) {
>   mach_was();
> }

Das gehoppel in mach_was() möchte ich nicht sehen, wenn die Taste ein 
bisschen prellt.

von Moritz (Gast)


Lesenswert?

Also als Bsp so:



while () {

   aktualisiere_LCD_wegen_Zeit();

   if (Taste gedrückt) {
       lass mich im Lotto gewinnen;
   }
}


aber was ist, wenn die Aktualisierung des LCDs 5 Minuten dauert, dann 
kann ich in dieser Zeit den Taster drücken wie ich will und dann werde 
ich nie im Lotto gewinnen oder?

von Oliver J. (skriptkiddy)


Lesenswert?

Moritz schrieb:
> aber was ist, wenn die Aktualisierung des LCDs 5 Minuten dauert, dann
> kann ich in dieser Zeit den Taster drücken wie ich will und dann werde
> ich nie im Lotto gewinnen oder?
Multitasking

von Coder (Gast)


Lesenswert?

Vielleicht sollte sich der Threadersteller die Mühe machen und sich 
erstmal ein Konzept überlegen.  Wenn er das hat, schaut er sich mal an, 
was sein uC so kann. Als nächstes würde mal das Forum nach 
Informationen.

von Moritz (Gast)


Lesenswert?

Danke für die Antworten,

mir ging es vielmehr um das Verständins solch einer Realisierung. Also 
halte ich mal fest, dass es mit einem Atmega8 nicht möglich ist, einen 
Tastendruck einfach so während einer Aktion mitzubekommen.

Mir bleibt also generell nur, regelmäßig den Zustand des Ports an dem 
der Taster hängt abzufragen, ob die Taste zufällig gerade in dem Moment 
gedrückt wird. Richtig?

Ich habe schon diverse Tuts von dieser Seite hier versucht aber ich 
wollte auch gern mal wissen, wie das die Profis hier so realisieren und 
nicht wie ich meine das Tut interpretiert zu haben.

von Karl H. (kbuchegg)


Lesenswert?

Moritz schrieb:
> Danke für die Antworten,
>
> mir ging es vielmehr um das Verständins solch einer Realisierung. Also
> halte ich mal fest, dass es mit einem Atmega8 nicht möglich ist, einen
> Tastendruck einfach so während einer Aktion mitzubekommen.

Natürlich ist das möglich.

Du hast ja auch noch einen Timer.
Und dieser Timer kann regelmässige Interrupts auslösen.
Und in der zugehörigen ISR sieht man nach, ob und wenn ja welche Tasten 
gedrückt sind und merkt sich das in einer Variablen.

>
> Mir bleibt also generell nur, regelmäßig den Zustand des Ports an dem
> der Taster hängt abzufragen, ob die Taste zufällig gerade in dem Moment
> gedrückt wird. Richtig?

Im Prinzip richtig.
Nur macht man das mit einem Timer.

> wollte auch gern mal wissen, wie das die Profis hier so realisieren und
> nicht wie ich meine das Tut interpretiert zu haben.

Entprellung
-> die Komfortroutinen von Peter Danegger.
Alles was man braucht.

von Oliver J. (skriptkiddy)


Lesenswert?

Moritz schrieb:
> Mir bleibt also generell nur, regelmäßig den Zustand des Ports an dem
> der Taster hängt abzufragen, ob die Taste zufällig gerade in dem Moment
> gedrückt wird. Richtig?
Ja. Du musst halt nur aufpassen, dass die Hauptschleife schnell genug 
wiederholt wird.

Gruß Oliver

von Maxx (Gast)


Lesenswert?

Moritz schrieb:
> mir ging es vielmehr um das Verständins solch einer Realisierung. Also
> halte ich mal fest, dass es mit einem Atmega8 nicht möglich ist, einen
> Tastendruck einfach so während einer Aktion mitzubekommen.

Natürlich kann man das, allerdings mit zweifelhaften Nutzen und ein paar 
Pitfalls. (Das Entprellen z.B. nicht vergessen und immer gut aufpassen 
beim Ändern von Parametern mit denen zur gleichen Zeit gearbeitet wird)

> Mir bleibt also generell nur, regelmäßig den Zustand des Ports an dem
> der Taster hängt abzufragen, ob die Taste zufällig gerade in dem Moment
> gedrückt wird. Richtig?

Das ist richtig. Regelmäßig kann aber auch ein Timer Interrupt sein. 
Allerdings ist die Frage, wie dein Programm darauf reagieren soll, wenn 
es sowieso längere Zeit In einem Ablauf festhängt?
Eine Taste auf die erst Sekunden später reagiert wird ist weit 
ärgerlicher als eine Taste auf die gar nicht reagiert wird imho.

> Ich habe schon diverse Tuts von dieser Seite hier versucht aber ich
> wollte auch gern mal wissen, wie das die Profis hier so realisieren und
> nicht wie ich meine das Tut interpretiert zu haben.

Aufgaben in der Main granulieren. Statemachines sind dazu sehr gut 
geeignet. Zeitmessungen/Warten per Hardware-Timer realisieren. Das 
erlaubt dir auf Tastendrücke oder andere Events als Auslöser für 
Transitionen zu reagieren, Abläufe zu unterbrechen, manipulieren oder 
beenden.

Dokumentation kommt dabei quasi frei-haus dazu (FSM in Graphen gießen).

von Karl H. (kbuchegg)


Lesenswert?

Moritz schrieb:

> aber was ist, wenn die Aktualisierung des LCDs 5 Minuten dauert

... dann hast du bei der LCD-Aktualisierung was falsch gemacht.

von Dennis H. (t1w2i3s4t5e6r)


Lesenswert?

Moritz schrieb:
> Ich habe schon diverse Tuts von dieser Seite hier versucht aber ich
> wollte auch gern mal wissen, wie das die Profis hier so realisieren und
> nicht wie ich meine das Tut interpretiert zu haben.

Ich bin definitiv kein Profi, trotzdem kann ich dir verraten, wie es die 
meisten hier machen. Sehr viele Controller haben ja nicht nur einen 
Timer, sondern mindestens zwei. Und in den meisten Anwendungen benötigt 
man so oder so einen Interrupt, der sehr regelmäßig auftritt, ähnlich 
deinem Uhr Timer Interrupt, nur eben schneller. Als simples Beispiel 
wäre z.B. Multiplexing zu nennen. Da benötigst du einen Timer, der dir 
vielleicht alle 10ms einen Interrupt bringt. Es ist doch kein Problem, 
in diesem Interrupt auch mit zu schauen, ob eine Taste gedrückt wurde. 
Wie das effizient aussehen kann gibts hier genügend Codebeispiele, 
einfach mal nach Entprellung suchen. So kann dein Controller trotzdem 
die meiste Zeit schlafen, außerdem sind dem Controller die paar BEfehle 
sowas von egal, das macht zeitlich fast keinen Unterschied und vom 
Stromverbrauch isses auch recht egal.

Ich denke mal, dich stört es, das der Controller alle paar ms 
nachschaut, ob die Tasten gedrückt werden. Aber das ist doch völlig 
egal, wie oft er das macht, das ist ja kein Mensch, der Geld für die 
Zeit haben will, die er arbeitet.

MfG Dennis

von Moritz (Gast)


Lesenswert?

Danke für eure Tipps. Das ist genau die Hilfe, die ich gebraucht habe 
damit ich das ganze mal zusammenhängend erklärt bekomme. Die Tutorials 
sind zwar echt gut aber der Zusammenhang ist mir nicht klar geworden wie 
man das in einem größeren Projekt realisiert.

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.