Steffen schrieb:> ISR (TIMER0_COMPA_vect)
static tasten-time;
if (++tasten_time>=10){tasten_timer=0;Pedas_Tasten_Dingens() (oder ein
global_flag für die Main_Loop setzen);}
Nimm halt den 1ms Timer und rufe jedes 10. Mal die Routinen von Peter
auf.
Taster ist ja im Normalfall nichts mega hochpriores. Also reicht das
wahrscheinlich sogar über ein polling in Main.
Edit: zu langsam getippt 😄
Am übersichtlichsten finde ich:
Eine ISR, die einfach nur die "millisekunden" Variable hoch zählt. Dazu
für jede Aufgabe eine eigene Funktion. Und eine "main" Schleife, die
einfach nur reihum alle Funktionen aufruft.
Deine entprellen Funktion fragt dann die "millisekunden" Variable ab.
Wenn genug Zeit vergangen ist setzt sie eine Variable "taster1" oder
ähnliches.
Die Funktion, die deine Arbeit macht fragt dann die "taster1" Variable
ab.
(Das eigentliche Problem - mit der Zeit kommen immer mehr Ideen, die du
auch noch einbauen willst. Das Programm von vorn herein so anlegen, dass
die Funktionen einfach und überschaubar bleiben.)
Der Opa aus der Muppet Show schrieb:> Eine ISR, die einfach nur die "millisekunden" Variable hoch zählt. Dazu> für jede Aufgabe eine eigene Funktion. Und eine "main" Schleife, die> einfach nur reihum alle Funktionen aufruft.>> Deine entprellen Funktion fragt dann die "millisekunden" Variable ab.> Wenn genug Zeit vergangen ist setzt sie eine Variable "taster1" oder> ähnliches.
Wie so für 'jede' Funktion die ms prüfen? Bau dir 'Time-Slots'!
Da bleibst auch übersichtlicher.
Der Opa aus der Muppet Show schrieb:> Deine entprellen Funktion fragt dann die "millisekunden" Variable ab.
Nö, die Entprellfunktion muß in einem festen Intervall aufgerufen
werden, z.B. alle 10ms. Die Lösung dazu wurde ja schon von Teo D.
genannt.
Der Opa aus der Muppet Show schrieb:> Die Funktion, die deine Arbeit macht fragt dann die "taster1" Variable> ab.
Nö, die Mainloop fragt nur ganz bequem die Ereignisbits ab und löscht
sie.
Ihr ist im Prinzip egal, wer die Ereignisbits setzt. Man kann so ganz
einfach den Tasten am Gerät eine IR-FB oder Tastenbefehle über die UART
parallel schalten.
Steffen schrieb:> Wie kann ich am besten einen Timer mit 1ms für beide Aufgaben verwenden?
Indem du in der ISR beides nacheinander durchführst - das setzt
natürlich voraus, dass keine der Aufgaben (das können noch einige mehr
sein) die Ausführung länger blockiert, Delays sind verboten.
Ich führe praktisch alle Hintergrundtätigkeiten in einem regelmässigen
Time-Interrupt durch, manche auch nur in jedem 2. oder xten. Man muss
nur überschlagen, ob nicht die Bearbeitungszeit den Timer Tick
überschreiten kann. Aufgaben, die nicht in jedem Tick bearbeitet werden
verschachtelt man. So kann man auch auf einen extra 10ms Tick
verzichten.
bei 1 ms kann man einen Zähler verwenden:
Taster gedrückt:
ist der Wert < 10, dann um 1 hochzählen, bei 10 Flag für den Eingang
setzen.
ist der Wert 10, nichts
Taster nicht gedrückt:
Ist der Wert > 0, dann um 1 runterzählen, bei 0 Flag für den Eingang
rücksetzen.
Ist der Wert 0, nichts
Mit dem Maximalwert bestimmt man die Reaktionszeit - kurz für Gamer,
lang für Maschinenbediener, ist also sehr flexibel.
Georg
> Nö, die Entprellfunktion muß in einem festen Intervall aufgerufen> werden
Eigentlich nicht wirklich. In diesem Fall kommt es auf eine Millisekunde
hin oder her nicht an.
In Summe bekommst du die wenigsten Probleme, wenn du in den ISRs nur die
wirklich zeitkritischen Sachen machst. Na ja, in diesem Fall nicht so
wichtig, Entprellen braucht ja nur ein paar Taktzyklen.
> Nö, die Mainloop fragt nur ganz bequem die Ereignisbits ab und löscht> sie.
Kommt drauf an, wie umfangreich das Programm wird. Wenn das Programm 30
verschiedene Aufgaben gleichzeitig erledigt, wird so ein Ansatz halt
unübersichtlich, Fehler im Programmablauf suchen wird aufwendig.
> Bau dir 'Time-Slots'!
Ja, eine gute Richtung! Schau dir die Standard Designpattern an sobald
du genug Erfahrung hast um zu sehen, wie genial so einfach aussehende
Konzepte wie Time-Slots sind.
Der Opa aus der Muppet Show schrieb:> Eigentlich nicht wirklich. In diesem Fall kommt es auf eine Millisekunde> hin oder her nicht an.
Genau. Deshalb braucht man nicht umständlich die long Variable
Millisekunden überlauffest zu vergleichen. Es reicht ein simples Byte
bis 10 zu zählen.
Der Opa aus der Muppet Show schrieb:> Kommt drauf an, wie umfangreich das Programm wird. Wenn das Programm 30> verschiedene Aufgaben gleichzeitig erledigt, wird so ein Ansatz halt> unübersichtlich, Fehler im Programmablauf suchen wird aufwendig.
Im Gegenteil, gerade bei umfangreichen Programmen lohnt es sich
besonders, daß die Entprellung, Flankenerkennung, Repeat und Lang
Auswertung im Interrupt passiert. Es sind nur wenige logische
Operationen, d.h. nur sehr geringe CPU-Last.
Das Main darf sogar heftig beschäftigt sein und das Ereignisbit erst
auswerten, wenn schon wieder losgelassen wurde.
Die Fehlersuche vereinfacht sich auch erheblich, weil das Main ja mit
dem Tasten einlesen nichts mehr zu tun hat.
Es ist schon abenteuerlich, welche unübersichtliche und fehlerträchtige
Konstrukte manchmal erstellt werden, um mehr schlecht als recht im Main
zu entprellen.
> Im Gegenteil
Yeah! Genau deswegen bringen diese Mikrocontroller Projekte Spaß.
Hatte mal Bauing studiert. Da hatte man uns beigebracht, wir müssen
alles nach DIN Norm machen. Ende der Durchsage. Total langweiliger Job.
Wenn du als Programmierer fragst, wie man es macht, empfiehlt dir jeder
das Gegenteil. Und du musst selbst herausfinden, wie es am besten
funktioniert.
Teo D. schrieb:> Wie so für 'jede' Funktion die ms prüfen? Bau dir 'Time-Slots'!> Da bleibst auch übersichtlicher.
Sorry, vor Tastern habe ich keine Angst, aber das habe ich noch nie
gemacht.