Forum: Compiler & IDEs Frage zu C-Code


von André Wippich (Gast)


Lesenswert?

Hi.

Ich habe gerade etwas Schwierigkeiten wieder in C reinzukommen (2 Jahre
Pause, zwischendurch Assembler, PHP, Java und SQL g). Ich programmiere
jetzt einen ATmega162 in WinAVR mit der AVR-LIBC (vorher nur Assembler)
in C. Vielleicht kann mir jemand mit meinem Code helfen:

Also ich lese ein 8-bit-Register an RAM Adresse aus und speichere es in
einer Variable. Von diesem Byte einige Informationen:

Ist das erste Bit gesetzt?
Was ergeben die letzten vier Bits?
Beispiel: 1101 1010
-> Erstes Byte gesetzt; Die letzten vier ergeben 10

Das Register wurde bereits mit define als REG benannt.

Geht das so (?):
**************************************
CHAR temp = REG;

if ( (temp>>7) == 1)
{
    panic();
}

temp = REG;
char anz = (temp & 0x0F);
**************************************

Und anschließend muss ich die nächsten anz Bytes hinter der Adresse von
RAM auch auslesen (aber nicht mehr prüfen). Gibt es da eine einfache
Möglichkeit für? Wäre ziemlich umständlich, wenn ich das so machen
müsste:
if (anz >= 1) {var1 = REG1;}
if (anz >= 2) {var1 = REG2;}
.
.
.
if (anz >= 8) {var1 = REG8;}


Danke für Eure Hilfe!

von Michael Wilhelm (Gast)


Lesenswert?

Um anz zu testen geht deine if-Konstruktion nicht. Wenn z. B. anz 4 ist,
dann würden die ersten 4 Bedingungen zutreffen. Besser:

switch (anz)
{
 case 1: ...
 break;

 case 2: ...
 break;

 default:   // wenn kein Treffer
 break;
}

MW

von André Wippich (Gast)


Lesenswert?

Hi.

Uops, das hab ich nicht ganz verständlich erklärt. Es sollen in dem
Fall die nächsten 4 Byte übernommen werden.

Es ist so, dass sich die erste RAM Zelle (REG) in einem externen Gerät
befindet und das erste Byte eine Botschfat darstellt. Die Botschaften
können aber unterschiedlich lang sein und das erste Byte enthält unter
anderem die Botschafts-Länge. Durch meine Abfrage will ich rauskriegen,
wieviele Byte ich noch einlesen muss.

Gruß, André

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

.

  if ( (temp>>7) == 1)
  {
    panic();
  }

geht auch so:

  if (temp & 0x80)
    panic();

von Zotteljedi (Gast)


Lesenswert?

Beim avr-gcc ist IIRC char per default unsigned, aber das ist vom
C-Standard nicht vorgeschrieben, daher:

Bitfummeleien bitte nur bei unsigned Datentypen!

Gerade das Shiften nach rechts ist so eine Sache, denn ob das oberste
Bit (das auch das Vorzeichen kodiert) mitgeschoben werden soll oder
nicht, hängt davon ab, ob der Datentyp vorzeichenbehaftet ist, oder
nicht. Konkret sagt der Standard:

6.5.7 Bitwise shift operators
...
5 The result of E1 >> E2 is E1 right-shifted E2 bit positions.
  If E1 has an unsigned type or if E1 has a signed type and a
  nonnegative value, the value of the result is the integral
  part of the quotient of E1 / 2^E2. If E1 has a signed type and a
  negative value, the resulting value is implementation-defined.

Also auf Verständlich: shiftet man einen vorzeichenbehafteten Wert mit
gesetztem höchsten Bit nach rechts, ist das Ergebnis
implementierungsabhängig. Kann also bereits beim nächsten
Compiler-Release anders sein, sowas will man in der Regel nicht.

Ob der char jetzt per default signed oder unsigned ist, ist ebenfalls
implementierungsabhängig, bei allen anderen Ganzzahltypen ist signed
der default!

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.