Forum: Mikrocontroller und Digitale Elektronik struct definieren und verwenden


von Michael L. (Gast)


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

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Michael L. (Gast)


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?

von Karl H. (kbuchegg)


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

von Michael L. (Gast)


Lesenswert?

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

Gruß,
Michael

von Olaf (Gast)


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

von Michael L. (Gast)


Lesenswert?

Hmmmh??
Warum denn das?

von Olaf (Gast)


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

von Michael L. (Gast)


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

von Unbekannter (Gast)


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.

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.