Hallo zusammen,
Vielleicht ist es auch sehr trivial, allerdings finde ich seit Stunden
kein Ansatz. Im Beispiel Multitasking wird neben der UART-Lesung
eine LED in unterschiedlichen Frequenzen zum Blinken gebracht. Wenn der
Taster betätigt wird blinkt sie langsam, wenn er nicht betätigt wird
blinkt sie schneller.
In meinen Beispiel soll nun die LED für ~3sec aufleuchten wenn ich den
Taster einmal betätige mittels Kooperatives Multitasking.
Hier der Beispielcode:
1
#define F_CPU 2000000
2
#define LED PC1
3
#define taster PB1
4
5
#include<avr/io.h>
6
#include<avr/delay.h>
7
#include<avr/interrupt.h>
8
9
uint8_ttaste_lesen(void){
10
if(PINB&(1<<taster))
11
return1;
12
else
13
return0;
14
}
15
16
voidled_blinken(uint8_ttaste){
17
if(taste){
18
PORTC|=(1<<LED);
19
_delay_ms(3000);//hier ohne _delay_ms arbeiten !
20
}
21
else{
22
PORTC&=~(1<<LED);
23
}
24
}
25
26
intmain(void){
27
int8_ttaste;
28
29
DDRB&=~(1<<taster);
30
DDRC|=(1<<LED);
31
32
while(1){
33
taste=taste_lesen();
34
led_blinken(taste);
35
_delay_ms(1);// 1 ms warten
36
}
37
}
Kann mir jemand dabei helfen wie man das macht?
Vielen Dank
M. S. schrieb:> _delay_ms(3000); //hier ohne _delay_ms arbeiten !> ...> Kann mir jemand dabei helfen wie man das macht?
Genau - so wie es im Kommentar steht.
Eine FSM wäre die übliche Struktur für die Steuerung.
Danke für die Antwort. Allerdings hilft mir das nicht weiter. Hätte ich
gewusst wie ich es umsetze, hätte ich den Kommentar nicht in die Zeile
geschrieben.
Wie wäre es erstmal mit einem ganz einfachen Ansatz: auf Tastendruck
einen Timer aktivieren, d.h. mit den passenden Parametern für die 3 s
initialisieren plus LED einschalten, und in der dazugehörenden ISR den
Timer deaktivieren plus LED ausschalten.
Mag vielleicht nicht besonders elegant sein und hat wohl auch nicht
direkt etwas mit "Kooperativem Multitasking" zu tun, wird aber
funktionieren wie verlangt.
M. S. schrieb:> gibt es keinen anderen Weg ..es muss also mit FSM gemacht werden?
"Andere" Wege gibt es immer...
M. S. schrieb:> oder ist das einfach nur die "bessere" Lösung?!
Das ist eine ziemlich gute und wohl auch die einfachste Lösung.
Sowas sind Grundlagen, an denen man nicht vorbei kommt, wenn man
Programmieren lernen will.
M. S. schrieb:> gibt es keinen anderen Weg ..es muss also mit FSM gemacht werden?
Du hast doch "Kooperatives Multitasking" gewünscht. Wenn man kein
fertiges Betriebssystem laufen hat, dass das organisiert, muss man
selber etwas passendes aufbauen. Was stört dich an einer, in diesem
Falle zweifelsohne, minimalistischen FSM?
ich bin erstaunt wie wenig ich doch alleine schaffe. kann mir jemand mit
einem Beispiel ein kleinen Ansatz geben wie man so etwas realisiert. Ich
komme auch hier seit Stunden nicht weiter.
M. S. schrieb:> ich bin erstaunt wie wenig ich doch alleine schaffe. kann mir jemand mit> einem Beispiel ein kleinen Ansatz geben wie man so etwas realisiert. Ich> komme auch hier seit Stunden nicht weiter.
Vielleicht hilft dir das ja:
https://www.youtube.com/watch?v=RlAWHF3cqvs
M. S. schrieb:> gibt es keinen anderen Weg ..es muss also mit FSM gemacht werden?> oder ist das einfach nur die "bessere" Lösung?!
Es gibt tausend Wege...
Aber alle, fast alle, Programme welche auf µC laufen, und das gewollte
tun, sind endliche Automaten. Auch gerne mehrere miteinander verschränke
STM.
Und das hat nichts damit zu tun, ob der Programmierer das Konzept kennt,
so nennt, oder gar es verstanden hat.
Man kann sich z.B. einen Timerservice implementieren, der im Interrupt
(ausgelöst durch einen Timer, der z.B. alle 1 ms aktiviert wird), diesen
auf Bereit stellt und nur dann etwas macht. Mesit wird dies dann so
gemacht, dass man z.B. eine globale timervariable hochzählt, die
Systemzeit quasi und die Timer oder was man davon benötigt dann bei
einer bestimmten Systemzeit auf bereit gesetzt werden. In der
Hauptschleife wird dieses bereit Flag dann ausgewertet und der
entsprechnde Code durchgeführt.
Lies dir doch mal das hier durch "Verbesserter Ansatz mit Timer" unter
https://www.mikrocontroller.net/articles/Multitasking dort ist
beschrieben, wie sowas gehen kann.
@ M. S. (ekkie)
>ich bin erstaunt wie wenig ich doch alleine schaffe.
Ich auch.
> kann mir jemand mit>einem Beispiel ein kleinen Ansatz geben wie man so etwas realisiert.
Warum orientierst du dich nicht an genau DER Vorlage, die du schon
zitiert hast? Dort ist FAST genau das drin, was du brauchst.
> Ich komme auch hier seit Stunden nicht weiter.
Weil du weder lesen noch denken kannst oder willst?
Es gibt im Artikel die verbessere Variante mit delay_ms() in der
Hauptschleife oder sogar mit Timer. Mehr braucht man nicht.
Der Schöööööler hat nun die Aufgabe, aus einem Dauerblinken ein
einmaliges Blinken zu machen. Ob das möglich ist? Kleiner Tip. Nimm eine
Variable als Rückwärtszähler.
Schau mal hier, da hat jemand anderes genau das selbe "Problem". In
einer Antwort habe ich ein paar erklärende Links zu State Machines
gesammelt:
Beitrag "Re: Arduino mit Sender und Empfänger"
M. S. schrieb:> In meinen Beispiel soll nun die LED für ~3sec aufleuchten wenn ich den> Taster einmal betätige
Dann brauchst Du aber noch eine Entprellung mit Flankenerkennung.
In Deinem Code leuchtet sie permanent, solange die Taste gedrückt
gehalten wird.
Dein Code ist quasi eine verunglückte Ausschaltverzögerung. Die LED kann
kurz nach Loslasen ausgehen, oder max 3s danach.
GENAU! So hilft man Anfängern:
Kaum selbst verstandene Abkürzungen wie FSM und STM besser-
wisserisch als Lösungsweg aufzeigen.
Natürlich - man hat ja selbst keine Ahnung, warum das Schema
funktionieren KÖNNTE: NULL sachdienlichen Hinweis...
Jacko schrieb:> GENAU! So hilft man Anfängern:> Kaum selbst verstandene Abkürzungen wie FSM und STM besser- wisserisch> als Lösungsweg aufzeigen.
Anfänger haben Google, ein passendes Buch zum Einstieg und die Fähigkeit
durch Kombination von digitalen Inhalten und analogen Medien sich
fortzubilden.
Wer mit Statusmaschinen nichts anfangen kann, der lese, kerne und
versuche zu verstehen. Er stelle Fragen mit Sachbezug und mit Badacht.
Danke.
Also:
Google FSM bzw STM und gut ist.