Hallo Mikrocontroller-Gemeinde,
ich bin noch recht neu bei der MC-Programmierung und habe bisher meine
Wartezeiten (so wie im Tutorial) mit Zählschleifen erstellt.
Nun habe ich gelesen, dass man solche Zählschleifen soll, was mir auch
vollkommen einleuchtet, und stattdessen die Wartezeiten über einen Timer
realisiert.
Mir fehlt aber noch der zündende Funke für die Umsetzung. Ich habe hier
zwar schon ein paar Beispiele gesehen, aber die waren in C geschrieben
und meine Programmierkenntnisse in C belaufen sich gegen null bzw. zu
dem was ich durch Analogie zum Assemblerprogrammieren in diese Programme
hineininterpretiere.
Kennt jemand ein Assemblerbeispiel oder eine Seite wo das ganze gut
erklärt ist?
Grüße
Andy
Ich verwende einen ATMega8.
Aber spielt das denn eine Rolle? Die Controller unterscheiden sich doch
m.E. doch hauptsächlich in der Anzahl der Ein-/Ausgänge, Timer etc. und
Multitasking ist doch eher was softwareseitiges...
Andy schrieb:> Aber spielt das denn eine Rolle?
Meinst du denn ein Pic, ein ARM oder ein Intel kennt die gleichen
Assemblerbefehle wie ein 8 Bit Atmel µC?
Selbst innerhalb einer Familie spielt es eine Rolle, denn je nach Chip
hat der uU unterschiedliche Timer und unterschiedliche Interrupts.
Wenn du dich weiter in das Gebiet richtiges 'Multitasking' reinwagen
willst, dann wird das IMHO ohne eine Hachsprache aufwändig, weil du dann
einen Task komplett in Assembler nachbilden musst.
Aber glücklicherweise muss man das auf den kleinen µC gar nicht so weit
treiben, wie man das auf Desktop-Systemen macht.
Multitasking auf einem µC ist oft viel einfacher zu realisieren. Und da
geht es mehr um die Philosophie als um alles andere.
Der Ansatz den man geht lautet:
Es gibt nur eine große Schleife und das ist die Hauptschleife, in die
das Programm nach der Initialisierung der Komponenten einbiegt.
Innerhalb dieser Hauptschleife werden nacheinander mögliche 'Events'
(Ereignisse) abgefragt und wenn das entsprechende Ereignis vorliegt,
dann wird die zugehörige Aktion ausgeführt.
Ein Ereignis kann alles mögliche sein. Das kann ein ansprechender
Schalter sein, das kann aber auch zb der Fall sein, dass ein Timer eine
entsprechendes Zeitintervall runtergezählt hat und somit mit einem Event
signalisiert: Die Zeitdauer, die vorher irgendwann einmal gestartet
wurde, ist jetzt vergangen und die LED die damals eingeschaltet wurde,
muss jetzt wieder abgeschaltet werden.
Gerade bei lezterem (LED blinken) ist somit der konzeptionelle
Programmteil
1
loop:
2
wenn Taste gedrückt
3
LED einschalten
4
Zeit abwarten
5
LED ausschalten
6
7
rjmp loop
ersetzt worden durch
1
....
2
3
loop:
4
5
wenn Taste gedrückt
6
Timer laden und starten
7
LED einschalten
8
9
wenn Timer abgelaufen
10
LED ausschalten
11
12
rjmp loop
der entscheidende Punkt ist, dass der komplette Teil 'Zeit abwarten'
durch eine Timer Lösung ersetzt wurde. Und dadurch, dass nicht gewartet
wird, kriegt man die Kapazität frei, so dass der µC scheinbar mehrere
Dinge gleichzeitig machen kann. Er macht sie natürlich nicht
gleichzeitig sondern immer noch ineinandergeschachtelt hintereinander,
aber das geht so schnell, dass es keinen wirklichen Unterschied mehr zu
echt gleichzeitig macht.
Hallo zusammen,
das von Karl-Heinz skizzierte Scenario ist allerdings etwas anderes als
ein Multitasking. Beim MT ist es m.E. sogar verboten mit Interupts zu
arbeiten, da ausschliesslich der Scheduler über die Vergabe der
Prozzesorzeit entscheidet. Desweiteren gibt es natürlich noch
Prioritäten und auch eine Unterart der Interupts. Suche deshalb mal nach
Scheduler, sollte erstmal genügend Stoff zum Lesen geben. Wenn Du
allerdings nur einfache Aufgaben zu erledigen hast, kannst Du auch wie
beschrieben mittels eines Timer Prozzesortasks starten und stoppen.
Gruss
Roman
Roman schrieb:> Hallo zusammen,>> das von Karl-Heinz skizzierte Scenario ist allerdings etwas anderes als> ein Multitasking.
Ja, das stimmt schon.
Was ich versuchen wollte darzulegen ist, dass man echtes Multitasking
oft gar nicht wirklich benötigt, solange das Ergebnis dasselbe ist.
Gerade auf µC in der Kategorie Mega8 und Konsorten ist echtes
Multitasking oft einfach nur eine Menge Aufwand für einen Effekt, den
man anders mit etwas Disziplin auch viel einfacher erreichen kann.
@ Roman (Gast)
>ein Multitasking. Beim MT ist es m.E. sogar verboten mit Interupts zu>arbeiten,
Nein, das ist nur eine Sonderform.
>da ausschliesslich der Scheduler über die Vergabe der>Prozzesorzeit entscheidet.
Nein.
>Desweiteren gibt es natürlich noch>Prioritäten und auch eine Unterart der Interupts.
Das ist auch nur ein weiterführender Sonderfall.
Allgemein ist es im Artikel Multitasking beschrieben. Mit etwas
gutem Willen kann das auch ein Nicht-C Programmierer verstehen.
>Suche deshalb mal nach>Scheduler, sollte erstmal genügend Stoff zum Lesen geben.
Viel zu kompliziert.
Wie ich an manchen Antworten sehe, habe ich mich scheinbar nicht präzise
genug ausgedrückt. Deshalb danke ich Karl-Heinz und Roman, die den Sinn
meiner Frage getroffen haben.
Zum Thema Sheduler habe ich auch schon etwas gelesen, was mich aber eher
verwirrt hat, als zu helfen.
Karl Heinz Buchegger schrieb:> Die Zeitdauer, die vorher irgendwann einmal gestartet> wurde, ist jetzt vergangen und die LED die damals eingeschaltet wurde,> muss jetzt wieder abgeschaltet werden.
Das Grundprinzip ist mir soweit klar, aber was mache ich denn, wenn
während ich auf das Ausschalten der LED warte, auch noch Zeichen an ein
LCD oder über UART senden will? Dann brauche ich zwischen diesen Zeichen
ja auch noch Wartezeiten, wie bekomme ich denn mit, welche Zeit
abgelaufen ist und wo ich demzufolge hinspringen muss?
Hallo Andy,
der Prozessor wartet nicht auf den Ablauf der Zeit, sondern schaut nach
ob die Einschaltdauer schon abgelaufen ist und geht dann zum nächsten
Prozess. Ansonsten hat Falk auf eine sehr schönen Artikel hingewiesen,
der das Ganze etwas näher und sicherlich auch präzise erläutert.
Gruss
Roman
Andy schrieb:> Das Grundprinzip ist mir soweit klar, aber was mache ich denn, wenn> während ich auf das Ausschalten der LED warte, auch noch Zeichen an ein> LCD oder über UART senden will?
Du wartest ja eben NICHT auf das Ausschalten der LED.
Der Timer zählt in Hardware die Zeit runter und während der das tut,
kann dein Programm wieder ganz andere Dinge tun. Zb nachsehen, ob an der
UART ein Zeichen eingetroffen ist. Der Timer meldet sich schon, wenn die
Zeit durch ist.
1
....
2
3
loop:
4
5
wenn Taste gedrückt
6
Timer laden und starten
7
LED einschalten
8
9
wenn Timer abgelaufen
10
LED ausschalten
11
12
wenn Zeichen an der UART vorhanden
13
Zeichen holen und bearbeiten
14
15
rjmp loop
die loop - rjmp loop läuft ständig durch, OHNE auf irgendwas zu warten.
Die prüft nur ständig und dauernd ob irgendwelche Ereignisse vorliegen,
zb ob eine Taste gedrückt ist, zb ob ein Timer abgelaufen ist, zb ob an
der UART was reingekommen ist.
Wenn sie eines dieser Eregnidsse feststellt, dann bearbeitet sie das
( wenn eine Taste gedrückt, dann LED einschalten, wenn der Timer
abgelaufen, dann LED wieder ausschalten, ...)
und gleich danach geht es wieder zurück in die Hauptschleife auf der
Suche nach weiteren Ereignissen. Und weil du in den jeweiligen
Ereignisbehandlungen nirgends viel Zeit verplemperst, geht damit fast
alles quasi gleichzeitig. Oder zumindest mit einem Zeitverzug von nicht
mehr als ein paar µs.
Wichtig:
In meiner Programm-Skizze steht
1
wenn Timer abgelaufen
2
LED ausschalten
und nicht
1
warte darauf, dass der Timer abgelaufen ist
2
LED ausschalten
Da geht es also nur um die Fragestellung: Ist der Timer abgelaufen - ja
oder nein?
Wenn ja, dann mach die Aktion. Wenn nein, dann eben nicht. Dann wird die
Aktion eben bei einem anderen Durchlauf gemacht, wenn dann der Timer
irgendwann abgelaufen sein wird. Es geht in diesem Fall sofort mit der
nächsten wenn-Abfrage weiter.
Es gibt nur eine Schleife, die ständig wiederholt wird. Und das ist die
'loop-rjmp loop' Schleife.
Andy schrieb:> Das Grundprinzip ist mir soweit klar, aber was mache ich denn, wenn> während ich auf das Ausschalten der LED warte, auch noch Zeichen an ein> LCD oder über UART senden will? Dann brauche ich zwischen diesen Zeichen> ja auch noch Wartezeiten, wie bekomme ich denn mit, welche Zeit> abgelaufen ist und wo ich demzufolge hinspringen muss?
also Wartezeiten, welche beim Senden mit dem UART entstehen, oder
Mindestzeiten, die beim Zugriff aufs Display eingehalten werden müssen
musst du nicht versuchen durch einen Timer zu ersetzen! Erstens würde
das den Zugriff extrem verkomplizieren, da du ja alles mögliche
zwischenspeichern musst. Und damit würde bei den meist kurzen
Verzögerungen die gebraucht werden durch den Timer kein wirklicher
Vorteil entstehen.
Wenn du mehrere Zeiten brauchst, dann lasse einen Timer mit z.B. 100ms
laufen.
Timer_ISR: (100ms)
wenn Verzögerung_1 > 0 dann
Verzögerung_1--
wenn Verzögerung_2 > 0 dann
Verzögerung_2--
wenn Verzögerung_3 > 0 dann
Verzögerung_3--
//
damit kannst du mit einem Timer parallel mehrere Zeiten bereitstellen.
Sascha
Hi,
hol Dir mal dieses Buch
http://www.buecherbillig.de/grosse-picmikro-handbuch-p-40350.html
dort ist so ein, wie von Sascha beschriebenes, Zeitmanagement sehr gut
erklärt. Auch wenn Du keinen Pic verwenden möchtest sind dort die
wichtigsten Grundtechniken der Assembler-Programierung gut verständlich
beschrieben.
Andy schrieb:> Das Grundprinzip ist mir soweit klar, aber was mache ich denn, wenn...
Eben. Da Grundprinzip ist dir noch immer nicht klar, obwohl Karl Heinz
es eigentlich erschöpfend beschrieben hat. Ich versuche es mal mit der
bürokratischen Ansicht:
Stell dir eine riesengroße Verwaltung vor mit hunderten von Büros - aber
es gibt nur einen einzigen Beamten. Dieser rennt der Reihe nach in jedes
der vielen Büros, hechtet dort hinter den Schreibtisch und schaut, ob es
gerade jetzt_ und _hier etwas zu erledigen gibt. Wenn ja, dann
erledigt er es (z.B. auf ein Papier nen Stempel draufhauen und in den
Briefkasten des nächsten Büros reinwerfen). Wenn es nix gibt, dann saust
er sofort in das nächste Büro - und so kreiselt er durch alle Büros.
Immer wieder und wieder. Von außen sieht das aus, als ob in jedem Büro
ein Beamter säße, der nur darauf wartet, daß er was zum Bearbeiten
hereinkriegt - aber das ist ein falscher Eindruck. Der einzige Beamte im
Haus tut nur eines _nicht_: Er wartet an keinem der Schreibtische auf
irgend etwas und da er flink rennen kann, entgeht ihm auch kein Ereignis
in irgendeinem anderen Büro.
So kannst du dir das Ganze vorstellen.
Also: nicht prozedural denken, sondern ereignisorientiert.
Für dich wäre die Lernbetty hier im Forum genau das Richtige, damit du
siehst, wie ereignisorientierte Programmierung gemacht wird - auch wenn
du zur Zeit noch mit AVR bastelst. Die Thematik als solche ist
prozessorunabhängig.
W.S.
Klopp den Mega8 in die Tonne. Das ist ein Controller fuer Sparer bei
hohen Stueckzahlen. Nimm was groesseres. ZB ein Mega644 oder so. Der
Mehrpreis ist vernaclaessigbar fuer die Mehrausstattung bei kleinen
Stueckzahlen
.. schrieb:> Klopp den Mega8 in die Tonne. Das ist ein Controller fuer Sparer bei> hohen Stueckzahlen. Nimm was groesseres. ZB ein Mega644 oder so. Der> Mehrpreis ist vernaclaessigbar fuer die Mehrausstattung bei kleinen> Stueckzahlen
Genau. Und lass deinen Opel verschrotten. Kauf dir lieber einen Lkw, mit
dem du dann täglich zur Arbeit fährst...
Oder habe ich das nun falsch verstanden? ;-)
Mir wären die 40 Pins des ATmega644 zu unhandlich. Mein
Lieblingscontroller ist der ATtiny13A. Das musste mal gesagt werden.
Ich will hier mal den Post von Sascha im Stiele von W.S. ausführen.
Es gibt ja Büros wo Du nicht ständig nach schauen musst ob was los war.
zB. Wo es den Stempel für einen Tastendruck gibt. Reicht ja da mal nur
alle 50mS nach zu sehen ob Arbeit angefallen ist. (wo bei er auch gleich
entprellt wäre)
Mit diesem einfachem Timer-Interrupt
Sascha Weber schrieb:> Timer_ISR: (100ms)> wenn Verzögerung_1 > 0 dann> Verzögerung_1--> wenn Verzögerung_2 > 0 dann> Verzögerung_2--> wenn Verzögerung_3 > 0 dann> Verzögerung_3--> //
kannst Du so verschiedene "Bürogruppen" unterschiedlich oft(Zeiten)
anlaufen.
Was Dich Deinem Multitasking noch ein Schrittchen näher bringt. Man
muss(kann) auch nicht gleich für alles einen Interupt programmieren.
Lass Deine Tonne mal ruhig leer.
Wie die meisten hier gehe ich davon aus, dass Du Bastler bzw. Privatier
bist. Du hast also - warum auch immer - einen ATMega8. Du willst nicht
10000 Stück verbraten und als Anfangsprojekt weder MP3 noch Video
streamen. Für alles, was unter diesen Umständen anfällt, ist das Teil
ausreichend.
Wahrscheinlich geht es Dir um das m.E. sinnfreie Lernen. Also genau
richtig. Ganze Treats sind hier schon zerrissen worden, nur um
abschließend zu klären welcher Prozessor den der Beste bzw. Geeignetste
ist.
W.S. schrieb:> Andy schrieb:>> Das Grundprinzip ist mir soweit klar, aber was mache ich denn, wenn...>> Eben. Da Grundprinzip ist dir noch immer nicht klar, obwohl Karl Heinz> es eigentlich erschöpfend beschrieben hat. Ich versuche es mal mit der> bürokratischen Ansicht:>> Stell dir eine riesengroße Verwaltung vor mit hunderten von Büros - aber> es gibt nur einen einzigen Beamten.
Die Erklärung mit dem Beamten zeigt mir, dass ich das Grundprinzip doch
nicht verstanden hatte bzw. dass ich von einer anderen Richtung ran
gegangen bin:
Und zwar wollte ich anstatt den Beamten in jedem Büro vorbeilaufen zu
lassen, ihm einen Zettel in die Hand drücken, auf dem steht, dass in
Büro 127 Arbeit zu erledigen ist und er sich dorthin zu bewegen hat.
Aber wenn das richtig verstanden habe, ist das für meine Zwecke schon
wieder zu kompliziert.
Danke an alle die mir bei meinem Problem auf die Sprünge geholfen haben.
Denen, die nur Offtopic verbreiten, sei gesagt, nicht die Anzahl an
Beiträgen macht einen guten Forennutzer aus, sondern das was in den
Beiträgen steht.
Andy schrieb:> Und zwar wollte ich anstatt den Beamten in jedem Büro vorbeilaufen zu> lassen, ihm einen Zettel in die Hand drücken, auf dem steht, dass in> Büro 127 Arbeit zu erledigen ist
Und wer drückt ihm den in die Hand?
> und er sich dorthin zu bewegen hat.> Aber wenn das richtig verstanden habe, ist das für meine Zwecke schon> wieder zu kompliziert.
Nicht unbedingt. Es kann schon sein, dass wir im Grunde vom selben
reden.
Denn der Beamte muss ja nicht in jedes Büro tatsächlich hinlaufen. Es
reicht auch, wenn es ein schwarzes Brett gibt, auf dem jeder der etwas
zu erledigen hat, eine Nachricht hinterlässt und der Beamte ständig das
schwarze Brett von links nach rechts, von oben nach unten abgrast, ob
irgendwo ein Zettel hängt.
Dieser Zettel ist dann eben das, was ich weiter oben einen Event (ein
Ereignis) genannt habe.
Edit:
Falls es noch nicht klar geworden ist, das schwarze Brett bzw. die
Zetteln da drauf sind nichts anderes, als das, was andere die 'Jobflags'
nennen.
@ Andy (Gast)
>Die Erklärung mit dem Beamten zeigt mir, dass ich das Grundprinzip doch>nicht verstanden hatte bzw. dass ich von einer anderen Richtung ran>gegangen bin:
Hast du mal den Artikel Multitasking in Ruhe gelesen und drüber
nachgedacht?
Falk Brunner schrieb:> @ Andy (Gast)>>>Die Erklärung mit dem Beamten zeigt mir, dass ich das Grundprinzip doch>>nicht verstanden hatte bzw. dass ich von einer anderen Richtung ran>>gegangen bin:>> Hast du mal den Artikel Multitasking in Ruhe gelesen und drüber> nachgedacht?
Ich denke die Grundidee, so einfach sie auch ist, erschliesst sich
vielen nicht sofort. Die Vorstellung, dass man in einer Schleife ständig
alle möglichen 'Auslöser' überprüft und dadurch viele Dinge
'gleichzeitig' macht, ist uns nicht wirklich vertraut bzw. scheitert in
der Realität daran, dass wir Menschen ganz einfach zu langsam sind.
Ein Fallensteller, der jeden Tag seine Fallen abklappert ist nun mal den
ganzen Tag unterwegs um 'parallel' 12 Füchse zu fangen.
Falk Brunner schrieb:> @ Andy (Gast)>>>Die Erklärung mit dem Beamten zeigt mir, dass ich das Grundprinzip doch>>nicht verstanden hatte bzw. dass ich von einer anderen Richtung ran>>gegangen bin:>> Hast du mal den Artikel Multitasking in Ruhe gelesen und drüber> nachgedacht?
Ja habe ich. Und der Punkt "Message passing Framework" sollte das, was
ich erst vor hatte. Wobei ich dabei irgendwie an Details gespart wurde -
oder liegts nur an mir und euch ist das alles sonnenklar?
Ich werde mich jetzt erstmal ransetzen und die Variante mit dem Abfragen
aller Ereignisse programmieren. Vielleicht kommt mir ja da noch das
fehlende Puzzlestück für die andere Variante zugeflogen und wenn nicht
reicht das mit allen Ereignissen abfragen sicherlich auch aus.
Andy schrieb:> Und zwar wollte ich anstatt den Beamten in jedem Büro vorbeilaufen zu> lassen, ihm einen Zettel in die Hand drücken, auf dem steht, dass in> Büro 127 Arbeit zu erledigen ist und er sich dorthin zu bewegen hat.> Aber wenn das richtig verstanden habe, ist das für meine Zwecke schon> wieder zu kompliziert.
Genau. Es sind nämlich bei normalen Anwendungen keine hunderte Büros
sondern nur ein paar wenige. Eins zum Taster abfragen, eins zum UART
abfragen, eins zum LED blinken, eins zum LCD aktualisieren, ... Da geht
es schneller und einfacher bei jeder Runde in jedes Büro reinzuschauen
als so eine Zettelwirtschaft zu verwalten.
Das System mit den Zetteln würde man grob gesagt Task-Scheduler nennen.
Das braucht man aber erst bei größeren Systemen. Dein PC macht das zum
Beispiel so ähnlich. Da kommt dann auch noch dazu, dass es einen Chef
gibt, der den Beamten bei seiner Arbeit in einem Büro unterbrechen und
in ein anderes schicken kann, wenn es ihm zu lange dauert oder es dort
dringendere Dinge zu erledigen gibt. Außerdem hat man in PCs heutzutage
nicht nur einen Beamten sondern gleich zwei, vier oder noch mehr ...
Andy schrieb:> Und zwar wollte ich anstatt den Beamten in jedem Büro vorbeilaufen zu> lassen, ihm einen Zettel in die Hand drücken, auf dem steht, dass in> Büro 127 Arbeit zu erledigen ist und er sich dorthin zu bewegen hat.
naja, irgendwer müßte ja identifizieren und dem Beamten "sagen", daß er
zum Büro 127 hechten soll. Das gibt es auch, daß geht dann in Richtung
"Präemptives Multitasking" (-> Wikipedia)
im Beamten-Beispiel: Der Beamte flitzt zuerst blizeschnell von Büro zu
Büro, und STELLT DORT FEST, daß es etwas zu tun gibt. Er macht aber
selber nix, sondern gibt es seinen Vorgesetzen weiter. Der notiert sich
da, und entscheidet aufgrund von einer Prioritäten-Tabelle, daß die
Aktivität in "Raum 127 - Ausgangspost abstempeln" niedrigere Priorität
hat als diejenige in "Raum 19 - Wasserkocher pfeift und muß abgestellt
werden". dann flitzt der Beamte also (zuerst) zu Raum 19, macht dort ein
bischen, und danach macht er das nächste auf seiner ihm zugewiesenen
Prioritätenliste.
Vielleicht wird er mittendrin von einer weiteren
Unterbrechungsanforderung gestört (sofern er nicht eine Interrupt-Sperre
eingeschalten hat, weil er grade mit einer Sondertask beschäftigt ist:
"Raum 00 - Darm entleeren"
Die Unterbrechungsanforderung kann z.B. sein: sein Vorgesetzter treibt
ihn wieder: "Was ist denn nun, ich brauche mal wieder ein Update darüber
wo du noch was zu tun hast" (die Rumguck-Schleife)
oder sein Vorgesetzter sagt: "lass alles stehen und liegen, und mach
erst mal nach was in Raum 4 zu tun ist (Wasserrohr-Bruch, höchste
Priorität)
.... aber ich glaube, solche Beamten wie hier im Beispiel gibts in echt
gar nicht ;-)
Andy schrieb:> Ja habe ich. Und der Punkt "Message passing Framework" sollte das, was> ich erst vor hatte. Wobei ich dabei irgendwie an Details gespart wurde -> oder liegts nur an mir und euch ist das alles sonnenklar?
:-)
Über solche Dinge werden ganze Bücher geschrieben.
Diiiieeeecke Bücher!
Andy schrieb:> Ich werde mich jetzt erstmal ransetzen und die Variante mit dem Abfragen> aller Ereignisse programmieren. Vielleicht kommt mir ja da noch das> fehlende Puzzlestück für die andere Variante zugeflogen und wenn nicht> reicht das mit allen Ereignissen abfragen sicherlich auch aus.
Du wirst sehen, es ist viel simpler als du jetzt denkst.
Man muss nur den Dreh mal raus haben. Und das geht am Besten, in dem man
da selber mal was programmiert. Wir können dir hier viel erzählen ....
:-)
Hi
Nun will ich mich doch auch mal einmischen. Ich glaube, nicht
multitasking sondern ein flottes Programm ist erwünscht und es läuft da
schon auf Jobflags hin. Um das zu verstehen, ist der Timer ein guter
Start.
Nur mal so angedacht:
Du willst eine Uhr bauen und erzeugst in jeder mSek. einen Interrupt.
Jetzt kannst du in der ISR beginnen, eingroßes Programmgebilde
aufzubauen, was natürlich den Interrupt völlig überlastet.Auch braucht
deine Uhr keine mSek. sondern bestenfalls Sekunden.(Ausnahme:Stoppuhr)
Also zählst du z.B. in der ISR einen Zähler bis hundert (1/10 Sek).
darauf setzt du einen Zähler bis 10 und hast Sekunden.
In der Skizze wird der Ablauf verdeutlicht. Das in der ISR gesetzte Bit
wird nun so ca. jede Sekunde gesetzt. Dir ist es aber egal, ob ein paar
hundertstel später, weil insgesamt passt es dann wieder. In der
Subroutine für den zeitzähler setzt du das Bit dann wieder zurück.
Dies ist ein Einstieg in die Jobflags. Deinem Programm ist es nämlich
egal, ob das Bit durch eine ISR gesetzt wird, oder durch ein anderes
Ereignis. So kannst du bspw. auch Tastersignale auf Bits setzen, wenn
diese gedrückt werden. Das Ereignis kommt dann einem KeyPressed gleich.
Auch dieses Bit setzt du nach Bearbeitung zurück. Die Flankenauswertung
bekommst du mit einer Exclusiv-Oder Verknüpfung des "alten"
Signalstatus. Nur bei einer Änderung ist das Ergebnis "1". Auch dafür
gibt's eine Skizze...
Die Befehle mußt du dir selbst raussuchen, aber das dürfte deinem
"Multitasking" sehr nahe kommen. Das Programm rotiert in einer "IDLE"
und nur, wenn ein Job ansteht, wird er erledigt. Die Flankenbits werden
in gleicher Weise wie das Zeitbit verarbeitet. Das sollte dir erst
einmal genug Stoff für Experimente sein
Gruß oldmax
Karl Heinz Buchegger schrieb:> Über solche Dinge werden ganze Bücher geschrieben.> Diiiieeeecke Bücher!
Eben, nur versteht die keiner mehr, weil sie zu abstrakt geschrieben
sind oder die Beispiele nix taugen.
Karl Heinz Buchegger schrieb:> Du wirst sehen, es ist viel simpler als du jetzt denkst.
Das ist wohl wahr.
Man muss aber erstmal bereit sein, nicht mehr in Schleifen und
Prozeduren zu denken, sondern in Ereignissen und State-machines. Und man
muss statt auf eine Bedingung zu warten einfach zur Tagesordnung
(schwarze Brett gucken) zurückkehren. Um das zu können, müssen die zu
erledigenden Aufgaben in kleinere Stücke zerlegt werden, statt einer
Schleife zum Blinken (LED an, warten, LED aus, warten, von vorn...) ist
nur in definierten Zeitabständen der Verzögerungszähler zu vermindern
und auf Erreichen von 0 zu prüfen. Wird er 0, dann ist die LED zu
toggeln und der Zähler wieder auf Start zu setzen. Und natürlich ist zu
prüfen, ob der Merker, der da sagt, dass geblinkt werden soll (also ein
"Zustand"), immernoch sagt, dass geblinkt werden soll. Läuft der
Blinkdauerzähler nicht ab, dann wird nix weiter gemacht, also sofort
alle anderen Jobflags (am schwarzen Brett) prüfen und ggf. (einen
kleinen Schritt) einer andere Aufgabe erledigen.
...
@ Andy (Gast)
>> Hast du mal den Artikel Multitasking in Ruhe gelesen und drüber>> nachgedacht?>Ja habe ich. Und der Punkt "Message passing Framework" sollte das, was>ich erst vor hatte.
Typisch deutsch! Einfach ist zu einfach. Du must erstmal das Prinzip
verstehen und erfolgreich anwenden!!!
DAS ist dein Lernobjekt!
http://www.mikrocontroller.net/articles/Multitasking#Ein_einfaches_Beispiel_f.C3.BCr_den_AVRhttp://www.mikrocontroller.net/articles/Multitasking#Verbesserter_Ansatz>Wobei ich dabei irgendwie an Details gespart wurde -
Sicher, es ist ein halbgar hingeklatschter Abschnitt, der wenig erklärt
und viel verwirrt. Wie leider so viele in diversen Artikeln.
>Ich werde mich jetzt erstmal ransetzen und die Variante mit dem Abfragen>aller Ereignisse programmieren.
Falsch! Das Programmieren ist der vorletzte Schritt. VORHER kommt das
VERSTEHEN!
@ oldmax (Gast)
>Nun will ich mich doch auch mal einmischen. Ich glaube, nicht>multitasking sondern ein flottes Programm ist erwünscht und es läuft da>schon auf Jobflags hin.
Das IST Multitasking! Multitasking heißt NICHT, dass immer ein fetter
Quad Core Pentium mit 10GHz dahintersteckt. Multitasking geht viel
einfacher. Aber eben dieses einfache will man ja (gerade als Deutscher)
nicht haben, das ist ja unter dem Niveau.
> Um das zu verstehen, ist der Timer ein guter>Start.
Nö.
>Die Befehle mußt du dir selbst raussuchen, aber das dürfte deinem>"Multitasking" sehr nahe kommen. Das Programm rotiert in einer "IDLE">und nur, wenn ein Job ansteht, wird er erledigt.
Dazu muss man auch ein paar einfache Grundlagen zum Thema
statemachine kennen.
@ Hannes Lux (hannes)
>> Über solche Dinge werden ganze Bücher geschrieben.>> Diiiieeeecke Bücher!>Eben, nur versteht die keiner mehr, weil sie zu abstrakt geschrieben>sind oder die Beispiele nix taugen.
Eben.
>Man muss aber erstmal bereit sein, nicht mehr in Schleifen und>Prozeduren zu denken, sondern in Ereignissen und State-machines.
Genau!
>(schwarze Brett gucken) zurückkehren. Um das zu können, müssen die zu>erledigenden Aufgaben in kleinere Stücke zerlegt werden, statt einer>Schleife zum Blinken (LED an, warten, LED aus, warten, von vorn...)
Eben. Und genau DAS steht im Artikel Multitasking. Muss man halt mal
lesen und auchmal bissel nachdenken.
Falk Brunner schrieb:> Eben. Und genau DAS steht im Artikel Multitasking. Muss man halt mal> lesen und auchmal bissel nachdenken.
Und .... weils weiter oben mal vom TO ausgesprochen wurde ....
sich auch mal darauf einlassen, dass man C Code liest. Sooo schwer ist
das nämlich nicht. Jemand der eine Programmiersprache beherrscht, kann
fast alle anderen Programmiersprachen ebenfalls lesen. Zumindest solange
es in dem Schwierigkeitsgrad sich bewegt, wie im Artikel.
Die Attitüde "Ich kann nur Assembler und kein C" liest man allzu häufig.
Jeder, der Assembler kann, sollte unmittelbar verstehen, was eigentlich
zb
DDRD = 0xFF;
macht.
In Assembler schreibt er halt
LDI r16, 0xFF
OUT DDRD, r16
aber die Zutaten sind da wie dort die gleichen. Da gibt es ein DDRD und
es gibt einen Wert 0xFF. Und die 0xFF müssen ins DDRD Register. Dieses
'Grundkonzept' ist in C auch kein anderes als in Assembler. Die
Schreibweise ist ein wenig anders und als Hochsprache befreit mich der
C-Compiler davon, dass ich mir ein freies Register suchen muss, in dem
ich den Wert zwischenparken kann, damit ich ihn dann mit OUT ausgeben
kann, aber die Grundidee ist da wie dort genau die gleiche.
Und das gilt für Timer-Konfigurieren genauso, wie es für UART
initialisieren und den ADC und ... gilt. 70% eines Programms, nämlich
der Teil in dem es darum geht, dass der AVR irgendwas Spezielles macht,
bewegt sich auf so einer Ebene.
Aber allzuoft wird mit dem Hinweis man sei doch Assembler-Programmierer
einfach ein Verweis auf einen C-Code abgewunken. Dabei ist das Lesen des
Codes im Regelfall nicht allzu schwer (Lesen - nicht selber Schreiben)
und die Grundkonzepte sind viel leichter zu verstehen, weil die ganzen
kleinen technischen Details, die zum Konzept nichts beitragen, durch die
Hochsprache verborgen sind.
Karl Heinz Buchegger schrieb:> Und .... weils weiter oben mal vom TO ausgesprochen wurde ....> sich auch mal darauf einlassen, dass man C Code liest. Sooo schwer ist> das nämlich nicht. Jemand der eine Programmiersprache beherrscht, kann> fast alle anderen Programmiersprachen ebenfalls lesen.
Das kann, ich als Assemblerprogrammierer, nur voll und ganz
unterschreiben.
Teo
Falk Brunner schrieb:> Falsch! Das Programmieren ist der vorletzte Schritt. VORHER kommt das> VERSTEHEN!Falk Brunner schrieb:> Meine Empfehlung. Programmier BEIDE Beispiele aus dem Artikel in ASM> nachzuprogrammieren, das bringt dir einen guten Lerneffekt.
Du widersprichst dir da gerade ein bisschen. Soll ich jetzt
programmieren oder nicht?
Ich werde es trotzdem direkt in meinem aktuellen Projekt probieren. Und
wenn ich dann dreimal so lange brauche, wie wenn ich die Programme
nachprogrammiert habe, dann ist ja zum Glück meine Zeit die dabei drauf
geht und nicht eure ;-)
Karl Heinz Buchegger schrieb:> Die Attitüde "Ich kann nur Assembler und kein C" liest man allzu häufig.
Ich hoffe, dass sich das nicht auf mich bezogen hat, denn so habe ich
mich hier keineswegs geäußert.
Also bei echtem Multitasking braucht es einen Scheduler mit Round-Robin
und vor allem bei Echtzeitsystemen wie es ja µCs sind mit passender
Priorisierung.
Das ganze in assembler nachzubilden ist ziemlich aufwändig, jeder
einzelne Task muß gesichert werden und gewährleistet das die
Zeitscheiben auch eingehalten werden.
Sinnvoller ist da schon das genannte, denn das paßt erstens in einen µC
gut hinein und macht zweitens keinen großen Aufwand.
@ kopfkratzer (Gast)
>Also bei echtem Multitasking braucht es einen Scheduler mit Round-Robin>und vor allem bei Echtzeitsystemen wie es ja µCs sind mit passender>Priorisierung.
Keine Sekunde. Multitasking fängt DEUTLICH einfacher an.
>Das ganze in assembler nachzubilden ist ziemlich aufwändig, jeder>einzelne Task muß gesichert werden und gewährleistet das die>Zeitscheiben auch eingehalten werden.
Alles viel zu kompliziert. Deutsch.
Falk Brunner schrieb:> Alles viel zu kompliziert. Deutsch.
Das würde ich nichtmal als "typisch Deutsch" bezeichnen, sondern eher
als "typisch akademisch". ;-)
...
@ Hannes Lux (hannes)
>> Alles viel zu kompliziert. Deutsch.>Das würde ich nichtmal als "typisch Deutsch" bezeichnen, sondern eher>als "typisch akademisch". ;-)
Noch schlimmer! 8-0