Nabend,
ich tüftele gerade an dem Assembler Programm für meine neue Schaltung.
Es handelt sich dabei quasi um eine Art Led-Lauflicht.
Alle 100µS wird eine LED per Timerinterrupt weitergezählt und nach 40
Schritten soll einmal ausgesetzt werden und ein Reset durchgeführt
werden. Ausserdem sollen im selben Takt mit dem die Leds durchgezählt
werden noch diverse Eingänge eingelesen und je nachdem entsprechende
Ausgänge geschaltet werden. Sonst eigentlich nichts.
Nun dachte ich mir es würde sich ja anbieten quasi das komplette
Programm in den Interrupt zu verlagern da ja sowieso alle Aktionen im
Interrupt-Takt ausgeführt werden sollen und ich mir so das Abfragen von
diversen Flags in der Hauptschleife sparen könnte. Das Programm dürfte
schätzungsweise maximal 100Befehle lang werden und der Controller läuft
mit 20Mhz. Es bleibt also mehr als genug Zeit.
Meine Frage ist nun ob man das so machen kann oder ob das
programmiertechnisch eher ein absolutes No-Go ist?
Danke schonmal im vorraus!
Gruß,
Thomas (ein unerfahrener Programmierer)
Also guter Stil ist es jedenfalls nicht. Grundsätzlich sollte man in
einer ISR so wenig Code wie möglich ausführen. Auch wenn man im Programm
genug Zeit hat. Allein schon, um sich sowas gar nicht erst anzugewöhnen.
Die ISR sollte nach Ablauf der geforderten Zeit einfach ein Flag setzen,
auf das du im Hauptprogramm prüfst.
Ein wenig Code um ggf. mehrere ISR Durchgänge auf deine Zeit
aufzusummieren darf natürlich in die ISR rein.
In den Interrupt gehören Codesegmente, die zeitkritisch sind und
unmittelbar ausgeführt werden müssen und nicht unterbrochen werden
dürfen. Alles andere findet im Hauptprogramm statt.
Thommy schrieb:> Alle 100µS wird eine LED per Timerinterrupt weitergezählt und...Thommy schrieb:> Das Programm dürfte> schätzungsweise maximal 100Befehle lang werden und der Controller läuft> mit 20Mhz. Es bleibt also mehr als genug Zeit.
Und der Controller verbraucht mehr als genug Strom dafür. Nimm 1Mhz als
Taktfrequenz und nutze den Sleep-Modus, aus dem der Controller alle
100µs geweckt wird, wenn sonst nichts anliegt.
Hi
Du machst einen Denkfehler. Klar, Timer-Interrupt ist wichtig, aber ob
du nun eine 1/100 Sekude später erst das Licht der LED erblickst ist
irrelevant.
Den Taster den du dückst... so kurz kannst du nicht drücken, das es der
Controller nicht mitbekommt, es sei denn, du hälst dein Hauptprogramm
künstlich auf. Stichwort Wait oder Delays.
Die Erkenntnis daraus ist, das du in deiner ISR ein Flag setzt, dieses
in deinem Hauptprogramm erkennst, einen Job daraufhin erledigst und dann
dieses Flag zurücksetzt. So kannst du z. B. Teile um 1/10 oder
Sekundentakt bearbeiten. Wenn du z.B. eine LED einschaltest, muss das
nicht in jedem Zyklus geschehen, sondern nur einmal, wenn ein Ereignis
eintritt, welches für's einschalten zuständig ist. Im Gegenzug natürlich
erfolgt das Ausschalten auch nur 1 mal bei einem entsprechenden
Ereignis.
Natürlich mußt du in jedem Zyklus auf solche Ereignisse prüfen. Auch das
Einlesen der IO-Ebene erfolgt in jedm Zyklus, aber nicht in jedem Zyklus
ändert sich die IO-Ebene. Das bekommst du heraus, wenn du dir den alten
Zustand der Eingänge merkst und die neu eingelesenen Werte mit einer
Exclusiv-Oder Verknüpfung prüfst.
Da solltest du dein Augenmerk darauf legen. Interrupt in der IO ist nur
bei schnellen Signalen erforderlich, wo befürchtet werden muss, das der
Zyklus länger dauert, wie das Signal ansteht.
Beispiel:
Angenommen, du hast einen Magneten am Fahrrad und einen Reed Kontakt.
Nun dreh das Rad ganz schnell. Der Impuls vom Reed-Lontakt ist
vielleicht nur 1° der Umdrehung aktiv, also sehr kurz. Um diesen Impuls
nicht zu "verpassen", ist eine Interrupt-Behandlung des Eingangs evtl.
erforderlich.
Gruß oldmax
Wenn feststeht, dass der MC nichts weiter als das beschriebene zu tun
hat, ist dein Ansatz völlig in Ordnung.
Pseudocode:
ISR: setze flag
return
main: flag gesetzt?
wenn ja, Programmteil ausführen
goto main
oder (deine Variante)
ISR: Programmteil ausführen
return
main: tue gar nichts
Jacke wie Hose. Problematisch kann das allenfalls werden, wenn andere
Interrupts dazukommen
Ich schließe mich der Meinung von crazyhorse an: Wenn das Programm nur
aus einem zyklisch auszuführenden Teil (und sonst nichts) besteht, ist
es nicht nur möglich, sondern sogar sinnvoll, alles in einer
Timer-Interruptroutine auszuführen. Da dann im Main nichts getan werden
muss, kann man den Controller dort schlafenlegen, und Strom sparen.
Die Regel, dass der Interruptcode möglichst kurz sein soll, gilt nur
dann, wenn im Hauptprogramm tatsächlich etwas sinnvolles ausgeführt
wird, was hier aber nicht der Fall ist.
H.joachim Seifert schrieb:> Wenn feststeht, dass der MC nichts weiter als das beschriebene zu tun> hat, ist dein Ansatz völlig in Ordnung.
Das ist genau der Knackpunkt, so ein Programm ist schlecht erweiterbar.
Wenn Du nur eine Interruptquelle hast, dann kannst Du auf das
Interruptflag einfach pollen. Spart schonmal 8 CPU-Zyklen und 2 Bytes
SRAM für den Interruptcall ein.
So sehen viele meiner main procedures aus:
while (1)
{
// do nothing, just wait interrupts - I love it!
ClrWdt();
}; // while
Also kein Problem alles in ISR zu haben.
Es hängt aber auch von der Art des Programmes ab.
Aber, was du oben beschrieben hast funzt in ISRs.
Ich vermeide pollen so gut es eben geht!
Das hier ist ja auch nur ein einfaches Lauflicht:
Beitrag "Re: AVR Sleep Mode / Knight Rider"
Aber dann kommt noch eine Taste zum Bedienen hinzu und schon geht es
nicht mehr nur mit Interrupt alleine.
Das Main muß auch was tun.
Peter
Yalu X. schrieb:> Die Regel, dass der Interruptcode möglichst kurz sein soll, gilt nur> dann, wenn im Hauptprogramm tatsächlich etwas sinnvolles ausgeführt> wird, was hier aber nicht der Fall ist.
...oder wenn das Interrupt-Programm auch mal so lange dauert, dass ein
Interrupt verloren gehen kann...
Gruß Dietrich
Thommy schrieb:> ich tüftele gerade an dem Assembler Programm für meine neue Schaltung.
Bei Assembler sind die Spielregeln etwas anders.
Ich würde das gesamte Programm in den Reset-Interrupt packen, aus dem es
nie herauskommen muß. Die Timer-Flags würde ich pollen.
Bei einem LED-Lauflicht würde ich allerdings nicht die 10-20mW für den
µC einsparen wollen; das ist die falsche Stelle und nur ein pseudo
Argument.
m.n. schrieb:> Bei Assembler sind die Spielregeln etwas anders.> Ich würde das gesamte Programm in den Reset-Interrupt packen
Das macht jedes Programm.
Thommy schrieb:> Alle 100µS wird eine LED per Timerinterrupt weitergezählt und nach 40> Schritten soll einmal ausgesetzt werden und ein Reset durchgeführt> werden. Ausserdem sollen im selben Takt mit dem die Leds durchgezählt> werden noch diverse Eingänge eingelesen und je nachdem entsprechende> Ausgänge geschaltet werden. Sonst eigentlich nichts.
Das sind aber schon zwei Programmteile, von denen das Einlesen der
Klassiker fürs Hauptprogramm ist.
Thommy schrieb:> Meine Frage ist nun ob man das so machen kann oder ob das> programmiertechnisch eher ein absolutes No-Go ist?
Kann man so machen.
Thommy schrieb:> (ein unerfahrener Programmierer)
Aber in deinem Fall würde ich dir raten, das Programm "normal"
aufzubauen.
Peter Dannegger schrieb:> Aber dann kommt noch eine Taste zum Bedienen hinzu
Das ist gerade bei so einem Progrämmchen das Problem. Ein einfaches
Lauflicht wird schnell langweilig. Das schreit ganz schnell nach
Erweiterung. Das ist eigentlch nie fertig. Und dann bekommst du
irgendwann Probleme.
Denn so wenig
>Sonst eigentlich nichts.
ist das auch jetzt schon nicht.
Thommy schrieb:> Das Programm dürfte schätzungsweise maximal 100Befehle
Daraus kann man auch nicht schliessen, daß die Routine besonders schnell
fertig wird. 100 Befehle sind nicht nur 100 Takte.
label: jmp label
Das ist nur ein Befehl und läuft bis der Controller kaputt geht.
Carsten H. schrieb:> Ich vermeide pollen so gut es eben geht!
Mache ich auch. Aber wenn man das Letzte aus dem Controller rauskitzeln
will, ist das vozuziehen:
Peter Dannegger schrieb:> Spart schonmal 8 CPU-Zyklen und 2 Bytes SRAM für den Interruptcall ein.
mfg.
Thomas Eckmann schrieb:>> Ich würde das gesamte Programm in den Reset-Interrupt packen> Das macht jedes Programm.
Dann kann es ja nicht falsch sein :-)
Anstatt dem TO alle möglichen Probleme zu konstruieren, sollte Thommy
einfach einmal anfangen. Weichware kann man schließlich ohne Löterei
anpassen.
Thommy schrieb:> Meine Frage ist nun ob man das so machen kann oder ob das> programmiertechnisch eher ein absolutes No-Go ist?
Das ist voellig in Ordnung, wenn du weisst, was du tust.
99% der Leute, die dir was Anderes erzaehlen wollen, geben nur
unreflektiert wieder, was sie mal hier gelesen haben. Solche
Standardregeln sind sinnvoll fuer Anfaenger - aber mit steigender
Erfahrung sollten durch eigene Erkenntnisse ersetzt werden. Und dann
weiss man auch, wann man davon abweichen kann und sollte.
xXx schrieb:> Solche> Standardregeln sind sinnvoll fuer Anfaenger
Nö, die Regeln sind auch für Profis.
Es bringt nichts, sich für kleine Programme einen extra Programmierstil
anzugewöhnen. Das ist nur doppelt lernen.
Peter
Es gibt meiner Meinung nach nur eine wichtige Regel: Ich mache es mir so
einfach wie möglich - und das gilt im Besonderen für Anfänger.
Wenn ich nur ein Ereignis habe, mit dem ich synchron bleiben muss,
brauche ich auch keinen Interrupt. Wenn das Programm nachher um ein
zeitkritisches Ereignis erweitert werden muss, dann habe ich am Anfang
mies geplant. Also vorher überlegen, was nötig ist und den leichtesten
Weg wählen. Der ist dann auch am einfachsten zu "entwanzen".
Yalu X. schrieb:> Die Regel, dass der Interruptcode möglichst kurz sein soll, gilt nur> dann, wenn im Hauptprogramm tatsächlich etwas sinnvolles ausgeführt> wird ...
... oder wenn es mehrere konkurrierende Interrupts gibt.
Hi
Programmtechnisch ist alles erlaubt, was zuverlässig arbeitet, Ich
denke, das sollte nicht die Frage sein, sondern "hab ich nach einer Zeit
noch den Durchblick, um Änderungen einzupflegen"
Ein Profi schreibt vielleicht die ersten Programme komplett, aber je
mehr Quellen und Tools er hat, um so mehr greift er auch darauf zurück.
Niemand wird ihm sagen "so ist der einzig wahre Weg". Das wird er selbst
feststellen, wenn der Weg im Nirwana landet. Kurz:
Willst du ein übersichtliches Pogrammgebilde haben, so nutze die ISR, um
Ereignisse zu erfassen und festzuhalten. Die Bearbeitung allerdings
erledigst du anhand gesetzter Flags im Programmzyklus. Es ist nur ein
Rat, keine Vorschrift.
Das Ergebnis ist etwa folgender Aufbau:
Loop:
Read_IO
Chk_RS232
Chk_ISR_Flg
Send_RS232
Write_IO
Jmp_Loop
ISR_Timer
Set_ISR_Time_Flg
RETI
ISR_RS232
Set_ISR_RS232_Flag
RETI
etc.
Natürlich verzweigen deine Aufrufe weiter, denn das kann noch kein
vollständiges Programm sein. Allerdings erkennst du, wohin der µC läuft
und was er macht. Wenn eine abgeschlossene ISR läuft, wird sie auch
nicht mehr angefasst.
Grad bei Assembler hat man schnell den Durchblick verloren. Kommt mir
bitte nicht mit "unnützen Aufrufen" und "verschwenden von Zeit und
Speicher". Bevor der Assemblerprogrammierer in kritische Zonen kommt,
ist er vermutlich durchgedreht.... Ne, mal im Ernst, von "zeitkritisch"
und "Speicherknappheit" zu reden, davon ist hier noch lange kein Grund
zu. Und was solls, es ist alles bezahlt, was im Controller eingebaut
ist. Daher kann man es auch nutzen und bevor der Speicher aufgrund
komplexer Programme knapp wird. So kann erst mal eine Grundroutine zu
strukturierten Programmieren erarbeitet werden.
Gruß oldmax
Eine Interruptroutine, die nur ein Flag setzt und nichts anderes tut,
ist sinnlos. Die Hardware setzt bereits Flags für alle Ereignisse, die
auch einen Interrupt auslösen können.
Interrupts werden erst interresant, wenn ich in der ISR tatsächlich
etwas tue, z.B. einen Ringpuffer füllen oder leeren, um zeitkritische
Abläufe vom Hauptprogramm abzukoppeln. Dafür muss es aber tatsächlich
auch zeitkritische Abläufe geben, die das Hauptprogramm überfordern
würden.
Aber, wer gern sinnloses tut - bitteschön, das funktioniert natürlich
genauso gut.
Hi
Na Klaus, überleg mal.... natürlich interessiert nicht das
Interrupt-Flag, sondern es wird ein Ereignis erfasst, z. B. in der
Timer-ISR und nun will ich jede Sekunde etwas machen. Also wird
natürlich in der ISR erst einmal ein Wert berechnet, und wenn der dann
aufgrund genügender Timer-Aufrufe seine Zeit sieht, setzt er das Flag
für die Sekunde. Das Hauptprogramm arbeitet nun dieses Ereignis ab und
setzt das Sekundenflag zurück. Also, so blöd wie du meinst, sind die
Kollegen nun auch nicht. Sorry, aber das musste bei diesem (gefühlt
arroganten) Post sein.
Gruß oldmax
Klaus hat schon Recht. Genauso arbeiten SPS.
Es gibt halt viele Wege und eingewöhnte Programmierstile. Z.B. kann man
auch jedem Interrupt einen Counter beigeben und damit mehrere
Interrupt-Ereignisse puffern: Der Interrupt zählt den Counter eins hoch,
die Routine die das Ereignis bearbeitete, den Zähler wieder eins runter.
Obendrauf läuft eine Routine, die periodische alle Counter auf einen
Schwellwert überprüft. Ist einer der Counter zu hoch geworden, ist das
Programm instabil und man kann das übergeordneten Kontrolleinheiten
weitergeben <Mensch>.
Abdul K. schrieb:> Genauso arbeiten SPS.
SPS ist keine Programmierung, sondern eine Anwendung, die parametriert
wird. Ob und wieviel darin an Interrupts ablaufen, weiss der der
SPS-Anwendungsprogrammierer doch gar nicht. Muß er auch nicht.
Das wissen nur die Leute, die das SPS-System programmiert haben. Und die
befinden sich auf der Ebene des Mikrocontrollers.
Das Beispiel taugt leider überhaupt nichts. Da hättest du auch mit Excel
kommen können.
Und deswegen kann man Oldmax nur Recht geben.
oldmax schrieb:> Also, so blöd wie du meinst, sind die> Kollegen nun auch nicht. Sorry, aber das musste bei diesem (gefühlt> arroganten) Post sein.
mfg.
>Eine Interruptroutine, die nur ein Flag setzt und nichts anderes tut,>ist sinnlos.
Seh ich auch so. Zwei Aspekte dazu:
1) wenn das Flag aber dazu dient einen bestimmten Programmierstil (der
hier leider von den meisten missionarisch vertreten wird) zu
ermöglichen, so ist es an sich nicht sinnlos.
2) Dieser Programmierstil (kurze Interrupt-Routinen, alles im main
abwickeln) ist nicht immer das Gelbe vom Ei. Wenn Ausgaben gemacht
werden sollen, die keinen "Jitter" durch das Hauptprogramm vertragen, so
haben längere ISR durchaus Berechtigung und Inhalte.
Warum wird eigentlich die Frage des TE nicht beantwortet (von wenigen
schon).
Also an Thommy: ja, mach es. Software ist Software und jederzeit
änderbar.
Mach die ISR wie es Dir gefällt, Du wirst die Software schreiben und
warten, Du lernst was dabei.
Spar nicht an Befehlen (nicht im uSec-Bereich), Speicherplatz (was soll
ein uC mit 2k Ram und 10 byte belegt, da kriegst Du auch kein Geld
zurück). uC sind billig. Schnellere und größere kosten auch nix mehr.
So what?
Peter Dannegger schrieb:> Das ist genau der Knackpunkt, so ein Programm ist schlecht erweiterbar.
Da man aber nicht päpstlicher als der Papst sein muss, muss auch nicht
jedes Programm erweiterbar sein. Er reicht, sich der "Verantwortung"
bewusst zu sein, dass man sich im Falle einer Erweiterung mehr Arbeit
einhandelt.
Wenn man sauberes und sicheres Programmieren mit "setze Flag in ISR und
reagiere in Hauptprogrammschleife auf Flags" zusammenfassen könnte, gäbe
es keine fehlerhaften Programme auf dieser Welt.
slow schrieb:> Also an Thommy: ja, mach es. Software ist Software und jederzeit> änderbar.> Mach die ISR wie es Dir gefällt, Du wirst die Software schreiben und> warten, Du lernst was dabei.
100% ACK
Lasst uns nun trauern!
Autor: Thommy (Gast)
Datum: 17.10.2011 01:35
hat sich in einer empfohlenen Reset Interuptschleife gefangen und
kommt nun nicht mehr heraus. Das ist schade.
Gruss Klaus
Klaus De lisson schrieb:> Lasst uns nun trauern!>> Autor: Thommy (Gast)> Datum: 17.10.2011 01:35>> hat sich in einer empfohlenen Reset Interuptschleife gefangen und> kommt nun nicht mehr heraus. Das ist schade.>> Gruss Klaus
Nicht jeder hat tagsüber Zeit zu Antworten. Ich bin auch einer der
Kandidaten, die nur Abends schreiben können, da ich tagsüber einer
geregelten Arbeit nachgehe.
Drum Äschert Tommy nicht schon ein :)
Mir hat der Thread ein paar gute Erkenntnisse aus dem Programmier-Altag
gegeben, wie Profis das handhaben.
Danke.
MFG
Stephan
Stephan ,
es war nicht bös gemeint. Nein wirklich nicht .
Ich hatte nur darüber nachgedacht was alles schon gepostet wurde
ohne das Thommy etwas davon hatte.
Thommy hat im Gedanken nämlich vollkommen Recht wenn da nicht die
"wenns"
und "Abers" wären.
Da ich glaube, es erklären zu können, warte ich auf ihn.
Klaus
Ps.:
du schreibst: "wie Profis das handhaben."
Das gibt es nicht ! Alle kochen mit dem gleichen wasser.
Thomas Eckmann schrieb:> Abdul K. schrieb:>> Genauso arbeiten SPS.> SPS ist keine Programmierung, sondern eine Anwendung, die parametriert> wird. Ob und wieviel darin an Interrupts ablaufen, weiss der der> SPS-Anwendungsprogrammierer doch gar nicht. Muß er auch nicht.> Das wissen nur die Leute, die das SPS-System programmiert haben. Und die> befinden sich auf der Ebene des Mikrocontrollers.
Genausowenig weißt du über das Mikropogramm einer CPU. Die Ansicht ist
also schlicht falsch.
Die klassische SPS lädt den momentanen Zustand als Vektor, ändert diesen
und schreibt ihn dann zum nächsten Timestep wieder komplett als ganzes
raus. Das geht dann so weiter...
Schönes Beispiel für effiziente und hochzuverlässige Programmierung ist
was Meinzer sich für die Satelliten der Amateurfunker einfielen ließ.
Eine Art SPS gekreuzt mit Forth.
> Das Beispiel taugt leider überhaupt nichts. Da hättest du auch mit Excel> kommen können.
Keine schlechte Idee ansich, auch wenn ich Excel hasse.
> Und deswegen kann man Oldmax nur Recht geben.> oldmax schrieb:>> Also, so blöd wie du meinst, sind die>> Kollegen nun auch nicht. Sorry, aber das musste bei diesem (gefühlt>> arroganten) Post sein.>
Und was das soll, das weiß niemand. Mit dem falschen Bein aufgestanden?
Keine Angst, ich bin noch da ;)
Durch meine Arbeitszeiten bin ich leider erst jetzt dazu gekommen mich
durch die vielen Antworten (für die ich mich an dieser Stelle erstmal
recht herzlich bedanken möchte!) durchzuarbeiten.
Ich habe letzte Nacht bevor es hier mit den Antworten richtig los ging
jedenfalls schonmal nach der "alles in den Interrupt reinstopfen"
Methode drauf los programmiert und auch schon eine grobe Testversion zum
laufen gebracht. Nach dem was ich hier so rauslese ist das zwar nicht
umbedingt die feine Art aber es spricht auch nichts dagegen, solange es
funktioniert!
Bei meinen bisherigen Programmen habe ich eigentlich immer darauf
geachtet die Interrupts möglichst kurz zu halten, aber hier tue ich mich
dabei irgendwie recht schwer. Es hängt ja quasi alles mit dem Timer-Takt
zusammen. Auch die Eingänge sollen nur 1 Mal bei jedem Interrupt
abgefragt werden.
Momentan sieht das ganze ungefär so aus:
- Zählerstand abfragen und evtl zu Reset springen
- Zählerstand abfragen und evtl AusgangY setzen
- Reset-Ausgang = 0
- Vorheriges LED Muster löschen
- Neues LED Muster an den Ports anlegen
- Eingänge abfragen und evtl. AusgängeX setzen
- Zähler dekrementieren
- Nächstes Muster vorladen
Reset:
- Reset Ausgang = 1
- AusgängeX und Y wieder zurücksetzen
- Zähler reseten
- Led-Muster reseten
Vielleicht mach ich mir aber trotzdem mal den Spass und probiere es
trotzdem nochmal auf die andere Art.
Gruß,
Thomas
PS: Jetzt wo ich das geschrieben habe, fällt mir zumindest auf, dass ich
ja die Abfrage des Zählerstandes sowie den Reset eigentlich prima in die
Hauptschleife verfrachten könnte :) (auch wenn es am Ende bei so einem
unkritischen Programm wohl eh keinen unterschied macht)
Hi tom,
ich hatte mich da mal reingehängt, da ich dachte dass du so ähnliche
Verständnisprobleme hattest wie ich damals mal.
Daher will ich dir gern erklären, was ein INT ist.
Ich fange aber oben and und sage mal dass ein Hauptprogramm mit
DO
LOOP
END
schon ganz toll ist.
Das teil läuft also immer im Kreis und es wird nichts getan.
Das Programm mit:
DO
GOSUB "etwas"
LOOP
END
SUB "etwas"
RETURN
Hier hast du dann ein Unterprogramm eingebaut und es wird immer noch
nichts getan.
Nun gibt es die sogennanten Störungen (Interrupts), die ein
spezielles Ereignis benötigen um ein GOSUB auszuführen.
Wenn ich nun einen Taster hätte und würde schreiben:
DO
IF "Taster gedrückt" dann GOSUB "etwas"
LOOP
END
SUB "etwas"
RETURN
Dann würde also immer noch nichts getan aber der Tastendruck
würde die Verzweigung in das Unterprogramm erzwingen.
Ich wäre dann der Erzwinger der Verzweigung. (der Interrupter ?)
Insofern macht es zunächst mal keinen Unterschied.
Wenn aber nun 2 verschiedene Leuts wie ich einen Taster haben
wird es ein Durcheinander sein.
Für dich macht es keinen Unterschied ob du nun die ganze
Prozedur in die Int-Routine packst oder nicht.
Sobald du z.B. den 2ten Timer benutzen willst geht alles den Bach
runter,
weil du nicht mehr weisst, wer wann was drückt.
Für dein Programm macht es jedoch keinen Unterschied wenn du dich
jetzt schon an die Zukunft gewöhnst.
Du machst halt dein Programm so:
DO
If Interrupt = 1 then
"nichts tuen oder doch ?" <- hier kannst du alles Programm reinhauen
Interrupt = 0
end if
LOOP
END
Dein Unterprogramm (Gosub) ist nun ein INT Prog
Also "On Interrupt Gosub xxx"
Im Unterprogramm sagst du dann..
i=1
Return
Ich hoffe, du verstehst dass es bis auf die paar
Extrasprünge für dich keinen Unterschied machen wird,
ob du den einen oder anderen Weg wählst.
Gruss Klaus
Abdul K. schrieb:> Genausowenig weißt du über das Mikropogramm einer CPU.
Da sei dir man nicht so sicher. Zumal RISC-Prozessoren gar nicht über
Mikrocode verfügen.
mfg.
Thomas Eckmann schrieb:> Abdul K. schrieb:>> Genausowenig weißt du über das Mikropogramm einer CPU.> Da sei dir man nicht so sicher. Zumal RISC-Prozessoren gar nicht über> Mikrocode verfügen.>
Oh ja. Das wußte ich ja noch gar nicht. Vielen Dank Thomas!
Es ist natürlich vollkommen klar, Regeln wurden nur erfunden, um den
Anfängern das Programmieren zu erschweren. Und wenn der Anfänger auf den
Rat hört, lachen sich die Profis kaputt.
Es macht doch viel mehr Spaß, wenn man alle Programmiersünden und Fehler
erstmal selber macht. Da hat man doch viel länger Freude daran, bis es
endlich mal läuft. Und auch ein paar graue Haare und schlaflose Nächte
mehr.
Auf die Tips von erfahrenen Programmierern hören ja nur Weicheier.
Echte Männer lernen Programmieren auf die harte Tour. Und wenn man dann
seine früheren Programmierversuche Jahre später nochmal ansieht, möchte
man am liebsten vor Scham in der Erde versinken.
Peter
Peter Dannegger schrieb:>> Echte Männer lernen Programmieren auf die harte Tour. Und wenn man dann> seine früheren Programmierversuche Jahre später nochmal ansieht, möchte> man am liebsten vor Scham in der Erde versinken.>
True story :D
Man kann einfach nur aus Fehlern lernen. Was einem aber wirklich versaut
ist frühe Assemblerprogrammierung. Vor allem wenn es nur Bitcodes waren,
z.B. auf einem PET mit BASIC-Poke eingehakt. Danach ist man wirklich
gezeichnet. Kämpft um jedes Bit und jeden Taktzyklus und versteht die
Wartezeit auf den Compiler nicht.
Abdul K. schrieb:> Man kann einfach nur aus Fehlern lernen.
Nein.
Man kann aus Fehlern lernen. Aber nur, wenn man diese auch erkennt. Aber
nicht, wenn man auf Leute hört, die einem sagen, daß das schon so in
Ordnung ist.
Aber man kann auch lernen, indem man vorher fragt, wie man es richtig
macht.
mfg.
m.n. schrieb:> Aber das WARUM wird einem dabei nicht klar :-)
Was ist denn das für ein Quatsch?
Man muß nur bereit das anzunehmen, was man gesagt bekommt. Auch wenn man
meint, daß man eine tolle Idee hat. Das ist leider das Problem.
Daß man nicht in eine Kreissäge fassen darf, lernt man auch nicht nur
dadurch, daß man einmal reingefasst hat.
mfg.
Peter Dannegger schrieb:
>> Echte Männer lernen Programmieren auf die harte Tour. Und wenn man dann> seine früheren Programmierversuche Jahre später nochmal ansieht, möchte> man am liebsten vor Scham in der Erde versinken.>
Nimms nicht so schwer, als Perfektionist wird man nie zufrieden. Andere
wären einfach stolz darauf, dass sie sich verbessern konnten. ;)
Du hast schon recht mit den Regeln, die einem die Erfahrung lehrt, aber
man muss sie selber verstehen und nachvollziehen können. Ich kann das,
weis aber auch dass ich es irgendwann noch nicht konnte. Es ist doch so,
dass Erfahrungen nicht ohne Umwege ins "Brain1.0 gemappt" werden können.
Gruß (vor allem an die "PET-Versauten" - hallo Abdul übrigens),
Edson
Thomas Eckmann schrieb:> Man muß nur bereit das anzunehmen, was man gesagt bekommt.
Dann wird man um die wichtigsten Erfahrungen im Leben betrogen.
Oder anders ausgedrückt: Du sagst und alle anderen machen es dann so?
So funktioniert das nicht!
m.n. schrieb:> Dann wird man um die wichtigsten Erfahrungen im Leben betrogen.> Oder anders ausgedrückt: Du sagst und alle anderen machen es dann so?> So funktioniert das nicht!
Eben genau das ist es.
Das ist oft das Problem bei Foren mit Spezialisten.
Ich meine nicht speziell dieses Forum, aber man wird als Fragesteller
dann oft um den Weg zur Erkenntnis betrogen.
(Ich lass mal die Leute mit den Schulaufgaben aussen vor).
Es ist fast wie die Bausätze von "woauchimmer" .
Die kannst du zusammenlöten und es funktioniert einfach nicht.
Diesem problem muss man dann irgendwann mit geballter Erkenntnis
gegenüberstehen und erkennen, dass der Bausatz Müll ist.
Thats the way Love goes (Janet Jackson).
Klaus
m.n. schrieb:> Dann wird man um die wichtigsten Erfahrungen im Leben betrogen.
Nun komm' mal wieder runter.
Es geht in diesem Thread um Programmierregeln. Und um Erfahrungen, die
andere schon gemacht oder in irgendwelchen Büchern gelesen oder in
einer Vorlesung gehört haben.
> Oder anders ausgedrückt: Du sagst und alle anderen machen es dann so?
Ich schreibe niemandem etwas vor. Mach' doch, was du willst. Ist mir
doch egal. Aber wenn jemand fragt, bekommt er eine Antwort. Und die
heisst nicht "Probier' es selber aus". Denn darauf hätte er auch selber
kommen können. Aber er hat gefragt. Und dann lass' ich ihn nicht ins
offene Messer laufen.
Und dementsprechend habe ich dem TO geantwortet.
> So funktioniert das nicht!
Trial and Error ist also die Lösung.
Um mal wieder zum eigentlichen Thema zu kommen:
Ein aktuelles Projekt von mir sieht übrigends so aus:
int main(void)
{
Initialize();
while(true)
{
}
}
Dazu 2 ISRs.
Eigentlich genau das, was der TO vorhat.
Aber:
Thommy schrieb:> Thomas (ein unerfahrener Programmierer)
mfg.
Thomas Eckmann schrieb:> m.n. schrieb:>> Aber das WARUM wird einem dabei nicht klar :-)> Was ist denn das für ein Quatsch?> Man muß nur bereit das anzunehmen, was man gesagt bekommt. Auch wenn man> meint, daß man eine tolle Idee hat. Das ist leider das Problem.>> Daß man nicht in eine Kreissäge fassen darf, lernt man auch nicht nur> dadurch, daß man einmal reingefasst hat.>
Du bist ziemlich hochnäsig. Ich wette mal, du weißt nicht wie Menschen
lernen!
Daß ein Mensch nicht in eine Kreissäge greifen muß, hat er seinen
Spiegelneuronen zu verdanken. Die sind so etwas wie Brain 2.0 ! Sie
bieten tatsächlich eine Art Möglichkeit, ohne vorausgehender eigener
Erfahrung Wissen anderer Menschen zu übernehmen. Alles andere muß jedoch
gelernt werden. Nämlich all das, was nicht durch Gefühle wahrnehmbar
ist. Also Faktenwissen! Die Spiegelneuronen funktionieren nur mit
'Gefühlswissen'.
Für Faktenwissen greift wiederum die Erkenntnis, das man nur aus
negativen Erlebnissen lernen kann. Es ist ein Irrtum zu glauben, man
könne sich nicht an einer Herdplatte verbrennen, nur weil sie die
allermeiste Zeit aus ist! Gefragt ist der Zustand HEISS, dann ist die
negative Erfahrung rote schmerzende Hand. Danach muß der Herd nicht mehr
warm sein, damit man trotzdem vorsichtig sein wird.
Bist du vorm Herd alleine, ist es ziemlich schlecht. Steht aber Mama
dabei und tut so, als würde sie ihre Hand drauftun und macht dazu ein
schmerzhaftes Gesicht, so kann jedes Kleinkind sofort lernen, das
Draufgreifen keine gute Idee ist. DAS ist genau der Unterschied, den ich
beschrieb.
Thomas Eckmann schrieb:> int main(void)> {> Initialize();>> while(true)> {> }> }>> Dazu 2 ISRs.>> Eigentlich genau das, was der TO vorhat.
Er hat es einfacher, weil er nur 1 Interruptquelle verwendet.
> Aber:>> Thommy schrieb:>> Thomas (ein unerfahrener Programmierer)
Dann ist die einfache Struktur mit der leeren while(1) doch das Richtige
für ihn.
Gruß,
Edson
Abdul K. schrieb:> Du bist ziemlich hochnäsig. Ich wette mal, du weißt nicht wie Menschen> lernen!
Und du bist ziemlich unverschämt.
Und was soll dieser Text? Hast du immer noch nicht geschnallt, daß es
hier lediglich eine Frage beantwortet wurde, die sich auf Programmierung
bezog.
Und das hat mit dem Lernen fürs Leben überhaupt nichts zu tun.
Ausserdem habe ich nur in dem Punkt widersprochen, daß man NUR aus
Fehlern lernen kann.
Woraufhin sich dann einer um seine Erfahrungen betrogen fühlte.
m.n. schrieb:> Dann wird man um die wichtigsten Erfahrungen im Leben betrogen.
Das hat mit dem Thema doch überhaupt nichts zu tun.
Meister Eder schrieb:> Dann ist die einfache Struktur mit der leeren while(1) doch das Richtige> für ihn.
Das funktioniert auch, aber so macht man das einfach nicht.
Das ist eine ziemlich beschissene Art der Programmierung. Das ist
einfach nur Quick and Dirty, weil im Moment andere Sachen auf der
Prioritätenliste weiter oben stehen.
mfg.
Thomas Eckmann schrieb:> so macht man das einfach nicht.> Das ist eine ziemlich beschissene Art der Programmierung. Das ist> einfach nur Quick and Dirty
Also ich sehe darin ein Grundgerüst auf dem man aufbauen kann. Nichts
hindert einen daran, die ISR nach und nach zu entschärfen und mögliche
Aufgaben in die Hauptschleife zu verlagern.
Man könnte ja auch behaupten, dass
1
intmain(void)
2
{
3
InitSomething();
4
while(1)
5
{
6
DoSomething();
7
}
8
}
an sich schon schlechter Stil ist. Ich sehe da einen Rückgabewert, der
nie zurückgegeben wird, weil das Programm in einer Endlosschleife
hängenbleibt. ;)
Gruß,
Edson
Thomas Eckmann schrieb:> Abdul K. schrieb:>> Du bist ziemlich hochnäsig. Ich wette mal, du weißt nicht wie Menschen>> lernen!> Und du bist ziemlich unverschämt.>
Ist bei dir leider notwendig. Was soll man von einem halten, der seine
'Regeln' der Programmierung als per se allgemeingültig definiert? Gar
jegliche persönliche Lebenserfahrungen als überflüssig hinstellt, könne
man doch einfach durch stumpfes Nachäffen allen Widrigkeiten trotzen.
> Und was soll dieser Text? Hast du immer noch nicht geschnallt, daß es> hier lediglich eine Frage beantwortet wurde, die sich auf Programmierung> bezog.
Das Thema Programmieren wurde doch beendet. Oder kamen neue Verfahren
hinzu?
Also war das ein Sub-Thread.
> Und das hat mit dem Lernen fürs Leben überhaupt nichts zu tun.> Ausserdem habe ich nur in dem Punkt widersprochen, daß man NUR aus> Fehlern lernen kann.
Diesen Punkt habe ich danach extensiv ausgeführt, erklärt aus der Sicht
der Wahrnehmungsmechanismen. Die sind bei jedem Menschen gleich.
Indirekt hat das was mit Effizienz beim Programmieren zu tun.
> Woraufhin sich dann einer um seine Erfahrungen betrogen fühlte.
Was ja auch stimmt. Ich erklärte es bereits.
Ich habe keinerlei Lust mehr auf dich einzugehen. Einem fast 50 Jährigen
brauch keiner mehr vom Leben erzählen. Da habe ich genug hinter mir!
Abdul K. schrieb:> Ist bei dir leider notwendig.
Aha.
Abdul K. schrieb:> Ich habe keinerlei Lust mehr auf dich einzugehen. Einem fast 50 Jährigen> brauch keiner mehr vom Leben erzählen. Da habe ich genug hinter mir!
Jungspund. Aber so wie du dich aufführst, eher Rotznase.
Abdul K. schrieb:> Was soll man von einem halten, der seine> 'Regeln' der Programmierung als per se allgemeingültig definiert? Gar> jegliche persönliche Lebenserfahrungen als überflüssig hinstellt, könne> man doch einfach durch stumpfes Nachäffen allen Widrigkeiten trotzen.
Wo hast du denn diesen Schwachsinn gelesen? Du hast dcch irgendwas
genommen.
mfg.
Ihr benehmt euch ja fast so als hättet ihr keine Interuptroutine.
Vielleicht solltet Ihr mal ein SEI in euren Code einfügen.
Ich finde es köstlich aber nun ist doch auch gut .. oder ?
Gruss Klaus
Klaus De lisson schrieb:> Ich finde es köstlich aber nun ist doch auch gut .. oder ?
Ist es doch auch. Schade, daß man den Leuten nicht gegenübersitzt.
Klaus De lisson schrieb:> Vielleicht solltet Ihr mal ein SEI in euren Code einfügen.
Aber vielleicht wäre so langsam <Alles Markieren> Ctrl+X angebracht.
mfg.
Thomas Eckmann schrieb:> Ist es doch auch. Schade, daß man den Leuten nicht gegenübersitzt.
Musst mal vorbeikommen wenn ich ne Bierprobe durchführe.
Am besten du bringst dann dein eigenes SEI gleich mit.
k.
Hi
>Musst mal vorbeikommen wenn ich ne Bierprobe durchführe.>Am besten du bringst dann dein eigenes SEI gleich mit.
CLI
Push Arbeit
Wo gibt's ne Bierprobe ?
POP Arbeit
SEI
Darf ich dann auch mit meinen 60 den Barkeeper, ähh Moderator
spielen....
PS zur Sache: Jeder kann sein Programm so schreiben, wie er es möchte
und eigene Wege zu gehen ist nicht verkehrt. Doch wenn eine Frage
bezüglich der Vorgehensweise gestellt wird, dann erwartet der
Fragesteller auch eine qualifizierte Antwort und keinen
Glaubenskrieg....
Gruß oldmax
Thommy schrieb:> Nun dachte ich mir es würde sich ja anbieten quasi das komplette> Programm in den Interrupt zu verlagern da ja sowieso alle Aktionen im> Interrupt-Takt ausgeführt werden sollen und ich mir so das Abfragen von> diversen Flags in der Hauptschleife sparen könnte.
Diese Grundsatzdiskussion hier ist ja der reinste Glaubenskrieg...
Der Ansatz, den Du verfolgst, entspricht einer (sehr einfachen) Variante
eines Schedulers. Wenn Du sicher bist, dass Du keine wichtigeren
Interrupts verdrängst (weil der µC diese blockiert, während Deine
Timer-ISR abgearbeitet wird), ist Dein Ansatz absolut in Ordnung. Meine
µC-Programme sind ganz ähnlich strukturiert.
Der Vorteil ist, dass Du genau weißt, wie viel Zeit seit dem letzten
Aufruf der Routine vergangen ist; vor allem bei Regelalgorithmen ist das
hilfreich. Ich finde es persönlich eleganter. Wenn die Timer-ISR zu
lange braucht, ist m.E. die Zeit für einen Scheduler wie FreeRTOS
gekommen.
Es gibt natürlich auch den Ansatz "jedes Programm ist eine große
Main-Loop". Mich erinnert das immer an Polling und Spaghetti-Code, aber
das ist sicher subjektiv. Die Diskussion oben klang eher so, als sei das
die einzig wahre Profi-Lösung.
Meine Einschätzung: Es ist beides möglich, und es gibt keine falsche
oder richtige Lösung.
Just my 2ct.
Max