Hi Forum, Ich habe hier so ein schickes kleines Problem. Ich habe zum einen das Problem, dass ich glaube (ohne an den Compileroptimierungen zu spielen, Einstellung -0s) funktionieren regelmäßig meine delays nicht. Grund zu der Annahme: Meine startcheck() funktionier manchmal, aber nicht immer... Als weiteres kommt eine ganz wilde Sache hinzu: Wenn ich einen Portpin in der main toggeln lasse sehe ich am Pin nur rauschen, also nix. Lasse ich ihn hingegen in der ISR toggeln funktioniert das. (Und die Umschaltzeiten sollten gleich sein!) Hab das im Code auch dokumentiert wo es funktioniert und wo nicht. Ich hab mal meinen ganzen Code angehängt. Vielleicht schaut mal jemand rein und kann mir helfen. Ach ja die Ausgangspannung wird sauber geregelt (auch bei laständerungen), was heißt mein PI-Regler funktioniert. 2 Ideen was es sein könnte habe ich: - Irgendwas stimmt mit meinem statusregister nicht. - Ein kleiner dummer tippfehler... Bitte helft mir! Btw: Leider funktioniert der AVR-Simulator nicht ganz bei mir. Erstens hängt er sich regelmäßig auf, 2. sind 50% aller Bedingungen fälschlicherweise wahr (sollten aber falsch sein), sobald ich die Compileroptimierungen zulasse. Ohne meckert aber die delay.h
> // globales Statusregister > uint8_t status = 0; ^- als volatile deklarieren > status &= !(1<<TIMER_BIT); ^- das tut nicht das, was es dem augenschein nach tun soll '~' regelt ..weiter hab ich mich nicht vorgetraut HTH und HF
Hallo, // globales Statusregister uint8_t status = 0; änder das mal in volatile uint8_t status = 0;
1 | uint8_t status = 0; |
Ein Klassiker: such mal hier im Forum nach "+Interrupt +volatile" Wenn du den status nicht volatile machst, dann wird der in der Hauptschleife nicht mehr eingelesen, sondern nur mit einem statischen Registerwert gearbeitet... Deshalb wird sich status hier niemals ändern:
1 | while ( !( status & (1<<TIMER_BIT) ) ) // TIMER_BIT wird ungefähr jede ms in ISR gesetzt |
2 | __asm("NOP"); |
Oh DANKE jungs (und medl(s)?) das volatile wars... mensch jetzt funktioniert mein Regler auch ungefähr doppelt so stabil. Ja ok das kleine Ausrufezeichen... ist mir beim durchlesen um zu prüfen ob alles akzeptabel ankam dann ebenfalls aufgefallen ^^ Ich bin euch sooo Dankbar. Und dann auch noch so schnell die Antworten! Einfach klasse! Ihr habt mir den Abend gerettet! PS: Scheinbar wird aber das statusregister noch einmal geschrieben, bevor er es sich kopiert. Denn die while durchlaufen hat er sicher. sonst wäre die Ausgangsspannung nicht so stabil gewesen. aber ist ja auch egal. Nochmals 1000-Dank!
Soweit hatte ich mich garnicht vorgetraut ;) Noch zwei Anmerkungen. Das __asm("NOP"); kannst du weglassen, da reicht ein einzelnes ; Die Zugriffe auf das status byte sind nicht atomar. Vor Manipulation im Hauptprogramm deshalb Interrupts sperren. Sonst könnte es sein, das bei späteren Erweiterungen mit weiteren bits ggf im Interrupt welche gesetzt werden, die aber im Hauptprogramm überschrieben werden bevor sie ausgewertet werden. Das passiert, falls der Interrupt zwischen lesen und zurückschreiben des Wertes innerhalb von status &= !(1<<TIMER_BIT); oder ähnlichem auftritt. Gruß Marcus
eine Sache bleibt: Die Frequenz: hab ich mich verrechnet? mit meinem Oszi (Made in Germany, ein HAMEG HM 512, vermutlich älter als ich) messe ich eine Schaltdauer von ungefähr 0,3ms pro toggle. Errechnet hatte ich aber ungefähr 1ms... Rechnung: prescaler: 1 Takt: 9,6MHz Counter-TOP: 255 Softwareteiler: 38 => ( 1s / 9.600.000 ) 255 38 = 0,0010...s Fehler?! Wo?! Mein Oszi kann doch nicht mittlerweile um Faktor 3 langsamer geworden sein? Oder kann ein altes Oszi sowas?
Hallo lowPowerJunkie, ist der "Vernier" Regler vom Oszi am linken oder rechten Anschlag. Die alten Oszis haben tw. eine sog. Dehnung bei deinem Model geht die zufällig bis Faktor 3. Mit dem Finger an der Messpitze kann man gut die Netzfrequenz sehen. Hast du da 50Hz oder bist du auf Bahnfrequenz? Grüße Timo
> Noch zwei Anmerkungen. Das __asm("NOP"); kannst du weglassen, > da reicht ein einzelnes ; > > Die Zugriffe auf das status byte sind nicht atomar. Vor > Manipulation im Hauptprogramm deshalb Interrupts sperren. der erste tip ist klasse. Ich hab mir zwar schon länger gedacht dass er bei ";" ja nur ein NOP machen kann, aber gewusst hab ichs nicht. Danke. Oh gott... mit dem atomar hab ich jatz aber kämpfen müssen... aber danke auch für diesen Tip. Ich werde es beherzigen. Danke Marcus @Timo: Vernier? ich glaub ich muss mir das ding nochmal genauer anschauen... bis auf ein/aus/helligkeit, Fokus, Spannungsauswahll, frequenz, und niveau(was auch das immer ist) lösst sich irgendwie kein knopf mehr drehen. Irgendwie sind die Bomben fest, aber da ich nich weiß wozu die gut sind, hats mich nie gestört. Wer grad zufälig ne anleitung dazu hat, kann ja gerne mal posten. wird aber langsam Offtopic. Trotzdem DANKE für den Hinweis Timo.
"Irgendwie sind die Bomben fest" Besser als wenn sie locker sind. "niveau"=Wahrscheinlich Triggerpegel...
> der erste tip ist klasse. Ich hab mir zwar schon länger gedacht dass er > bei ";" ja nur ein NOP machen kann, aber gewusst hab ichs nicht. Danke. Er macht da aber kein NOP draus. Wäre aber auch unsinnig/überflüssig. Mit "while(x);" erzeugt man lediglich eine Schleife mit leerem Anweisungsteil. Leer heißt leer, also auch kein "NOP". In diesem Fall wird direkt das Abprüfen der Bedingung wiederholt... Gruss
Um auf deine eigentliche Frage zu kommen:
> Code tut nicht was er soll Kanns der Compiler sein?
Ja.
Wahrscheinlich ist es auch der Compiler. Normalerweise erzeugt er das
Programm so, wie man es ihm sagt, und nicht so, wie er soll.
Die Fälle, in denen es anders ist, sind wirklich selten.
Selbst wenn ; zu NOP kompiliert würde, hätte dies der Programmierer so nicht explizit gesagt. Das heißt - Status des IC vor NOP == Status des IC nach NOP -> der Compiler optimiert es weg.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.