Code:https://www.arduino.cc/en/tutorial/BlinkWithoutDelayMfGCode:https://forum.arduino.cc/index.php?topic=423688.0
Code:https://www.arduino.cc/en/tutorial/BlinkWithoutDelayMfGCode:https://forum.arduino.cc/index.php?topic=423688.0
Ich habe da folgende Vorgehensweise:
aber viele Wege führen zum Ziel, da hat sicher jeder eine andere Lösung...Code:typedef unsigned int TTimeValue; // ich nehme 16 Bit Werte für die Millisekunden Zeiten */ typedef volatile struct // in dieser Struktur werden alle Zeitwerte verwaltet { TTimeValue Led1BlinkTime; TTimeValue Led2BlinkTime; TTimeValue KeyTime; /* hier kann man beliebig erweitern */ } TimerStruct; volatile TimerStruct Timers; // das ist die gesamte Timerstruktur (die Instanz) //---------------------------------------------------------------- // der 1 Millisekunden Timer Interrupt: // hier wird jeder Zeitwert, solange er noch nicht 0 ist, um eins erniedrigt void TIMER0_IRQHandler (void) { int i; TTimeValue *p = (TTimeValue*) &Timers; /* initialize p to startaddress of the structure */ for (i=0; i< (sizeof(Timers) / sizeof(TTimeValue)); i++) { if (*p) /* if current addressed counter value is greater zero then */ --*p; /* decrement the counter value by one */ p++; /* p points now to the next counter value */ } } //---------------------------------------------------------------- // Jetzt kommen diverse Funktionen die ausgeführt werden sollen: void DoLed1(void) { static char BlinkPhase; if (Timers.Led1BlinkTime) return; // es gibt noch nichts zu tun, Zähler noch nicht 0 if (BlinkPhase) { // Led1On(); Timers.Led1BlinkTime = 250; // 250 ms ein } else { // Led1Off(); Timers.Led1BlinkTime = 100; // 100 ms aus } BlinkPhase = ! BlinkPhase; // BlinkPhase umdrehen } void DoLed2(void) { static char BlinkPhase; if (Timers.Led2BlinkTime) return; // es gibt noch nichts zu tun, Zähler noch nicht 0 if (BlinkPhase) { // Led2On(); Timers.Led1BlinkTime = 500; // 500 ms ein } else { // Led2Off(); Timers.Led1BlinkTime = 250; // 250 ms aus } BlinkPhase = ! BlinkPhase; // BlinkPhase umdrehen } void DoKeys(void) { if (Timers.KeyTime) return; // noch nix zu tun Timers.KeyTime = 20; // nächste Abfrage in 20ms // Tastenstatus auswerten usw..... } void main(void) // Hauptprogramm: { while (1) { DoLed1(); DoLed2(); DoKeys(); // ....usw.... } }
Siro
Die Verwendung einer Struktur hat nichts mit Größe oder Anzahl zu tun, sondern damit, die Variablen für einen Funktionsbaustein sinnvoll zusammenzuhalten und erweiterbar zu gestalten, so dass das weitermachen auch bei einem Fehlschlag oder einer neuen Anforderung noch Spaß macht! Guter Code entsteht niemals durch Zwang von Außen, sondern aus der einfachen Erkenntnis:
Wenn es machbar ist und ein Erfolg winkt, tue ich es. Damit es machbar ist und bleibt, vermeide ich Codegräber und schreibe wartbaren Code.
Dein Eingangsbeispiel zeigt doch schon drei Parameter auf. Mit denen funktioniert es nicht, da fehlt noch was. Das hast Du ja selber gemerkt.
Das kannst Du jetzt mit zusätzlichen Übergabeparametern ergänzen. Nur musst Du dann auch die Variablen einzeln für die Übergabe definieren.
Das gibt spätestens nach der 3. Änderungswelle ein heilloses, unwartbares Chaos. Bei jeder Erweiterung musst Du den aufgerufenen Funktionsrumpf ändern, alle Aufrufe anpassen und noch neue Variablen definieren.
Mit Strukturen erweiterst Du nur den Strukturtyp, setzt die Initialwerte der Definitionen (Variablen) und kümmerst Dich um das Wesentliche - den Code in Deiner Funktion.
Hallo Siro,
das: "sizeof(Timers) / sizeof(TTimeValue)" würde ich aus der For-Schleife raus nehmen und das Ergebnis in eine Variable packen.
Code:int irgendwas = sizeof(Timers) / sizeof(TTimeValue);
und die Schleife dann so ändern:
Evtl. funktioniert das ja auch noch mit "const" als Konstante, das weiß ich nicht an der Stelle.Code:for (i=0; i< irgendwas; i++)
Es sei denn, der Compiler würde das selbst optimieren. Sonst hättest Du bei jedem Schleifendurchlauf die Berechnung drin, deren Ergebnis sich nie ändert. Mit den verlorenen Taktzyklen kann man was anderes anfangen.
MfG
@Moppi:
Hatte ich Anfangs auch bedenken, aber wie HaWe schon schreibt, der Compiler setzt da eine Konstante ein.
Er macht selbst die Vorrausberechnung, das habe mir im Assemblercode vei verschiedenen Compilern jeweils angesehen.
Grade bei meinen kleinen PICs mit wenig Speicher, bin ich da immer am gucken was der Compiler für Code erzeugt,
Siro
Ich danke euch Allen erst einmal vielmals für die konstruktiven Antworten und Hinweisen.
Mit diesem Bsp spiele ich derzeit - muss dann in den nächsten Tagen auf meine zukünftig mutiplen Bedürfnisse angepasst werden.
__________________________________________________ _
| Sprache: C | Teensy 3.2 | Arduino 2.x | Status: EwigerAnfaenger |
Lesezeichen