www.mikrocontroller.net

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


Autor: Dennis (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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
if (clock0.taktbyte.bit2 == 1)
{
  PORTC |= (1 << PC2);
}
else
{
  PORTC &= ~(1 << PC2);
}

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

Stehen diese Zeilen stattdessen in der ISR...:
SIGNAL(SIG_OVERFLOW0)
{
  TCNT0 = STARTVAL_DEB;
  
  clock0.cval++;
  
  if (clock0.taktbyte.bit2 == 1)
  {
    PORTC |= (1 << PC2);
  }
  else
  {
    PORTC &= ~(1 << PC2);
  }
}

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

Autor: Christopher G. (cbg)
Datum:

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

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Benni (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mach mal am ende
Return 0;
 in die main

Autor: Dennis (Gast)
Datum:

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

Das bringt leider keine Besserung.. :(

Autor: Mirko (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mirko schrieb:
> Hast Du denn ein volatile vor dem union schon ausprobiert?

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

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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);

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Mirko && Martin:

Danke! Läuft!!

Autor: Andreas K. (derandi)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Glaskugel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Glaskugel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christopher G. (cbg)
Datum:

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.