PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RS232 seltsames Verhalten....



pete1612
17.04.2012, 17:36
Hallo,
mal wieder ein kleines RS232-Problem über das ich seit zwei Tagen brüte...
Über einer Konsolenanwendung in C (selbsterstelltes Programm in CodeBlocks) sende ich Zeichen, Bytes und Strings zu meinem Mikrocontroller.
Der Mikrocontroller ist in Bascom programmiert, tut aber eigentlich nichts weiter zur Sache.
In dem C Programm gebrauche ich die Header-Datei rs232.h.
Kleines Schema der Programms, das auf dem PC arbeitet:



#include "rs232.h"
int main(){
unsigned char zeichen;
int COM=2; *\Entspricht COM3\*
if(OpenComport(COM,19200)){
printf("COM3 nicht erreichbar!");}
else{
printf("COM3 aktiv!");}
printf("Bitte ein zu sendendes Zeichen eingeben: ");
fflush(stdin);
scanf("%c",&zeichen);
SendByte(COM,zeichen);
printf("\n");
}


So in etwa sieht das PC-Programm aus.

Das µC-Programm (eigentlich mit LCD Display) in BASIC als Schema:



$baud=19200
Dim Empangen as Byte
Cls
Locate 1,1
Lcd "Empangen:"
Do
If Ischarwaiting() = 1 Then
Empangen = Inkey()
Locate 2,1
Lcd Empangen
Loop
End


Folgendes Problem habe ich:

Wenn ich den USB/RS232-Wandler in den USB-Port einstecke und dann ein Zeichen von meinem C-Programm in den µC schicken möchte erscheint auf meinem LCD-Display immer eine 0
nachdem ich das Zeichen gesendet habe. Das heißt ja eigentlich, dass mein µC etwas empfangen hat, das aber nur eine 0 ist, die aus dem Puffer geholt wurde.
Das Problem habe ich solange, bis ich ein Zeichen über das RS232-Terminal in Bascom sende. Egal ob ich eine 0,1,2,3.... sende, nachdem ich über das Terminal ein Zeichen versandt habe, kann ich auch über mein C-Programm ein Zeichen senden, welches dann korrekt auf dem LCD erscheint.
Nach einem Neustart des Controllers bleibt das immernoch so. Wenn ich allerdings den USB/RS232 Adapter entferne und neu einstecke, kommt das selbe Problem wieder bis ich ein Zeichen über das Terminal sende.
Ich hab so viel probiert...Hat jemand eine Idee was das ist???

Danke! =)

pete1612
17.04.2012, 22:22
Niemand eine Idee? =(

Thomas E.
17.04.2012, 22:59
Ganz schnell geschossen:


$baud=19200
Dim Empangen as Byte
Cls
Locate 1,1
Lcd "Empangen:"
Do
If Ischarwaiting() = 1 Then
Empangen = Inkey()
Locate 2,1
Lcd Empangen
End If
Loop
End

pete1612
17.04.2012, 23:10
Danke =)
Aber abgesehen von den eingefügten Leerzeichen im If/Then Zweig ist das doch das gleiche Programm...Was meinst du damit?
Gruß,
Peter

Thomas E.
17.04.2012, 23:15
Danke =)
Aber abgesehen von den eingefügten Leerzeichen im If/Then Zweig ist das doch das gleiche Programm...Was meinst du damit?
Nein, ich habe per End If die von dir geöffnete If-Bedingung geschlossen. Mich wundert, dass dein Compiler nicht gemeckert hat...
;)

pete1612
17.04.2012, 23:30
Nein, nein.... =) Ich habe den Code in der Pause von der Firma aus aus dem Kopf abgetippt...Dumm, dass mir so ein Fehler unterlaufen ist..
Das End If ist natürlich mit im Code drin.. Wie gesagt, wenn ein Zeichen vom Terminal-Programm aus (also quasi per Hand) eingetippt wird, dann klappt es danach auch mit dem normalen von mir programmierten C-Programm auf dem Rechner...Bis man dann halt den USB/RS232-Adapter wieder vom Rechner trennt und neu aufsteckt...
Sendet denn ein Terminal-Programm beim ersten Mal eine besondere Zeichenfolge oder eine Art Konfiguration..Weil mein C-Programm sendet ja nur die nackten Bytes...

Thomas E.
17.04.2012, 23:37
Na dann... ;)


Sendet denn ein Terminal-Programm beim ersten Mal eine besondere Zeichenfolge oder eine Art Konfiguration..Weil mein C-Programm sendet ja nur die nackten Bytes...
Soweit ich weiß nicht.

pete1612
17.04.2012, 23:49
Morgen früh wollte ich mir mal einen zweiten USB/RS232-Adapter besorgen und dann einmal versuchen zwei virtuelle COM-Schnittstellen an meinem PC einzurichten.
Dann öffne ich zwei Terminal-Programme und sende Daten von dem Einen zum Anderen (COM3 zu COM4) und dann auch mal mit meinem Programm...
Vielleicht gibt mir das Aufklärung...wenn es denn funktioniert mit den USB-Adaptern wie ich das vorhabe...
Es sei denn jemand hat noch eine Idee. Das wäre echt toll...ist aber scheinbar ein Fehler, den scheinbar nur wieder ich habe =)
Oder es liegt an dem Header rs232.h . Aber dann hätten ja schon Andere so ein Problem gehabt...

pin117
18.04.2012, 05:08
Klingt als fehlt Deinem Csharp Sender ein EOL?! (0x0d)

pete1612
18.04.2012, 12:14
Hey,
das EOL-Zeichen wird bei meinem C-Programm gar nicht verwandt, da es ja auch keinen Zeilenumbruch erzeugt.
Was du sagst ist schon richtig, denn wenn das EOL-Zeichen nicht gesendet wird, dann kann auch eine INPUT-Anweisung in Bascom nicht erfüllt werden,
da dieser Befehl auf EOL wartet bis das Programm im Controller weiterläuft. Mit EOL hatte ich also auch anfangs in einem anderen Programm Probleme.
Danke trotzdem für deine Anregung.
Ich habe mir einen zweiten USB/RS232-Adapter besorgt und einmal versucht eine Verbindung aufzubauen.
Vorgehensweise:
-Einstecken beider Adapter in die USB-Ports.
-Mein C-Programm sucht sich selbstständig nach dem Start den ersten freien COM-Port (COM3)
-Im üblichen Windows-Hyperterminal erstelle ich eine Kommunikation über COM4
-Über das C-Programm versende ich ein Zeichen (z.B. 1,2,5,g,d,h,i, usw.) und bestätige die Eingabe mit Enter um scanf zu befriedigen.
-Im Hyperterminal kommt nichts an.
-Ich schließe das C-Programm und öffne das Terminal in BASCOM mit Kommunikation über COM3.
-Ich tippe auf der Tastatur auf eine Taste (z.B. 1,2,3, usw.). Bestätigung mit Enter ist hier nicht erforderlich.
-Das Zeichen wird anstandslos im Hyperterminal angezeigt.
-Ich öffne nun mein C-Programm und es wird wie zuvor COM3 erkannt.
-Ich tippe ein Zeichen ein und bestätige die Eingabe mit Enter.
-Das Zeichen erscheint wundervoll in Hyperterminal.

Von nun an funktioniert die Kommunikation wunderbar.
Bis ich dann den Konverter wieder vom USB-Port trenne und neu aufstecke...
Ich stehe immernoch vor einem Rätsel...
Kennt jemand vllt ein Terminal-Programmm, dass auch unsichtbare Zeichen wie z.B. das 0x0d nach dem Empfang anzeigt?
Ich bin mir fast sicher, dass so ein doofes Zeichen bei der ersten Übertragung gesendet wird, welches mein C-Programm nicht sendet.
Oder spricht das Terminal in Bascom die serielle Schnittstelle anders an????

pin117
18.04.2012, 14:26
Mich wundert dabei eher, dass Dein Terminal irgendetwas anzeigt, denn eigentlich ist ein ECHO an der Stelle sonderbar.

Aber auch Dein COM-Port scheint etwas durcheinander zu sein. Hast Du mal die USB-Treiber geupdatet?

Bezüglich der Anzeige von Antworten würde ich auch grundsätzlich kein Terminal nutzen sondern möglichst in Deinem CProg immer die Werte Prüfen. Am einfachsten im Debuggermode mit Haltepunkten und dann alles anzeigenlassen (hex etc).

Gerade das BASCOM sendet 2 Bytes EOLs (und CR oder so) soweit ich mich erinnere. Das kann evt zu Problemen führen.

pete1612
18.04.2012, 17:30
Okay... da hast du mich leider missverstanden. Bei Eingabe des Zeichens in das Terminal sehe ich das eingegebene Zeichen nicht in dem Terminal, wo ich es eingegeben habe. Das Zeichen sehe ich auf dem Terminal, das meinen COM-Port überwacht, an den ich das Zeichen schicke. Ein Echo gibt es dabei nicht...

Bezüglich der Anzeige von Antworten würde ich auch grundsätzlich kein Terminal nutzen sondern möglichst in Deinem CProg immer die Werte Prüfen. Am einfachsten im Debuggermode mit Haltepunkten und dann alles anzeigenlassen (hex etc).

Top! Gute Idee! Darauf bin ich noch gar nicht gekommen... Ich kann also einfach ein zweites Programm in C schreiben, welches dann die gesendeten Daten von meinem eigentlichen C-Programm empfängt...
Du meinst dann z.B. so:


#include rs232.h
int main(){
char incoming[10]={NULL};
int COM=3;
while(OpenComport(COM,19200)==0){
printf("Zeichen empangen....\n");
PollComport(COM,&incoming,sizeof(incoming-1));
printf("Empangenes Zeichen in hexadezimal: %x\n\n",incoming);
}
}

So sollte ich doch auch alle übertragenen Zeichen sehen können, oder???
Also auch 0x0d, etc.

Danke für Eure Hile!!! =)

pete1612
18.04.2012, 23:16
Hallo,
nach endloser googlei habe ich wenige Beiträge gefunden in denen Leidensgenossen ähnliche Probleme wie ich hatten.
Der Fehler liegt nicht am übertragenen Zeichen sondern schlichtweg an der Initialisierung des COM-Ports beim ersten Benutzen.
Mit OpenComport(COM,19200) ist es dann doch nicht getan. Das System möchte gerne noch Informationen bez. Parity,StopBits,zu übertragene Bits, etc haben.
Die rs232.h unterstützt solche Funktionen nicht, da gesagt wird, dass die Header das System automatisch auf den Standard einteacht. (8 Bits, no parity, 1 stopbit).
Die Windows-Library verfügt doch sicher über solch eine Funktion... Wie bekomme ich heraus, welche Funktion das ist und wie ich sie anwende...
Ich habe iwas gelesen von GetCommDCB(), aber mein Compiler erkennt die Funktion nicht, trotz windows.h .
Langsam wird es lästig, dabei wollte ich doch NUR einen COM in mein System einbinden.

Bitte, ich bin um jede Hilfe dankbar! Und wenn es nur Anhaltspunkte sind....

PicNick
19.04.2012, 07:43
"IScharwaiting()" funktioniert nur sinnvoll, wenn auch "config serialin=buffered" angegeben ist.
Hast du das ?

pin117
19.04.2012, 13:05
Wenn Du es Dir leicht machen willst. Ich verwende diese fertige Cpp-Klasse für die Kommunikation der RS232: http://www.hackchina.com/en/cont/16482

Sie lässt sich sehr leicht einbinden und bedienen, ist aber c++. Vielleicht trotzdem hilfreich für Dich?!

PS: Du brauchst aus dem Zip im Prinzip nur die Serial.cpp und Serial.h - der Rest hilft zum testen

Einbindung:
#include "Serial.h"
CSerial MySerial;
...
//Call
MySerial.Open(4,38400); // COM,Boud

CString test = "xyz";
MySerial.SendData(test,test.GetLength());

char EOL[] = {0x0d};
MySerial.SendData(EOL,1); // Für BASCOM
MySerial.Close();

Im Serial.cpp wird dann bei Bedarf noch 8N1 umgestellt, ist aber default 8N1
wsprintf( szComParams, "COM%d:%d,n,8,1, nPort,nBaud);

Lesen dann respektive> int CSerial::ReadData(void xbuffer, int limit);

Auf share würde ich den COM-Port nicht stellen, sondern wie gesagt in Deinem Programm die Ausgabe anzeigen lassen - notfalls im Debugger. Also ohne zusätzliches Terminal Programm.

pete1612
19.04.2012, 17:28
Danke Dir pin, nett dass du mir den Vorschlag machst!
Ich habe den Fehler gefunden! Und jetzt wird es interessant: Der Fehler lag weder an meinem Programm, noch an meinem µC oder am Terminal oder iwelchen Zeichen, die nicht gesendet werden.
Achtung:
Mit rs232.h bekommt man eine wirklich ausreichende Library+Header für die Ansteuerung der COM. Sehr einfach und daher leicht anzuwenden.
ABER: Die Initalisierung des Ports klappt nicht, denn in der rs232.c - Datei, die von rs232.h verwendet wird und die Funktionen enthält, steckt ein Bug!
Der Fehler steckt zw. Zeile 280 und 300, bei der Definition der Funktion int OpenComport(COM,baud)
Hab gerade die Datei nicht zur Hand, da ich nicht zuhause bin, aber hier ein ungefährer Auszug:


/*GANZ VIEL CODE/*
if(OpenComport(com,baud)){
printf("unable to open comport");
return(1);}
else{
return(0);}
/*GANZ VIEL CODE/*

Das return(0) muss weg!!!
Wenn das weg ist, dann wird die Funktion auch weiter abgearbeitet und nicht kurz vor BuildCommDCBA() abgebrochen.

Naja =) Jetzt klappts!

Danke euch allen!!!

pin117
19.04.2012, 17:32
Das return(x) ist ja nur für die Fehlerbehandlung in Deinem Call. Also der Rückgabewert, mit dem Du prüfen kannst, ob OpenComport(com,baud) geklappt hat oder nicht. Wenn er 0 postet, dann weil es nicht geklappt hat. Wenn Du die 0 löscht klappt es aber immer noch nicht bzw. macht die nichts, ausser Dich informieren?!?