Problem serielle Schnittstelle

Gast #2441010
Lesenswert?

Hi,

ich habe ein merkwürdiges Problem mit meiner seriellen Schnittstelle.
Nachdem mein PC hochgefahren ist, muss ich immer einmal Hyperterminal 
starten, damit mein C++ Programm funktioniert. Dann funktioniert aber 
mein C++ programm solange bis ich den PC neu starte. Daher vermute ich, 
dass es am Init der Schnittstelle liegt.

Meine Init (aus dem C++ Forum):
1
bool CSERIELL::Init(int iPort=3, int iBaud=9600, int iSize=8, int iParity=0, int stopbit=1, int fRtsControl=0, int iTimeout=0, int iTotalTimeout=0)
2
{
3
    char port[]= "COM0123456789:";          
4
    sprintf(port, "COM%i:", iPort);
5
           
6
    m_hPort = CreateFile(   port,
7
        GENERIC_READ | GENERIC_WRITE,
8
        0,
9
        NULL,
10
        OPEN_EXISTING,
11
        FILE_ATTRIBUTE_NORMAL,
12
        NULL);
13
    if((int)this->m_hPort == -1)         //COMx ist nicht vorhanden
14
            this->m_hPort=0;
15
    if(this->m_hPort !=0)                    
16
    {
17
        COMMTIMEOUTS comtime;  
18
        GetCommTimeouts(this->m_hPort, &comtime);
19
        comtime.ReadIntervalTimeout= iTimeout;
20
        comtime.ReadTotalTimeoutConstant= iTotalTimeout;
21
        comtime.WriteTotalTimeoutConstant= iTotalTimeout;
22
        comtime.ReadTotalTimeoutMultiplier=2;
23
        comtime.WriteTotalTimeoutMultiplier=0;
24
        SetCommTimeouts(this->m_hPort, &comtime);
25

26
        DCB dcb;           //Gerätekommunikationsanpassung
27
        GetCommState(this->m_hPort, &dcb);
28
        dcb.BaudRate= iBaud;
29
        dcb.ByteSize= iSize;
30
        dcb.DCBlength= 28;
31
        dcb.EofChar= 0;
32
        dcb.ErrorChar= 0;
33
        dcb.fRtsControl= fRtsControl;
34
        dcb.Parity= iParity;
35
        dcb.StopBits= stopbit;
36
        dcb.fInX=0;
37
        dcb.fOutX=0;
38
        dcb.fAbort O n E r r o r = 1;  //Bitte hier die leerzeichen
39
                // wegmachen. Vermutlich Bug im Forum
40
    SetCommState(this->m_hPort, &dcb);
41
    return true;

beim Hyperterminal verwende ich 9600-N-1.

gruß

evi
#2441041
Lesenswert?

evi schrieb:
> if((int)this->m_hPort == -1)         //COMx ist nicht vorhanden
>             this->m_hPort=0;
>     if(this->m_hPort !=0)
>     {

Anstelle dieser merkwürdigen Konstruktion könnte Dir,
je nach dem in welcher Umgebung du deine Objekt laufen lässt,
der folgende Code hilfreich sein:
1
  if(m_hPort == INVALID_HANDLE_VALUE)
2
  {
3
    error = GetLastError();
4
    switch(error)
5
    {
6
    case 2  : 
7
      sprintf(str,"Open(%s) not exist.\n",device); 
8
      break;
9
    case 5  : 
10
      sprintf(str,"Open(%s) Access is denied (is open).\n",device); 
11
      break;
12
    default :
13
         sprintf(str,"Open(%s) Error=0x%08lx.\n",device,error);
14
    }
15
    printf(str);
16
    return FALSE;
17
  }
Gast #2441108
Lesenswert?

hi,

danke schonmal für die ganzen antworten.

@Peter II: welche alten einstellungen meinst du?

@Volker: Habe ich probiert hat aber leider nicht geholfen :-( trotzdem 
danke.

Mit fehler meine ich: Ich schicke daten von meinem PC los, nur leider 
reagiert die Schaltung nicht. Wenn ich dann Hyperterminal starte und 
daten schicke,  kommen die bei der Schaltung an. Danach starte ich mein 
Programm wieder und dann kommen auch dessen daten an.
Wenn ich beide programm gleichzeitig starte beschweren sie sich auch, 
dass der Port schon belegt ist.

Außerdem habe ich auch nochmal deine Fehlerabfrage eingefügt, aber sie 
wird garnicht erst aufgerufen. Mein Programm scheint auch überall die 
richtigen Abzweigungen zu nehmen. Ich habe bei mir noch einige TRACE 
anweisungen eingefügt und weiß daher, dass alle Bedingungen erfüllt 
werden.

danke schonmal für die Hilfe

habt ihr noch ideen woran es liegen könnte??
#2441158
Lesenswert?

> Mit fehler meine ich: Ich schicke daten von meinem PC los, nur leider
> reagiert die Schaltung nicht.

Also das Öffnen des Ports geht ohne Fehler und Du kannst senden?
Wie hast Du das verifiziert?
Was ist der Rückgabewert von WriteFile(...) ?

Wenn du Senden kannst (im richtigen Format), liegt der Fehler nicht beim 
Öffnen des Ports.

Sicherheitshalber würde ich aber noch die beiden Funktionen
1
ClearCommError(...); PurgeComm(...);
aufrufen.

Volker
Gast #2441167
Lesenswert?

@Peter II: okay macht sinn. Leider weiß ich nicht genau, wie ich die 
Systemeinstellungen auslese (sorry bin noch anfänger). Könntest du mir 
da nochmal einen tip geben. Danke

@Dirk: ich verwende ein USB Kabel. Signalkette ist so:
PC( mit Virtual com treiber) -> USB Kabel-> ft232-> µC. Müsste 
eigentlich klappen. Ich kann ja auch daten senden, nur leider nicht von 
anfang an ;-).

@Rufus: ich habe die Zeilen von dir eingefügt. hat aber leider zu keiner 
verbesserung bei getragen.
Gast #2441220
Lesenswert?

@ Volker: also das Problem ist halt nur das sende bevor ich einmal das 
Hyperterminal gestarte habe. Einmal Hyperterminal benutzt, danach kann 
ich wieder mein c++ programm öffnen und solange und soviele daten 
schicken wie ich will. Die kommen auch richtig bei der Schaltung an.

daher gehe ich davon aus, dass das hyperterminal noch irgendwas 
einstellt oder macht, was ich vergessen habe. oder das ich an einer 
stell einen fehler habe.

Habt ihr noch irgendeine idee woran es liegen könnte?

lg evi
Gast #2441256
Lesenswert?

Wird sich schon finden ! Aber du kannst doch auch die DLL von FTDI 
benutzen dann kannste dir das Comport Progen sparen. Die hat noch 
zusätliche Features und kann zum Beispiel auch Baudraten einstellen wie 
3141592 Baud auch kann man dann das Gerät über den Namen öfnen und 
braucht sich nicht um die von Windows vergebene Commport Nummer zu 
kümmern.
http://www.ftdichip.com/Support/Documents/ProgramGuides/D2XX_Programmer%27s_Guide%28FT_000071%29.pdf
Gast #2441264
Lesenswert?

@volker: also das Programm läuft eigentlich. Nur wenn ich den Pc 
neustarte und probiere daten zu senden kommen die nicht an (schaltung 
macht nichts). Wenn ich dann Hyperterminal starte, eine Verbindung mit 
der Schaltung herstelle und danach wieder Hyperterminal beende, dann 
kann ich danach auch mit meinem c++ programm daten senden. sooft und 
solange ich will. Ich kann zwischendurch auch die Schaltung ausschalten 
und wieder an, es funktioniert immer. Wenn ich den Pc neustarte 
funktioniert es wieder nicht.

Daher denke ich, dass ich bei der Schnittstelle irgendwas vergessen habe 
zu setzen.

habe das programm im debugger laufen. werde mal gucken ob ich irgendwas 
mit breakpoints rausfinde.

habt ihr sonst noch ideen?
Persönliche Seite #2441297
Lesenswert?

evi schrieb:
> @Rufus: ich habe die Zeilen von dir eingefügt. hat aber leider zu keiner
> verbesserung bei getragen.
1
        dcb.DCBlength= 28;

Mach das weg. Das ist aus zweierlei Gründen falsch: Einerseits, was ist 
28? Andererseits ist, wenn Du vor dem Aufruf von GetCommState die 
Struktur richtig initialisierst, dieses Feld sowieso auf den korrekten 
Wert gesetzt.
Persönliche Seite #2441577
Lesenswert?

Uwe schrieb:
> Benutz die DLL

Also nicht das Problem lösen, sondern es umgehen?

Halt ich nicht für einen sinnvollen Ansatz.

evi schrieb:
> @rufus: habe ich schon nach deinem ersten beitrag gemacht.

Dann poste doch bitte mal den aktuellen Stand Deines Codes. Es ist ja 
nicht so, daß es nicht möglich ist, eine serielle Schnittstelle unter 
Windows zu nutzen, das haben schon ganz andere hinbekommen.
#2441582
Lesenswert?

und gewöhn dir an, die Returnwerte der Funktionen auszuwerten.
Wenn, wie im Falle von SetCommState die Funktion einen BOOL zurückgibt, 
dann reicht es schon, wenigstens eine MessageBox mit "Fehler" drinn 
auszugeben, wenn die Funktion FALSE liefert.

Wer Returnwerte ignoriert bzw in einer Debug Version nicht wenigstens 
meldet (und sei es nur mit einem ASSERT, so dass der Debugger stehen 
bleibt) und hinterher jammert, dass nichts funktioniert, kriegt von mir 
kein Mitleid. Er kriegt höchstens ein mitleidiges Lächeln gepaart mit 
einem "selber Schuld wenn du stundenlang Fehler suchst"
Persönliche Seite #2441676
Lesenswert?

Uwe schrieb:
> Nö ist einfach eleganter mit dll.

Ist es überhaupt nicht, weil damit nur die von der DLL unterstützten 
USB-Seriell-Bridges verwendbar sind, nicht aber serielle Schnittstellen 
allgemein.

Solange nicht irgendwelche Spezialiäten betrieben werden, die zwingend 
auf Funktionen der FTDI-Bausteine zugreifen (Auslesen der Seriennummer, 
Ansteuern der MPSSE oder Bitbanging), ist es definitiv nicht ratsam, 
die DLL zu nutzen.

Und die Hoffnung, daß der Threadstarter hier seine 
7287884731894789234ste Implementierung der Ansteuerung serieller 
Schnittstellen über die Win32-API noch richtig auf die Beine bekommt, 
die will ich noch nicht aufgeben.
Persönliche Seite #2441964
Lesenswert?

Wenn es dir nicht zu aufwendig ist, installiere doch mal die freie 
Version von Serialport Monitor und schaue mal deinem Programm und 
Hyperterminal über die Schulter.
Das hat bei mir auch schon bei manchen Problemen geholfen.
Möglich das vielleicht einfach nur was am Protokoll nicht richtig 
eingestellt ist.

Gruß Dennis

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren