Serielle Daten Senden von mehr als 2 Byte

OP #4040816
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
}
#4040820
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
...
#4040830
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
}
Gast #4040872
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.
OP #4040890
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.
OP #4040909
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
#4040919
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 ;-)
Gast #4040970
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.
Gast #4040985
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.
Gast #4041024
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

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.