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 implementierungGetCommState (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
ReadFileund 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
SetCommStateGetCommTimeout // Timeouts setzen und aktuelle gesetzte Werte erfragen
SetCommTimeoutGetCommMask // Eventmaske erfragen uns setzen
SetCommMaskGetCommConfig
SetCommConfig
SetDefaultCommConfigClearCommBreak // TXD auf definirten pegel setzen
SetCommBreakClearCommError
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