1 | #include <windows.h>
|
2 | #include <memory.h>
|
3 | #include "ComTools.h"
|
4 |
|
5 | #define MAX_COM_PORTS 8
|
6 |
|
7 | #ifdef UNICODE
|
8 | #define Z(a) L##a
|
9 | #else
|
10 | #define Z(a) a
|
11 | #endif
|
12 |
|
13 |
|
14 | static HANDLE hComFile[MAX_COM_PORTS];
|
15 | static BOOL bIsOpen [MAX_COM_PORTS];
|
16 |
|
17 | //*****************************************************************************
|
18 | //*
|
19 | //* ComInit
|
20 | //*
|
21 | //*****************************************************************************
|
22 | int ComInit()
|
23 | {
|
24 | return 1;
|
25 | }
|
26 |
|
27 | //*****************************************************************************
|
28 | //*
|
29 | //* ComExit
|
30 | //*
|
31 | //*****************************************************************************
|
32 | int ComExit()
|
33 | {
|
34 | int i;
|
35 |
|
36 | for(i=0;i<MAX_COM_PORTS;i++)
|
37 | {
|
38 | if(!bIsOpen[i])continue;
|
39 | ComClose(i);
|
40 | }
|
41 |
|
42 | return 1;
|
43 | }
|
44 |
|
45 | //*****************************************************************************
|
46 | //*
|
47 | //* ComOpen
|
48 | //*
|
49 | //*****************************************************************************
|
50 | // Öffnet eine serielle Verbindung
|
51 | // Nr : Ist die Nummer des Com-Ports (0=COM1 1=COM2 ...)
|
52 | // Baud : Ist die Bautrate
|
53 | // Parity : 0 = kein Parity Bit
|
54 | // 1 = gerade
|
55 | // 2 = ungerade
|
56 | // 3 = immer 0
|
57 | // 4 = immer 1
|
58 | // Stopbits : 0 = Ein Stopbit
|
59 | // 1 = Ein/einhalb Stopbits
|
60 | // 2 = Zwei Stopbits
|
61 | // Bits : 0 = 7 Datenbits
|
62 | // 1 = 8 Datenbits
|
63 | // 7 = 7 Datenbits
|
64 | // 8 = 8 Datenbits
|
65 | // Ergibt 1 wenn eine Schnittstelle geöffnet wurde
|
66 | int ComOpen(unsigned Nr,int Baud,int Parity,int Stopbits,int Databits)
|
67 | {
|
68 | static const int iPMode[]={NOPARITY,EVENPARITY,ODDPARITY,SPACEPARITY,MARKPARITY};
|
69 | static const int iSMode[]={ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS,ONESTOPBIT};
|
70 | TCHAR cName[]=Z("\\\\.\\COM1");
|
71 | HANDLE hFile;
|
72 | COMMTIMEOUTS sTo;
|
73 | DCB sDcb;
|
74 |
|
75 |
|
76 |
|
77 | if(Nr>=MAX_COM_PORTS)return 0;
|
78 | if(bIsOpen[Nr])return 0;
|
79 |
|
80 |
|
81 | cName[7]='1'+Nr;
|
82 |
|
83 | hFile= CreateFile(cName,GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
|
84 | if(hFile==INVALID_HANDLE_VALUE)
|
85 | {
|
86 | hFile=0;
|
87 | return 0;
|
88 | }
|
89 |
|
90 | if(Databits==7)Databits=0;
|
91 |
|
92 |
|
93 | memset(&sDcb,0,sizeof(sDcb));
|
94 | sDcb.DCBlength=sizeof(sDcb);
|
95 | sDcb.BaudRate = Baud;
|
96 | sDcb.fParity = (Parity!=0)? TRUE:FALSE;
|
97 | sDcb.fBinary = TRUE;
|
98 | sDcb.Parity = iPMode[Parity];
|
99 | sDcb.StopBits = iSMode[Stopbits&3];
|
100 | sDcb.fOutxCtsFlow = FALSE;
|
101 | sDcb.fOutxDsrFlow = FALSE;
|
102 | sDcb.fDtrControl = DTR_CONTROL_ENABLE;
|
103 | sDcb.fRtsControl = RTS_CONTROL_ENABLE;
|
104 | sDcb.fDsrSensitivity= FALSE;
|
105 | sDcb.fAbortOnError = FALSE;
|
106 | sDcb.ByteSize = (Databits)? 8:7;
|
107 |
|
108 | if(!SetCommState(hFile,&sDcb))
|
109 | {
|
110 | CloseHandle(hFile);
|
111 | return 0;
|
112 | }
|
113 |
|
114 |
|
115 | sTo.ReadIntervalTimeout = MAXDWORD; // 0 ms Read-Tomeout
|
116 | sTo.ReadTotalTimeoutMultiplier = 0;
|
117 | sTo.ReadTotalTimeoutConstant = 0;
|
118 | sTo.WriteTotalTimeoutMultiplier= 12000/Baud+1; // ? ms Write timeout per byte
|
119 | sTo.WriteTotalTimeoutConstant = sTo.WriteTotalTimeoutMultiplier+1;
|
120 | if(!SetCommTimeouts((HANDLE)hFile,&sTo))
|
121 | {
|
122 | CloseHandle(hFile);
|
123 | return 0;
|
124 | }
|
125 |
|
126 |
|
127 | hComFile[Nr]=hFile;
|
128 | bIsOpen [Nr]=TRUE;
|
129 |
|
130 |
|
131 | return 1;
|
132 | }
|
133 |
|
134 |
|
135 |
|
136 | //*****************************************************************************
|
137 | //*
|
138 | //* ComClose
|
139 | //*
|
140 | //*****************************************************************************
|
141 | // Schließt eine serielle Verbindung
|
142 | // Nr : Ist die Nummer des Com-Ports (0=COM1 1=COM2 ...)
|
143 | // Ergibt 1 wenn eine Schnittstelle geschlossen wurde
|
144 | int ComClose(unsigned Nr)
|
145 | {
|
146 |
|
147 | if(Nr>=MAX_COM_PORTS)return 0;
|
148 | if(!bIsOpen[Nr])return 0;
|
149 |
|
150 | CloseHandle(hComFile[Nr]);
|
151 | hComFile[Nr]=0;
|
152 | bIsOpen [Nr]=FALSE;
|
153 |
|
154 |
|
155 | return 1;
|
156 | }
|
157 |
|
158 |
|
159 | //*****************************************************************************
|
160 | //*
|
161 | //* ComDetectPorts
|
162 | //*
|
163 | //*****************************************************************************
|
164 | // Speichert in iCount die Anzahl der gefundenen COM Ports
|
165 | // In pMode werden die Portzustänte gespeichert
|
166 | // 0 = Nicht vorhanden
|
167 | // 1 = Vorhanden
|
168 | // 2 = Vorhanden und von einem anderen Programm benutzt
|
169 | // pMode[0] für COM1
|
170 | // pMode[1] für COM2
|
171 | // ...
|
172 | // iMaxPorts ist die Anzahl der Ports die gescannt werden.
|
173 | void ComDetectPorts(int &iCount,int *pMode,int iMaxPorts)
|
174 | {
|
175 | int i;
|
176 | TCHAR cName[]=Z("\\\\.\\COM1");
|
177 | HANDLE hCom;
|
178 |
|
179 |
|
180 |
|
181 | for(i=0;i<iMaxPorts;i++)
|
182 | {
|
183 | if(i<MAX_COM_PORTS && bIsOpen[i])
|
184 | {
|
185 | pMode[i]=1;
|
186 | iCount++;
|
187 | continue;
|
188 | }
|
189 |
|
190 | cName[7]='1'+i;
|
191 | hCom=CreateFile(cName,GENERIC_WRITE|GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
|
192 | if(hCom==INVALID_HANDLE_VALUE)
|
193 | {
|
194 | if(GetLastError()==ERROR_FILE_NOT_FOUND)
|
195 | {
|
196 | pMode[i]=0;
|
197 | continue;
|
198 | }
|
199 | else{
|
200 | pMode[i]=2;
|
201 | iCount++;
|
202 | continue;
|
203 | }
|
204 | }
|
205 |
|
206 | CloseHandle(hCom);
|
207 | pMode[i]=1;
|
208 | iCount++;
|
209 | }
|
210 |
|
211 | }
|
212 |
|
213 | //*****************************************************************************
|
214 | //*
|
215 | //* ComRead
|
216 | //*
|
217 | //*****************************************************************************
|
218 | // Ein Zeichen lesen
|
219 | // Nr : Ist die Nummer des Com-Ports (0=COM1 1=COM2 ...)
|
220 | // Ergibt -1 wenn nichts gelesen wurde sonst das Zeichen
|
221 | int ComRead(unsigned Nr)
|
222 | {
|
223 | unsigned char c;
|
224 | DWORD dwCount;
|
225 |
|
226 |
|
227 | if(Nr>=MAX_COM_PORTS)return -1;
|
228 | if(!bIsOpen[Nr])return -1;
|
229 |
|
230 | if(!ReadFile(hComFile[Nr],&c,1,&dwCount,0))return -1;
|
231 | if(dwCount!=1)return -1;
|
232 |
|
233 |
|
234 | return c;
|
235 | }
|
236 |
|
237 | //*****************************************************************************
|
238 | //*
|
239 | //* ComRead
|
240 | //*
|
241 | //*****************************************************************************
|
242 | // Mehrere Zeichen lesen
|
243 | // Nr : Ist die Nummer des Com-Ports (0=COM1 1=COM2 ...)
|
244 | // Buffer : Buffer in dem die Zeichen gespeichert werden
|
245 | // Max : Maximale Anzahl der zu lesenden Zeichen
|
246 | // Ergibt die Anzahl der gelesenen Zeichen
|
247 | int ComRead(unsigned Nr,void *Buffer,int Max)
|
248 | {
|
249 | DWORD dwCount;
|
250 |
|
251 |
|
252 | if(Nr>=MAX_COM_PORTS)return 0;
|
253 | if(!bIsOpen[Nr])return 0;
|
254 |
|
255 | ReadFile(hComFile[Nr],Buffer,Max,&dwCount,0);
|
256 |
|
257 | return dwCount;
|
258 | }
|
259 |
|
260 |
|
261 | //*****************************************************************************
|
262 | //*
|
263 | //* ComWrite
|
264 | //*
|
265 | //*****************************************************************************
|
266 | // Ein Zeichen senden
|
267 | // Nr : Ist die Nummer des Com-Ports (0=COM1 1=COM2 ...)
|
268 | // Zeichen : Ist das Zeichen das gesendet werden soll.
|
269 | // Ergibt die Anzahl der gesendeten Zeichen
|
270 | int ComWrite(unsigned Nr,int Zeichen)
|
271 | {
|
272 | DWORD dwCount;
|
273 |
|
274 |
|
275 | if(Nr>=MAX_COM_PORTS)return 0;
|
276 | if(!bIsOpen[Nr])return 0;
|
277 |
|
278 | WriteFile(hComFile[Nr],&Zeichen,1,&dwCount,0);
|
279 |
|
280 |
|
281 | return dwCount;
|
282 | }
|
283 |
|
284 | //*****************************************************************************
|
285 | //*
|
286 | //* ComWrite
|
287 | //*
|
288 | //*****************************************************************************
|
289 | // Mehrere Zeichen schreiben
|
290 | // Nr : Ist die Nummer des Com-Ports (0=COM1 1=COM2 ...)
|
291 | // Buffer : Buffer in dem die Zeichen gespeichert werden
|
292 | // Count : Anzahl der zu sendenden Zeichen
|
293 | // Ergibt die Anzahl der gesendeten Zeichen
|
294 | int ComWrite(unsigned Nr,void *Buffer,int Count)
|
295 | {
|
296 | DWORD dwCount;
|
297 |
|
298 |
|
299 | if(Nr>=MAX_COM_PORTS)return 0;
|
300 | if(!bIsOpen[Nr])return 0;
|
301 |
|
302 | WriteFile(hComFile[Nr],Buffer,Count,&dwCount,0);
|
303 |
|
304 | return dwCount;
|
305 | }
|
306 |
|
307 |
|
308 |
|
309 | //*****************************************************************************
|
310 | //*
|
311 | //* ComGetReadCount
|
312 | //*
|
313 | //*****************************************************************************
|
314 | // Ergibt die Anzahl der Bytes die im Lesepuffer der Schnittstelle sind
|
315 | // Nr : Ist die Nummer des Com-Ports (0=COM1 1=COM2 ...)
|
316 | // Ergibt die Anzahl der Bytes im Buffer
|
317 | int ComGetReadCount(unsigned Nr)
|
318 | {
|
319 | COMSTAT sComStat;
|
320 | DWORD dwErrorFlags;
|
321 |
|
322 |
|
323 | if(Nr>=MAX_COM_PORTS)return 0;
|
324 | if(!bIsOpen[Nr])return 0;
|
325 |
|
326 | dwErrorFlags=0;
|
327 |
|
328 | if(!ClearCommError(hComFile[Nr], &dwErrorFlags, &sComStat))return 0;
|
329 |
|
330 | return sComStat.cbInQue;
|
331 | }
|
332 |
|
333 | //*****************************************************************************
|
334 | //*
|
335 | //* ComGetWriteCount
|
336 | //*
|
337 | //*****************************************************************************
|
338 | // Ergibt die Anzahl der Bytes die im Schreibpuffer der Schnittstelle sind
|
339 | // Nr : Ist die Nummer des Com-Ports (0=COM1 1=COM2 ...)
|
340 | // Ergibt die Anzahl der Bytes im Buffer
|
341 | int ComGetWriteCount(unsigned Nr)
|
342 | {
|
343 | COMSTAT sComStat;
|
344 | DWORD dwErrorFlags;
|
345 |
|
346 |
|
347 | if(Nr>=MAX_COM_PORTS)return 0;
|
348 | if(!bIsOpen[Nr])return 0;
|
349 |
|
350 | dwErrorFlags=0;
|
351 |
|
352 | if(!ClearCommError(hComFile[Nr], &dwErrorFlags, &sComStat))return 0;
|
353 |
|
354 | return sComStat.cbOutQue;
|
355 | }
|