Atmega8 und C - Eine Frage zur Programmgestaltung

Gast #2863341
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?
Gast #2863353
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.
#2863405
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
Gast #2863424
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?
Gast #2863444
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.
Gast #2863470
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.
#2863488
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.
Gast #2863497
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).
#2863504
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
Gast #2863507
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren