Probleme beim öffnen der Seriellen Schnittstelle mit C++



  • Hi,

    ich bin gerade halb am Verzweifeln,
    ich versuche die Serielle Schnittstelle zum lesen und schreiben zu öffnen.
    Überall im Netz wo ich suche finde ich nur den Quelltext welchen ich auch mehr oder weniger verwende, nur leider Funktioniert die Funktion GetCommState() nicht. Ebenso auch SetCommState() nicht 😞
    Hier mal ein Auszug des Quellcodes in dem ich nur erstmal Versuche mit GetCommState() die derzeitigen Parameter auszulesen.

    OS: WinXP 32bit
    IDE: Bloodshed dev c++

    #include <iostream>
    #include <windows.h>
    #include <stdio.h>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
    
        HANDLE hPort;
        hPort == CreateFile("COM1",
                            GENERIC_READ | GENERIC_WRITE,
                            0,
                            0,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL,
                            0);
    
        if (hPort == INVALID_HANDLE_VALUE)
        {
                  cout << "Konnte Port COM1 nicht öffnen"<<endl;
        }else {   cout << "Port COM1 offen"<<endl;}
    
        DCB PortDCB;
        PortDCB.DCBlength = sizeof(DCB);
        if (!GetCommState(hPort, &PortDCB))   // Hier springt er immer in die FALSE Schleife
        {cout << "GetCommState fehlgeschlagen"<<endl;};                                                         
    
        cout << "DCBlength: "<<PortDCB.DCBlength<<endl;
        cout << "BaudRate: "<<PortDCB.BaudRate<<endl;
        cout << "StopBits: "<<PortDCB.StopBits<<endl;
        cout << "Parity: "<<PortDCB.Parity<<endl; 
        CloseHandle(hPort);
        system("PAUSE");
        return EXIT_SUCCESS;
    
    }
    

    Hab den Port und das Kabel mit nem fertigen Terminal Prog getestet, alles i.O. kann den Port öffnen, Baudrate einstellen und auch Daten senden.
    Also HW Probs schließe ich deswegen aus.

    Irgendwas is in meinem Quelltext madig ....

    Vielen Dank schonmal für eure Hilfe
    Alm





  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum Rund um die Programmierung in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Vieleleicht hilft das auf 0 setzen der Struktur?

    memset(&PortDCB, 0, sizeof(DCB));
    PortDCB.DCBlength = sizeof(DCB);
    

    Und immer schön GetLastError() ausführen, damit du mitbekommst warum etwas fehlschlägt.
    Das kannst du dir generell mal merken, meist erübrigt sich dann ein Post hier, da du selbern auf die Lösung kommst.



  • hPort=CreateFile(...) //=, nicht ==
    

    Du hat ein doppeltes Gleichheitszeichen verwendet (also verglichen und nicht zugewiesen)...

    EDIT: Bei solchen Fehler empfiehlt es sich, einfach mal als Debug zu kompilieren, dann sollte der Compiler mindestens eine Warnung raushauen (Variable benutzt, aber nicht initialisiert).



  • Du hat ein doppeltes Gleichheitszeichen verwendet (also verglichen und nicht zugewiesen)...

    Jup, mist das wars ... Danke.
    Da stiert man ewig auf den Quelltext und vergleicht im Netz mit anderen und sieht sowas nich 😞

    Und immer schön GetLastError() ausführen, damit du mitbekommst warum etwas fehlschlägt.
    Das kannst du dir generell mal merken, meist erübrigt sich dann ein Post hier, da du selbern auf die Lösung kommst.

    werd ich mir merken ^^

    Dev C++ ist veraltet!

    Danke Rüdiger für deine Meinung.

    An den Rest viel dank für das lesen meines Probs ...



  • Nochmal eine Frage,
    vielleicht kann die mir einer beantworten.

    Nach dem ich GetCommState() ausgeführt habe,
    kann ich mit diesen Befehlen

    cout << "DCBlength: "<<PortDCB.DCBlength<<endl;
        cout << "BaudRate: "<<PortDCB.BaudRate<<endl;
        cout << "StopBits: "<<PortDCB.StopBits<<endl;
        cout << "Parity: "<<PortDCB.Parity<<endl;
    

    Leider nur PortDCB.DCBlength und PortDCB.BaudRate auslesen.
    Die Parität und Anzahl der STopbits ist leer.

    Kann man diese Werte nicht auslesen?

    Danke schonmal
    Alm



  • almighty667 schrieb:

    Die Parität und Anzahl der STopbits ist leer.

    Was heißt denn für dich leer? Steht da jeweils ne 0 drin? Vielleicht heißt das auch einfach nur, dass keine Parität und 0 Stopbits eingestellt sind...





  • Was heißt denn für dich leer? Steht da jeweils ne 0 drin? Vielleicht heißt das auch einfach nur, dass keine Parität und 0 Stopbits eingestellt sind...

    nee .. leer heißt leer, 0 ist ja nicht leer 😉
    also es kommt garnix...

    Bnutze die, die läuft: http://www.codeproject.com/KB/system/serial.aspx

    Ok danke, werde die Bibliothek mal antesten.



  • almighty667 schrieb:

    Was heißt denn für dich leer? Steht da jeweils ne 0 drin? Vielleicht heißt das auch einfach nur, dass keine Parität und 0 Stopbits eingestellt sind...

    nee .. leer heißt leer, 0 ist ja nicht leer 😉
    also es kommt garnix...

    Um wirklich zu sehen, welchen Wert eine Variable hat, solltest du den Debugger benutzen, da kannst du es dann sehen. Eine int-Variable kann nicht leer sein, sobald sie existiert. Irgendwas steht immer an der Stelle im Speicher. Sie kann höchstens nicht initialisiert sein, so dass quasi ein zufälliger Wert drin steht. Ich fänd es aber sehr komisch, wenn GetCommState da nichts 'reinschreibt...

    Also: was heißt "es kommt gar nix"? Wie überprüfst du das?



  • Also: was heißt "es kommt gar nix"? Wie überprüfst du das?

    Also überprüfen tu ich es eigentlich nicht,
    ich lass mir den Wert eben nur ausgeben wie du im Quelltext siehst.
    Und bei der Ausgabe kommt eben nix Anzeigbares, bleibt quasie schwarz auf der konsole ...

    Aber ich hätte eben erwartet das man da Zeichenketten auslesen kann,
    immerhin setzt man ja auch Zeichenketten (wie NOPARITY, ONESTOPBIT, etc)

    Ich hab die GetCommState() Funktion jetzt 2 mal in meinem Code,
    Einmal gleich am ANfang, dann die SetCommState() und dann nochmal die GetCommState().

    Und was ich sehe ist eben das er mir die Baudrate sehr schön Anzeigt, vorher liest er 1200 aus, dann setz ich auf 115200, und dann kann ich diesen wert auch schön auslesen.

    Eine int-Variable kann nicht leer sein, sobald sie existiert.

    Was für ein Variablen Typ das is weiß ich nicht genau, da das Array ja durch die DCB Struct irgendwie erzeugt wird

    #include <iostream>
    #include <windows.h>
    #include <stdio.h>
    
    using namespace std;
    //##############Globale Deklerationen##########################################
    HANDLE hPort;
    //##############Funtionsblock##################################################
    
    int openPort()
    {hPort = CreateFile("COM1",
                            GENERIC_READ | GENERIC_WRITE,
                            0,
                            0,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL,
                            0);
    
        if (hPort == INVALID_HANDLE_VALUE)
        {
                  cout << "Konnte Port COM1 nicht öffnen"<<endl<<endl;;
        }else {   cout << "Port COM1 offen"<<endl<<endl;;}
    
        DCB PortDCB;
        PortDCB.DCBlength = sizeof(DCB);
        if (!GetCommState(hPort, &PortDCB))
        {cout << "GetCommState fehlgeschlagen"<<endl;}                                                         
    
        cout << "Originale Port Config:"<<endl;
        cout << "====================="<<endl;
        cout << "BaudRate: "<<PortDCB.BaudRate<<endl;
        cout << "ByteSize:"<<PortDCB.ByteSize<<endl;
        cout << "Parity: "<<PortDCB.Parity<<endl; 
        cout << "StopBits: "<<PortDCB.StopBits<<endl<<endl;
    
        PortDCB.BaudRate=  CBR_115200;
        PortDCB.ByteSize=  8;
        PortDCB.Parity=    NOPARITY;
        PortDCB.StopBits=  ONESTOPBIT;
    
        if(!SetCommState(hPort, &PortDCB))
        {cout<<"Setzen der Port Werte Fehlgeschlagen"<<endl;}
        else{
             if (!GetCommState(hPort, &PortDCB))
             {cout << "GetCommState fehlgeschlagen"<<endl;}
             else{
                  cout << "Neu gesetzte Port Config:"<<endl;
                  cout << "====================="<<endl;
                  cout << "BaudRate: "<<PortDCB.BaudRate<<endl;
                  cout << "ByteSize:"<<PortDCB.ByteSize<<endl;
                  cout << "Parity: "<<PortDCB.Parity<<endl; 
                  cout << "StopBits: "<<PortDCB.StopBits<<endl<<endl;
                  }  
             }
    }
    
    //############################################################################
    //####################### M A I N  ANWEISUNGSBLOCK ###########################
    //############################################################################
    
    int main(int argc, char *argv[])
    {
    
        openPort();
        CloseHandle(hPort);
        system("PAUSE");
        return EXIT_SUCCESS;
    
    }
    

    irgendwie kann ich hier kein Bild einfügen, deswegen würd ich sagen,
    probier einfach mal den obigen Code aus.



  • Dein Problem ist, dass in der DCB-Struktur Parity und StopBits vom Typ BYTE (unsigned char) sind. Wenn du diese Werte nun mit cout ausgeben willst, dann werden sie als Zeichen (weil Typ char) interpretiert (0 ist kein druckbares Zeichen, daher siehst du nix). Tatsächlich steht (bei mir, bei dir wahrscheinlich auch) sowohl in Parity als auch in StopBits der Wert 0. Das bedeutet kein Paritätsbit und ein Stopbit (ONESTOPBIT, was du verwendest, ist übrigens mit 0 definiert, nicht mit 1, wie man annehmen könnte).

    Wenn du einfach den Inhalt der Variablen in deiner Ausgabe sehen willst, dann kannst du nach int casten:

    cout << "StopBits: "<<(int)PortDCB.StopBits<<endl<<endl;
    

    Sinnvoller wäre aber eine Fallunterscheidung, die berücksichtigt, was sich hinter den Werten versteckt:

    cout << "StopBits: ";
    	switch(PortDCB.StopBits) {
    		case ONESTOPBIT:
    			cout << "1";
    			break;
    		case ONE5STOPBITS:
    			cout << "1.5";
    			break;
    		case TWOSTOPBITS:
    			cout << "2";
    			break;
    		default:
    			cout << "invalid value";
    	}
    	cout<<endl<<endl;
    

    Das ist übrigens ein schönes Beispiel dafür, warum es manchmal einfach sinnvoller ist, sich die tatsächlichen Werte von Variablen im Debugger anzusehen (Haltepunkt setzen, schrittweise ausführen, per Tooltip oder im Überwachungsfenster Werte anschauen).


Anmelden zum Antworten