Hallo zusammen,
ich habe ein Problem, was die serielle Kommunikation zwischen den beiden
o.g. Devices angeht. Es geht darum, eine (zuverlässige) Kommunikation
zwischen PC und µC herzustellen.
Generell scheint die Kommunikation auch recht gut zu funktionieren. Ich
teste das ganze mit Hilfe von Abfragen und Reaktionen darauf. Z.B: µC
wartet auf Daten. Ich kann quasi 2 Befehle vom PC auf den µC senden. Die
Befehle heißen "increment" und "decrement". Je nach Befehl führt der µC
dann unterschiedliche Anweisungen durch und sendet einen aktuellen Wert
an den PC zurück, z.B. "2000". Mein Problem ist, dass an dem Port immer
komische Daten anliegen.
Lustigerweise scheinen immer dieselben falschen Datenstrings anzukommen,
wenn ich einen gewissen Befehl verwende. Das erste Bild zeigt die
Fehlerhaften Daten, die ankommen, wenn ich den Befehl "increment" zum µC
schicke.
Wenn ich den Befehl "decrement" sende, erscheinen die fehlerhaften Daten
im 2. Bild.
Ich verstehe nicht, woher diese fehlerhaften Daten kommen. Meine Idee
war, dass der PC sich irgendwie selbst Daten sendet??
Die Befehle "increment" und "decrement" werden tatsächlich richtig vom
µC verarbeitet, das konnte ich beim Debuggen feststellen.
Aber woher kommen diese komischen Daten? Die Frage konnte ich mir bisher
nicht erklären. Die Parameter zur seriellen Kommunikation sind auf PC
und µC identisch.
//EDIT: Vielleicht noch als wichtige Info: Nach einem Neustart des µC
wird dieser neu initialisiert und sendet am Ende der Initialisierung die
Information "Init complete". Diese Daten werden immer richtig gelesen.
Die fehlerhaften Daten treten erst danach auf.
//
Ich hänge mal meinen Code zum initialisieren des Ports auf dem PC an.
1
intserialCommunication::serialInit(void){
2
3
//non overlapped communication
4
hComm=CreateFile(gszPort.c_str(),
5
GENERIC_READ|GENERIC_WRITE,
6
0,
7
0,
8
OPEN_EXISTING,
9
0,
10
0);
11
12
if(hComm==INVALID_HANDLE_VALUE){
13
cout<<"Error opening port."<<endl;
14
return0;
15
}
16
else{
17
cout<<"Opened Port successfully."<<endl;
18
}
19
20
if(SetCommMask(hComm,EV_RXCHAR)==FALSE){
21
cout<<"Error setting communications mask."<<endl;
22
return0;
23
}
24
else{
25
SetCommMask(hComm,EV_RXCHAR);
26
cout<<"Communications mask set successfully."<<endl;
Alex K. schrieb:> Aber woher kommen diese komischen Daten?
Wie sieht denn die Beschaltung und die Masseführung aus?
Dieser Kommentar im Code gibt mir zu denken:
> Delete last sign in buffer, otherwise one "0" too much shows up
Warum das?
Ein solcher "Workaround" ist immer ein Zeichen dafür, dass da noch was
faul ist...
> Ich verstehe nicht, woher diese fehlerhaften Daten kommen.
Hast du ein Oszilloskop? Oder einen Logikanalyzer? Damit könntest du mal
feststellen, ob die Bytes tatsächlich auf der RXD-Leitung des PC
auftauchen.
Martin schrieb:> Wie sieht denn der Code aufm dem Controller aus?> Funktioniert ein Loopback?
Die loop für die Abfrage der Daten ist folgende:
BEim Debuggen konnte ich wie schon erwähnt feststellen, dass der
COntroller tatsächlich auch in die If- Schleifen von "increment" und
"decrement" reinspringt und die Befehle ausführt.
m.n. schrieb:> Nimm mal einen anderen STM32.
Das Problem ist, dass es sich um ein ganzes, fest verbautes Board
handelt. Mal sehen, ob ich eins auftreiben kann
Auch wenn du sagst, die Paramter sind gleich, sieht das für mich rein
optisch erstmal nach falscher Baudrate aus.
Vielleicht ist diese im Init ja noch anders, das seh ich hier nicht.
Lässt sich wohl zu 100% nur mit dem Oszi klären.
Okay,
vielen Dank erstmal für eure Hilfe! Das Problem lag wirklich am µC....
Ich habe es an 2 anderen µC's ausprobiert und das Programm funktioniert
bisher fehlerfrei. Vielleicht ist an dem einen Board intern was falsch
verbunden gewesen. Sorry, dass ich das nicht zuerst probiert habe, bevor
ich den Thread hier eröffnet habe.
Nico W. schrieb:> buf[0] = '\0';> Löscht sicher nicht den kompletten Buffer.
Könnte man das in diesem Zusammenhang vielleicht noch klären? Ich dachte
mir das so, dass, falls mal irgendwelche Daten im Buffer übrig geblieben
sind, ich den Buffer lieber nochmal nach jedem Befehl von Hand
zurücksetze. Habe die Zeile, die du zitierst hast, jetzt mal
auskommentiert und du hast Recht damit, dass das gar nicht den
gewünschten Effekt hat. Bzw. scheint die Zeile vollkommen überflüssig zu
sein
Alex K. schrieb:> Generell scheint die Kommunikation auch recht gut zu funktionieren.> Wenn ich den Befehl "decrement" sende, erscheinen die fehlerhaften Daten> im 2. Bild.>> Ich verstehe nicht, woher diese fehlerhaften Daten kommen. Meine Idee> war, dass der PC sich irgendwie selbst Daten sendet??> Die Befehle "increment" und "decrement" werden tatsächlich richtig vom> µC verarbeitet, das konnte ich beim Debuggen feststellen.>> Aber woher kommen diese komischen Daten?
es ist gut das zu ergründen (zu wollen) aber wenn man es nicht ergründen
kann, und sonst alles funktioniert, wie wäre es mit einfach ignorieren?
Ich prüfe alles was kommt
1. auf isprint und/oder nach Bedarf
isalnum, isalpha, isascii, isblank, iscntrl, isdigit, isgraph, islower,
isprint, ispunct, isspace, isupper, isxdigit
passt es nicht oder ich brauche es nicht wird es ignoriert, alles kann
man nicht ergründen, solange es trotzdem fehlerfrei funktioniert was man
möchte....
Die gezeigten Zeichen passen ja auch nicht zu "increment" und
"decrement"
also unwichtig, ich vergleiche meine commands auch und was der µC nicht
kennt wird verworfen
Joachim B. schrieb:> also unwichtig, ich vergleiche meine commands auch und was der µC nicht> kennt wird verworfen
Das wird für mich wohl auch der richtige Ansatz sein, da ich nicht zu
100% durchblicke, was PC und µC zu welchem Zeitpunkt genau machen.
Alex K. schrieb:> Joachim B. schrieb:>> also unwichtig, ich vergleiche meine commands auch und was der µC nicht>> kennt wird verworfen>> Das wird für mich wohl auch der richtige Ansatz sein, da ich nicht zu> 100% durchblicke, was PC und µC zu welchem Zeitpunkt genau machen.
so auch bei meinem AVR Webserver NETIO, manchmal reagiert er nicht mehr,
ABER
er ist immer ansprechbar per RS232, dann schicke ich "reset", er
antwortet mit "eset" oder "unbekannter Befehl" es ist also was im Buffer
angekommen was er nicht versteht!
wenn ich dann noch mal "reset" schicke startet er halt neu und ist
wieder ansprechbar.
Ich sollte noch eine kill buffer Routine einbauen bei derlei Unsinn im
Buffer, aber es eilt ja nicht :)
Alex K. schrieb:> Nico W. schrieb:>> buf[0] = '\0';>> Löscht sicher nicht den kompletten Buffer.> Könnte man das in diesem Zusammenhang vielleicht noch klären? Ich dachte> mir das so, dass, falls mal irgendwelche Daten im Buffer übrig geblieben> sind, ich den Buffer lieber nochmal nach jedem Befehl von Hand> zurücksetze.
Mit diesem Befehl "löschst" du nur das erste Zeichen vom Puffer (wobei
"löchen" hier eigentlich auch falsch ist, denn da wird nur an die erste
Zelle der Strinterminator 0 geschrieben).
Wenn du da im Puffer sonst nichts zurücksetzt (z.B. mit memset(buf,0);),
dann muss nur irgendwer in diese erste Speicherzelle irgendwas ungleich
0 reinschreiben und auf wunderbare Weise "erscheint" der gelöscht
geglaubte Pufferinhalt wieder...