16bit USART Übertragung auf 7-Segment

OP #4546019
Hallo Community,

leider stoße ich bei der Übertragung einer 16bit Zahl via. USART an 
meine Grenzen was die Fehlersuche angeht.

Ich möchte von einem ATMega8 zu einem anderen ATMega8 eine 16bit große 
Zahl senden, um diese auf einer 4-stelligen 7-Segment-Anzeige anzeigen 
zu lassen.
Ich hatte zunächst davon gelesen, dass man (da der USART nur 8bit 
überträgt) die 16bit Zahl in 2*8bit aufteilt, was ich nun schon den 
ganzen Tag lang versuche, es mir aber nicht gelingt, da auf der Anzeige 
nur wirre Zustände abgebildet werden.

Die Übertragung via USART in 8bit hatte ich erfolgreich hinbekommen, 
also sowohl 7-Segment-Ansteuerung als auch Zahlenabbild via USART 8bit 
hat funktioniert.

Im Anhang ist mein Code zum SENDEN und EMPFANGEN. (Code ist auf den 
USART beschränkt... die USART Settings und andere Funktionen der 
7-Segment Ansteuerung sind der Übersichtlichkeit wegen entfernt)

Ich bin über jeden Tipp dankbar.
Gast
Wie synchronisiert sich Deine Übertragung? Woher weiß der Empfänger, ob 
jetzt gerade Highbyte oder Lowbyte kommt?

Du solltest Dir Gedanken über ein Protokoll für die Übertragung machen.
Hallo!

Du gehst bei dieser Übertragung davon aus das kein Störzeichen 
hinzukommt bzw. kein Zeichen verschluckt wird. Wenn z. B. beim 
Initialisieren des Empfängers ein Byte in das Empfangsregister gerät 
werden bei allen weiteren Übertragungen High- und Low-Byte vertauscht. 
Du solltest also besser eine Übertragungsart wählen bei der man das 1. 
Byte jedes Datenpakets erkennen kann, z. B. indem du die 16 Bit auf 3 
Bytes verteilst und dann z. B. im ersten Byte zusätzlich das oberste Bit 
setzt. Damit kann man dann beim Empfang das erste Byte eines neuen 
Wertes korrekt erkennen.
Gast
Außerdem wäre noch zu fragen, ob Du Deine Zahl für die Anzeige 
aufbereitet hast. In welcher Darstellung (binär, BCD, ...) kommt sie in 
Dein Programm? In welcher Darstellung (Kodierung) wird sie dem LCD/LED 
geschickt?
Schau her, wie Microsoft das in den 80'ern gelöst hat mit ihren Mäusen. 
Eine serielle Microsoft-Maus überträgt regelmäßig zwei 8 Bit Werte plus 
zwei Tastenwerte an den Rechner.

http://paulbourke.net/dataformats/serialmouse/

Es wird ein 7-Bit Datenformat verwendet und pro Paket drei Zeichen 
gesendet. Beim ersten Zeichen ist Bit 6 auf 1 - damit weiß der PC, dass 
das der Anfang eines Pakets ist. Die anderen beiden Bytes haben Bit 6 
auf 0.

Ich empfehle Dir, 2 Stop-Bits zu verwenden, das kann die Zuverlässigkeit 
bei der Synchronisation erhöhen. Und/oder zwischen zwei Paketen 
mindestens 11-Bitzeiten Zeit zu lassen.

fchk
OP
Bei dem Beispiel mit der Microsoft-Maus:


/*
   s should consist of 3 bytes from the mouse
*/
void DecodeMouse(unsigned char *s,int *button,int *x,int *y)
{
   *button = 'n'; /* No button - should only happen on an error */
   if ((s[0] & 0x20) != 0)
      *button = 'l';
   else if ((s[0] & 0x10) != 0)
      *button = 'r';
   *x = (s[0] & 0x03) * 64 + (s[1] & 0x3F);
   if (*x > 127)
      *x = *x - 256;
   *y = (s[0] & 0x0C) * 16 + (s[2] & 0x3F);
   if (*y > 127)
      *y = *y - 256;
}



Kann mir jemand erklären, was die Sternchen vor den Variablen zu 
bedeuten haben?
@ Markus Eff (opc)

/*
   s should consist of 3 bytes from the mouse
*/
void DecodeMouse(unsigned char *s,int *button,int *x,int *y)
{
   *button = 'n'; /* No button - should only happen on an error */
   if ((s[0] & 0x20) != 0)
      *button = 'l';
   else if ((s[0] & 0x10) != 0)
      *button = 'r';
   *x = (s[0] & 0x03) * 64 + (s[1] & 0x3F);
   if (*x > 127)
      *x = *x - 256;
   *y = (s[0] & 0x0C) * 16 + (s[2] & 0x3F);
   if (*y > 127)
      *y = *y - 256;
}


>Kann mir jemand erklären, was die Sternchen vor den Variablen zu
>bedeuten haben?

Das hat 2 Bedeutungen.

void DecodeMouse(unsigned char *s,int *button,int *x,int *y)

*s ist ein Zeiger auf ein char Array.
*button ist ein Zeiger auf ein int Array.
*y ist ein Zeiger auf ein int Array.

*button = 'l';

Dereferenzierung. Der INHALT, auf den button zeigt, wird auf '1' 
gesetzt.
Gast
Um 16bit UInt über USART zu senden mach ich immer ein Bitshift in ein 
Char-Array und wieder zurück:

Zum empfangen z.b.:
1
uint16_t dataL1;
2

3
dataL1 = uart_string[0] + (uart_string[1]<<8);

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.