Hallo zusammen,
ich habe vllt eine komische Frage an euch. Ich habe 2 µC die sich über
SPI bzw. CAN Bus unterhalten. Nun zu meiner Frage, ich kann bisher nur
Decimal Zahlen schicken z.B. 0x22=34 aber wie macht man das wenn man -34
oder 22.5 schicken will ? weil -34 FFFFFFFFFFFFFFDE in HEX ist. Ich
hoffe dass ich mein Problem erklären könnte.
LG
Mark schrieb:> Nun zu meiner Frage,
Die ist so komisch dass man annehmen muss dass heute schon
Freitag ist. Denn ich glaube schon das nicht:
Mark schrieb:> Ich habe 2 µC die sich über SPI bzw. CAN Bus unterhalten.
Bzw wenn du das kannst dann brauchst du keine solch komische
Frage stellen.
Mark schrieb:> ich habe vllt eine komische Frage an euch.
Mark schrieb:> weil -34 FFFFFFFFFFFFFFDE in HEX ist.
Du könntest dich mit dem anderen µC drauf einigen, dass dezimal -34
hexadezimal FFDE ist.
Falls 22.5 auch heil rüberkommen soll, bietet sich z.B. an
22.5 002D
-34 FF6C
Mark schrieb:> Ich> hoffe dass ich mein Problem erklären könnte.
Da kann ich dich völlig beruhigen, das konntest du. Dein Problem ist
einfach, das du keine Ahnung vom Unterschied zwischen einer Zahl (an
sich) und deren möglichen Repräsentation hast.
Lerne das. Dann wird es dir wie Schuppen aus den Haaren fallen...
Tipp: über den CAN-Bus wird typisch die Zahl an sich (bzw. deren binäre
Repräsentation) übertragen. Das ist also ein Bus, den nur Leute benutzen
sollten, die sowas beherrschen...
Was dir dein Debugger anzeigt, ist (nach Wahl) meist eine
"Hex"-Repräsentation oder auch eine dezimale. Es ist aber immer dieselbe
Zahl, die da über den Bus ging. Der Wechsel der Repräsentation ist nur
Eye-Candy für Dummies.
Dasselbe gilt für die verschiedenen Darstellungsmöglichkeiten derselben
Zahl in Quelltexten. In C z.B. ist 0xB9 dasselbe wie 185, aber nicht
dasselbe wie "B9".
Denn das ist wiederum eine Repräsentation als Hex-String. Das ist zwar
hübscher zu lesen, wenn's über einen Bus geht und der Bus-Spion nur
ASCII-Zeichen anzeigt, aber höchst ineffizient, weil dafür zwei Bytes
statt nur eines über den Bus gehen müssen, wenn man es in dieser
Repräsentation verschicken wollte...
Kurz: das kann die keiner wirklich erklären, das kannst du nur selber
lernen...
Hallo Mark,
Mark schrieb:> Hallo zusammen,>> ich habe vllt eine komische Frage an euch. Ich habe 2 µC die sich über> SPI bzw. CAN Bus unterhalten. Nun zu meiner Frage, ich kann bisher nur> Decimal Zahlen schicken z.B. 0x22=34 aber wie macht man das wenn man -34> oder 22.5 schicken will ? weil -34 FFFFFFFFFFFFFFDE in HEX ist. Ich> hoffe dass ich mein Problem erklären könnte.
es gibt keine Normdarstellung für Zahlen. Es gibt verschiedene
Zahlformate.
Welches Format das richtige ist, hängt davon ab, was die Endpunkte
Deiner Busverbindung erwarten.
Die Zahl -34 kann man als vorzeichenbehafteten Integer, als Zahl im
Zweierkomplement aber auch in Fließpunktdarstellung codieren.
Die Länge einer solchen Codierung variiert dann z.B. von 1 (Integer
vorzeichenbehaftet oder Zweierkomplement) bis 8 Byte
(Fließpunktdarstellung als "Double").
Zahlreiche weitere Darstellungen sind möglich.
c-hater schrieb:> Kurz: das kann die keiner wirklich erklären, das kannst du nur selber> lernen...
Oh je. Das kann man doch wunderbar erklären, oder?
Mark schrieb:> ch kann bisher nur Decimal Zahlen schicken z.B. 0x22=34 a
Nein spi und can kennen nur Bytes. Wie du die Bits interpretierst oder
wie du die Bytes zu größeren Zahlen zusammenfasst, bleibt dir
überlassen. Manche lehnen sich da an die Repräsentationen des
verwendeten uC und der Programmiersprache an. Muss aber nich.
Mark schrieb:> Nun zu meiner Frage, ich kann bisher nur> Decimal Zahlen schicken z.B. 0x22=34 aber wie macht man das wenn man -34> oder 22.5 schicken will ? weil -34 FFFFFFFFFFFFFFDE in HEX ist.
ist es aber nur als 64 bit Zahl, wie schon merhfach erwähnt ist das
alles definitionssache.
du brauchst also eine Art "Protokoll" zum übertragen der Daten.
Mark schrieb:> SPI bzw. CAN Bus unterhalten.
du musst also entweder ein bestehendes nehmen oder ein eigenes erfinden.
Wenn du alles selber machts kannst du in C eine Union zwischen z.b.
deiner 64 bit zahl und einem uint8_t array machen, die zahl in die Union
schreiben, das array auf den bus schicken, und auf der anderen Seite vom
Bus ins Array schreiben und die Zahl auslesen. hat aber noch keine
Synchronisation (wann beginnt eine neue Zahl die aus mehreren Byte
besteht) und kann nur Punk zu Punkt.
dabei ist dann was die Bytes darstellen völlig unabhängig von der
Übertragung, ob da nun 8 ASCII Zeichen kommen oder ein Double oder long
sieht gleich aus.
daher brauchst du auch ein Protokoll was sagt was da ankommt und wo es
beginnt.
Beschreib also mal ein weniger gröber was das große Ganze werden soll.
Mark schrieb:
>Ich habe 2 µC die sich über>SPI bzw. CAN Bus unterhalten.
Ist wie wenn sich zwei Menschen über eine Telefonleitung
unterhalten und es soll dem anderen Zahlen erzählt werden.
Dann würde ich wenn der Mensch am anderen Ende der Leitung
ein Chinese ist, ihm die Zahlen auf Chinesisch erzählen,
und wenn es ein Engländer ist, würde ich ihm die Zahlen
auf englisch erzählen. So ist es auch mit dem µC, du
must also wissen, in welcher Codierung erwartet der µC
die Zahlen, oder du denkst dich daß für beide Seiten
selber aus. Zum beispiel könnte man BCD-Ziffern verwenden,
benötigt 4Bit, in einen Byte wären dann noch 4Bit frei.
davon könnte ein Bit fürs Vorzeichen verwendet werden.
Wie man Zahlen darstellen kann, da gibt es die
verschiedensten Varianten.
https://de.wikipedia.org/wiki/BCD-Codehttps://www.punkt-akademie.de/wp-content/uploads/2017/04/zahlendarstellung-im-computer.pdf
Günter Lenz schrieb:> So ist es auch mit dem µC, du> must also wissen, in welcher Codierung erwartet der µC> die Zahlen, oder du denkst dich daß für beide Seiten> selber aus.
Nö, die Übermittlung erfolgt als Hex.
Außer du schickst es als "Text".
Auch da wird es auf Hex/Bin runtergebrochen.
michael_ schrieb:
>Nö, die Übermittlung erfolgt als Hex.
Und die Hexzahlen können nicht verschieden
codiert sein? In so ein Byte, also zweistellige
Hexzahl, könnte man zum Beispiel eine Dezimalzahl
binär unterbringen (0 bis 255), oder zwei BCD-Stellen
(0 bis 99), oder als ASCII (0 bis 9), oder als
Baudot-Code (0 bis 9). Das sind nur vier Beispiele,
es gibt noch eine ganze Reihe mehr. Für was er sich
nun entscheidet bleibt seiner Fantasie überlassen.
Mark schrieb:> aber wie macht man das wenn man -34 oder 22.5 schicken will ?
Man schickt einzelne ASCII-Zeichen wie z.B. '-', '3' und '4' oder '2',
'2', '.' und '5'.
Denn dann kann man 1. für das sowieso nötige Protokoll (Anfangs- und
Endekennzeichnung der Übertragung) die "üblichen" Steuerzeichen STX,
ETX, CR, LF usw. verwenden und 2. das Ganze mit jedem x-beliebigen
Terminal mitlesen.
Aber letztlich wird dann z.B. natürlich auch ein '-' als hexadezimaler
Wert 0x45 gespeichert und als binäre Bitfolge 0100_0101 übertragen
(Stichwort dazu: ASCII-Tabelle)
Andreas B. schrieb:> michael_ schrieb:>> Nö, die Übermittlung erfolgt als Hex> Nö, immer noch binär.
Hex und Binär und Dezimal sind letztlich nur verschiedene "Blickwinkel"
auf die selbe Zahl. Mit ein bisschen Übung ist das ganz einfach das
Selbe. So, wie wenn einer "Semmel" oder "Schrippe" oder "Brötchen"
sagt und doch nur einen "Wecken" meint...
Lothar M. schrieb:>> Nö, immer noch binär.> Hex und Binär und Dezimal sind letztlich nur verschiedene "Blickwinkel"> auf die selbe Zahl. Mit ein bisschen Übung ist das ganz einfach das> Selbe. So, wie wenn einer "Semmel" oder "Schrippe" oder "Brötchen"> sagt und doch nur einen "Wecken" meint...
Das ist ASCII auch. Hex ist eine Zusammenfassung von (willkürlich
gewählten) 8 Bit. Ich kann auch recht schnell von Binär auf Dezimal
umrechnen, aber darum geht's ja gar nicht.
Übertragen wird das aber alles als Binär. Jedenfalls bei den heutigen
Computern.
\\ Erbsenzählermodus aus
Lothar M. schrieb:> Aber letztlich wird dann z.B. natürlich auch ein '-' als hexadezimaler> Wert 0x45 gespeichert und als binäre Bitfolge 0100_0101 übertragen
0x45 ist immer noch "E"
Route 6. schrieb:> 0x45 ist immer noch "E"
Ja, zum Glück... ;-)
Andreas B. schrieb:> Ich kann auch recht schnell von Binär auf Dezimal umrechnen, aber> darum geht's ja gar nicht.
Man muss es eben nicht "umrechnen", sondern lediglich
"uminterpretieren".
Umrechnen muss man es nur, wenn man es mit ASCII-Zeichen darstellen
will. Und das passiert dann auch in deinem Kopf, solange du eine Zahl
zwischen diesen drei Darstellungen "umrechnen" musst: du betrachtest
jede einzelne Ziffer als Zeichen und rechnest ihren Wert aus, um diese
Zeichenkette dann auf ein Blatt Papier hinschreiben zu können.
> Das ist ASCII auch. Hex ist eine Zusammenfassung von (willkürlich> gewählten) 8 Bit. Ich kann auch recht schnell von Binär auf Dezimal> umrechnen, aber darum geht's ja gar nicht.
ASCII ist aber eben nicht nur eine andere Interpretation der exakt
selben Bitfolge, sondern es ist ein umcodierte Bitfolge, die mehr
Bits/Platz braucht als die "reine" Binär-/Hex-/Dezimalzahl.
222 braucht in ASCII drei Bytes: 0x32, 0x32 und 0x32.
Als vorzeichenloser Integerwert braucht es aber nur 1 einziges Byte:
0xde alias 1100_1101 oder eben 222
Und natürlich wird auch die Übertragung der in lesbaren Text übersetzten
ASCII-Variante 3 mal so lange dauern, wie die des
Binär-/Hex-/Dezimalrohwertes.
Andreas B. schrieb:> \\ Erbsenzählermodus aus
Eso es!
Wolfgang schrieb:> Route 6. schrieb:>> 0x45 ist immer noch "E">> Das ist es nur, wenn im Zeichensatz vereinbart ist, das 0x45 für "E"> steht (z.B. ASCII oder EBCDIC)
Lesen ist nicht so deine Sache?
Lothar schrieb ganz eindeutig ASCII!