Forum: Compiler & IDEs AVR überspringt Wertzuweisung


von Thomas G. (mrmp3)


Angehängte Dateien:

Lesenswert?

Hey Leute

Ich hab für nen Feuerwehrwettkampf ne Stoppuhr gebaut. Das Teil 
funktioniert auch wunderbar. Da ich noch genug Platz aufm Prozessor hab, 
hab ich gedacht, kann man ja auch die Echtzeit anzeigen lassen solange 
der Wettkampf nicht losgeht. Also hab ich in die Main eine Unterfunktion 
gepackt die die ganze Zeit durchlaufen wird wenn die Funktion "Echtzeit" 
ausgewählt wurde. Zu Beginn kann man die Uhrzeit Ziffernweise 
einstellen. Dazu blinkt die ausgewählte Ziffer. So nun zum eigentlichen 
Problem.

Wenn ich die Ziffern blinken sollen, dann gibt es in der Main eine 
Routine die die nächste anzuzeigende Zahl berechnet und das 
Timer-Interrupt zeigt dann die Zahl an.

Bei der Berechnung dieser Zahl überspringt der AVR aber immer die 
Zuweisung der Variable (z_sekunde,zehntel,hundertstel)

Das komische ist, das es bei der Variable (sekunde) alles wunderbar 
funktioniert.

Ich hab die komplette Main angehangen und füge hier mal einen der 4 
wichtigen Abschnitte ein.

Ich hoffe irgendjemand hat eine Idee was das Problem sein könnte.
1
    while(((zahl&0x07)==0)&&(funktion==ECHTZEIT))        //einstellen der 10 sekunde
2
    {      
3
      if((k<2)&&(inkrement==1))                //uhrzeit kann nicht größer als 24 uhr sein              
4
      {
5
        k+=inkrement;
6
        inkrement=0;
7
      }
8
      
9
      else if((k>0)&&(inkrement==-1))
10
      {
11
        k+=inkrement;
12
        inkrement=0;    
13
      }
14
15
      if((NEW_TIME)!=0)                    //soll neuer wert berechnet werden ?
16
      {    
17
        ziffern|=(1<<3);                  //Z_SEKUNDE aktualisieren
18
        
19
        if((zahl&(1<<7))!=0)                //flag gesetzt ?
20
        {
21
          z_sekunde=ANZEIGE_LEER;       //diese anweisung wird übersprungen
22
          zahl&=~(1<<7);
23
        }
24
25
        else
26
        {
27
          z_sekunde=k;                 //und diese ebenfalls
28
          zahl|=(1<<7);                //zahl wird ordnungsgemäß verändert
29
        }
30
31
      NEW_TIME_DEL;
32
33
      }
34
    }

von Peter II (Gast)


Lesenswert?

ich bin mir hier nicht sicher ob

volatile uint8_t ziffern=0,zahl=0,rfm_test2=0;


das gleiche ist wie

volatile uint8_t ziffern=0;
volatile uint8_t zahl=0;
volatile uint8_t rfm_test2=0;

es kann durchaus sein das zahl und test2 nicht volatile sind.

von Rolf Magnus (Gast)


Lesenswert?

Die Variablen sind nicht volatile, werden aber in einer ISR und 
außerhalb verwendet.

von Thomas G. (mrmp3)


Lesenswert?

Hallo Peter

Also da bin ich mir eigentlich sicher das das mit dem volatile so 
stimmt, da ziffern und rfm_test2 im interrupt korrekt geändert werden 
und sonst die anzeige der zahlen nicht funktionieren würde, weil die 
variable ziffern speichert die bits welche zahlen aktualisiert werden 
sollen

von Thomas G. (mrmp3)


Lesenswert?

Hmm jetz nochmal was wegen volatile sollte ich mir da doch gedanken 
machen ?

Danke für den Hinweis aber wieso stimmt das nicht ?

von Rolf Magnus (Gast)


Lesenswert?

Ich hab die anderen, im Ursprungsposting erwähnten Variablen gemeint:
1
uint8_t hundertstel=0,zehntel=0,sekunde=0,z_sekunde=0;

von Thomas G. (mrmp3)


Lesenswert?

Hmm... Hab ich jetz nen Denkfehler ?

Volatile werden doch Variaben deklariert die in einer ISR verändert 
werden oder nicht ?

Meine Variablen werden doch hingegen nur in einer ISR benutzt und nicht 
verändert. Die Änderung der Werte passiert ja in der Main.

von ... (Gast)


Lesenswert?

Da fehlt wohl 'volatile'
1
volatile uint8_t hundertstel=0,zehntel=0,sekunde=0,z_sekunde=0;
eventuell auch noch an weiteren Stellen, hab jetzt nicht alles 
durchgeschaut.

von Peter II (Gast)


Lesenswert?

Der code ist leider recht unübersichtlich. Funktionen haben keine klaren 
namen und aufgaben.

Du hast viel zu viel code in der ISR, durch funktionaufrufe in der ISR 
wird sie selber recht langsam (weil alle Register gesichert werden 
müssen) und durch das sleep in ziffer sogar eine warteschleife. Das 
ganze sollte man auf jeden fall nicht machen.

von Thomas G. (mrmp3)


Lesenswert?

Das is ja echt nen Ding. Habs grad geändert und es funktioniert.
Hab ich das mit dem volatile falsch verstanden ?

von Peter II (Gast)


Lesenswert?

Thomas G. schrieb:
> Das is ja echt nen Ding. Habs grad geändert und es funktioniert.
> Hab ich das mit dem volatile falsch verstanden ?
was hast du geändert? und wie hast du es verstanden?

von Thomas G. (mrmp3)


Lesenswert?

Ich hab vor die Variablen nen volatile gesetzt und jetz funktioniert es.
Ich hatte volatile immer so verstanden das man damit nur Variablen 
deklariert die auch von ISR verändert werden können.

Welche Funktion hat keine richtige Aufgabe ?

die Funktion ziffer muss nen Delay haben sonst erkennt der BCD-Baustein 
der hinten dran hängt die Flanke nicht und um Sekundengenau zu sein 
berechne ich die neue Zeit in der Main und aktualisiere die Zahlen in 
der ISR... ist meine herangehnsweise so falsch ? wie hättest du das denn 
gelöst ?

von Peter II (Gast)


Lesenswert?

Thomas G. schrieb:
> Ich hab vor die Variablen nen volatile gesetzt und jetz funktioniert es.
> Ich hatte volatile immer so verstanden das man damit nur Variablen
> deklariert die auch von ISR verändert werden können.
fast, alle Variabeln die in der ISR geändert und im Hauptprogramm 
gelesen werden. Variabeln die in der ISR geändert werden und sonst nicht 
gebraucht werden brauchen kein volatile. Volatile macht auch zugriffe 
langsamer, aus dem grund sollte man sparsam damit umgehen.


> Welche Funktion hat keine richtige Aufgabe ?

ziffer

keine weiss damit etwas anzufangen, etweder sotwas wie SetZiffer oder 
SendZiffer oder was auch immer das ding macht.

> die Funktion ziffer muss nen Delay haben sonst erkennt der BCD-Baustein
> der hinten dran hängt die Flanke nicht und um Sekundengenau zu sein
> berechne ich die neue Zeit in der Main und aktualisiere die Zahlen in
> der ISR... ist meine herangehnsweise so falsch ? wie hättest du das denn
> gelöst ?
das die Zeitberechung in der ISR ist, ist schon richtig. Aber das 
übertagen der Ziffer kann man ja in der Main machen.

von ... (Gast)


Lesenswert?

Thomas G. schrieb:
> Volatile werden doch Variaben deklariert die in einer ISR verändert
> werden oder nicht ?
>
> Meine Variablen werden doch hingegen nur in einer ISR benutzt und nicht
> verändert. Die Änderung der Werte passiert ja in der Main.

Es spielt keine Rolle wer was verändert. Im Bsp aus Deinem ersten Post 
kann der Compiler locker die Zuweisungen zu z_sekunde aus der Schleife 
rausoptimieren und dahinter setzen. Woher soll der schließlich auch 
wissen, das die (Zwischen-)Werte in irgendwelchen ISRs auch noch benutzt 
werden?

von ... (Gast)


Lesenswert?

... gar nicht gesehen, im Anhang steht direkt hinter der while Schleife 
sowiso ein "z_sekunde=k;". Dann sind die Zuweisungen innerhalb der 
Schleife für den Compiler einfach mal nur noch sinnlos und er schmeißt 
sie komplett weg.

von Thomas G. (mrmp3)


Lesenswert?

Das mit dem volatile versteh ich nicht meine Variablen veränder ich nur 
in der Main und nicht in einer ISR wieso müssen die dann volatile sein ?

Ich hab mir gedacht wenn die in der ISR ein Flag setzte das ich in der 
Main auswerte dann dauert das doch bestimmt länger bis es ausgeführt 
wird als die Zeit in der Main zu berechnen und wenn der Zeitpunkt 
gekommen ist einfach die ziffern zu aktualisieren.

Falscher Ansatz ?

Danke ...
jetz hab ichs verstanden :D
schwere Geburt... Danke

also sagt volatile dem Compiler noch das er die Variable ne optimieren
soll ?

von ... (Gast)


Lesenswert?

Thomas G. schrieb:
> Das mit dem volatile versteh ich nicht meine Variablen veränder ich nur
> in der Main und nicht in einer ISR wieso müssen die dann volatile sein ?

Aber Du liest Sie in der ISR!

> also sagt volatile dem Compiler noch das er die Variable ne optimieren
> soll ?

Kann man so sagen ja, ist aber eigentlich nur ein Nebeneffekt. 
'volatile' sagt dem Compiler, das er alle Operationen auf eine derartige 
Variable genau so ausführen muß, wie sie im Source stehen. Er muß immer 
damit rechnen, das der Wert außerhalb seines Zuständigkeitsbereiches 
geändert wurde bzw. das Schreiboperationen unbekannte Nebeneffekte 
haben.

von Rolf Magnus (Gast)


Lesenswert?

Thomas G. schrieb:
> Das mit dem volatile versteh ich nicht meine Variablen veränder ich nur
> in der Main und nicht in einer ISR wieso müssen die dann volatile sein ?

Wo du sie veränderst, ist völlig WURSCHT! Du benutzt sie in der ISR und 
in der Main, also brauchst du volatile.

> Ich hab mir gedacht wenn die in der ISR ein Flag setzte das ich in der
> Main auswerte dann dauert das doch bestimmt länger bis es ausgeführt
> wird als die Zeit in der Main zu berechnen und wenn der Zeitpunkt
> gekommen ist einfach die ziffern zu aktualisieren.

Eine Warteschleife in der ISR blockiert aber den kompletten Prozessor. 
Für das beste Zeitverhalten sind ISRs, die möglichst schnell wieder 
zurückkehren, immer von Vorteil.

> also sagt volatile dem Compiler noch das er die Variable ne optimieren
> soll ?

volatile sagt dem Compiler, daß die Variable evtl. außerhalb des 
normalen Programmablaufs gelesen oder geschrieben werden könnte und 
deshalb alle Zugriffe auf diese auch tatsächlich auch dort, wo sie im 
Code stehen, ausgeführt werden müssen.

von Thomas G. (mrmp3)


Lesenswert?

Ihr habt ja recht ich hab grad nochmal gelesen, der Chip brauch ne 
Pulsweite von 250ns da könnte ich das delay doch weglassen, die 
verzögerung macht die abarbeitung des befehls

ok... Problem gelöst

Danke Leute

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.