Hi all, vielleicht gibt es ja hier einen Crack, der mir helfen kann: Ein ausgereiftes Programm (seit 2 Jahren erfolgreich im Einsatz) funktioniert plötzlich auf meinem (nur diesen!) PC nicht mehr. Phänomen: Der Port kann geöffnet werden, das Handle ist gültig aber dann kann der Port weder gelesen, noch beschrieben werden (GetLastError()== 29 bzw. 30)... Wenn ich jetzt irgendein anderes Programm, das auf die RS232 zugreift starte (Hyperterminal, OCConsole, HotSync) und wieder beende funktioniert mein Programm auch wieder, bis zum nächsten Kaltstart. Ich habe ein anderes Tool geschrieben, das verfügbare COM-Ports auflistet. In diesem wird die WMI bemüht (IWbemLocator). Auch danach funktioniert der Port auch wieder wie erwartet. An fehlenden Administratorrechten liegt es übrigens auch nicht, das habe ich schon getestet. Ich befürchte, das ist ein BIOS od. Treiberproblem, daher noch kurz das Board benannt: ASUS P5B mit Windows XP. Google hat dazu nicht viel ausgespuckt, einen Leidensgenossen habe ich gefunden: http://www.cygwin.com/ml/cygwin/2006-01/msg01092.html Bei ihm lag's jedoch an Cygwin, das ich bei mir nicht installiert habe... Kann sich da jemand einen Reim drauf machen? Danke und Gruß, Andreas Martin
Hilft es, die COM-Ports im Gerätemanager zu löschen? (und dann Neustart) Das BIOS hat da ausser Port ein/ausschalten eigentlich nicht viel zu sagen. Wenn Windows mit sowas anfängt hilft evtl. Neuinstallation ;)
Neuinstallation ist gut. Der Rechner ist nagelneu... Proprietäre Software hat ja kein Problem mit der RS232. Das ist ja gerade das was mich ärgert: An was haben DIE gedacht, was ICH nicht beachtet habe..? Auf meinem alten Rechner lief alles keimfrei, deshalb hole ich den jetzt aber nicht wieder raus :) Gruß, Andreas Martin
CTS aktiv ??? . Versuche mal mit dienem Code die Handschakeleitung zu bewegen. SetCom-Break ect. Mit LED-Status ansehen.
Holger, ja, das Programm funktioniert einwandfrei. Da bin ich mir 100% sicher (2 Jahre Einsatz/Entwicklung). Ein Thread arbeitet im Hintergrund und erkennt das angeschlossene Gerät. Mit den Handshakeleitungen wird die Stromversorgung für das Gerät geschaltet. Das funktioniert auch. Lediglich Daten Senden/Empfangen scheitert. Ich muss nach jedem Kaltstart einmalig Hyperterminal o.ä. auf COM1 schalten und dann ist der Port "reanimiert". An den Defaulteinstellungen für den Port liegt es auch nicht: Nachdem das Programm wieder läuft hatte ich die Einstellungen mal verstellt (alles). Danach funktionierte es trotzdem. Ich werd' wohl einen neuen Port kaufen müssen... Danke und Gruß, Andreas
Mir ist da noch was eingefallen. Schau mal in der Systemsteuerung die COM Ports an. Handschake Baudrate ect. Das Hotsync als Task installiert für PDA_s ist ein ganz gefährliches Teil. ( Dienst Kanalarbeiter Prozess ) Das Pollt und Triggert die Handschakeleitungen rum. Tip: Mach dir mal ein extra USB-COM Port da dran,und versuche das zu öffnen., und im Loop-Back zu schreiben.Pin.2<---->Pin.3- Schau dir mal mit den Status-Leds den Com-Port beim hochbooten an, ob da die Handschake-Pins sich toggeln. ( Das Handshake Toggen kan man mit dem Reg-Editor sogar unterbinden. ) Lösche mal brutal die Com-Ports aus dem System, Bau dir mal ein kleines Terminal-Prog mit dienem Compiler auf dem System. Open Close ect. Wenn der DCB nicht genullt ist, und die DCB-Struktur nicht richtig, oder der Transmit-Receiver-Buffer = Null ect.. Poste mal dein Test Code für das Mini-Terminal hier rein. ) ( Was habe ich vergessen ??? was andere da noch machen ) Was ist das für ein Compiler ??? Ich hatte mal mit XP-Laptop USB-COM so was ähnliches. Habe den Treiber entfernt u. explizit neu aufgezogen.... Gruss Holger.
Mir ist da noch was eingefallen. Die neuen COM-Chips haben sogar sleep Funktioen, Fifo-Buffers und Timeouts. Auf welchem Betriebssystem hast du das Prog. vorher entwickelt. Hast du eine echte HW-COM oder USB-COM Kanst du das Kompilat auf einer anderen XP-Platform testen ???. Kanst du ein TestCom-Prog mit z.B MS-VC 6.x machen. Mit dem Tool womit du die freien Com-Ports ermittelst geht das eigentliche Prog. danach. ???? ( Damit wird der Driver ja auch verkettet u. ermittelt ect. Properies ... Ist dein Handle global ???? und auch im DCB eingetragen. Worauf hin wird Thread Prozess gestartet. bzw auf welches Ereignisses Synchronisiert ect. ( Interprozesskommunikation ) Das XP-System ist nach dem Kaltstart hochgebootet. Deine Com-Exe wird gestartet. Daraufhin wird der Com-Treiber VXD ,Com-.Dll in den Cache Dll-Cache geholt. Der Thread wird ..... auf erfolgreiches Open gestartet oder ..sync-timing .... Ich denke da an das Timing was da abgeht. Nachrichtenschleife ect... Der Com-Empfangsbuffer-Treiber wird durch das XP-System alloziert ect. Versuche mal eine Aplikation mit deinem Compiler-Tool zu schreiben, die ohne den "Thread" für den (Handshake ect.pp ) auskommt, und einfach nur sendet. Du must das Problem auf diesem System frakturiesieren. ( Ich habe damals unter NT-4 Prozessverhalten erlebt die bei WIN98 ganz anders abliefen Nachrichtenschleife ect. Oder auch speziell nur unter NT so realieserbar waren ) Schade das du nich noch mal das gleiche XP-System u.HW hast. Ich habe immer grosse Interesse an solchen Effekten. Ich hatte mal mit XP-Laptop und USB-COM so was ähnliches. Das Prog. lief auf dem Teil schon immer gut. Bis ich es eines Tages neu angestöpselt hatte, u die Com auch noch explizit auf die Nummer gesetzt hatte, weil beim USB die Com immer mit einem neuen Nummer vergeben wird, wenn man nicht den gleichen USB-Buchsenklinke nimmt, die man vorher hatte. ( USB-Bus ist Platz-Portorientiert ) Das war ein simples Terminal-Prog mit poll Thread für die Zeichen. Geschreiben in MS-VC 6.0 Trotz Loop-Back von 2 auf 3 Pin, ging nix rein was auf dem Keyboard getippt wurde . ( Bis ich daraufhin den Treiber neu aufgedröselt hatte ) ( Also HW-Treiber und Prozessoren u. Compiler-Tools u. die entsprechenden Platformen-Betriebssysteme sind immer für Überraschungen gut.) Bei den neuen Doppel-KernProzessoren kan auch noch der Zonk drin sein. FTDI 232 ect. hat sogar extra Treiber für AMD Prozessoren..Derivate..... Mach mal einen File-Compare von den beiden Compilaten, alt u. neu System. Das muss man halt einkreisen. Hier im Formum habe ich auch schon so etwas in der Richtung vor ca. 6 Monaten gelesen. Berichte mal wie du da vorgehst. Gruss Holger.
Holger, erstmal vielen Dank für Deine Unterstützung! Ich habe ein kleines Testprogramm geschrieben und hiermit stellt sich für mich wieder alles auf den Kopf: Danach funktioniert auch mein "Problem-Programm"... Das kann doch alles nicht wahr sein! In dem anderen Programm nutze ich die SAPI (sourceforge.net) und hat auf mehreren Rechnern (mind. 6) nie Probleme gemacht... Wenn ich doch noch was Interessantes herausfinden sollte poste ich es. Aber möglichweise kann jemand anderes ja den Code für eigene Zwecke gebrauchen:
1 | #define WIN32_LEAN_AND_MEAN
|
2 | #include <windows.h> |
3 | #include <stdio.h> |
4 | |
5 | HANDLE hCom = INVALID_HANDLE_VALUE; |
6 | DCB dcb = {sizeof(DCB)}; |
7 | DCB dcb_check; |
8 | COMMTIMEOUTS to = {0}; // Disable all timeouts |
9 | COMMTIMEOUTS to_check; |
10 | DWORD dwEaten; |
11 | FILE *stream; |
12 | |
13 | #define PRINTF_DCB_MEMBER(member) fprintf(stream, "%20s: %d\n", #member, dcb.member)
|
14 | #define COM_PORT "COM1"
|
15 | #define USE_LOG_FILE 1
|
16 | |
17 | const char strTest[] = "Testing COM port..."; |
18 | char inBuf[MAX_PATH]; |
19 | |
20 | void check_err(int ok) |
21 | {
|
22 | if(!ok) |
23 | {
|
24 | fprintf(stream, "Error!\n\n\n"); |
25 | if(hCom != INVALID_HANDLE_VALUE) CloseHandle(hCom); |
26 | if(stream != stdout) fclose(stream); |
27 | abort(); |
28 | }
|
29 | else
|
30 | {
|
31 | fprintf(stream, "ok\n"); |
32 | }
|
33 | }
|
34 | |
35 | int main(int argc, char *args[]) |
36 | {
|
37 | stream = stdout; |
38 | |
39 | #if(USE_LOG_FILE)
|
40 | stream = fopen("E:\\xp_com_test\\log.txt","w"); |
41 | if(!stream) |
42 | {
|
43 | printf("Could not create log file!\n"); |
44 | abort(); |
45 | }
|
46 | #endif
|
47 | |
48 | fprintf(stream, "Opening COM Port "COM_PORT":..."); |
49 | hCom = CreateFile( COM_PORT, |
50 | GENERIC_READ | GENERIC_WRITE, 0, |
51 | 0, OPEN_EXISTING, |
52 | 0, NULL); |
53 | |
54 | check_err(hCom != INVALID_HANDLE_VALUE); |
55 | |
56 | fprintf(stream, "GetCommState()..."); |
57 | check_err(GetCommState(hCom, &dcb)); |
58 | |
59 | dcb.BaudRate = 9600; |
60 | dcb.ByteSize = 8; |
61 | dcb.StopBits = ONESTOPBIT; |
62 | dcb.Parity = NOPARITY; |
63 | dcb.fParity = (dcb.Parity != NOPARITY); |
64 | |
65 | // No flow control by default
|
66 | dcb.fOutxCtsFlow=0; |
67 | dcb.fOutxDsrFlow=0; |
68 | dcb.fDsrSensitivity=0; |
69 | |
70 | dcb.fRtsControl=RTS_CONTROL_DISABLE; |
71 | dcb.fDtrControl=DTR_CONTROL_DISABLE; |
72 | |
73 | dcb.fOutX=0; |
74 | dcb.fInX=0; |
75 | |
76 | fprintf(stream, "SetCommState()..."); |
77 | check_err(SetCommState(hCom, &dcb)); |
78 | |
79 | fprintf(stream, "GetCommState() for verifying..."); |
80 | check_err(GetCommState(hCom, &dcb_check)); |
81 | |
82 | fprintf(stream, "Verify DCB parameters..."); |
83 | check_err(!memcmp(&dcb, &dcb_check, sizeof(DCB))); |
84 | |
85 | fprintf(stream, "\nDCB members:\n"); |
86 | PRINTF_DCB_MEMBER(BaudRate); |
87 | PRINTF_DCB_MEMBER(fBinary); |
88 | PRINTF_DCB_MEMBER(fParity); |
89 | PRINTF_DCB_MEMBER(fOutxCtsFlow); |
90 | PRINTF_DCB_MEMBER(fOutxDsrFlow); |
91 | PRINTF_DCB_MEMBER(fDtrControl); |
92 | PRINTF_DCB_MEMBER(fDsrSensitivity); |
93 | PRINTF_DCB_MEMBER(fTXContinueOnXoff); |
94 | PRINTF_DCB_MEMBER(fOutX); |
95 | PRINTF_DCB_MEMBER(fInX); |
96 | PRINTF_DCB_MEMBER(fErrorChar); |
97 | PRINTF_DCB_MEMBER(fNull); |
98 | PRINTF_DCB_MEMBER(fRtsControl); |
99 | PRINTF_DCB_MEMBER(fAbortOnError); |
100 | PRINTF_DCB_MEMBER(XonLim); |
101 | PRINTF_DCB_MEMBER(XoffLim); |
102 | PRINTF_DCB_MEMBER(ByteSize); |
103 | PRINTF_DCB_MEMBER(Parity); |
104 | PRINTF_DCB_MEMBER(StopBits); |
105 | PRINTF_DCB_MEMBER(XonChar); |
106 | PRINTF_DCB_MEMBER(XoffChar); |
107 | PRINTF_DCB_MEMBER(ErrorChar); |
108 | PRINTF_DCB_MEMBER(EofChar); |
109 | PRINTF_DCB_MEMBER(EvtChar); |
110 | fprintf(stream, "\n"); |
111 | |
112 | fprintf(stream, "Set timeouts..."); |
113 | to.ReadTotalTimeoutConstant = 500; // Waits 0,5 sec before timout occures |
114 | check_err(SetCommTimeouts(hCom, &to)); |
115 | |
116 | fprintf(stream, "GetCommTimeouts() for verifying..."); |
117 | check_err(GetCommTimeouts(hCom, &to_check)); |
118 | |
119 | fprintf(stream, "Verify timeout paramters..."); |
120 | check_err(!memcmp(&to, &to_check, sizeof(COMMTIMEOUTS))); |
121 | |
122 | fprintf(stream, "Write test string..."); |
123 | check_err(WriteFile(hCom, strTest, strlen(strTest), &dwEaten, (LPOVERLAPPED)NULL)); |
124 | |
125 | fprintf(stream, "All characters written? ..."); |
126 | check_err(dwEaten == strlen(strTest)); |
127 | |
128 | fprintf(stream, "Reading COM port..."); |
129 | check_err(ReadFile(hCom, inBuf, sizeof inBuf, &dwEaten, (LPOVERLAPPED)NULL) && dwEaten>0); |
130 | |
131 | fprintf(stream, "Read from COM port: \"%*s\"", dwEaten, inBuf); |
132 | |
133 | fprintf(stream, "\n\nDone!\n\n"); |
134 | |
135 | |
136 | CloseHandle(hCom); |
137 | if(stream != stdout) fclose(stream); |
138 | return 0; |
139 | }
|
Das Ganze spuckt dann folgendes aus: Opening COM Port COM1:...ok GetCommState()...ok SetCommState()...ok GetCommState() for verifying...ok Verify DCB parameters...ok DCB members: BaudRate: 9600 fBinary: 1 fParity: 0 fOutxCtsFlow: 0 fOutxDsrFlow: 0 fDtrControl: 0 fDsrSensitivity: 0 fTXContinueOnXoff: 0 fOutX: 0 fInX: 0 fErrorChar: 0 fNull: 0 fRtsControl: 0 fAbortOnError: 0 XonLim: 2048 XoffLim: 512 ByteSize: 8 Parity: 0 StopBits: 0 XonChar: 17 XoffChar: 19 ErrorChar: 0 EofChar: 0 EvtChar: 0 Set timeouts...ok GetCommTimeouts() for verifying...ok Verify timeout paramters...ok Write test string...ok All characters written? ...ok Reading COM port...ok Read from COM port: "Testing COM port..." Done! Gruß, Andreas
Die andere Variante zum Erzeugen des DCB ausprobiert? Wenn auch das keinen Anhaltspunkt bringt, würde ich auch auf den Treiber tippen.
1 | if (!GetCommState(handle, &dcb)) { ... } |
2 | if (!BuildCommDCB("baud=9600 parity=N data=8 stop=1", &dcb)) { ... } |
3 | dcb.XonLim = dcb.XoffLim = dcb.fOutX = dcb.fInX = 0; |
4 | SetCommState(handle, &dcb); |
p.s. u.U. nochmal mit anderen Timeouts und anderen Buffergrößen (SetupComm) probieren.
Ich habe den (meinen) Fehler gefunden: Nur(!) auf meinem neuen Rechner ist das Flag fDsrSensitivity per default auf 1 gesetzt. Daher konnten keine Zeichen gelesen werden. Ich habe den DCB immer mit GetCommState() ausgefüllt, daher blieb das Flag gesetzt. (So'n Mist) Danke trotzdem Holger, Arc Net und *.* Gruß, Andreas
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.