www.mikrocontroller.net

Forum: GCC Datenzuweisung an Struct

Autor: Sven (Gast)
Datum: 30.04.2008 00:22

Hallo,

ich kann meinen ATmega32 mit dem AVR-GCC einigermassen gut
Programmieren, bin aber auf eine Sache gestossen die ich nicht lösen
kann. Habe versucht darüber Informationen zu finden, allerdings ohne
Erfolg.

Mein Problem ist folgendes:

Ich habe einen Struct definiert und möchte gerne "numerisch" auf die
jeweiligen Elemente zugreifen.

Der Struct:

struct zeitformat
  {
  uint8_t sekunden;
  uint8_t minuten;
  uint8_t stunden;
  } aktuellezeit;

Jetzt lese ich die RTC aus und weise aktuellezeit.sekunden die Sekunden
zu, das selbe mache ich mit den Minuten und Stunden. Dies funktioniert
auch alles, nur muss ich für jedes Element des Struct's eine Zuweisung
schreiben (viel Programmcode). Einfacher wäre eine Schleife - geht das ?

Gibt es eine Möglichkeit auf die Elemente des Sruct's auch mit einer
Variablen zuzugreifen?

Vielen Dank für einen Tip
Autor: Nex (Gast)
Datum: 30.04.2008 06:32

Oder mit nem Pointer darauf zugreifen
Autor: Eugen (Gast)
Datum: 30.04.2008 07:37

soetwas hab ich mal benutzt um beim initialisieren ein struct zu löschen
(als ich noch nicht wusste wie es anders geht).

dabei musste ich erst die Pointeradresse des structs in ein u_int casten
(zum zählen, sonst zählt er dabei bei (&STRUKTUR)+i das i als vielfache
von sizeof(STRUKTUR) )
und dann diesen neuen u_int als charpointer casten um auf einzelne Bytes
schreiben zu können

//löschen des structs
for(unsigned int i =0;i<sizeof(STRUKTUR);i++)
{
      *(unsigned char*)((unsigned int)(&STRUKTUR)+i)=0;
}

in deinem Fall würde ich aber aufpassen, denn sobald du verschiedengroße
Datentypen in deinem struct hast, musst du sowieso für jede Variable dir
überlegen wie groß die Variable ist und was da rein muss.
ein Feld von void* (wegen den verschiedenen Datentypen) würde dir
vieleicht helfen. dann könntest du zum einem auf die Werte per Zeiger
iterativ zugreifen und zum anderen ihnen per defines Namen geben.
Autor: Karl heinz Buchegger (kbuchegg) (Moderator)
Datum: 30.04.2008 07:54

> Jetzt lese ich die RTC aus und weise aktuellezeit.sekunden die
> Sekunden zu, das selbe mache ich mit den Minuten und Stunden. Dies
> funktioniert auch alles, nur muss ich für jedes Element des
> Struct's eine Zuweisung schreiben (viel Programmcode).

Das wirst du nicht einfacher machen können. Sind doch nur 3.
  aktuellezeit.sekunden = sekunden_vom_rtc;
  aktuellezeit.minuten  = minuten_vom_rtc;
  aktuellezeit.stunden  = stunden_vom_rtc;

Allenfals könnte man sich noch eine Funktion dafür schreiben:
void AssignTime( struct zeitformat* zeit,
                 uint8_t stunden, uint8_t minuten, uint8_t sekunden )
{
  zeit->sekunden = sekunden;
  zeit->minuten  = minuten;
  zeit->studnen  = stunden;
}

und die dann benutzen, wenn so eine Zuweisung häufiger auftritt
    ...
    AssignTime( &aktuellezeit, stunden_vom_rtc, minuten_vom_rtc, sekunden_vom_rtc );
    ....
    ....
    AssignTime( &aktuellezeit, stunden_vom_rtc, minuten_vom_rtc, sekunden_vom_rtc );

Falls du Zeiten aneinander zuweisen musst, dann kannst du das mit
einer normalen Zuweisung machen
   struct zeitformat a;
   struct zeitformat b;

   ...
   AssignTime( &a, stund, minut, sekund );
   ...
   b = a;

Wenn du die Zeit auf 0 setzen musst, kannst du alternativ
  AssignTime( &a, 0, 0, 0 );
oder
  memset( &a, 0, sizeof( a ) );
benutzen.
Autor: Rup (Gast)
Datum: 30.04.2008 18:29

Die Strukturzuweisung nach ANSI C99 lautet:
struct zeitformat a;

a = { .sekunden = x, .minuten = y, .stunden = z };

Das sollte jeder moderner GNU-Compiler ab 3.0 können.
Man kann sich auch leicht ein Makro daraus bauen:
#define MAKE_ZEITFORMAT(stu, min, sek) (struct zeitformat){.sekunden = sek, .minuten = min, stunden = .stu}
Autor: holger (Gast)
Datum: 30.04.2008 18:39

>Ich habe einen Struct definiert und möchte gerne "numerisch" auf die
>jeweiligen Elemente zugreifen.

Wozu definierst du dann ein struct? Nimmst halt ein Array.
Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum: 30.04.2008 21:00

Rup wrote:

> Die Strukturzuweisung nach ANSI C99 lautet:

Es gibt kein “ANSI C99”.  Es gibt nur ein “ISO/IEC 9899:1999”, kurz
“ISO C99”.

> a = { .sekunden = x, .minuten = y, .stunden = z };

Das ist keine Zuweisung, sondern eine Initialisierung und auch
nur in diesem Kontext zulässig.
Autor: Martin L. (melvin_the_moose)
Datum: 30.04.2008 21:51

struct zeitformat
  {
  uint8_t sekunden;
  uint8_t minuten;
  uint8_t stunden;
  };

typedef struct zeitformat zeitformat_t;

union zeit_union
  {
  zeitformat_t s;
  uint8_t b[3];
  } aktuellezeit;

  /*Zuweisung durch Strukturelement*/
  aktuellezeit.s.sekunden = 12u;
  aktuellezeit.s.minuten  = 34u;
  aktuellezeit.s.stunden  = 11u;

  /*Zuweisen in einer Schleife*/
  for (unsigned int i=0; i<3; i++)
  {
  aktuellezeit.b[i]=0;
  }

Ich habe das Beispiel nicht compiliert. Ich hoffe, es sind keine
Syntaxfehler drin...
Aber so müßte es gehen, wenn es sein muß. Empfehlenswert ist diese Art
des Zugriffs auf Strukturelemente jedoch nicht, da der Compiler je nach
Elementtypen im struct Lücken im Speicherlayout einfügen kann. Ein
bestimmter Arrayindex entspricht dann nicht immer einem bestimmten
Strukturelement. Dieses Verhalten ist (Compiler-)
implementierungsabhängig und möglicherweise nicht portabel.
Autor: Also nee (Gast)
Datum: 30.04.2008 23:32

Man könnte auch ein Array definieren und den Inidzes vorher per Makros
Namen geben:
typedef uint8_t zeitformat[3];

#define SEKUNDEN 0
#define MINUTEN 1
#define STUNDEN 2

aktuellezeit[SEKUNDEN] = 12;
aktuellezeit[MINUTEN] = 34;
aktuellezeit[STUNDEN] = 11;

for (unsigned int i=0; i<3; i++)
{
   aktuellezeit[i]=0;
}

So kann man auf union-Hacks verzichten.

Antwort schreiben

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

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos verwenden, Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net