Forum: Mikrocontroller und Digitale Elektronik 16bit USART Übertragung auf 7-Segment


von Markus E. (opc)



Lesenswert?

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.

von UART (Gast)


Lesenswert?

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.

von Heiko G. (heikog)


Lesenswert?

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.

von UART (Gast)


Lesenswert?

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?

von Frank K. (fchk)


Lesenswert?

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

von Markus E. (opc)


Lesenswert?

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?

von Falk B. (falk)


Lesenswert?

@ 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.

von rung. (Gast)


Lesenswert?

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

Die sind nur zur Verzierung.

Alternativ: Lese ein C-Buch.

von Wolfgang (Gast)


Lesenswert?

Frank K. schrieb:
> Und/oder zwischen zwei Paketen mindestens 11-Bitzeiten Zeit zu lassen.

Der Fall "Und" ist Zeitverschwendung.

von Draco (Gast)


Lesenswert?

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);

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.