Forum: Mikrocontroller und Digitale Elektronik Serielle Daten Senden von mehr als 2 Byte


von A. R. (and)


Lesenswert?

Hallo,

ich möchte gerne eine Integer Zahl die gröer als 255 spricht mehr als 
2Byte hat über UART senden.

Ich Schreibe die Zaheln über eine Varibale und einen Aufruf in das UDR 
register. Ist der Wert kleiner 256 spricht hat nur zwei Byte kommen die 
entsprechend beim Empfänger an.
Ist die Zahl größer 255 also 3 Byte so kommen beim Empfänger (HTERM) nur 
die letzten beiden Stellen Hexadezimal an.

Beispiel:
Sende: 99 (INT) Empfänger: 63 (HEX)
Sende: 255 Empfänger: FF
Sende: 300 Empfänger: 2C statt 12C
Sende: 1222 Empfänger: C6 statt 4C6

Controller: Atmega 1284P

1
........
2
3
int uart_putc (int16_t sende) {
4
    while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
5
    {
6
    }                             
7
 
8
    UDR0 = sende;                      /* sende Zeichen */
9
    return 0;
10
}
11
 
12
.........
13
14
int main (void) {  
15
16
int16_t s1=0, s2=0, s3=0, s4=0;
17
uart_init();
18
19
    while (1){
20
  
21
        s1 = 99;        
22
23
        uart_putc (s1);
24
    }
25
....
26
}

von Karl H. (kbuchegg)


Lesenswert?

A. R. schrieb:

> int uart_putc (int16_t sende) {

Das kannst du dir gleich wieder abschminken.
Über die UART geht 1 Byte raus. 1 Byte und nicht mehr als 1 Byte.

Wenn du mehr Bytes brauchst, dann musst du eben uart_putc mit den 
entsprechenden EInzelteilen entsprechend oft aufrufen.

Du gibst ja auch einen String (Text) so aus, dass du nacheinander 
Buchstabe für Buchstabe ausgibst. Das ist hier auch nicht anders.

1
...
2
         uart_putc (s1 & 0xFF);   // zuerst das Low-byte
3
         uart_putc (s1 >> 8 );    // dann das High-byte
4
...

von Karl H. (kbuchegg)


Lesenswert?

Daher baut man sich vernünftigerweise auch ein paar Hilfsfunktionen, die 
einem das immer gleiche Aufbrechen in die einzelnen Bytes zentralisieren 
und abnehmen

zb:
1
// Ausgabe eines Textes
2
void uart_puts( const char* txt )
3
{
4
  while( *txt )
5
    uart_putc( *txt++ );
6
}
7
8
// Ausgabe einer Zahl in Textform
9
void uart_puti( int16_t zahl )
10
{
11
  char txt[8];
12
13
  itoa( txt, zahl, 10 );
14
  uart_puts( txt );
15
}

oder eben bei dir
1
// Ausgabe einer Zahl in binärer Form (2 Bytes)
2
void uart_puti_bin( int16_t zahl )
3
{
4
  uart_putc( zahl );
5
  uart_putc( zahl >> 8 );
6
}

von n.b. (Gast)


Lesenswert?

A. R. schrieb:
> ich möchte gerne eine Integer Zahl die gröer als 255 spricht mehr als
> 2Byte hat über UART senden.

Dir ist schon klar, dass 2 Byte für den Zahlenraum bis 65535 ausreicht 
und dass ein UART nur einzelne Bytes versenden kann. Guck mal in ein 
Datenblatt von einem µC, der ein UART hat.

von A. R. (and)


Lesenswert?

Mit 4Byte HEX bekomm ich auch Zahlen bis 65535 dargestellt.
Wenn ich jetzt eine 2Byte Zahl, also bis 255 in das UDR lade wie in 
meinem Quelltext wird das auch korrekt übertragen.
Ich hääte jetzt gerne aber meine Zahl größer 255 als HEX gesendet. So 
das ich den z.B. in Hterm eine "12C" für meine Zahl 300 erhalte.

von Karl H. (kbuchegg)


Lesenswert?

A. R. schrieb:
> Mit 4Byte HEX bekomm ich auch Zahlen bis 65535 dargestellt.

Das kommt jetzt drauf an.
4 Bytes binär oder 4 Zeichen (also in Textform)?

Binär brauchst du für unsigned Zahlen bis 65535 nur 2 Bytes. Denn genau 
so gross ist ein uint16_t: 2 Bytes.

von vloki (Gast)


Lesenswert?

Ich glaube da ist was durcheinander geraten ;-)

Ein "Hex Zeichen" in HTerm entspricht nur 4 Bit.
x12C ist eigentlich "x012C" oder b0000 0001 0010 1100

von A. R. (and)


Lesenswert?

Karl Heinz schrieb:
> ...
>          uart_putc (s1 & 0xFF);   // zuerst das Low-byte
>          uart_putc (s1 >> 8 );    // dann das High-byte
> ...

Habe jetzt das veruscht und festgestellt das es in etwas ander 
Reihenfolge funktioniert:

So bekomme ich jetzt in meienr Endhardware richtig angezeigt:
1
    uart_putc (s1 >> 8 );    // dann das High-byte
2
    uart_putc (s1 & 0xFF);   // zuerst das Low-byte

von vloki (Gast)


Lesenswert?

oder anders gesagt - in einem Byte stecken zwei Hex-Zeichen

von vloki (Gast)


Lesenswert?

A. R. schrieb:
> abe jetzt das veruscht und festgestellt das es in etwas ander
> Reihenfolge funktioniert:

http://de.wikipedia.org/wiki/Byte-Reihenfolge
(ich habe es jetzt nicht gelesen, aber wird vermutlich schon halbwegs 
stimmen)

von Karl H. (kbuchegg)


Lesenswert?

A. R. schrieb:
> Karl Heinz schrieb:
>> ...
>>          uart_putc (s1 & 0xFF);   // zuerst das Low-byte
>>          uart_putc (s1 >> 8 );    // dann das High-byte
>> ...
>
> Habe jetzt das veruscht und festgestellt das es in etwas ander
> Reihenfolge funktioniert:

:-)

Ja ja, die Endianess.

Wie ich immer sage:
Wenn es 2 Möglichkeiten gibt, dann hat man eine 80% Chance sich zuerst 
für die Falsche zu entscheiden ;-)

von A. R. (and)


Lesenswert?

Karl Heinz schrieb:
> Wenn es 2 Möglichkeiten gibt, dann hat man eine 80% Chance sich zuerst
> für die Falsche zu entscheiden ;-)

wie berechnet man das ??? ;)

von Volker S. (vloki)


Lesenswert?

A. R. schrieb:
> wie berechnet man das ??? ;)

Empirisch, oder über den Empirismus ;-)

von Karl H. (kbuchegg)


Lesenswert?

A. R. schrieb:
> Karl Heinz schrieb:
>> Wenn es 2 Möglichkeiten gibt, dann hat man eine 80% Chance sich zuerst
>> für die Falsche zu entscheiden ;-)
>
> wie berechnet man das ??? ;)

Formel nach Murphy
http://de.wikipedia.org/wiki/Murphys_Gesetz

auch bekannt als die 'Karl Heinzsche Gleichverteilung'

von Volker S. (vloki)


Lesenswert?

Karl Heinz schrieb:
> Formel nach Murphy

Müssten es dann nicht 100% sein ?

Egal, 20% Optimismus kann ja nicht schaden ...

von Karl H. (kbuchegg)


Lesenswert?

Volker SchK schrieb:
> Karl Heinz schrieb:
>> Formel nach Murphy
>
> Müssten es dann nicht 100% sein ?
>
> Egal, 20% Optimismus kann ja nicht schaden ...

Ja, so bin ich halt. Immer optimistisch.

Der Wikipedia Eintrag ist fad. Der hier ist besser
http://murphyslaws.net/german.htm

von n.b. (Gast)


Lesenswert?

A. R. schrieb:
> Mit 4Byte HEX bekomm ich auch Zahlen bis 65535 dargestellt.

Das was du da als HEX bezeichnest, ist eine Textdarstellung. Dir 
scheinen noch ein paar Grundlagen zu Binärzahlen und deren Darstellung 
zu fehlen.

Mit n Byte kannst du den Zahlenraum von 0 bis 2^(8*n)-1 abbilden.

von dummschwaetzer (Gast)


Lesenswert?

> So bekomme ich jetzt in meienr Endhardware richtig angezeigt:
>
>    uart_putc (s1 >> 8 );    // dann das High-byte
>    uart_putc (s1 & 0xFF);   // zuerst das Low-byte

mit Sicherheit nicht! Mit s1 >> 8 shiftest du deine unteren 8Bit ins 
nirvana.

von Tom Thomsen (Gast)


Lesenswert?

dummschwaetzer schrieb:
> mit Sicherheit nicht! Mit s1 >> 8 shiftest du deine unteren 8Bit ins
> nirvana.

... deshalb auch High-Byte ;-)

von Karl H. (kbuchegg)


Lesenswert?

dummschwaetzer schrieb:
>> So bekomme ich jetzt in meienr Endhardware richtig angezeigt:
>>
>>    uart_putc (s1 >> 8 );    // dann das High-byte
>>    uart_putc (s1 & 0xFF);   // zuerst das Low-byte
>
> mit Sicherheit nicht! Mit s1 >> 8 shiftest du deine unteren 8Bit ins
> nirvana.

Jep. Das ist auch so gewollt.

von A. R. (and)


Lesenswert?

Funktioniert aber einwandfrei so wie ich es gemacht habe.
Habe kompletten WErtebereich bis 65.000 getestet. und gerade läuft 
dauertest

von Karl H. (kbuchegg)


Lesenswert?

A. R. schrieb:
> Funktioniert aber einwandfrei so wie ich es gemacht habe.

Das passt schon.

> Habe kompletten WErtebereich bis 65.000 getestet. und gerade läuft
> dauertest

:-)
Das eigentliche Problem kommt noch.

von dummschwaetzer (Gast)


Lesenswert?

Karl Heinz schrieb:
> Jep. Das ist auch so gewollt.

Das must du mir erklären:
Zerstöre durch shiften das low-byte, das vorherige high-byte ist das 
neue low-byte
sende dieses low-byte
verodere das low-byte mit FF
sende es noch mal

mit
So bekomme ich jetzt in meienr Endhardware richtig angezeigt:

    uart_putc (s1 >> 8 );
    uart_putc (s1 & 0xFF);

sendet nur das high-byte von s1 doppelt

von Volker S. (vloki)


Lesenswert?

dummschwaetzer schrieb:
> Zerstöre durch shiften das low-byte, das vorherige high-byte ist das
> neue low-byte

Da steht nicht s1 = s1 >> 8 !

von dummschwaetzer (Gast)


Lesenswert?

danke

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.