Hiho zusammen,
mein erstes etwas größeres uC-Projekt und irgendwie hakt es dauernd...
Mein aktuelles Problem ist, das das Programm zu groß geworden ist,
nachdem ich alle Einzelteile zusammen gebaut habe.
Ich habe 1k Flash zur Verfügung, das Programm ist aber ca. 3k groß.
Liegt es an meiner umständlichen/ineffizienten Programmierung oder ist
der Flash einfach nur zu klein für den Funktionsumfang?
Ich habe die '.c' mal angehängt. Vielleicht hat ja jemand kurz Zeit,
sich das Gewurstel mal anzusehen...
Danke schonmal...
Wenns ein einzelstück sein soll: nimm nen größeren µC (wird vmtl. dann
4kb werden)
Wenns Massenware sein soll: versuchs auf 2kb zu kriegen und nimm ne 2kb
µC
Wenn du nicht grade mit debug-Optimierung und nur floating point
berechnung gearbeitet hast, dann wirst du nie aus 3kb eines machen, da
sind 2 schon sportlich.
Bernd N schrieb:> Welchen MSP verwendest du hier ? Optimizer angeschmissen ? Welcher C> Compiler ?
MSP ist der G2131, Optimierer auf kleinste Größe und Compiler ist der
vom CCS.
Ich kann mir nicht vorstellen, dass diese paar Zeilen 3k erzeugen.
Schau mal dein MAP-File an, was da noch alles drin ist.
Irgendwelche Libs dazugelinkt, die nicht gebraucht werden?
Ausserdem fehlt das While(1){} in der main.
Daniel V. schrieb:> Ich kann mir nicht vorstellen, dass diese paar Zeilen 3k erzeugen.
So gings mir auch, ich habe auch mal kurz quer überflogen und habe weder
floating point gefunden noch printf oder andere Dinge, die viel Platz
brauchen.
Ich kenne die MSPs nicht, aber das bischen C Code gibt doch keine 3K?
Also MAP File, im Zweifel mal posten.
Ich habe zuletzt die "Dauermessung" mit dem WDT als Status-LED-Timer
eingebaut.
Vorher hatte ich knapp 1k, jetzt bekomme ich 'ne Fehlermeldung, dass das
Programm nicht in den Speicher passt und wenn ich die angegebene
HEX-Zahl umrechne, bin ich bei gut 3kByte.
Andere LIBs hab ich nicht eingebunden...
Und die Endlosschleife habe ich weg gelassen, weil die bei den
TI-Beispielen auch nicht da war, aber daran liegt es glaube ich auch
nicht...
so dass keine Floating Point Berechnung mehr auftaucht und dein
Speicherverbrauch wird wieder sinken.
Du musst ja nicht mit 0.1 multiplizieren! Mal 10 durch 100 tuts auch.
Mal 1 durch 10, bzw. mal 9 durch 10 ist noch besser, weil es die Gefahr
eines Overflows während der Berechnung kleiner macht.
Aber diese beiden Multiplikationen ziehen einen ganzen Rattenschwanz mit
ins Programm hinein.
> so dass keine Floating Point Berechnung mehr auftaucht und dein> Speicherverbrauch wird wieder sinken.>> Du musst ja nicht mit 0.1 multiplizieren! Mal 10 durch 100 tuts auch.> Mal 1 durch 10, bzw. mal 9 durch 10 ist noch besser, weil es die Gefahr> eines Overflows während der Berechnung kleiner macht.> Aber diese beiden Multiplikationen ziehen einen ganzen Rattenschwanz mit> ins Programm hinein.
Das werde ich nachher ausprobieren. Hätte nicht gedacht, das *0.9 was
anderes macht als /10 *9...
Dominik R. schrieb:> Das werde ich nachher ausprobieren. Hätte nicht gedacht, das *0.9 was> anderes macht als /10 *9...
sogar *9/10 ist noch was anderes!
Dominik R. schrieb:> Das werde ich nachher ausprobieren. Hätte nicht gedacht, das *0.9 was> anderes macht als /10 *9...
0.9 ist eine Gleitkommazahl, also muß die Bibliothek für
Gleitkomma-Berechneungen bemüht werden. 10 und 9 sind dagegen nur
Integers, brauchen das also nicht.
Dominik R. schrieb:> Hier ist noch das MAP.
.text ist nur 0x3d4 gross, also 980 Byte.
Wie kommst du auf 3k? Eventuell ist dein Hexfile 3k gross. Lade doch das
Programm einfachmal auf deinen uC....
Dominik R. schrieb:> Ich habe zuletzt die "Dauermessung" mit dem WDT als Status-LED-Timer> eingebaut.>> Vorher hatte ich knapp 1k, jetzt bekomme ich 'ne Fehlermeldung, dass das> Programm nicht in den Speicher passt und wenn ich die angegebene> HEX-Zahl umrechne, bin ich bei gut 3kByte.> Andere LIBs hab ich nicht eingebunden...>> Und die Endlosschleife habe ich weg gelassen, weil die bei den> TI-Beispielen auch nicht da war, aber daran liegt es glaube ich auch> nicht...
Hab ich jetzt erst gesehen.
Ich tippe:
Map-File und C-File passen nicht zusammen.
Kann sein, dass das map-file noch eins von dem stand ist, wo ich die
"dauermessung" noch nicht drin hatte. Ich überprüfe das nachher noch
einmal und lade die aktuelle map noch mal hoch. Sorry.
Das ein integer etwas anderes ist als ein float ist mir bewusst. Ich war
nur davon ausgegangen, dass eine implizierte konvertierung durchgeführt
wird, wenn man zwei integer dividiert, bei denen ein Rest übrig bleibt.
Ich werde nachher die ...*0.9 durch (.../9)*10 und die ...*0.1 durch
.../10 ersetzen. Damit müsste ich ja Platz schaffen können. Vielleicht
passt es dann ja schon wieder.
Bei manchen C-Compilern muss man die Bibliotheken, die plötzlich nicht
mehr benötigt werden explizit aus den Listen entfernen. Sonst werden sie
weiterhin unnötig hinzu gelinkt, zumindest der Rumpf.
Ralf G. schrieb:> Dominik R. schrieb:>> (.../9)*10>> *9/10>> Außer, du willst da jetzt was ganz anderes ausrechnen...
Ja, klar. *9/10 meinte ich.
Ich habe das jetzt auch geändert und bin somit auf 1258 Byte. Leider
immer noch knapp 270 Byte zuviel... mal davon abgesehen, dass ich bisher
immer dachte, 1 kByte wären 1024 Byte. Platz ist aber nur 992 Byte.
Noch irgend jemand 'ne Idee, wo man noch etwas optimieren kann?
Ach ja, hier noch das aktuelle Map-File.
> timerCount = (timerCount + 1) % 120; //ca. 1 Min.
Mach da mal
timerCount = (timerCount + 1) % 128; //ca. 1 Min.
draus. Wird wohl egal sein obs etwas mehr als 1 Minute ist.
volatile uint8_t m;
for(m = 0; m < 60; m++){
Was soll das volatile da? Mach das weg.
Wenn du deine Werte für ledstatus ein wenig intelligenter vergeben
würdest, anstatt einfach von 0 beginnend durchzuzählen, dann würdest du
dir hier
1
switch(ledStatus){
2
case1:
3
P1OUT^=LED_GREEN;
4
P1OUT|=LED_YELLOW+LED_RED;
5
break;
6
case2:
7
P1OUT&=~LED_GREEN;
8
P1OUT|=LED_YELLOW+LED_RED;
9
break;
10
case3:
11
P1OUT&=~LED_YELLOW;
12
P1OUT|=LED_GREEN+LED_RED;
13
break;
14
case4:
15
P1OUT&=~LED_RED;
16
P1OUT|=LED_GREEN+LED_YELLOW;
17
break;
18
case5:
19
P1OUT^=LED_RED;
20
P1OUT|=LED_GREEN+LED_YELLOW;
21
break;
zb schon eine ganze Menge sparen.
Denn deine LED sind am Port sowieso an benachbarten Pins angeordnet, so
dass du im Grunde nichts anderes tun musst, als ledStatus genau den
binären 3-Bit Wert zu geben, den du ganz einfach am Port ausgeben
kannst.
>Irgendwie verteilst du volatile mit dem Gießkannanprinzip.
Genau. Einfach einmal messwert in eine lokale Variable
holen und den ganzen Klimbim dann damit ausführen.
Sonst muss messwert ja jedesmal neu aus dem Speicher gelesen werden.
So ganz hab ich noch nicht durchschaut, wozu du den Watchdog Timer
benötigst.
Wenn ich das richtig sehe, dann ist der Watschdog doch sowieso nur an
einer einzigen Programmsequenz aktiv - nämlich der Schleife in der die
Messungen gemacht werden. An deren Ende steht aber ein delay. Da frage
ich mich: Hä? Wozu der ganze Klimbim mit dem Watchdog - mach doch den
Update der LEDs gleich in dieser Schleife und spar dir den ganzen
Hackmack mit Watchdog aktivieren, konfigurieren und eigener ISR.
Oder übersehe ich da jetzt was?
Johann L. schrieb:> Irgendwie verteilst du volatile mit dem Gießkannanprinzip. Z.B. ist /> messwert/ volatile und dann sowas. Das muß zu ineffizientem Code> führen!
Ja, stimmt schon.Ich bin mir halt unsicher, wann der Compiler vielleicht
wichtige Dinge "wegoptimiert"...
Karl Heinz Buchegger schrieb:> Denn deine LED sind am Port sowieso an benachbarten Pins angeordnet, so> dass du im Grunde nichts anderes tun musst, als ledStatus genau den> binären 3-Bit Wert zu geben, den du ganz einfach am Port ausgeben> kannst.
da stehe ich jetzt etwas auf dem Schlauch. ledStatus 2 wäre dann z.B.
0xC0 (also P1.7 HI, P1.6 HI, alles andere auf LO) oder wie muss ich mir
das vorstellen?
Karl Heinz Buchegger schrieb:> So ganz hab ich noch nicht durchschaut, wozu du den Watchdog Timer> benötigst.>> Wenn ich das richtig sehe, dann ist der Watschdog doch sowieso nur an> einer einzigen Programmsequenz aktiv - nämlich der Schleife in der die> Messungen gemacht werden. An deren Ende steht aber ein delay. Da frage> ich mich: Hä? Wozu der ganze Klimbim mit dem Watchdog - mach doch den> Update der LEDs gleich in dieser Schleife und spar dir den ganzen> Hackmack mit Watchdog aktivieren, konfigurieren und eigener ISR.> Oder übersehe ich da jetzt was?
Ja, stimmt... vorher hatte ich den WDT auch noch für was anderes. Das
ist aber irgendwann geändert worden und ich habe nicht daran gedacht,
dass ich die LED-Anzeige dann ja auch ohne WDT machen kann...
>Ja, stimmt schon.Ich bin mir halt unsicher, wann der Compiler vielleicht>wichtige Dinge "wegoptimiert"...
Wer eine globale Variable "i" anlegt sollte sich um ganz andere
Dinge sorgen machen. Und diese ganzen Delays in den Interrupts.
Ganz klares NoGo.
Das mit dem globalen i war nur ein Versuch, aus zwei Variablen, die ja
auch etwas Speicher brauchen, eine zu machen, da ich an zwei Stellen
eine Zähler-Variable brauchte, aber beide Stellen nie gleichzeitig
zählen. Dass es das nicht gebracht hat, ist mir inzischen auch schon
klar ;-)
Wo sollen die Delays denn sonst hin?
Anbei noch einmal die '.c' ohne WDT. Leider fehlen mir immer noch 148
Bytes...
Man lese diesen Beitrag:
Beitrag "Re: MSP430G211 analoge Eingänge"
Der Code ist für ein Kundenprojekt. lol
Dem ganzen Projekt fehlt es an Struktur. Erst wurde die HW verbastelt,
jetzt ist die SW dran.
Das bisschen Gefrickele passt doch locker in den 1k. Ein Blick in die
Projektkonfiguration kann helfen.
ich kann lesen schrieb:> Dem ganzen Projekt fehlt es an Struktur. Erst wurde die HW verbastelt,> jetzt ist die SW dran.
Für die Hardware kann ich nunmal nichts, die habe ich so vorgegeben
bekommen.
Und ja, jetzt ist die Software dran. Aber da ich wie gesagt noch ein
ziemlicher Anfänger im Bereich uC bin und das eher als Hobby sehe, mit
dem ich mir ein paar Euros dazu verdienen kann, weiss ich nicht, wo dein
Problem ist.
Aber wenn du mir jetzt noch sagst, was ich in der Projektkonfiguration
einstellen muss, damit das bisschen gefrickel auch in die 1k passt, wäre
ich echt ein ganzes Stück weiter.
Daniel V. schrieb:> Ausserdem fehlt das While(1){} in der main.
gute Frage,
Dominik R. schrieb:> Und die Endlosschleife habe ich weg gelassen, weil die bei den> TI-Beispielen auch nicht da war, aber daran liegt es glaube ich auch> nicht...
falsche Antwort. Besser wäre: Aus dem LPM kommt der MSP nur per
Interrupt. Nach Abarbeitung der ISR wird das Statuswort restauriert und
damit wieder in den LPM geschaltet.
Karl Heinz Buchegger schrieb:> spar dir den ganzen> Hackmack mit Watchdog aktivieren, konfigurieren und eigener ISR.> Oder übersehe ich da jetzt was?
Der Watchdog kann beim MSP als einfacher Timer genutzt werden.
>Aber wenn du mir jetzt noch sagst, was ich in der Projektkonfiguration>einstellen muss, damit das bisschen gefrickel auch in die 1k passt
Du kannst in den Projektoptionen nichts einstellen
was deinen vergurkten Code verbessert.
Die meisten deiner volatiles sind überhaupt nicht notwendig.
DA holst du dir dein Flash zurück.
holger schrieb:>>Aber wenn du mir jetzt noch sagst, was ich in der Projektkonfiguration>>einstellen muss, damit das bisschen gefrickel auch in die 1k passt>> Du kannst in den Projektoptionen nichts einstellen> was deinen vergurkten Code verbessert.>> Die meisten deiner volatiles sind überhaupt nicht notwendig.> DA holst du dir dein Flash zurück.
Die volatiles sind in der aktuellen Version gar nicht mehr drin.
ich kann lesen schrieb:> Der Watchdog kann beim MSP als einfacher Timer genutzt werden.
Ich hatte den WDT als einfachen Timer genutzt, war aber - wie kbuchegg
schrieb - gar nicht mehrnötig, also auch entfernt.
Sind noch irgendwelche unnötigen Bib's drin?
Welche Variablen können vom Datentyp kleiner werden?
Auf gleiche Konstanten bei den Wartezeiten gehen!?
Delay über Timer?
Inlinefunktionen?
Anderer Algorithmus überlegen?
...
holger schrieb:> Du kannst in den Projektoptionen nichts einstellen> was deinen vergurkten Code verbessert.
:-D Das stimmt zu 100%!
Aber man kann einmal nachsehen, was noch so alles zum Kraut und Rüben
Programm dazu kommt. ;-)
>> Die meisten deiner volatiles sind überhaupt nicht notwendig.>> DA holst du dir dein Flash zurück.>>Die volatiles sind in der aktuellen Version gar nicht mehr drin.
Ich habe nicht gesagt ALLE sollten kein volatile sein.
Wo ist denn der derzeitige Flash Bedarf?
Dominik R. schrieb:> Ich verstehe nicht wirklich, wann der Compiler ggf. eine Variable> wegoptimiert und diese somit als volatile gekennzeichnet werden muss...
Der Compiler wird nur Variablen "wegoptimieren", die nicht verwendet
werden.
Hier aber wird er optimieren (nicht "wegoptimieren"):
Johann L. schrieb:> if(messwert < 0){> ledStatus = 1;> }> else if((messwert > 0) && (messwert < wert10)){> ledStatus = 2;> }> else if((messwert > wert10) && (messwert < wert90)){> ledStatus = 3;> }> else if((messwert > wert90) && (messwert < tarawert)){> ledStatus = 4;> }> else if(messwert < tarawert){> ledStatus = 5;> }
"messwert" wird EINMAL in ein Register eingelesen und dann wird mit dem
Register gerechnet.
Falls du "messwert" als volatile definiert hast, wird der Compiler
"messwert" bei jedem Vergleich neu in ein Register lesen. Das macht die
Kiste langsamer und den Code grösser.
Falls sich "messwert" während diesem Vergleich ändern kann (z.B. wenn
die Variable in einem Interrupt verändert wird) UND du möchtest, dass
immer mit dem aktuellen Wert gerechnet wird, dann ist "volatile"
angesagt.
Ansosnten kannst du dir "volatile" sparen.
>Ja, stimmt schon.Ich bin mir halt unsicher, wann der Compiler vielleicht
wichtige Dinge "wegoptimiert"...
Sowas gibt es gar nicht, resp darf es nicht geben. Das ist das
Wichtigste. Man muss sich drauf verlassen koennen, dass das geschieht,
was man will. Deswegen ist Debuggen auch Teil des Entwicklungsprozesses,
und nicht etwas Unerwuenschtes, das man leider nachher noch anfuegen
muss.
Hallo nochmal,
ich habe es leider immer noch nicht geschafft, das Programm so weit zu
verkleinern, dass es in den uC-Speicher passt.
Auch diese Aussage hilft nicht wirklich weiter:
ich kann lesen schrieb:> Jetzt habe ich zum Spaß das Programm unverändert mit den> Standardeinstellungen MAKEn lassen und 984 bytes of CODE memory> 62 bytes of DATA memory (+ 20 absolute )> 3 bytes of CONST memory>> Errors: none> Warnings: none>> Geht doch!
984+62+3 = 1049 Bytes => zu groß für den 992 Byte großen Speicher (oder
wird DATA und CONST nicht im Flash abgelegt?)
Vielleicht kannst du mir auch noch sagen, was du für ein Compiler
benutzt hast, denn wenn ich den Code mit CCS 5.5 und den
Standardeinstellungen kompiliere, ist das Programm doch noch etwas
größer.
Ich habe den Code noch weiter bearbeitet, so dass ich mit meinen
Einstellungen auf 1060 Byte komme. So sind es aber leider immer noch 68
Byte zuviel. Ich habe den aktuellen Stant noch einmal angehängt. Gibt es
noch weiteres Einsparungspotential?
Da ich noch nicht so lange in C und mit Mikrocontrollern arbeite, würde
ich auch gerne wissen, was strukturell vielleicht noch verbessert werden
könnte. Ja, ich weiss, dass man von Interrupt-Routinen aus keine
Methoden aufrufen sollte, schon gar nicht mit Delays, aber wenn ein
Interrupt verschluckt wird, ist das hier nicht sooo tragisch. Außerdem
weiss ich nicht, wie ich es besser machen sollte. Ist es ok, erst das
Flag zu clearen und dann eine Methode aus der ISR heraus aufzurufen?
Was mir an meinem Code gar nicht gefällt ist diese if ... 3x else if ...
else Katastrophe, aber ich habe auch keine Idee, wie ich das eleganter
lösen sollte...
Danke schonmal.
Dominik R. schrieb:> Was mir an meinem Code gar nicht gefällt ist diese if ... 3x else if ...> else Katastrophe, aber ich habe auch keine Idee, wie ich das eleganter> lösen sollte...
Das ist nun wirklich das allerkleinste Problem an dem Code ...
Ganz ernst gemeinter Rat: Lösch den Murks und schreib es nochmal. Nimm
es auch nicht als Vorlage für ein neues Programm. Fang nochmal mit einer
leeren Datei an und schreib es ohne Interrupts und volatile, einfach
geradeaus mit Polling. Danach ist das Programm nur noch halb so groß,
verständlich und funktioniert auch sauber.
Der Gedanke das obige Programm ins Flash zu bekommen, wo scheinbar nur
noch so wenig "abzuschneiden" ist, ist aus sportlicher Sicht bestimmt
reizvoll.
Bedenke aber bitte folgendes:
- Durch trickreiche Konstrukte kann man einiges an Speicher sparen,
aber die Wartbarkeit auf null drücken.
- Bist Du Dir 100% sicher, das, kaum dass es passt, nicht noch
irgendwas nachgerüstet werden muss? Dann landest Du nämlich auf
direktem Weg in der Abteilung: "Typischer Fall von Denkste". Die
liegt übrigens gleich neben der Abteilung: "Außer Spesen nix
gewesen".
Ganz ohne Interrupts wird es nicht gehen, da sich der uC im LPM befinden
soll, wenn gerade nich gemessen wird. Ich hab da keinen Schimmer, wie
ich das umsetzen sollte.
Und nur, damit ich es das nächste Mal besser machen kann - was ist denn
besonderer Murks (mal abgesehen von den Delays, die aus den ISR
aufgerufen werden)? - vielleicht habe ich die rosarote Brille auf oder
noch zu wenig Plan von C, aber ist es echt soo schlimm?
Dominik R. schrieb:> wird DATA und CONST nicht im Flash abgelegt?
Richtig, DATA ist RAM.
Das Ganze wurde mit dem IAR erstellt. Aber auch das hilft dir nicht. Das
Programm ist bestimmt noch nicht fertig, du brauchst mehr Speicher.
Dominik R. schrieb:> Gibt es> noch weiteres Einsparungspotential?
Sind die ganzen delays nötig? In einer ISR wird 5s gewartet!
Da würde ich dringend den Ablauf und die Struktur überdenken.
ich kann lesen schrieb:> In einer ISR wird 5s gewartet!
Die LED soll 5s leuchten, bevor der Wert gespeichert wird. Und da in der
Zeit weder auf Taster noch auf Timer reagiert werden soll, dachte ich,
das das Delay in der ISR ok ist.
Aber wenn das Programm auf biegen und brechen nicht in den uC passt,
hilft das alles nichts...
>Gibt es noch weiteres Einsparungspotential?
Ja, gibt es. Mach keine Berechnungen oder Vergleiche
mit volatile Variablen. Vermeide überflüssige Berechnungen.
Danke für den Hinweis. Natürlich muss wert10 und wert90 nicht 60 mal
berechnet werden. Hätte ich auch früher mal sehen können.
Hat 8 Byte gebracht. Bleiben leider immer noch 60 über. Ich denke, das
wird nichts mehr.
Ist volatile bei den beiden Variablen überhaupt notwendig? Ich bin mir
da nicht so ganz sicher. Normalerweise muss man ja volatile deklarieren,
wenn sich der Wert einer Variablen während der Verarbeitung durch eine
andere ISR ändern könnte, oder? Aber eigentlich kann / soll sich der
Wert der beiden Variablen an der Stelle der Berechnung gar nicht ändern.
Also ist Volatile hier notwendig?
Dominik R. schrieb:> Ganz ohne Interrupts wird es nicht gehen, da sich der uC im LPM> befinden> soll, wenn gerade nich gemessen wird. Ich hab da keinen Schimmer, wie> ich das umsetzen sollte.
Ich kenne den Controller nicht, aber es sollte doch ausreichen, wenn er
per Interrupt geweckt wird und dadurch wieder in die Hauptschleife
springt? Der Interrupt selber muss dann gar nichts machen.
> Und nur, damit ich es das nächste Mal besser machen kann - was ist denn> besonderer Murks (mal abgesehen von den Delays, die aus den ISR> aufgerufen werden)? - vielleicht habe ich die rosarote Brille auf oder> noch zu wenig Plan von C, aber ist es echt soo schlimm?
Äußerlich:
- Unsaubere Codeformatierung (fehlende Leerzeichen vor Klammern und
teilweise in Ausdrücken)
- Unheitliche Bezeichner (timerCount, daycount), Deutsch und Englisch
gemischt
- Unklare Bezeichner (interval15, praktisch alle Funktionsnamen)
Technisch:
- Kein static vor den Hilfsfunktionen (hier: alle außer main) und den
Modulvariablen (hier: alle globalen Variablen). Alleine das könnte schon
zur Größenreduktion reichen.
- Globale Variablen statt lokale (statische) Variablen. Z.B. wird
timerCount nur in der ISR Timer_A benutzt, würde also als
static-Variable in diese Funktion gehören.
- Unsinnige volatiles. Wie gesagt, ohne Interrupts bräuchte man
überhaupt keine. Falls man eine volatile-Variable in einer Funktion mehr
als einmal benutzt, lohnt es sich, sie in eine lokale Variable
umzukopieren und nur mit der lokalen Variable zu arbeiten. Das kann der
Compiler dann optimieren.
- Unklarer Programmfluss durch willkürliche Funktionen mit unklaren
Namen. Normalerweise sollte alleine durch den Prototyp einer Funktion
(Name, Rückgabewert, Parameter) klar sein, was sie tut und möglichst
keine globalen Variablen verändern. Bei der Funktion "void
dauerMessung(void)" ist exakt das Gegenteil der Fall ...
Ich weiß, gerade letzteres ist als Anfänger nicht so einfach zu
erreichen, dazu braucht man Erfahrung. Bevor man aber willkürlich
irgendwelche Funktionen definiert, halte ich es dann immer noch für
besser, zunächst mal den kompletten Kontrollfluss in eine Funktion zu
packen und die einzelnen Abschnitte sinnvoll zu kommentieren.
Wenn man darin dann einen Teil erkennt, der eine in sich geschlossene
Funktionalität darstellt, am besten mit wenigen Eingabeparametern, ohne
Nebenwirkungen und mit einem Ergebnis, das man zurückgeben kann, dann
macht man daraus eine Funktion. Deren Name sollte mit einem Verb
beginnen und genau das beschreiben was sie tut. Und sie darf dann auch
nur genau das machen und nichts anderes. Nur so erhält man sinnvolle
Funktionen, die beim Verständnis des Codes helfen.
Zuletzt dann noch die Delays ... Die will man eigentlich auch nicht
haben, schon gar nicht im Interrupt. In einem einfachen Programm, das
sonst nichts machen muss, als eine lineare Befehlsfolge abarbeiten, sind
sie aber OK. Nur dann wie gesagt bitte keine Interrupts, das passt
schlichtweg nicht zusammen.
Danke für die Hinweise. Ich werde die Ratschläge beherzigen und noch
einmal versuchen, eine Poll-Version zu machen, die dann evtl. auch etwas
kleiner ausfällt.
Ich wünsche noch eine gute Nacht.
Martin H. schrieb:> für ihre> Konstanten stets Typen für ihre Konstanten angeben
???
Martin H. schrieb:> sicherlich nicht> unnötig
Wo besteht der Zusammanhang mit Konstanten?
Oder meinst du, dass daraus durch den Cast eine Variable wird? ;-)))