Ströme lenken



  • So jetzt hab ich mir mal die Zeit genommen und die Klasse fertig geschrieben. Ich poste sie jetzt mal hier rein:

    cport.h

    #ifndef CPORT_H
    #define CPORT_H "cport.h"
    
    #include <windows.h>
    
    class ComPort
    {
    private:
       HANDLE hCom;
    public:
       enum {OFF,ON};
       enum {MAX_PORT = 6};
       enum {STATE_ERR = -3, OPEN_ERR, WRONG_PORT, COMM_OK};
    
       ComPort(void);
       ~ComPort(void);
    
       HANDLE GetHCom(void);
    
       int OpenCom(int portnr);
       void CloseCom(void);
    
       BOOL SetUART(DCB *dcb);
       BOOL SetUART(long baud, char bytes, char parity, char stopbit);
    
       BOOL SetTimeouts(COMMTIMEOUTS *timeouts);
       BOOL SetTimeouts(long interval, int multiplier, int constant);
    
       void SetDTR(int kz);
       void SetRTS(int kz);
       void SetTXD(int kz);
       void SetAll(int kz);
       void SetAll(int dtr, int rts, int txd);
    
       BOOL GetCTS(void);
       BOOL GetDSR(void);
    
       unsigned long Send(const char *text);
       unsigned long Receive(char *text, size_t maxsize);
    
       static const char *GetCP(int index);
    };
    
    #endif
    

    cport.c

    #include "cport.h"
    
    ComPort::ComPort(void)
    {
       hCom=INVALID_HANDLE_VALUE;
    }
    
    ComPort::~ComPort(void)
    {
       CloseCom();
    }
    
    HANDLE ComPort::GetHCom(void)
    {
       return hCom;
    }
    
    int ComPort::OpenCom(int portnr)
    {
       DCB dcb;
       BOOL res;
    
       if(portnr<=0||portnr>MAX_PORT)
          return(WRONG_PORT);
    
       hCom = CreateFile(GetCP(portnr-1), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
       if(hCom==INVALID_HANDLE_VALUE)
          return(OPEN_ERR);
    
       res=GetCommState(hCom, &dcb);
       if(!res)
       {
          CloseCom();
          return(STATE_ERR);
       }
    
       return(COMM_OK);
    }
    
    void ComPort::CloseCom()
    {
       CloseHandle(hCom);
       hCom=INVALID_HANDLE_VALUE;
    }
    
    BOOL ComPort::SetUART(DCB *dcb)
    {
       if(hCom!=INVALID_HANDLE_VALUE)
          return(SetCommState(hCom, dcb));
       else
          return(false);
    }
    
    BOOL ComPort::SetUART(long baud, char bytes, char parity, char stopbit)
    {
       if(hCom!=INVALID_HANDLE_VALUE)
       {
          DCB dcb;
    
          dcb.BaudRate=baud;
          dcb.ByteSize=bytes;
          dcb.Parity=parity;
          dcb.StopBits=stopbit;
    
          return(SetCommState(hCom, &dcb));
       }
       else
          return(false);
    }
    
    BOOL ComPort::SetTimeouts(COMMTIMEOUTS *timeouts)
    {
       if(hCom!=INVALID_HANDLE_VALUE)
          return(SetCommTimeouts(hCom, timeouts));
       else
          return(false);
    }
    
    BOOL ComPort::SetTimeouts(long interval, int multiplier, int constant)
    {
       if(hCom!=INVALID_HANDLE_VALUE)
       {
          COMMTIMEOUTS timeouts;
    
          timeouts.ReadIntervalTimeout=interval;
          timeouts.ReadTotalTimeoutMultiplier=multiplier;
          timeouts.ReadTotalTimeoutConstant=constant;
    
          return(SetCommTimeouts(hCom, &timeouts));
       }
       else
          return(false);
    }
    
    void ComPort::SetDTR(int kz)
    {
       if(hCom!=INVALID_HANDLE_VALUE)
          if(kz==ON)
             EscapeCommFunction(hCom, SETDTR);  // setzen
          else
             EscapeCommFunction(hCom, CLRDTR);  // Loeschen  
    }
    
    void ComPort::SetRTS(int kz)
    {
       if(hCom!=INVALID_HANDLE_VALUE)
          if(kz==ON)
             EscapeCommFunction(hCom, SETRTS);  // setzen
          else
             EscapeCommFunction(hCom, CLRRTS);  // Loeschen      
    }
    
    void ComPort::SetTXD(int kz)
    {
       if(hCom!=INVALID_HANDLE_VALUE)
          if(kz==ON)
             EscapeCommFunction(hCom, SETBREAK);  // setzen
          else
             EscapeCommFunction(hCom, CLRBREAK);  // Loeschen    
    }
    
    void ComPort::SetAll(int kz)
    {
       SetAll(kz, kz, kz);
    }
    
    void ComPort::SetAll(int dtr, int rts, int txd)
    {
       SetDTR(dtr);
       SetRTS(rts);
       SetTXD(txd);
    }
    
    BOOL ComPort::GetCTS(void)
    {
       if(hCom!=INVALID_HANDLE_VALUE)
       {
          DWORD COMStatus;
    
          GetCommModemStatus(hCom, &COMStatus);  
          if(COMStatus & MS_CTS_ON)
             return ON;
    
          return OFF;
       }
       else
          return OFF;
    }
    
    BOOL ComPort::GetDSR(void)
    {
       if(hCom!=INVALID_HANDLE_VALUE)
       {
          DWORD COMStatus;
    
          GetCommModemStatus(hCom, &COMStatus);  
          if(COMStatus & MS_DSR_ON)
             return ON;
    
          return OFF;
       }
       else
          return OFF;
    }
    
    unsigned long ComPort::Send(const char *text)
    {
       if(hCom!=INVALID_HANDLE_VALUE)
       {
          unsigned long sent;
    
          WriteFile(hCom, text, strlen(text), &sent, NULL);
    
          return(sent);
       }
       else
          return(0);
    }
    
    unsigned long ComPort::Receive(char *text, size_t maxsize)
    {
       if(hCom!=INVALID_HANDLE_VALUE)
       {
          unsigned long received;
    
          ReadFile(hCom, text, maxsize, &received, NULL);
          text[received]=0;
    
          return(received);
       }
       else
          return(0);
    }
    
    const char *ComPort::GetCP(int index)
    {
       static const char *CP[]={"COM1","COM2","COM3","COM4","COM5","COM6"};
    
       if(index>-1&&index<ComPort::MAX_PORT)
          return(CP[index]);
       else
          return("");
    }
    

    Mit freundlicher Unterstützung von mynona, die das Grundgerüst lieferte und der Webseite http://www.htl-rankweil.vol.at/lhr/ze/c/serialport.html , auf der einige nützliche Informationen über die seriellen Schnittstellen stehen.

    Wenn ihr irgendwelche Fehler entdeckt, schreibt mir bitte eine E-Mail, damit ich es korrigieren kann. Ihr könnt auch gerne mit einer E-Mail die Quellcodedateien anfordern bei mir.

    Wäre nett, wenn sich Marc++us vielleicht dazu bereit erklärt, die Dateien auf dem Server zum Download bereitzustellen.

    WICHTIG!!!
    Ich hab die Dateien mit dem Compiler Borland 5.5 compiliert. Es gibt also keine Gewährleistung, dass der Quellcode bei jedem Compiler funktioniert (Feedback obs geht, wäre spitze). Ich konnte den Quellcode auch leider nicht direkt Testen, da mir dazu momentan die Mittel fehlen (auch hier wäre Feedback erwünscht).

    Edit: //aj: Verbesserung des Quellcodes (statt static const -> ENUM; deutschsprachige Methoden in englisch unbenannt)

    [ Dieser Beitrag wurde am 24.05.2002 um 23:52 Uhr von AJ editiert. ]



  • @AJ: Wieso machst du aus deinen ganzen static-Konstanten keine Enums? Zudem ist eigentlich alles durchgehend in Englisch, nur das hier nicht:

    HANDLE HolHCom(void);
    

    Bin ich richtig in der Annahme, das das "Hol Handle Com-Port" heißen soll?

    Zudem würde ich nie ein Handle zurückgeben, der User kann dann mit CloseHandle() deinen Com-Port schließen, ohne das dies deine Klasse merkt.

    MfG SideWinder



  • @SideWinder

    du meinst das mit den enums wohl so oder :

    anstelle von

    static const int MAX_PORT=6;
    
       static const int ON=1;
       static const int OFF=0;
    
       static const int COMM_OK=0;
       static const int WRONG_PORT=-1;
       static const int OPEN_ERR=-2;
       static const int STATE_ERR=-3;
    

    meintest du wohl so

    enum {OFF,ON};
       enum {MAX_PORT = 6};
       enum {COMM_OK};
       enum {STATE_ERR = -3, OPEN_ERR, WRONG_PORT};
    

    oder ?

    [ Dieser Beitrag wurde am 24.05.2002 um 22:12 Uhr von firefly editiert. ]



  • Yo, das mein ich!

    MfG SideWinder



  • @Side
    Lässt sich ja noch ändern 😉
    Übrigens merkt meine Klasse schon, ob das Handle geschlossen wurde von außen. Was meinst du wofür ich bei jeder Methode eine Abfrage eingebaut hab, ob es ein INVALID_HANDLE_VALUE ist? Ich vermute mal, dass CloseFile() schon so klug ist und den Handle auf diesen Wert setzt. Habs nur sicherheitshalber beim Schließen eingebaut, falls doch nicht ;).

    Falls es nicht auf den Wert gesetzt wird und das macht jemand, dass er das Handle einfach von außen schließt und greift dann nochmal drauf zu, dann kann ich ihm auch nicht helfen. Ich kann nicht jeden Fehler jedes potenziellen Programmierers abfangen. Da würde ich ja ewig dran rumprogrammieren.

    Etwas Selbstinitiative erwarte ich schon, z. B. dass man sich informiert über die seriellen Schnittstellen bevor man damit rumspielt. Deswegen hab ich auch den Link hinzugefügt.

    Ich kann ja noch ein Beispiel dazu angeben, wie man es verwendet. Jetzt ändere ich erstmal den Code um, wegen den ENUMS und der Sprachunterschiede.



  • @mynonA:
    Du bist erst 13 und kannst schon sowas??????????????????????????
    Oh schei*e!!!!!!!!
    Du bist ja echt sup er!
    Der Thread witrd aber gefaqt!



  • Yo, sicherlich aber ich warte noch auf weitere Verbesserungsvorschläge zu Mynonas und AJs Klasse.

    Nur perfekt ist gut genug ;).

    MfG SideWinder



  • @Side
    Perfekt gibt es nicht 😉

    Ich glaube du kannst das so lassen und in die FAQ stellen. Bevor ich noch auf die Idee komme und sämtliche Protokolle einbaue 😃 (auch wenn ich mich darüber erst informieren müsste ;)).



  • Jede Idee wäre mir recht :), ich schau mal den Code selbst durch mach noch ein paar dumme Anmerkungen und verschiebe nach deinen Antworten das ganze in die FAQ ;).

    MfG SideWinder



  • meine güte, leute, wenn ich ewusst hätte, was ich mit dieser frage aushelöst habe, dann hätte ich sie glaube ich gar net gestellt.
    scheint ja wohl doch relativ komplex zu sein, dabei hatte ich ursprünglich vor, einfach nur ein paar selbstgebaute schaltungen über den pc zu steuern. naja, also dann will ich mich bei euch allen erst einmal HERZLICH BEDANKEN, ich glaube einen ausführlicheren Lösungsweg wird man wohl nirgendwo anders finden. also, nochmals vielen DANK für euer aller Mühen
    gruß konstantin



  • @konstantin
    Also wenn du es noch ausführlicher haben willst, dann hätte ich da noch ne Lösung 😃



  • also ich würde sagen immer her damit mit der andren lösung dann wird es immer besser für die FAQ

    gruß
    firefly



  • @firefly
    Das geht aber dann in Richtung Interrupts und noch tiefer rein. Außerdem kann man das nur noch mit einem DOS-Compiler übersetzen.



  • hmm dann doch eher nich oder 🙂 auser jemand will die klasse nur unter dos verwenden



  • nix Klasse. Schönes, reines, pures C 😃



  • Interrupts

    Oje, wir sind verloren ... sobald AJ mit Interrupts beginnt ist alles vorbei ;).

    MfG SideWinder



  • Jaaaaaaaaa!!!!!

    Back to Basics!

    (nicht zu verwechseln mit der Fast-Programmiersrpache Basic ;))



  • ahhhhh, vielen Dank @elise und den anderen, die die sources geschrieben haben.
    hab den beitrag nämlich neulich mal wieder gesucht und net gefunden...is ja auch schwer, bei sovielen postings.....
    also, viele grüße
    konstantin


Anmelden zum Antworten