www.mikrocontroller.net

Forum: Compiler & IDEs int in zwei uint8_t verpacken (TWI Übertragung)


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Forum, ich habe zwei Controller über den TWI-Bus gekoppelt (zwei 
Atmega 8 @ 16MHz)

Jetzt würde ich gerne einen 16 Bit int Wert übertragen (in diesem Fall 
einen Messwert und eine Jahreszahl).
Ich habe etwas im Forum geschaut und denke, dass man den 16 Bit Wert auf 
zwei Variablen mit je 8 Bit aufteilen muss, um ihn zu übertragen:

volatile unsigned int year;
uint8_t yearL, yearH;

yearL = year;
yearH = year >> 8;


Damit sollte der int in zwei uint8_t zerlegt sein, die sich so 
prinzipiell auch übertragen lassen.
Wie muss ich nun die beiden empfangenen Werte verknüpfen, um wieder 
einen int zu erhalten? Mit zwei uint8_t kann ich recht wenig anfangen, 
geschweige denn berechnen oder darstellen.

Vielen Dank & Gruß

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
volatile unsigned int year;
uint8_t yearL, yearH;

year  = yearL;
year |= yearH << 8;

MfG

Autor: D. E. (stb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Obiges Beispiel müsste fehlerhaft sein, da yearH << 8 null ergibt, wenn 
yearH eine 8-Bit Variable ist.

So sollte es ohne Compilerwarnungen tun:

volatile unsigned int year;
uint8_t yearL, yearH;

year = (unsigned int) yearH;
year <<= 8;
year |= (unsigned int) yearL;

STB

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

diese Struktur ermöglicht einen Byte bzw Integer Zugriff auf die 
gemeinsamme Var val.

   //--------------------------------------
   union
   {
      uint val;
      struct
      {
         uchar msb;
         uchar lsb;
      }a;
   }b;
   //--------------------------------------
   b.val = xy;  // Wert in int schreiben
   x = b.a.msb; // msb lesen
   y = b.a.lsb; // lsb lesen


Gruß Jürgen

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
D. E. wrote:
> Obiges Beispiel müsste fehlerhaft sein, da yearH << 8 null ergibt, wenn
> yearH eine 8-Bit Variable ist.
Spielt aber im Grunde genommen keine Rolle, da Berechnungen 
grundsätzlich mindestens in 16 Bit (int) durchgeführt werden 
(ANSI-konform).

Was allerdings immer gemacht werden sollte, ist eine Konversion nach 
unsigned, sonst kann es beim Schieben Probleme geben (allerdings eher 
beim Schieben nach rechts).

Generell ist eine Typkonversion jedoch ratsam. Dann weiß der Compiler 
auch, dass man das wirklich so meint, wie es da steht...

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

der OP fragte nach dem "Prinzip" und nicht nach lauffähigem Code.

@ D.E
@ Johannes M.
durch die Deklaration der Variablen hat der Compiler alles was er 
braucht.

@ D.E
@ Jürgen
in der Programmiersprache C liegt die Würze in der Kürze :-)

MfG

Autor: D. E. (stb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Ich
Auch Du wirst lernen, daß sauberer Programmierstil unter Umständen mehr 
Zeit spart als die paar Millisekunden die Du beim Tippen sparst. <:O)


Grüße

STB

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes M. wrote:
> D. E. wrote:
>> Obiges Beispiel müsste fehlerhaft sein, da yearH << 8 null ergibt, wenn
>> yearH eine 8-Bit Variable ist.
> Spielt aber im Grunde genommen keine Rolle, da Berechnungen
> grundsätzlich mindestens in 16 Bit (int) durchgeführt werden
> (ANSI-konform).

Dann ist entweder die Aussage falsch, der Compiler (gcc 4.3.2) nicht 
ANSI-konform, oder er hat nen Bug.

Aus
unsigned char year, yearL, yearH;
void foo()
{
    year  = yearL;
    year |= yearH << 8;
}

bastelt avr-gcc 4.3.2 -Os -std=c99 -ansi
foo:
  lds r24,yearL   ;  yearL, yearL   ;  8  *movqi/4  [length = 2]
  sts year,r24   ;  year, yearL   ;  10  *movqi/3  [length = 2]
  ret   ;  25  return  [length = 1]

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

volatile unsigned int year;
uint8_t yearL, yearH;

year = (unsigned int) yearH;
year <<= 8;
year |= (unsigned int) yearL;


Funktioniert perfekt! Vielen Dank dafür!
Die anderen Beispiele funktionieren alle genauso, ich habe mir über den 
UART die Ergebniss der anderen Umwandlungen mit verschiedensten Werten 
ausgeben lassen. Leider bin ich noch ziemlich am Anfang mit meinen 
Kenntnissen, deswegen kann ich da auf den ersten Blick keinen 
Unterschied erkennen, funktioniert ja alles wie es soll...

>der OP fragte nach dem "Prinzip" und nicht nach lauffähigem Code.

Och naja, den Umsatz Prinzip->Quellcode hätte ich dann auch noch 
erfragt, so fit bin ich nicht. Prinzipiell muss ich ja auch nur die 
Operation umkehren, das Prinzip habe ich schon verstanden ;-)

Vielen Dank & Grüße

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

@ Johann L.

> unsigned char year, yearL, yearH;
year war als unsiged int deklariert.
yearL und yearH als uint8_t

MfG

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. wrote:
> Dann ist entweder die Aussage falsch, der Compiler (gcc 4.3.2) nicht
> ANSI-konform, oder er hat nen Bug.
Ersteres! Klar, ist ja AVR, und bei einer 8-Bit-Plattform muss der 
Compiler sowas natürlich optimieren dürfen. Wäre ziemlich katastrophal, 
wenn tatsächlich alles in 16 Bit gerechnet würde...

EDIT:
Ich hat allerdings auch (ausnahmsweise?) recht: Das Ergebnis sollte 
schon 16 Bit haben...

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich wrote:
> Hallo,
>
> @ Johann L.
>
>> unsigned char year, yearL, yearH;
> year war als unsiged int deklariert.

oops, der böse tipp-Teufel war am Werk

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... habe immer recht :-)

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich wrote:
> ... habe immer recht :-)
"Ich lüge nie" sagte der notorische Lügner...;-)

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.