www.mikrocontroller.net

Forum: Compiler & IDEs GCC ignoriert Zuweisung in struct


Autor: Andreas G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich schaffs nicht, in einer schleife nem Struct einen Wert zuzuweisen.

Der struct ist global definiert:

struct {
  u08 high:8;
  u08 low:8;
} servo1;

Beim Init wird der Timer0 gestartet, welcher beim Überlauf die
Compare-Werte des Timer1 setzt:
OCR1H = servo1.high;
OCR1L = servo1.low;

Die Variablen werden vorher in der Main-Funktion mit:
servo1.high = 16000/256;
servo1.low  = 16000%256;
gesetzt.

Soweit funktionierts noch. (Sowohl in AVRStudio als auch in Hardware)
Im Hauptprogramm (main()) befindet sich jetzt folgende Schleife:
while (1)
{
  if (bit_is_clear(PINC,0))
  {
    sbi(PORTC,2);
    servo1.high = 46;
    servo1.low  = 224;
  }
  else
  {
    cbi(PORTC,2);
    servo1.high = 31;
    servo1.low  = 64;
  }
}

Mit dieser Schleife kann ich bei drücken auf den Schalter an PINC,0 die
LED an PORTC,2 ausschalten. Nur leider wird der Wert in meinem struct
nicht verändert. Ein Blick in den ASM-Code zeigt:

SBIC    0x13,0           Skip if bit in I/O register cleared
RJMP    PC+0x0003
SBI     0x15,2           Entspricht sbi(PORTC,2);
RJMP    PC-0x0003
CBI     0x15,2           Entspricht cbi(PORTC,2);
RJMP    PC-0x0005

d.h. gcc ignoriert einfach meine Zuweisung.
Jetzt bin ich etwas ratlos. Ich hoffe, es kann mir von euch jemand
helfen.

Gruss, Andreas

Autor: Daniel Jelkmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Andreas,

vermutlich hat der GCC zuviel wegoptimiert. Werden die Werte in der
Structure servo1 irgendwann nochmal verwendet?
Versuch mal ein volatile vor die struct zu schreiben, also:

volatile struct {
  u08 high:8;
  u08 low:8;
} servo1;

Vielleicht hilft das. Ansonsten poste mal bitte etwas mehr Code, das
macht die Fehlersuche einfacher.

Bye
  Daniel Jelkmann

Autor: Mike (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur am Rande:
Verwende in Zukunft nicht mehr sbi (...) und cbi (...), diese Ausdrücke
sind veraltet.
OCR1 kannst du direkte ansprechen, warum der Umweg über Low- und
High-Byte?

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel hat Recht.
Dein Code wurde wegoptimiert. War ja auch völlig sinnlos ;-)
Alternativ zu volatile kannst Du gcc nach den Zuweisungen noch etwas
mit den Werten arbeiten lassen. Denn nur wenn er den Eindruck hat,
wirklich gebraucht zu werden, arbeitet er auch klaglos. Also z.B.
folgendes anhängen:

  if ((servo1.low + servo1.high) > 200){
    beschaeftigungstherapie();
  }


Gruß, Stefan

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Btw:

volatile struct {
  u08 high:8;
  u08 low:8;
} servo1;

Wo ist da der Sinn? Das ist keine "struct" in dem Sinne, sondern ein
Bitfeld. Richtiger wäre da wohl eher:

volatile struct {
  u08 high;
  u08 low;
} servo1;

...IMHO...

Autor: Andreas G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke!

Wurde tatsächlich wegoptimiert. volatile hat geholfen. Wundert mich nur
etwas, denn ich hab im Makefile extra die optimierung auf 0 gestellt.

@Mike: was wird statt sbi() und cbi() verwendet? Das konstrukt aus dem
Wiki (PORTA &= ~(1<<MEINBIT);) find ich ziemlich unmerkbar, und sbi()
wird doch schön in Assembler übersetzt.

@OldBug: ...richtig!

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, unmerkbar oder nicht: es ist schlicht und einfach Standard-C ;-)
Es gibt auf der Doku-Seite der avr-libc eine Seite mit abgekündigten
funktionen, unter anderen sind da auch sbi und cbi vermerkt.
Also besser jetzt schon mal an diese Schreibweise gewöhnen, in der
nächsten avr-libc release wirds wohl laut Jörg Wunsch nicht mehr
vorhanden sein...

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

du kannst dir ja definitonen machen fuer sbi und cbi.

Mfg

Dirk

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist aus den aktuellen Quellen bereits raus.  U. a.  wegen solcher
Mißverständnisse:

> "und sbi() wird doch schön in Assembler übersetzt."

Wurden sie nämlicht mitnichten zwangsläufig, da sie seit mehreren
Jahren bereits weiter nichts als Aliase für die Standard-C-
Bitmanipulationen waren.  D.h. insbesondere, daß mit -O0 keine
Optimierung in SBI/CBI automatisch stattfand.

Mit -O>=1 erfolgt die Umsetzung, sofern die übrigen Randbedingungen
eine solche gestatten, d.h. nur ein Bit wird gesetzt oder gelöscht,
die Bitnummer ist zur Compilezeit bekannt/konstant, und das
IO-Register liegt im erreichbaren Bereich für SBI/CBI.

Autor: OsiriS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier mal mein Problem, vielleicht kann mir ja ein alter C-Hase sagen,
was ich falsch mache:

struct {
  char     *MenuKey;
  unsigned char  MenuButton;
  } Menu_1[20]  = {
    "\t\t +++ Mainmenu +++\n\n", 0,
    "\t\t Menupunkt1\n\n", '1',
    "\t\t Menupunkt2\n\n", '2',
    "\t\t Menupunkt3\n\n", '3',
    "\t\t Menupunkt4\n\n", '4',
    "\t\t Exit\n\n"},      '5',
  },
  Menu_2_1[20] = {
    "\t\t +++ Submenu 1 +++\n\n", 0,
    "\t\t Unterpunkt_1_1\n\n", '1',
    "\t\t Unterpunkt_1_2\n\n", '2',
    "\t\t Unterpunkt_1_3\n\n", '3',
    "\t\t Unterpunkt_1_4\n\n", '4',
    "\t\t Unterpunkt_1_5\n\n", '5',
    "\t\t Unterpunkt_1_6\n\n", '6',
    "\t\t Unterpunkt_1_7\n\n", '7',
  };

Unter Borland C geht das wunderbar, bei GCC krieg ich nur
Fehlermeldungen...
habs auch schon mit geschweiften Klammern um die einzelnen Einträge
versucht...dann krieg ich "menu.inc:26: warning: initialization makes
pointer from integer without a cast" als Fehler
Hab in der Doku von der Lib nix gefunden.
Hat da jemand noch ne andere Doku?
Greetz  OsiriS

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Schachteln der Klammern ist laut Standard notwendig.

Der `pointer from integer' ist wohl die herumlungernde '5' dort
(zwischen dem Initializer von Menu_1[] und Menu_2_1[]).

Aber sei gewarnt: der Krempel geht komplett in den RAM.  In der
fertigen Lösung wirst Du das wohl so nicht wollen.  Außerdem
verplemperst Du Platz, da Du den Arrays eine explizite Größe verpasst,
diese aber nicht ausnutzt.

Bitte für neue Fragen auch einen neuen Thread aufmachen, das hat mit
dem ursprünglichen Thread ja absolut nichts mehr gemein.

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.