Forum: Mikrocontroller und Digitale Elektronik uint16 in uint8 umwandeln


von Lars (Gast)


Lesenswert?

Hallo,
ich möchte mir gerne werte über uart an meinem computer senden.
1
void sendUartData( unsigned char data )
2
{
3
/* Wait for empty transmit buffer */
4
while ( !( UCSR0A & (1<<UDRE0)) );
5
/* Put data into buffer, sends the data */
6
UDR0 = data;
7
8
}

Der Funktionsaufruf beinhaltet allerdings einen uint16. Hiervon wird 
allerdings nur die ersten 8bits benötigt.

z.B.
uint16_t value = 200
sendUartData(value);

egal was ich mache, auf dem Computer kommt immer nur 0 an.
Was muss ich machen, damit die 200 ankommt?

value muss uint16 sein, da vorherige rechenoperationen höhere ZAhlen 
haben.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Lars schrieb:
> sendUartData(value);

sendUartData((value << 8) & 0xFF);

von Rolf M. (rmagnus)


Lesenswert?

Lars schrieb:
> z.B.
> uint16_t value = 200
> sendUartData(value);
>
> egal was ich mache, auf dem Computer kommt immer nur 0 an.

Und sendUartData() ist genau die obige Funktion? Und bei 8-Bit-Variablen 
funktioniert alles?

> Was muss ich machen, damit die 200 ankommt?

Nichts weiter normalerweise. Poste doch bitte mal ein möglichst 
minimales, aber vollständiges Programm, das auch genau so den Fehler 
erzeugt hat. An dem, was du gepostet hast, ist kein Grund zu erkennen, 
warum es nicht gehen sollte.

von Dirk B. (dirkb2)


Lesenswert?

Kommen irgendwelche Warnungen vom Compiler?
(Hast du auch die Warnungen aktiviert?)

von MaWin (Gast)


Lesenswert?

Matthias S. schrieb:
> sendUartData((value << 8) & 0xFF);

Unsinn

von Wolfgang (Gast)


Lesenswert?

Lars schrieb:
> Der Funktionsaufruf beinhaltet allerdings einen uint16. Hiervon wird
> allerdings nur die ersten 8bits benötigt.
>
> z.B.
> uint16_t value = 200
> sendUartData(value);

Falls du mit "die ersten" die obersten 8 Bit meinst, wäre doch nichts 
anderes als 0 zu erwarten. Du solltest allerdings überprüfen, ob deine 
sendUartData() Funktion überhaupt ein uint16_t als Argument erwartet. 
Sonst solltest du den zu übertragenden Wert erstmal in den richtigen Typ 
umwandeln, bevor irgendwelche dir unbekannte Default-Mechanismen 
zuschlagen.

von HildeK (Gast)


Lesenswert?

Lars schrieb:
> uint16_t value = 200
> sendUartData(value);

Warum machst du nicht
1
uint16_t value = 200;
2
sendUartData( (uint8_t)value);

von MaWin (Gast)


Lesenswert?

Wolfgang schrieb:
> Du solltest allerdings überprüfen, ob deine
> sendUartData() Funktion überhaupt ein uint16_t als Argument erwartet.

Die Funktion ist im ersten Posting enthalten.

Das Problem ist ohne mehr Code/Informationen nicht lösbar, wie bereits 
früh geantwortet wurde.

von Maxim B. (max182)


Lesenswert?

1
void sendUartData( unsigned char data )
1
UDR0 = data;
1
uint16_t value = 200
2
sendUartData(value);

Hier ist wohl auch Problem: die Funktion wartet auf unsigned char, und 
du willst uint16_t senden.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Lars schrieb:
> egal was ich mache, auf dem Computer kommt immer nur 0 an.
Wie siehst du dir diese "200" bzw die "0" auf "dem Computer" an?
Mit einem Terminalprogramm?
Was kommt an, wenn du sowas machst:
sendUartData('a');

Maxim B. schrieb:
> Hier ist wohl auch Problem: die Funktion wartet auf unsigned char, und
> du willst uint16_t senden.
Das geht problemlos solange der Wert maximal 255 ist.

: Bearbeitet durch Moderator
von Walter T. (nicolas)


Lesenswert?

Wahrscheinlich kann die Konsole einfach kein "╚" darstellen.

Edit: Das war wohl eine Doppelung mit Lothar.

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

MaWin schrieb:
> Die Funktion ist im ersten Posting enthalten.

Da steht aber nichts von uint16_t als Argument

Wenn man Rapsöl in den Autotank kippt, tut man auch gut daran, vorher zu 
klären, was der Motor damit macht  ;-)

von Rolf M. (rmagnus)


Lesenswert?

Wolfgang schrieb:
> MaWin schrieb:
>> Die Funktion ist im ersten Posting enthalten.
>
> Da steht aber nichts von uint16_t als Argument

Du bist ja auch der einzige, der das behauptet hat.
Die Funktion muss gar kein uint16_t annehmen, da die oberen 8 Bit gar 
nicht gebraucht werden. Eine Konvertierung passiert automatisch.

von Robert S. (bimbo385)


Lesenswert?

Also die Funktion sendUartData erwartet ein unsigned char was beim 
AVR-GCC ein einfaches Byte = 8-Bit = uint8_t ist.

Wenn man jetzt einen größeren Datentyp übergibt, verwendet die Funktion 
nur die niederwertigsten 8 Bit und der Compiler gibt auch eine Warnung 
aus, dass die Datentypen nicht passen.

Korrekter Weise sollte man also bei einem größeren unsigned Datentyp 
vorher auf >UINT8_MAX prüfen, ggf. begrenzen und explizit casten: 
sendUartData((uint8_t)meinUint16_t);
Für die grundlegende Funktion ist das aber nicht notwendig.

Zu beachten ist vielmehr, dass wie Walter Tarpan schon sagte, 200 keinem 
standard ASCII-Zeichen entspricht und je nach verwendetem 
Terminalprogramm u.U. einfach nichts angezeigt wird.

Wenn eine Ausgabe als ASCII String erwartet wird, muss die Zahl zunächst 
in einen String umgewandelt werden, welcher dann aus mehreren Zeichen 
besteht.

Ich benutze als Terminalprogramm gerne HTerm, dies verfügt auch über 
eine Anzeige in Dezimal und Hex und kann somit die 200 auch als 200 
dezimal anzeigen. Putty und andere Terminalprogramme tun das 
normalerweise nicht.

Was passiert wenn man 'a' versucht auszugeben, erscheint dann ein a im 
Terminalfenster???

Mfg Bimbo385

von Stefan F. (Gast)


Lesenswert?

Was willst du eigendlich senden?

Ein Byte mit dem Wert 200, oder
ein String mit dem Wert "200" ?

Terminalprogramme stellen normalerweise Zeichen und Strings dar.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Dabei einfach mal vorausgesetzt, dass die Verdrahtung und die Baudrate 
passen...

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.