Forum: Mikrocontroller und Digitale Elektronik Code tut nicht was er soll Kanns der Compiler sein?


von lowPowerJunkie (Gast)


Angehängte Dateien:

Lesenswert?

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

von g457 (Gast)


Lesenswert?

> // 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

von Marcus O. (marcus6100)


Lesenswert?

Hallo,

// globales Statusregister
uint8_t status = 0;

änder das mal in

volatile uint8_t status = 0;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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");

von lowPowerJunkie (Gast)


Lesenswert?

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!

von Marcus O. (marcus6100)


Lesenswert?

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

von lowPowerJunkie (Gast)


Lesenswert?

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?

von Timo S. (kaffeetas)


Lesenswert?

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

von name (Gast)


Lesenswert?

> 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.

von Timo S. (kaffeetas)


Lesenswert?


von faustian (Gast)


Lesenswert?

"Irgendwie sind die Bomben fest"

Besser als wenn sie locker sind.

"niveau"=Wahrscheinlich Triggerpegel...

von klaus (Gast)


Lesenswert?

> 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

von horst (Gast)


Lesenswert?

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.

von Phantomix X. (phantomix)


Lesenswert?

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
Noch kein Account? Hier anmelden.