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.
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.
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
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.
>Kann mir jemand erklären, was die Sternchen vor den Variablen zu >bedeuten haben? Die sind nur zur Verzierung. Alternativ: Lese ein C-Buch.
Frank K. schrieb: > Und/oder zwischen zwei Paketen mindestens 11-Bitzeiten Zeit zu lassen. Der Fall "Und" ist Zeitverschwendung.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.