Forum: Mikrocontroller und Digitale Elektronik UART Verstädnissfrage


von Sercan S. (disaster35)


Lesenswert?

Hallo,

ich beziehe mich bei der UART Kommunikation auf ein Bluetooth Modul und 
Smartphone mit UART.

Soweit ich das nun richtig verstanden habe muss erstmal eine Baudrate 
eingestellt werden, die auf beiden Seiten identisch sein muss. Hierzu 
gab es auch in den BT-Modulen verschiedene Empfang und Sende 
"Erfolgsraten" in bestimmten Baudrate-Bereichen.

Auf beiden Seiten muss für die Verbindung eine bestimmte Anzahl von 
Datenbits eingestellt werden ? Beispielsweise 8 Bits ohne Paritätscheck 
sprich 8N1. Aus der Schul/Studiumszeit weiß ich noch, dass der 
Paritätstbit je nach Anzahl der Nullen oder Einsen 0 oder 1 wird. Bsp.: 
Wir haben ein Paritätstcheck nach den Einsen, würden 4 Einsen ein 
Paritätsbit von 0 ergeben, da 4 eine gerade Anzahl von Einsen sind.

Aber um die Parität muss ich mich ja nicht kümmern oder? Da ich aus dem 
GCC-Tutorial nichts darüber finden konnte, gehe ich davon aus, dass es 
vom BT-Modul selbst übernommen wird und erst nach erfolgreicher 
Paritätscheck beim Mikrocontroller etwas ankommt?

Das ich TX an RX und RX an TX vom Bluetooth-Modul an den Mikrocontroller 
anschließen muss ist auch verständlich.

Nach erfolgreicher Konfiguration und Verbindung vom Smartphone und 
BT-Modul muss ich ja quasi wie folgt vorgehen oder?:

Nehmen wir mal an ich will eine x-Beliebige 4-Stellige Zahl senden:

Auf Smartphone Seite muss ich ja die 4-Stellige Ziffer einfach an den 
BT-Modul senden und vom BT-Modul aus bekomme ich an den Mikrocontroller 
anschließend die Zeichen in ASCII-Form.


Verstehe ich das so richtig: Ich sende die Zahl 1234 vom Smartphone an 
den BT-Modul und vom Mikrocontroller kann ich mit uart_getc() die Zahlen 
nacheinander in ASCII bekommen sprich ich bekomme die 4 Werte 
nacheinander rein:

uint8_t ersterWert = uart_getc();
uint8_t zweiterWert = uart_getc();
uint8_t dritterWert = uart_getc();
uint8_t vierterWert = uart_getc();

Nun würde in den o.g. Variablen folgendes stehen:
ersterWert  = 49
zweiterWert = 50
dritterWert = 51
vierterWert = 52

und kann diese dann anschließend weiterverarbeiten?

Ist das alles richtig so oder stelle ich mir das einfacher vor als es 
ist?

Liebe Grüße :)

von Thomas E. (thomase)


Lesenswert?

Sercan S. schrieb:
> Ist das alles richtig so oder stelle ich mir das einfacher vor als es
> ist?

Wenn du nacheinander einzeln die Ziffern sendest, ist das so einfach. 
Also "1", senden, "2" senden ...
Sendest du den String "1234" kommt das auch so an.

Hast du jedoch die Zahl 1234 als Intergervariable vorliegen und diese 
wird nicht in einen Dezimalstring umgewandelt, wird der Inhalt dieser 
Variable gesendet so gesendet, wie er drinsteht.

Der ist aber nicht 1234, sondern diese Dezimalzahl entspricht lediglich 
dem Inhalt der Variable. Computer wissen nämlich nicht, was 
Dezimalzahlen sind und µC schon gar nicht.

In der Variablen steht 0x04D2. Aus diesen 4 Ziffern werden ASCII-Zeichen 
gebildet, die dann auch so vom µC empfangen werden:

0x30  = '0'
0x34  = '4'
0x44  = 'D'
0x32  = '2'

Möglich ist auch, daß die führende 0 gar nicht und das 'D' als 'd' 
gesendet wird oder die Reihenfolge umgekehrt ist.

Auf jeden Fall ist die Umwandlung mit Hexzahlen einfacher.

: Bearbeitet durch User
von Sercan S. (disaster35)


Lesenswert?

@Thomas Heckmann
Also, wenn ich die Ziffern als String sende, bekomme ich beim uC beim 
uart_getc() die Zahl beispielsweise 49 für die 1.

Wenn ich 4 Ziffern als String sende sprich "1234" bekomme ich beim 
ersten lesen mit uart_getc() 49, dann beim nächsten aufruf uart_getc() 
die 50 und so weiter? Also kann ich mir das wie ein umgekehrtes Stack 
vorstellen, wobei ich beim lesen jeweils den nächsten Ziffer bekomme bis 
nichts mehr vorhanden ist?

und wenn ich es als Integer sende, sprich 1234 bekomme ich beim ersten 
einlesen die 0 als erstes, dann die 4, D, 2 jeweils beim einlesen.
Die ASCII 39 (HEX 30) sprich 0 steht am Anfang ja dafür, dass ich weiß 
das es eine positive Zahl ist oder (ich erinnere mich an so etwas aus 
der Schulzeit noch). Würde da die 0 am Anfang nicht stehen, wäre es ja 
statt eine positive (1234) Zahl, eine negative (-1234) Zahl.


Stimmt das soweit? Verstehe ich das richtig?

von Sascha W. (sascha-w)


Lesenswert?

Sercan S. schrieb:
> @Thomas Heckmann
> Also, wenn ich die Ziffern als String sende, bekomme ich beim uC beim
> uart_getc() die Zahl beispielsweise 49 für die 1.
ja
> Wenn ich 4 Ziffern als String sende sprich "1234" bekomme ich beim
> ersten lesen mit uart_getc() 49, dann beim nächsten aufruf uart_getc()
> die 50 und so weiter? Also kann ich mir das wie ein umgekehrtes Stack
> vorstellen, wobei ich beim lesen jeweils den nächsten Ziffer bekomme bis
> nichts mehr vorhanden ist?
ja, man sendet in der Regel noch ein CR (0x13) oder was anderes was in 
den Daten selbst nicht vorkommen kann als Kennzeichen für das Ende einer 
Übertragung

> und wenn ich es als Integer sende, sprich 1234 bekomme ich beim ersten
> einlesen die 0 als erstes, dann die 4, D, 2 jeweils beim einlesen.
> Die ASCII 39 (HEX 30) sprich 0 steht am Anfang ja dafür, dass ich weiß
> das es eine positive Zahl ist oder (ich erinnere mich an so etwas aus
> der Schulzeit noch). Würde da die 0 am Anfang nicht stehen, wäre es ja
> statt eine positive (1234) Zahl, eine negative (-1234) Zahl.

Du kannst ein INT senden, das sind 16Bit also 2Byte, mit MSB-First wird 
im 1.Byte 0x04 übertragen im 2.Byte 0xD2,

Oder du überträgst den Wert als Text aber wandelst ihn vorher in 
Hexadezimale Schreibweise um, bei deinem 1.Beispiel hast du den INT ja 
in Text in dezimaler Schreibweise.
Die Hex-Schreibweise vereinfacht auf dem μC die Konvertierung zurück in 
einen INT

In Hexadezimaler Schreibweise gibt es keine Negativen Werte, negative 
Werte werden im binärsystem im 2'er Komplement gespeichert.
Bei einem INT
0 dez 0x0000 hex
1 dez 0x0001 hex
-1 dez 0xffff hex

Sascha

: Bearbeitet durch User
von Sercan S. (disaster35)


Lesenswert?

Okay, damit ich das alles besser verstehe. Sollte ich am besten üben und 
ausprobieren.

Ich habe mir zur Testzwecken jetzt ein USB-UART Konverter geholt:
http://www.ebay.de/itm/152255441128?_trksid=p2057872.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

Ich denke mal das sollte ausreichen um vom Hyper-Terminal aus die 
Ziffern zu senden und mal in String und Integervariante auszuprobieren.

von Thomas E. (thomase)


Lesenswert?

Sercan S. schrieb:
> Stimmt das soweit? Verstehe ich das richtig?

Bis auf das mit den Vorzeichen, das hat Sascha ja schon erklärt, ist das 
richtig.

Ob die führende 0 mitgesendet wird oder nicht, ist für den Zahlenwert 
egal.

Es kommt darauf an, wie der Integerwert in einen String umgewandelt 
wird. Werden führende Nullen nicht mitgesendet, ist die Länge des 
übertragenen Strings von der Größe der Zahl abhängig. Das erfordert 
immer eine Terminierung. Werden führende Nullen mitgesendet, ist die 
Länge bei gleichen Variablentypen immer gleich. Das erfordert nicht 
unbedingt eine Terminierung.

: Bearbeitet durch User
von M. Н. (Gast)


Lesenswert?

Sercan S. schrieb:
> Aus der Schul/Studiumszeit weiß ich noch, dass der
> Paritätstbit je nach Anzahl der Nullen oder Einsen 0 oder 1 wird. Bsp.:
> Wir haben ein Paritätstcheck nach den Einsen, würden 4 Einsen ein
> Paritätsbit von 0 ergeben, da 4 eine gerade Anzahl von Einsen sind.

Er scheint mir, als ob du da etwas durcheiander bist. Kann aber sein, 
dass ich das nur falsch verstanden habe.

Ein Paritätsbit geht in der Regel immer nach den Einsen. Es gibt Odd 
(Ungerade) und Even (gerade) Parität. Bei Even Parität, wird das 
Paritätsbit so gesetzt, dass die Gesamtanzahl der Einsen im Wort gerade 
ist. Bei Odd dementsprechend ungerade. Hast du also eine gerade Parität 
und dein Wort weißt 5 Einsen auf, so ist das Paritätsbit 1, um eine 
gerade Anzahl zu erreichen.

Sercan S. schrieb:
> Aber um die Parität muss ich mich ja nicht kümmern oder? Da ich aus dem
> GCC-Tutorial nichts darüber finden konnte, gehe ich davon aus, dass es
> vom BT-Modul selbst übernommen wird und erst nach erfolgreicher
> Paritätscheck beim Mikrocontroller etwas ankommt?

Das Blutooth Modul wird kaum seine eigene Parität überprüfen. Die 
Parität wird vom Sender gesetzt und vom Empfänger verifiziert. Sie ist 
dafür da, den Übetragungskanal, die serielle Schnittstelle, zu sichern. 
Welchen Sinn macht es, die Parität in ein und dem selben Chip zu 
generieren und zu verifizieren?
Natürlich kann der AVR die Parität in Hardware überprüfen bzw. beim 
Senden selbstständig setzen. Er wirft einen Fehler/Interrupt, wenn ein 
falsches Frame empfangen wird. Dazu einfach einen Blick ins Datenblatt 
werfen.

von Eric B. (beric)


Lesenswert?

Thomas E. schrieb:
> Hast du jedoch die Zahl 1234 als Intergervariable vorliegen und diese
> wird nicht in einen Dezimalstring umgewandelt, wird der Inhalt dieser
> Variable gesendet so gesendet, wie er drinsteht.

So weit, so gut.

> Der ist aber nicht 1234,

Doch!

> In der Variablen steht 0x04D2.

Was auch nur die hexadezimale Repräsentation der Zahl 1234 ist.
Egal ob ich 1234, 0x04D2 oder gar 0b0000010011010010 schreibe, es ist 
und bleibt die Zahl Eintausend-zweihunderd-vierunddreißig. Wie diese 
Zahl übertragen wird, hängt voll und ganz davon ab wie der Sender das 
definiert!

Der Sender kann z.B. senden:
- Eine tekstuelle Repräsentation der dezimale Darstellung:
  "1234" (oder 0x31, 0x32, 0x33, 0x34, mit oder ohne abschießendes 0x00)

- Eine tekstuelle Repräsentation der hexadezimale Darstellung:
  "04D2" (oder 0x30, 0x34, 0x44, 0x32, mit oder ohne abschießendes 0x00)

- der direkte binäre Wert (also nicht tekstuell):
  0x04, 0xD2

- der direkte Wert als 32-bit Wert mit Least-Significant-Byte first:
  0xD2, 0x04, 0x00, 0x00

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.