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!
uint8_t HighByte = (180 >> 8); uint8_t LowByte = 180 & 0xFF;
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 );
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
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.
Oder du benutzt gleich die 16-Bit Register (von Timer oder ADC) als solche:
1 | uint16_t value = 902; |
2 | OCR1 = value; |
3 | ICR1 = value; |
4 | value = ADC; //ADCW ginge auch |
5 | UBRR = value; |
6 | /* etc.*/
|
hth. Jörg
> 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.
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?
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.
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.
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.
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
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 :-)
@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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.