mikrocontroller.net

Forum: Compiler & IDEs 16Bit Zahl in 2 8 Bit zahlen teilen


Autor: Michl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hy Leute!

Hab mal ne kurze Frage an euch. Ich hab ne Zahl wie zB.: 180 und die 
muss in zwei 8Bit Variablen reingeschrieben werden. (Anwendung: Timer 1 
- High und Low). Kann mir vl irgendwer sagen obs da ne Funktion gibt, 
die mir das umrechent oder muss ich mir das mühsam berechnen (immer /2 
und schaun ob ein Rest bleibt)?

Danke im Voraus!

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uint8_t HighByte = (180 >> 8);
uint8_t LowByte = 180 & 0xFF;

Autor: Sardaukar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du Deine 180 bereits im Speicher liegen hast (z.B. als unsigned 
short), dann erledigt das der Compiler für Dich:

unsigned short a = 180;

unsigned char lo, hi;

lo = ( unsigned char )a;
hi = *( ( unsigned char* )a + 1 );

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sardaukar wrote:
> Wenn Du Deine 180 bereits im Speicher liegen hast (z.B. als unsigned
> short), dann erledigt das der Compiler für Dich:
>
> unsigned short a = 180;
>
> unsigned char lo, hi;
>
> lo = ( unsigned char )a;
> hi = *( ( unsigned char* )a + 1 );

Ja, bei Little Endian Maschinen ist das so.
http://de.wikipedia.org/wiki/Byte-Reihenfolge

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sowas erledigt man am besten mit zwei Macros in einem Headerfile:

   #define LOW_BYTE(x)        (x & 0xff)
   #define HIGH_BYTE(x)       ((x >> 8) & 0xff)

Dann ist der Code portabel.

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder du benutzt gleich die 16-Bit Register (von Timer oder ADC) als 
solche:
uint16_t value = 902;
OCR1 = value;
ICR1 = value;
value = ADC; //ADCW ginge auch
UBRR = value;
/* etc.*/
hth. Jörg

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> hi = *( ( unsigned char* )a + 1 );

Da ist ein & verloren gegangen:

  hi = *( ( unsigned char* )&a + 1 );

Ansonsten würde ich aber, wo dies möglich ist, Jörgs Weg mit den
16-Bit-Zugriffen bevorzugen: Sieht am maximal gut aus, ist maximal
kurz und liefert in allen Kontexten maximal effizienten Code.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
yalu wrote:
>> hi = *( ( unsigned char* )a + 1 );
>
> Da ist ein & verloren gegangen:
>
>   hi = *( ( unsigned char* )&a + 1 );
>
> Ansonsten würde ich aber, wo dies möglich ist, Jörgs Weg mit den
> 16-Bit-Zugriffen bevorzugen: Sieht am maximal gut aus, ist maximal
> kurz und liefert in allen Kontexten maximal effizienten Code.

Komisch, letztens ging das nicht mit dem UBBR Register vom UART bei mir. 
(Aktuelle WinAVR Version)

Hängt das vielleicht mit dem URSEL Bit zusammen?

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

Bewertung
0 lesenswert
nicht lesenswert
Simon Küppers wrote:
> Komisch, letztens ging das nicht mit dem UBBR Register vom UART bei mir.
> (Aktuelle WinAVR Version)
>
> Hängt das vielleicht mit dem URSEL Bit zusammen?
Das URSEL-Bit gibts ja nur bei einigen wenigen AVRs (Mega16 und 
verwandte). Da muss man natürlich ein bisschen aufpassen und 
sicherstellen, dass das URSEL auch wirklich 0 ist. Bei den anderen AVRs 
sollte das aber unproblematisch sein.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes M. wrote:
> Simon Küppers wrote:
>> Komisch, letztens ging das nicht mit dem UBBR Register vom UART bei mir.
>> (Aktuelle WinAVR Version)
>>
>> Hängt das vielleicht mit dem URSEL Bit zusammen?
> Das URSEL-Bit gibts ja nur bei einigen wenigen AVRs (Mega16 und
> verwandte). Da muss man natürlich ein bisschen aufpassen und
> sicherstellen, dass das URSEL auch wirklich 0 ist. Bei den anderen AVRs
> sollte das aber unproblematisch sein.

Ja, um den Mega16 geht's. Problem: UBRR ist nicht definiert. includet 
habe ich <avr/io.h>
UBRRH und UBRRL hingegen gab es.

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

Bewertung
0 lesenswert
nicht lesenswert
Simon Küppers wrote:
> Ja, um den Mega16 geht's. Problem: UBRR ist nicht definiert. includet
> habe ich <avr/io.h>
> UBRRH und UBRRL hingegen gab es.
Hmm, ist mir bisher nie aufgefallen. Aber ist zumindest nachvollziehbar, 
dass es tatsächlich am URSEL (oder an der Ursel;-?) liegt.

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sry, falls ich Verwirrung gestiftet hab ;)
Das UBRR kann man scheinbar nur auf wenigen AVRs als 16Bit-register 
benutzen (scheinbar nur auf neueren Atmegas, neuer als z.B. die 
mega16/32)
Das ist aber auch nicht so tragisch, da beim UBRR die Reihenfolge der 
Zugriffe keine Rolle spielt! (und  UBRRH i.d.R. mit 0 vorbelegt  ist).

hth. Jörg

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg X. wrote:
> sry, falls ich Verwirrung gestiftet hab ;)
> Das UBRR kann man scheinbar nur auf wenigen AVRs als 16Bit-register
> benutzen (scheinbar nur auf neueren Atmegas, neuer als z.B. die
> mega16/32)
> Das ist aber auch nicht so tragisch, da beim UBRR die Reihenfolge der
> Zugriffe keine Rolle spielt! (und  UBRRH i.d.R. mit 0 vorbelegt  ist).
>
> hth. Jörg

Bei der Initialisierung hat das keinen Effekt, sehe ich auch so. Dennoch 
steht im Datenblatt:

> Writing UBRRL will trigger an immediate update of
> the baud rate prescaler.

Sprich: UBRRL forciert während einer laufenden Transmission das Update 
der Baudrate.
Erledigt man das aber im Voraus ist das wohl egal, da es hier nicht 
dieses "Buffer"-prinzip gibt, wie zum Beispiel beim Timer. (Erst Low 
bzw. High Register laden, das landet dann in einem Temporärregister. 
Nach dem Laden des High bzw. Low Registers werden dann der Wert dieses 
mit dem Wert im Temporärregister auf einen Schlag geladen). Und das ist 
vermutlich das, was du meintest :-)

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@simon:
Ja, das meinte ich.
>> Writing UBRRL will trigger an immediate update of
>> the baud rate prescaler.
Das hab ich zum ersten mal gesehen :(  -- da muss man ja doch aufpassen.

thx. Jörg

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.