Is doch Wurscht...
Passt rein in den Controller und funktioniert...
Also wozu noch Lebenszeit vernichten und abändern??
Schaltung aufbauen, Glücklichsein und ab zum nächsten Projekt.
MfG, dl1akp
Is doch Wurscht...
Passt rein in den Controller und funktioniert...
Also wozu noch Lebenszeit vernichten und abändern??
Schaltung aufbauen, Glücklichsein und ab zum nächsten Projekt.
MfG, dl1akp
Das hier:
Kannst du z.B. so umändern:Code:If Modus = 0 Then If State = 0 Then Incr C_r Decr C_b If C_r = 255 Then State = 1 End If If State = 1 Then Decr C_r Incr C_g If C_g = 255 Then State = 2 End If If State = 2 Then Decr C_g Incr C_b If C_b = 255 Then State = 0 End If End If If Modus = 1 Then If State = 0 Then If C_r < 255 Then Incr C_r If C_r = 255 Then State = 1 End If If State = 1 Then If C_b < 255 Then Incr C_b If C_b = 255 Then State = 2 End If If State = 2 Then If C_g < 255 Then Incr C_g If C_g = 255 Then State = 3 End If If State = 3 Then If C_r > 1 Then Decr C_r If C_g > 50 Then Decr C_g If C_b > 1 Then Decr C_b If C_r = 1 Then State = 4 End If If State = 4 Then If C_g < 255 Then Incr C_g If C_b < 255 Then Incr C_b If C_b = 255 Then State = 5 End If If State = 5 Then If C_g > 1 Then Decr C_g If C_b > 1 Then Decr C_b If C_g = 1 Then State = 0 End If End If
Und für Modus = 1 ersetzt du die ganzen If-Abfragen ebenfalls durch Select-Case. Ob es das Programm nun wirklich kleiner macht weiß ich nicht aber auf jedenfall wird es übersichtlicher.Code:If Modus = 0 then Select Case State Case 0 : Incr C_r Decr C_b If C_r = 255 Then State = 1 Case 1 : Decr C_r Incr C_g If C_g = 255 Then State = 2 Case 2 : Decr C_g Incr C_b If C_b = 255 Then State = 0 End Select
Den Rest wüsste ich nun nicht wie man den noch optimieren kann. Das Hauptprogramm beinhaltet nicht soviel Code, wobei ich die ISR vom Timer noch schlanker machen würde. In etwa so:
Und dann im Hauptprogramm:Code:ISR_Timer0: Interruptflag_Timer0 = 1 Return
Dies machst du aus dem Grund, weil man eine ISR möglichst kurz halten sollte (gut in deinem Programm macht das nun nichts aus, weil du nur eine ISR hast).Code:Do If Interruptflag_Timer0 = 1 then If Pwm_count = 255 Then Pwm_count = 0 'PWM-Variable bei 255 resetten Incr Pwm_count 'PWM-Variable erhöhen If Div = 10000 Then 'Teilervariable bei 10000 resetten Div = 0 Gosub Fading 'Springe bei 10000 zu Fading End If Incr Div 'Teilervariable erhöhen End if Loop End
Weil wenn du mehrere Interruptquellen in einem Programm hast können eventuell Interrupts verschluckt werden, weil deine ISRs zu lang sind.
Deswegen mach ich das immer so das ich in den ISRs (wenn möglich) nur ein Bit setze, weil das schön schnell geht.
Wenn du in ISRs sowas wie "Print" Befehle o.ä. reinknallst kann es gut sein, dass der Controller beim ausführen der ISR einen anderen Interrupt ignoriert, weil so ein "Print" Befehl richtig viel Zeit braucht.
So würde ich das optimieren....ich weiß allerdings nicht in wie weit das eine Optimierung ist, weil ich selber nicht so der eingefleischte Programmierer bin
Aber das Select-Case macht das Programm auf jedenfall überschaubarer.
Edit: Hab gerade gesehen, dass du von der ISR in ein Unterprogramm springst.....versuch sowas zu vermeiden
Wie gesagt nutze die Methode wo du in den ISR einfach nur Bits setzt und die Auswertung macht dann das Hauptprogramm.
Geändert von Kampi (08.03.2012 um 08:38 Uhr)
Schaut ruhig mal auf meiner Homepage vorbei:
http://kampis-elektroecke.de
Oder folge mir auf Google+:
Daniel Kampert
Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.
Gruß
Daniel
Hallo Thomas,
Ich würde das auch so sehen, dass wenn es funktioniert es doch ok ist.
Wenn du beim nächsten Mal etwas verbessern möchtest, dann würde ich das gar nicht mal so sehr in deinen IF-Abfragen sehen, obwohl die Variante von Kampi sicherlich besser zu lesen ist.
Vielmehr würde ich die SoftPWM mal überdenken.
Dein µC läuft mit 9,6MHz, dein Timer ist 8-bit, läuft also 9.600.000 / 256 = 37500 mal pro Sekunde über. Das ist viel mehr als nötig. Es führt dazu, dass dein µC fast nichts anderes mehr tut, als andauernd die ISR aufzurufen. Hätte er jetzt noch andere Aufgaben, würde dies sicherlich schiefgehen.
Ich bin sicher, dass du für den Timer einen Prescaler von 8 oder 64 angeben könntest, ohne die Funktion zu verschlechtern. Dann müsstest du allerdings auch den Div-Wert von 10000 entsprechend auf 1250 bzw. 160 ändern.
Damit würde dein µC auf einen Schlag nur noch etwa 1% seiner Leistung in die PWM stecken.
Vielleicht probierst du es mal aus.
Hallo,
In diesem Fall ist Start Timer0 überflüssig, da der Timer schon durch Config Timer0 gestartet wird.Code:Config Timer0 = Timer , Prescale = 1 On Timer0 Isr_timer0 Enable Timer0 Start Timer0
Es gibt eine ISR und von der ISR wird nochmal ein Unterprogramm aufgerufen. Nach der Berechnung von dieser Seite: http://halvar.at/elektronik/kleiner_...swstack_frame/ oder auch nach der englischen mcs Seite wäre der $hwstack bei Dir viel zu klein bemessen.
Ich hab mir angewöhnt, in den Programmkopfbemerkungen immer die Bascom Version mit reinzuschreiben, in der das Programm läuft. Es gibt von Version zu Version manchmal sehr einflußreiche Änderungen.
Gruß
Searcher
Hoffentlich liegt das Ziel auch am Weg
..................................................................Der Wegzu einigen meiner Konstruktionen
Hallo!
Vielen Dank für eure Antworten.
Diese Einstellung will ich nicht teilen. Ich möchte nicht nur ein Projekt nach dem anderen machen, sondern ich möchte auch meine Programmierkenntnisse verbessern sowie auch verstehen, warum und wieso etwas funktioniert, gut funktioniert, schlecht funktioniert oder überhaupt nicht funktioniert. Für mich gehört dies genauso zum Prozess des Lernens. Es bedeutet einen Ansporn, gute und ressourcensparende Programme zu entwicklen und ich gebe mich nicht mit einem "funktioniert, ab in die Schublade" zufrieden.
Ob das Ersetzen der If-Abfragen durch Select-Case Flash spart, werde ich sofort testen. Aber eines stimmt mit Sicherheit, es macht den Code übersichtlicher. Danke für den Hinweis!
Ich dachte, der Controller speichert Interrupts ab und führt sie direkt im Anschluss aus, wenn er noch in der Abarbeitung eines Interrupts steckt?
Eine interessante Idee. Das werde ich versuchen. Danke!
Also bei mir reicht der Stack aus, aber ich werde trotzdem den Sprung von der ISR in die Sub ändern. Danke für den Hinweis!
Grüße
Thomas
mmmh das mit den Interrupts speichern ist ein guter Einwand.....da weiß ich gerade nicht so recht bescheid drüber ob das so ist.
Mir wurde während meiner Ausbildung öfters gesagt, dass man nicht soviel Code in die ISR packen soll, damit die ISR nicht zu lang wird.
Vielleicht kann jemand anders hier Licht ins dunkel bringen ob der Controller sich die Interrups merkt wenn er eine ISR abarbeitet oder nicht
Würde ich auch gerne wissen.
Schaut ruhig mal auf meiner Homepage vorbei:
http://kampis-elektroecke.de
Oder folge mir auf Google+:
Daniel Kampert
Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.
Gruß
Daniel
Hallo!
Ich habe nun folgende Änderungen vorgenommen:
- If-Abfragen durch Select-Abfragen ersetzen
- Sprung von der Timer-ISR zur Sub Fading über ein Flag in die Hauptschleife verlegt
Durch die Änderung der If-Abfragen nach Select-Abfragen konnte ich etwa 1% Flash sparen, was anschließend durch den veränderten Sprung zur Sub Fading wieder belegt wurde. Somit stehe ich wieder bei 90% Speicherbelegung.
Eine Veränderung des Timer-Prescalers brachte flackern mit sich, so wie ich mir das gedacht habe.![]()
Grüße
Thomas
Pro Interrupt gibt es einen "1 Bit" Speicher, das Interruptflag. Er kann sich soviele Interrupte merken, wie es Quellen gibt. Wenn ich innerhalb eines Handler das Flag am Anfang zurücksetze, kann er einen, aber nur einen weiteren gleichen Interrupt auch während der Laufzeit des Handlers merken. Wenn der Interrupthandler unterschiedlich lange dauert oder die Interrupte in unterschiedlichen Abständen kommen, kann einen das retten.
MfG Klebwax
Strom fließt auch durch krumme Drähte !
Lesezeichen