Forum: Compiler & IDEs ATmega128 UART bidirektionale Kommunikation (UC=Slave)


von Patrick B. (p51d)


Lesenswert?

hallo miteinander

Ich habe seit neustem ein Projekt übernommen, an dem ich jetzt schon 1 
Tag lang herumgebastelt habe, wie es mit der UART aussieht.

Die Grundidee:
-Ein Linux-Server sendet über RS232 steuerbefehle
-MCU gibt Register (32bit) zurück
-Mögliche Steuerbefehle: read, write, reset
=> nach write sollten 32Bit übertragen werden, vom MCU in eine Variable 
übernommen und dann weiter im Programm

Die ganze Kommunikation sollte über Hex-werte laufen :
1) 01 => write
2) FFFFFFFF => register
3) 03 => ok (vom mcu)

Bis jetzt läuft mehr oder weniger das senden, aber das empfangen noch 
gar nicht.

hier ist der code:
1
//USART
2
UBRR0H = (unsigned char)(ubrr>>8);            //Set baud rate 
3
UBRR0L = (unsigned char)ubrr;
4
UCSR0B = (1<<RXCIE0)|(1<<RXEN)|(1<<TXEN);        //Enable receiver and transmitter 
5
UCSR0C = (1<<USBS)|(1<<UCSZ01)|(1<<UCSZ00);      //Set frame format: 8data, 2stop bit 
6
7
void USART_Transmit(unsigned char data){          //Senden-Funktion mit Variable
8
  while (!( UCSR0A & (1<<UDRE0))){}  //Wait for empty transmit buffer
9
  UDR0 = data;    //Put data into buffer, sends the data 
10
}
11
ISR(USART0_RX_vect){    //RS232 Receive
12
  receive = UDR0;    //Take data of buffer
13
}

1. Problem: wie kann ich machen, dass senden/empfangen via hex-werte 
funktioniert?
2. Problem: funktioniert das überhaupt? 32Bit über uart oder muss ich 4 
mal 8 bit senden?
3. Gibt es etwas, dass ich unbedingt beachten sollte?

Ich wäre froh, wenn jemand meinen Code rasch verifizieren könnte und 
eventuell noch tips für das Hex-Problem hat.

Danke im foraus für die Hilfe
P51D

von gast (Gast)


Lesenswert?

der uartbuffer ist nur 8 bit breit
ebenso sendet jede uart RS232 nur 8bit daten

wenn du 32bit senden oder empfangen willst musst du ein paket schnüren
wie das paket aussieht musst du dir überlegen oder von einer anwendung 
übernehmen

da das senden klappt wie du sagst is das schonmal ok

ISR(USART0_RX_vect){    //RS232 Receive
  receive = UDR0;    //Take data of buffer
}

hier landen die daten zwar in einer variable receive ... aber dann ???
man sollte hier die daten in einen buffer werfen

wenn du von ausgehen kannst maximal 32bit zu erhalten sollte ein 
buffer[4] reichen
wenn nun was im buffer steht
also buffer[0] != '/0'
vergleichst du es mit den werten auf die du reagieren willst
is nix dabei ...  buffer[0] = '/0'

wenn nun im buffer[0] == 0xFF steht ..
und in den nächsten auch ... dann haset dein FF FF FF FF  gefunden

wenn da 0x01 steht ...eben write erkannt
wenn da 0x03 steht  war es ein OK

usw ,,,




entsprechend auswertung starten und buffer leeren für neue daten

von gast (Gast)


Lesenswert?

korrektur ,,, uart kann 7-9 bits senden ^^
normal sinds eben 8 ...

aber 32er oder mehr muss man als paket schnüren

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Der Code zeigt lediglich die Low-Level-Routinen für UART-Init, 
UART-Sendeeinzeichen und UART-Empfangsinterruptroutine.

Es fehlt der komplette High-Level Code also die Abwicklung des eigenen 
Protokolls.

1. Sorry, das ist mir zu umfangreich.

2. 4 mal 8 bit ist richtig, wenn du den 32-Bit Wert binär 
transportierst. Du kannst auch 8 mal 8 Bit senden, wenn du den 32-Bit 
Wert in ASCII Form transportierst.

3. Gehe nicht davon aus, dass du eine fehlerfreie Übertragung hast. Mach 
dein Protokoll so stabil, dass die Telegramme (write, register, ok) auf 
Vollständigkeit und Korrektheit geprüft werden können. Verwende 
eindeutige Start und Endezeichen für dein Telegramm, die in der Nutzlast 
(register) nicht vorkommen können. Bsp. wenn du register in ASCI 
überträgst, sind nur die Zeichen 0123456789ABCDEF möglich und es müssen 
8 Stück sein. Diese Zeichen sollten beim Start/Endezeichen nicht 
vorkommen. Bei binärem Versand ist die Beschränkung der Zeichen schlecht 
möglich. Vermeide bestimmte binäre Steuerzeichen, die bei fehlerhaft 
eingestelltem RS232 Kanal die Übertragung stoppen (Software-Handshake 
XON/XOFF). Verwende nach Mäglichkeit keine Zeichen mit gesetztem 8. Bit.

von Patrick B. (p51d)


Lesenswert?

erstmals danke für eure Antworten.
das Empfangs-Problem habe ich mittlerweile gelöst, wenn auch nicht 
wirklich:
Bis jetzt verwendete ich ein normales Terminal, bei dem ich zwar 
umstellen konnte ob ich ASCII oder Hex-Werte empfange, aber beim Senden 
wusste ich nicht, was es war. Heute hatte ich Docklight installiert und 
siehe da, es funktionierte.

@"gast"
ich hatte das mir in etwa so vorgestellt, dass receive als buffer dient. 
Die 32Bit werden dann über schiebebefehle zusammengesetzt. Aber 
irgendwie passt mir deine Variante besser. Sie scheint mir etwas 
sicherer zu sein, es können keine Daten verlohren gehen, durch verfühtes 
überschreiben von receive.

@Stefan B.
ZITAT:
1
Der Code zeigt lediglich die Low-Level-Routinen für UART-Init,
2
UART-Sendeeinzeichen und UART-Empfangsinterruptroutine.
Das ist beabsichtigt so, denn ich habe im main nur noch auf receive 
abgefragt, ob es != 0 ist, und dann ein Port gesetzt. Banal, aber 
effektif.

ZITAT:
1
Sorry, das ist mir zu umfangreich.
Kein Problem, es läuft ja mitlerweile.
Zu 2) Was macht mehr sinn? ASCII oder Hex Werte? Man muss beachten, dass 
das ganze von einem Linux server gestuert wird(Consolen-Aufbau)

ZITAT:
1
...fehlerfreie Übertragung hast...stabil...auf
2
Vollständigkeit und Korrektheit geprüft werden können
Fehlerfrei wird es nicht immer laufen, ist auch meine Ansicht.
stabil?? wie kann ich die Übertraung stabiler machen?
Eine Überprüfung fand ich auch sinfoll, da es recht viele Daten sind. 
Das Paritätsbit ist mir allerdings zu ungenau. Da dachte ich mir, dass 
ich nach empfangen der Daten vom Rechner gleich alles zurückschicke, 
damit der PC die Werte überprüfen kann. Beim senden des 
Registerzustandes werde ich wohl 2 mahl den Wert senden.

ZITAT:
1
Vermeide bestimmte binäre Steuerzeichen, die bei fehlerhaft
2
eingestelltem RS232 Kanal die Übertragung stoppen (Software-Handshake
3
XON/XOFF)
Das verstehe ich nicht. könntes du mir das erklähren?


Nochmals danke für eure Hilfe. Ich werde nächste woche mal schauen, ob 
ich noch etwas am Projekt machen kann...
MFG
Patrick

von Karl H. (kbuchegg)


Lesenswert?

Patrick B. schrieb:

> Zu 2) Was macht mehr sinn? ASCII oder Hex Werte? Man muss beachten, dass
> das ganze von einem Linux server gestuert wird(Consolen-Aufbau)

Das ist nicht das entscheidende Kriterium.
Entscheidend ist, welche Vorgaben hast du in Bezug 
Übertragungsgeschwindigkeit. In dem einen Fall überträgst du einen Wert 
in 4 Bytes im anderen Fall in 8 Bytes, also doppelt so lange.
Wenn das kein Problem darstellt, würde ich auch zu ASCII raten.

Mit Binärzahlen, in denen grundsätzklich jedes Byte vorkommen kann, ist 
es schwierig ein zuverlässiges Protokoll hinzubekommen. Mit ASCII ist 
das leichter, weil du dir selbst die Synchronisierzeichen aussuchen 
kannst (=deine Steuerbuchstaben). Das Problem ist vom Schwierigkeitsgard 
analog zu: Du hebst den Telefonhörer ab und platzt mitten in ein 
Gespräch, mitten in ein Wort hinein. Deine Aufgabe ist es jetzt aus dem 
Buchstabensalat den Beginn des nächsten Wortes, des nächsten Satzes 
herauszufiltern. Ohne spezielle Zeichen im Datenstrom geht das aber so 
gut wie gar nicht.


> Fehlerfrei wird es nicht immer laufen, ist auch meine Ansicht.
> stabil?? wie kann ich die Übertraung stabiler machen?

Indem man ein Protokoll entwirft, welches es auch verkraftet, wenn das 
Kabel einfach abgezogen und wieder angesteckt wird.

> Da dachte ich mir, dass
> ich nach empfangen der Daten vom Rechner gleich alles zurückschicke,
> damit der PC die Werte überprüfen kann.

Eine Checksumme mitschicken tuts auch.

> ZITAT:
1
> Vermeide bestimmte binäre Steuerzeichen, die bei fehlerhaft
2
> eingestelltem RS232 Kanal die Übertragung stoppen (Software-Handshake
3
> XON/XOFF)
4
>
> Das verstehe ich nicht. könntes du mir das erklähren?

Im ASCII Code wird für jeden möglichen (7-Bit) Byte Wert ein Zeichen 
definiert. Da gibt es zb das Zeichen 'A' oder 'Z' oder '0' oder '%'. Es 
gibt aber auch spzielle Zeichen, die die Übertragung selbst steuern 
können. Der eine Partner kann zb zum anderen das Zeichen XOFF schicken, 
um ihn auzufordern mit dem Senden kurzzeitig aufzuhören.
Google nach Software Handshake.

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.