mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik struct definieren und verwenden


Autor: Michael L. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hab ein Problem mit der definition einer Struktur. Ich brauch ein
paar Bits, die mir gewisse Zustände anzeigen. Hierür möchte ich nicht
jedesmal ein ganzes Byte verschwenden. Hierfür gibts doch die
Strukturen, oder?
Ich hab folgendes global definiert:

volatile struct bitstates {
  u8 zc:1;
  u8 fired:1;
  u8 soft:1;
  }state;

Die Bits zc.state und fired.state werden in Interrupts (die stehen in
der main.c Datei wie auch die Definition) verwendet und funktionieren
auch prima. soft.state sollte in einer anderen *.c Datei abgefragt
werden. Mein Compiler meldet mir, dass er state nicht kennt.

Warum denn das? Ist doch global definiert???
Kann mir bitte jemand helfen?

Gruß,
Michael

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falsche Notation.

Auf Strukturelemente greift man zu, in dem zunächst der Name der
Strukturvariablen und dann das Strukturelement angegeben wird.

Statt

  zc.state

muss es heißen

  state.zc

Wenn Du aus einem anderen Sourcemodul auf diese Struktur(-variable)
zugreifen willst, dann musst Du verfahren, wie bei globalen Variablen
üblich:


Strukturdeklaration und extern-Deklaration einer Instanz der Struktur
in eine Headerdatei packen:

  struct bitstates
  {
    u8 zc:1;
    u8 fired:1;
    u8 soft:1;
  };

  extern volatile struct bitstates state;

Diese Headerdatei in jedes Modul einbinden, in dem auf die Instanz der
Struktur zugegriffen werden soll und in genau einem Modul eine Instanz
der Struktur definieren:

  #include "blafusel.h"

  volatile struct bitstates state;


Fertig.

Autor: Michael L. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wow, so tuts.

Zum ersten, das war ein Schreibfehler, im Programm hats gestimmt.
Sorry! (Schäm)

Zum Verständnis, ich hab versucht die Struktur in eine Headerdatei zu
packen. Und zwar so wie ichs oben geschrieben hab. Ohne die Extrazeile

extern volatile struct bitstates state;

und ohne in einem Modul

volatile struct bitstates state;

einzufügen.
Wozu brauch ich das denn???
Wenn ich eine globale Variable deklarier mach ich das doch auch nur an
einer Stelle, ohne Headerdatei. Oder ist das falsch?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geh auf

http://www.mikrocontroller.net/articles/Spezial:Allpages

und lies den Artikel
"Funktionen auslagern (C)"
Da gibt es auch einen Abschnitt wie Variablen verteilt werden.

(ICh kann leider keinen Link setzen, da die Forensoftware
Unterstriche seltsam behandelt).

Autor: Michael L. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klasse!!! Einfach super dein Artikel! Jetzt hab ichs kapiert.
Tausend Dank an euch beide!

Gruß,
Michael

Autor: Olaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaub du hast es noch nicht so recht kapiert.

Du willst auf ein Bit im innerhalb eines Bytes in einem Interrupt
zugreifen und auf ein anderes Bit im selben Byte normal im Programm?

Damit hast du eine gute Chance ein richtig schoenen fetten Fehler
einzubauen der nur gelegentlich mal auftritt und den du dank deines
tollen struct niemals finden wirst. .-)

Olaf

Autor: Michael L. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmmh??
Warum denn das?

Autor: Olaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vermutlich wird dein Compiler nicht bitweise auf das Byte zugreifen. DAs
sieht dann etwa so aus:

1. Lese das Byte
2. Aendere ein Bit
3. Schreibe das Byte zurueck

Jetzt stell dir mal vor genau zwischen 1 und 2 passiert ein Interrupt.
Sobald der Interrupt dann beendet wird gehen die Aenderungen verloren
wenn in Zeile 3 das Byte erneut geschrieben wird.

Es koennt sogar sein das dein Compiler je nachdem ob die CPU das kann
oder auf welche optimierung er eingestellt ist, wirklich Bitweise
zugreift. Dann funktioniert das. Willst du aber denselben Source
naechstes Jahr bei einer anderen CPU verwenden knallt es.
Oder deine CPU unterstueztz bitweisen Zugriff nur bei einer bestimmten
Anzahl von Bytes und wenn du naechstens Monat was aenderst so
verschiebt sich der struct im Ram und es geht nicht mehr.

Ich kann dir nur dringend empfehlen Daten die im Interrupt gebraucht
werden von allem anderen getrennt zu halten.

Olaf

Autor: Michael L. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, nachvollziehbarer und berechtigter Einwand.

Ich hab mich jetzt von der Struktur verabschiedet und zwei globale
Variablen angelegt. Eine für die Interruptsteuerung und die andere für
den Rest. Werd die dann übers maskieren ansprechen. Tut auch schon ganz
gut.

Vielen Dank!

Michael

Autor: Unbekannter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach, so schlimm ist das nicht mit dem Bitfeld und Interrupt.

Einfach den Zugriff aus dem Hauptprogramm mit cli() und sei() klammern,
dann passiert nichts, weil das Bitfeld ja als volatile definiert ist.

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.