Probleme mit SeriellerSchnitstelle



  • Hi,

    ich soll über die COM1 mit einem Geräht kommunizieren. Das Protokoll sieht vor, das befor die kommunikation mit einer bestimmten Geschwindigkeit (z.B. 9600 Baud)gestartet wird TxD eine definierte Zeit auf low und auf high gehen soll (25ms low und 25 ms higt), damit das Geräht die eingehende kommunikation erkennt. Diereckt nach der High impuls folgen dann die Datenbits.

    Verwendetes OS: XP

    1. Versuch

    mitels folgendem code versucht zu realisieren.

    SetCommBreak 
    Sleep(25);
    ClearCommBreak
    Sleep(25);
    
    // weiter mit normaler kommunikation.
    

    Problem Sleep rundet bei mir immer auf vielfache von 15.5ms auf.

    2. Versuch

    Bei einer Baudrate von 200Baud und dem übertragen von 0xf0 wirde genau dieser puls generiert ( Start und Stopbits berücksichtigt) Direcht danauch muss aber auf eine andere Baudrate umgeschaltet werden. Und hier fangen meine Probleme an...
    nachfolgend ein kleiner auschnitt aus der implementierung

    GetCommState (porth, &PortDCB1); // Port State runterladen für veränderungen
        GetCommState (porth, &PortDCB2); // Port State sichern
    
        PortDCB1.BaudRate = 200; // neue Baudrate einstellen
        SetCommState (porth, &PortDCB1); // neue Baudrage setzen
    
        SetCommMask (LOWL_astThreadData[bPortIdentifier].hInterface, EV_TXEMPTY);
    
        // Wackeup senden
        WriteFile (porth,                       // Port handle
                   &wackeUp,                    // Pointer to the data to write 
                   (DWORD)length_write,         // Number of bytes to write
                   &length_writen,              // Pointer to the number of bytes written
                   NULL);                       // Must be NULL for Windows CE
    
        events = EV_TXEMPTY;
        WaitCommEvent (porth,&events,NULL);     // Warten bis wackeup gesendet wurde.
    
        // Protokoll daten übertragen
        WriteFile (porth,                       // Port handle
                   &data,                       // Pointer to the data to write 
                   (DWORD)dlength_write,        // Number of bytes to write
                   &dlength_writen,             // Pointer to the number of bytes written
                   NULL);                       // Must be NULL for Windows CE
    
        // Warten bis die übertragung beginnt 
        WaitCommEvent (porth,&events,NULL);
        // Orginal baudrate für die übertragung wieder herstellen
        // Wieso das erst nach dem wait gemacht werden muss ist mir etwas schleiderhaft aber so 
        // funktionierts bisher am besten.
        SetCommState (porth, &PortDCB2);
    

    so und nun meine Probleme. Soweit sieht auch alles gut aus. nur das timig stimmt nicht. Start bit und datenbits wirden des WackUp impulses werden mit 200Baud übertragen. Soweit OK. das StopBit Aber wird durch die Letzte umschaltung mit der neuen Baudrate übertreagen. ( wers nicht glaubt solls selber ausprobieren , ich hab hier ein oscar neben mir stehen der mir die zeiten simlich exakt angibt. ) er rest wird dann weiter mit 9600 übertragen.

    Das Problem scheint WaitCommEvent zu machen. Bei EV_TXEMPTY Steht zwar in der MSDN "The last character in the output buffer was sent." drinn. nur scheint das nicht zu bedeuten, das auch das stop bit gesendet wurde. grrrrr.

    Weiter überschreibt SetCommState die einstellungen des ports auch wenn bereits daten gesendet werden. Dadurch werden z.b. die ersen bits langsam und die lezten schnell übertragen.

    Villeicht kennt jamand ja eine lösung für das problem. Lösungsansatz 1 hab ich bisher nicht weiterverfolgt, nachdem das sleep so verrücktgespielt hat. die 2. seiht bisher recht vielversprechend aus. nur vehlen mir noch 4ms beim high impuls.

    gruss Termite

    PS. ich krigt hier lansam einen kleinen hass auf m$



  • Hi

    hab das problem soweit in den griff gekriegt. Sende an stelle von 8 bits für den WackUp impuls nur 7 (0x78). Mit dem Start bit sind das dann 8 bit die mit einer entsprechenden Baudrate ( 160 Baud ) gesendet werden. Das Stopbit das dan noch übrichbleibt und mit 9600 Baud übertragen wird kann ich hoffentlich vernachlässigen.

    aber nu is wochenende

    Termite



  • Könnt ich bitte den ganzen Code haben?
    Ich wollte schon immer mal Strom über Com leiten, hab aber nie richitg hinbekommen.



  • Hi

    ist hir im speziellen fall etwas komplizierter da sich da noch ein protokoll drum herum befindet und das ganze noch in einer dll verpackt wurde. Ich hab auch nicht alles selber implementiert und hab gerade keinen zugriff drauf. ( wochenende )

    Hier im Forum sind noch einge Threads zu dem Thema die mir auch ein bischen weitergeholfen haben. einfach mal die such funktion anschmeissen.

    im prinzip geht das wie bei einer Datei

    CreateFile
    WriteFile
    ReadFile

    und zusätzlich gibts noch einie funktionen speziell für die Schnitstelle.

    // generieren der DCB Struckturen aus Strings
    BuildCommDCB
    BuildCommDCBAndTimeouts

    // Comm configureiren
    GetCommState // Einstellungen der Schnistelle setzen und erfragen
    SetCommState

    GetCommTimeout // Timeouts setzen und aktuelle gesetzte Werte erfragen
    SetCommTimeout

    GetCommMask // Eventmaske erfragen uns setzen
    SetCommMask

    GetCommConfig
    SetCommConfig
    SetDefaultCommConfig

    ClearCommBreak // TXD auf definirten pegel setzen
    SetCommBreak

    ClearCommError

    WaitCommEvent // Auf einen Ereignis der Comm Schnitstelle warten

    CommConfigDialog

    Sieht jetzt viel aus. normalerweise wird aber nicht alles gebraucht. und meistens nur zur initallisierung.

    also wie gesagt entweider mal hier im Forum suchen oder mal googel anschmeissen oder in der MSDN nachschauen was die funktionen bedeuten

    gruss Termite


Anmelden zum Antworten