-
16bit UART Übertragung
Hallo Community,
Auf Empfehlung sponsere ich dem Thema einen eigenen Thread^^
mein Vorhaben ganz simpel: eine Zahl (16bit) soll in 2x(8bit) zerlegt werden und via UART auf einen zweiten µC gesendet und auf einer 7-Segment LED-Anzeige ausgegeben werden.
Mit einer 8-bit Zahl habe ich die Ansteuerung des 7-Segment Displays getestet um dies schonmal abzuhaken in seiner Funktion.
Problem ist, wenn ich eine 16-bit Zahl (hier 6789) sende, gibt die LED-Anzeige lauter Zufallszahlen aus und wechselt hin- und her.
Ich stehe mit meiner Programmiererfahrung noch ziemlich am Anfang und habe versucht eine Lösung zu finde, jedoch ohne Erfolg. Ich poste die wichtigen Ausschnitte meines Codes (unwichtiges rausgelöscht) was das Senden und Empfangen angeht, wäre nett wenn mir einer helfen kann (ist ja bestimmt nichts großes) :)
SENDEN
Code:
.
.
.
.
uint16_t zahl=6789;
uint8_t HByte;
uint8_t LByte;
void daten_senden (uint8_t data)
{
while (!(UCSRA & (1<<UDRE))){} //warten bis senden möglich ist
UDR = data; //Zeichen in den Ausgabepuffer schreiben
}
void usart_init (void)
{
UCSRB |= (1<<TXEN); //Daten senden
UCSRC = (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1); // Asynchron 8N1
UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;
}
int main(void)
{
usart_init();
while (1)
{
HByte = (zahl >> 8);
LByte = zahl & 0xff;
daten_senden(HByte);
daten_senden(LByte);
}
}
EMPFANGEN
Code:
.
.
.
uint16_t zahl;
uint8_t usart_empfang;
void usart_init (void)
{
UCSRB |= (1<<RXEN) |(1<<RXCIE) ; //Daten empfangen und Interrupt für Datenempfang enable
UCSRC = (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1); // Asynchron 8N1
UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;
}
ISR(USART_RXC_vect)
{
usart_empfang = UDR;
}
int main(void)
{
usart_init();
sei();
while (1)
{
uint8_t HByte = usart_empfang;
uint8_t LByte = usart_empfang;
zahl = (((uint16_t) HByte) << 8 ) | LByte;
zahl_ausgeben(zahl);
}
}
-
welche µCs programmierst du?
Ich habe perfekt funktionierenden UART-Code in C/C++ (synchron, quasi per handshake), sowohl für Arduino-Arduino als auch Raspi-Arduino.
Arduino- und Raspi Codes sind fast 100% identisch, da ich nicht auf die super-speziellen Arduino-libs zugreife:
Arduino-Arduino
http://www.mindstormsforum.de/viewto...tart=15#p67476
Raspi-Arduino
http://www.mindstormsforum.de/viewto...p=67907#p67815
-
AVR ;)
Du kannst mir deinen Code ja trotzdem mal schicken, vlt. erkenne ich den Fehler denn komme einfach nicht drauf.
Wäre nett, danke.
Edit: habe die Links jetzt auch gesehen danke :D bin für jeden Tipp dankbar...
-
ps, lass dich von den Arduino-Display-Treibern nicht verwirren, ich musste den Code so schreiben, dass er mit verschiedenen TFTs und ihren libs funktioniert.
-
Hallo,
das Problem ist wohl eher, dass hier nicht wirklich synchronisiert wird.
Die beiden Mikrocontroller starten sicher nicht gleichzeitig in die int main und schon kann es passieren, dass der Empfänger z.B. ein Byte hinterher "hinkt".
Auch bei dieser Konstruktion
Code:
uint8_t HByte = usart_empfang;
uint8_t LByte = usart_empfang;
hab ich so meine Bedenken. Ja, die globale Variable usart_empfang wird in der ISR gesetzt.
Aber wie wird sichergestellt, dass genau in dem passenden Moment auch das nächste Byte vom Sender kommt?
Es kann hier passieren, dass zweimal das gleiche Byte abgespeichert wird, weil einfach das Timing nicht hinhaut.
Überlege gerade, ob man usart_empfang nicht sogar als volatile deklarieren sollte...
Probiere es mal mit Byte pollen an dieser Stelle.
Und überlege dir was zur Synchronisation.
Wenn der Empfänger "irgendwann" einliest, kann er am Datenstrom nicht erkennen, wo die most und least significant bytes sind.
Aber keine Panik, das bekommst du sicher hin. So wild ist das nicht ;)
Grüße,
Bernhard
-
seltsam ist schon, dass du beide Bytes getrennt sendest, so kommen sie sicher verzögert an.
Besser wäre es schon mal, einen Byte-Array zu senden.
Außerdem ist UART extrem fehleranfällig. Daher verwende ich ein Start-sync-byte und eine checksum, um sicher zu sein, dass auf beiden Seiten der selbe Array rein und wieder raus kommt.
- - - Aktualisiert - - -
aaahh, haha, hat sich überschnitten... ;)
-
Ich dachte (uSart s=synchron), dass die Synchronisierung der AVR selbst regelt.
Ok ich muss mich erstmal einlesen, was man unter Byte pollen versteht... an der Stelle sei erneut betont, mein Wissen ist eher dies eines Anfängers^^
-
jo, ich weiß wohl, warum ich Arduinos und Raspis verwende ;)
-
Ich glaube ich bin im falschen Forum ;)
-
nee, wenn dann hast du eher den falschen µC ;)
wie schon in meinem eigenen Topic geschrieben:
"funktioniert auch sehr schnell, dabei scheint die Display-Ausgabe auf dem Arduino zu Debug-Zwecken noch am meisten die UART-comm auszubremsen....
Die Display Ausgabe muss künftig unbedingt als eigener Task per Multitasking (Arduino Due: <Scheduler.h> ) laufen !!"
- - - Aktualisiert - - -
böde "Powered by Google"-Reklame immer ! :(