Forum: Mikrocontroller und Digitale Elektronik Phänomen oder Fehlbedienung?!


von Dennis (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich steige bei meinem Programm nicht hinter das Problem.

Im Anhang findet Ihr den Code eines -wie ich finde- sehr simplen 
Programmes.

Es soll nicht mehr passieren, als dass von einem Zählwert der in der ISR 
inkrementiert wird, auf Port C ein einzelnes Bit angezeigt wird.

Jetzt zum Problem:

Wenn (wie im Codebeispiel) die Zeilen
1
if (clock0.taktbyte.bit2 == 1)
2
{
3
  PORTC |= (1 << PC2);
4
}
5
else
6
{
7
  PORTC &= ~(1 << PC2);
8
}

in der Endlosschleife stehen, bleibt der Wert an PORT C auf 0x00.

Stehen diese Zeilen stattdessen in der ISR...:
1
SIGNAL(SIG_OVERFLOW0)
2
{
3
  TCNT0 = STARTVAL_DEB;
4
  
5
  clock0.cval++;
6
  
7
  if (clock0.taktbyte.bit2 == 1)
8
  {
9
    PORTC |= (1 << PC2);
10
  }
11
  else
12
  {
13
    PORTC &= ~(1 << PC2);
14
  }
15
}

... macht das Programm was es soll und PC2 blinkt.

Kann mir jemand sagen, was ich falsch mache?

Danke für jeden Tipp!!

Grüße

Dennis

von Christopher G. (cbg)


Lesenswert?

Stichwort volatile.
Der Compiler sieht in der Main keinen schreibenden Zugriff, also denkt 
er, der Wert kann sich gar nicht ändern.

von Dennis (Gast)


Lesenswert?

Das Problem ändert sich auch nicht, wenn ich aus der Main in ein 
Unterprogramm springe. Was muss ich denn machen, damit der Compiler 
dieses Denken sein lässt?

von Benni (Gast)


Lesenswert?

mach mal am ende
1
Return 0;
 in die main

von Dennis (Gast)


Lesenswert?

Benni schrieb:
> mach mal am endeReturn 0; in die main

Das bringt leider keine Besserung.. :(

von Mirko (Gast)


Lesenswert?

Hast Du denn ein volatile vor dem union schon ausprobiert? Vermutlich 
ist es so wie Christopher sagt: clock0.taktbyte.bit2 wird in der 
while-Schleife nicht verändert, deshalb optimiert der Compiler rigoros 
weg, was danach passieren soll.

Mirko

von Dennis (Gast)


Lesenswert?

Mirko schrieb:
> Hast Du denn ein volatile vor dem union schon ausprobiert?

Ja, das habe ich ausprobiert. Das Problem besteht weiterhin.

von Martin (Gast)


Lesenswert?

Den 'else' Teil aus 'main' übersetzt der Compiler dank der Optimierung 
in einen Kreisverkehr (sieh Code 1).

Lösung: 'volatile' vor der 'union' (Code 2).

Code 1

    {
      PORTC &= ~(1 << PC2);
    }


+00000049:   98AA        CBI       0x15,2         Clear bit in I/O 
register
+0000004A:   98AA        CBI       0x15,2         Clear bit in I/O 
register
+0000004B:   CFFD        RJMP      PC-0x0002      Relative jump

Code 2

60:           if (clock0.taktbyte.bit2 == 1)
+00000042:   91800060    LDS       R24,0x0060     Load direct from data 
space
+00000044:   FF82        SBRS      R24,2          Skip if bit in 
register set
+00000045:   C005        RJMP      PC+0x0006      Relative jump
62:             PORTC |= (1 << PC2);
+00000046:   9AAA        SBI       0x15,2         Set bit in I/O 
register
60:           if (clock0.taktbyte.bit2 == 1)
+00000047:   91800060    LDS       R24,0x0060     Load direct from data 
space
+00000049:   FD82        SBRC      R24,2          Skip if bit in 
register cleared
+0000004A:   CFFB        RJMP      PC-0x0004      Relative jump
66:             PORTC &= ~(1 << PC2);
+0000004B:   98AA        CBI       0x15,2         Clear bit in I/O 
register
+0000004C:   CFF5        RJMP      PC-0x000A      Relative jump
66:             PORTC &= ~(1 << PC2);

von Dennis (Gast)


Lesenswert?

@Mirko && Martin:

Danke! Läuft!!

von Andreas K. (derandi)


Lesenswert?

Dennis schrieb:
> Mirko schrieb:
>> Hast Du denn ein volatile vor dem union schon ausprobiert?
>
> Ja, das habe ich ausprobiert. Das Problem besteht weiterhin.

Martin schrieb:
> Lösung: 'volatile' vor der 'union' (Code 2).

Dennis schrieb:
> @Mirko && Martin:
>
> Danke! Läuft!!

Ja wie jetzt?

von Glaskugel (Gast)


Lesenswert?

Vermutung:

1. Nach dem Tip
>Stichwort volatile.
>Der Compiler sieht in der Main keinen schreibenden Zugriff, also denkt
>er, der Wert kann sich gar nicht ändern.

und der Antwort:

"... wenn ich aus der Main in ein Unterprogramm springe."

hat der TO wahrscheinlich nicht das fehlen von volatile als eigentliche 
Ursache verstanden, sondern ein Problem in speziell der Verbindung von 
main und dem fehlenden schreibenden Zugriff gesehen, das er mit der 
Benutzung einer Unterfunktion (die dann natürlich nicht main heisst) 
beheben wollte.

Die Erklärung dazu, dass durch die fehlende Änderung an der Variablen 
der Compiler den Zugriff wegoptimiert, hat er nicht als allein 
hinreichend wahrenommen.

Das das Problem grundsätzlich auf jede Funktion zutrifft war aus dem 
Satz nicht wirklich zu erkennen. Vielmehr muss der Anfänger den Satz 
wörtlich nehmen und ihn, wie vermutlich geschehen auf die Funktion main 
und den fehlenden schreibenden Zugriff in Konjunktion beziehen. Das er 
das zu umgehen versucht, in dem er nur eine der beiden 
Bestimmungsgrössen ändert ist für mich durchaus verständlich und 
konsequent.

Der Antworter hat main hier nicht als konkrete Ausprägung einer 
grösseren Menge von Fällen dargestellt, sondern (sehr wahrscheinlich 
unabsichtlich) suggeriert, dass main selbst auch eine Ursache des 
Problems ist.

von Glaskugel (Gast)


Lesenswert?

Man könnte noch hinzufügen, das durch die Tatsache das volatile fehlt 
die Ursache allein schon hinreichend beschrieben ist. Denn ein Zugriff 
auf eine Variable kann (abgesehen von der Initialisierung) ohnehin in C 
nur innerhalb einer Funktion erfolgen.

Somit ist der Zusatz "in main" oder auch "in einer Funktion" in 
zweifacher Hinsicht irreführend, denn selbst der fortgeschrittene 
Anfänger könnte unter Beachtung eben dieser Tatsache auf den Gedanken 
kommen, das main eine Sonderrolle spielt, zumal dies in anderer Hinsicht 
auch der Fall ist, weil main die einzige Funktion ist, die er nicht 
ausdrücklich aufzurufen braucht, so das ihm die suggerierte Sonderrolle 
von main in Bezug auf volatile nicht unplausibel scheinen mag.

Ich möchte noch hinzufügen, dass ich mit dieser Kritik den Antworter in 
keiner Weise herabsetzen möchte. Ich hoffe nur, damit die Qualität der 
Antworten hilfreich zu beeinflussen.

von Christopher G. (cbg)


Lesenswert?

Stichwort volatile hätte auch gereicht. Bin ja nicht der Kindergärtner.
Selber lesen macht schlau!

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.