在PDA中获取GPS信息。
2009-08-31 09:46
246 查看
http://www.cnblogs.com/anhlyiling/archive/2008/12/04/1347623.html
在PDA中获取GPS信息。
近日一个项目需要用在PDA上读
取GPS卫星信号,在网上搜了一圈,整理出一个GPS的类,大家可以直接加入项目
使用。可以获得当前的经纬度、海拔、速度、连接卫星数等信息
Code
1
using
System;
2
using
System.Collections.Generic;
3
using
System.Text;
4
using
System.Runtime.InteropServices;
5
6
namespace
AnhlYiling
7
{
8
public
class
GPS
9
{
10
11
public
string
PortNum;
12
public
int
BaudRate;
13
public
byte
ByteSize;
14
public
byte
Parity;
//
0-4=no,odd,even,mark,space
15
public
byte
StopBits;
//
0,1,2 = 1, 1.5, 2
16
public
int
ReadTimeout;
17
18
//
comm port win32 file handle
19
private
int
hComm
=
-
1
;
20
21
public
bool
Opened
=
false
;
22
23
//
win32 api constants
24
private
const
uint
GENERIC_READ
=
0x80000000
;
25
private
const
uint
GENERIC_WRITE
=
0x40000000
;
26
private
const
int
OPEN_EXISTING
=
3
;
27
private
const
int
INVALID_HANDLE_VALUE
=
-
1
;
28
29
[StructLayout(LayoutKind.Sequential)]
30
public
struct
DCB
31
{
32
//
taken from c struct in platform sdk
33
public
int
DCBlength;
//
sizeof(DCB)
34
public
int
BaudRate;
//
指定当前波特率 current baud rate
35
//
these are the c struct bit fields, bit twiddle flag to set
36
public
int
fBinary;
//
指定是否允许二进制模式,在windows95中必须主TRUE binary mode, no EOF check
37
public
int
fParity;
//
指定是否允许奇偶校验 enable parity checking
38
public
int
fOutxCtsFlow;
//
指定CTS是否用于检测发送控制,当为TRUE是CTS为OFF,发送将被挂起。 CTS output flow control
39
public
int
fOutxDsrFlow;
//
指定CTS是否用于检测发送控制 DSR output flow control
40
public
int
fDtrControl;
//
DTR_CONTROL_DISABLE值将DTR置为OFF, DTR_CONTROL_ENABLE值将DTR置为ON, DTR_CONTROL_HANDSHAKE允许DTR"握手" DTR flow control type
41
public
int
fDsrSensitivity;
//
当该值为TRUE时DSR为OFF时接收的字节被忽略 DSR sensitivity
42
public
int
fTXContinueOnXoff;
//
指
定当接收缓冲区已满,并且驱动程序已经发送出XoffChar字符时发送是否停止。TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动
程序已经发送出XoffChar字符中止接收字节之后,发送继续进行。 FALSE时,在接收缓冲区接收到代表缓冲区已空的字节XonChar且驱动程序
已经发送出恢复发送的XonChar之后,发送继续进行。XOFF continues Tx
43
public
int
fOutX;
//
TRUE时,接收到XoffChar之后便停止发送接收到XonChar之后将重新开始 XON/XOFF out flow control
44
public
int
fInX;
//
TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去接收缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去 XON/XOFF in flow control
45
public
int
fErrorChar;
//
该值为TRUE且fParity为TRUE时,用ErrorChar 成员指定的字符代替奇偶校验错误的接收字符 enable error replacement
46
public
int
fNull;
//
eTRUE时,接收时去掉空(0值)字节 enable null stripping
47
public
int
fRtsControl;
//
RTS flow control
48
/**/
/*
RTS_CONTROL_DISABLE时,RTS置为OFF
49
RTS_CONTROL_ENABLE时, RTS置为ON
50
RTS_CONTROL_HANDSHAKE时,
51
当接收缓冲区小于半满时RTS为ON
52
当接收缓冲区超过四分之三满时RTS为OFF
53
RTS_CONTROL_TOGGLE时,
54
当接收缓冲区仍有剩余字节时RTS为ON ,否则缺省为OFF
*/
55
56
public
int
fAbortOnError;
//
TRUE时,有错误发生时中止读和写操作 abort on error
57
public
int
fDummy2;
//
未使用 reserved
58
59
public
uint
flags;
60
public
ushort
wReserved;
//
未使用,必须为0 not currently used
61
public
ushort
XonLim;
//
指定在XON字符发送这前接收缓冲区中可允许的最小字节数 transmit XON threshold
62
public
ushort
XoffLim;
//
指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数 transmit XOFF threshold
63
public
byte
ByteSize;
//
指定端口当前使用的数据位 number of bits/byte, 4-8
64
public
byte
Parity;
//
指定端口当前使用的奇偶校验方法,可能为:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY 0-4=no,odd,even,mark,space
65
public
byte
StopBits;
//
指定端口当前使用的停止位数,可能为:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS 0,1,2 = 1, 1.5, 2
66
public
char
XonChar;
//
指定用于发送和接收字符XON的值 Tx and Rx XON character
67
public
char
XoffChar;
//
指定用于发送和接收字符XOFF值 Tx and Rx XOFF character
68
public
char
ErrorChar;
//
本字符用来代替接收到的奇偶校验发生错误时的值 error replacement character
69
public
char
EofChar;
//
当没有使用二进制模式时,本字符可用来指示数据的结束 end of input character
70
public
char
EvtChar;
//
当接收到此字符时,会产生一个事件 received event character
71
public
ushort
wReserved1;
//
未使用 reserved; do not use
72
}
73
74
[StructLayout(LayoutKind.Sequential)]
75
private
struct
COMMTIMEOUTS
76
{
77
public
int
ReadIntervalTimeout;
78
public
int
ReadTotalTimeoutMultiplier;
79
public
int
ReadTotalTimeoutConstant;
80
public
int
WriteTotalTimeoutMultiplier;
81
public
int
WriteTotalTimeoutConstant;
82
}
83
84
[StructLayout(LayoutKind.Sequential)]
85
private
struct
OVERLAPPED
86
{
87
public
int
Internal;
88
public
int
InternalHigh;
89
public
int
Offset;
90
public
int
OffsetHigh;
91
public
int
hEvent;
92
}
93
94
[DllImport(
"
coredll.dll
"
)]
95
private
static
extern
int
CreateFile(
96
string
lpFileName,
//
要打开的串口名称
97
uint
dwDesiredAccess,
//
指定串口的访问方式,一般设置为可读可写方式
98
int
dwShareMode,
//
指定串口的共享模式,串口不能共享,所以设置为0
99
int
lpSecurityAttributes,
//
设置串口的安全属性,WIN9X下不支持,应设为NULL
100
int
dwCreationDisposition,
//
对于串口通信,创建方式只能为OPEN_EXISTING
101
int
dwFlagsAndAttributes,
//
指定串口属性与标志,设置为FILE_FLAG_OVERLAPPED(重叠I/O操作),指定串口以异步方式通信
102
int
hTemplateFile
//
对于串口通信必须设置为NULL
103
);
104
[DllImport(
"
coredll.dll
"
)]
105
private
static
extern
bool
GetCommState(
106
int
hFile,
//
通信设备句柄
107
ref
DCB lpDCB
//
设备控制块DCB
108
);
109
[DllImport(
"
coredll.dll
"
)]
110
private
static
extern
bool
BuildCommDCB(
111
string
lpDef,
//
设备控制字符串
112
ref
DCB lpDCB
//
设备控制块
113
);
114
[DllImport(
"
coredll.dll
"
)]
115
private
static
extern
bool
SetCommState(
116
int
hFile,
//
通信设备句柄
117
ref
DCB lpDCB
//
设备控制块
118
);
119
[DllImport(
"
coredll.dll
"
)]
120
private
static
extern
bool
GetCommTimeouts(
121
int
hFile,
//
通信设备句柄 handle to comm device
122
ref
COMMTIMEOUTS lpCommTimeouts
//
超时时间 time-out values
123
);
124
[DllImport(
"
coredll.dll
"
)]
125
private
static
extern
bool
SetCommTimeouts(
126
int
hFile,
//
通信设备句柄 handle to comm device
127
ref
COMMTIMEOUTS lpCommTimeouts
//
超时时间 time-out values
128
);
129
[DllImport(
"
coredll.dll
"
)]
130
private
static
extern
bool
ReadFile(
131
int
hFile,
//
通信设备句柄 handle to file
132
byte
[] lpBuffer,
//
数据缓冲区 data buffer
133
int
nNumberOfBytesToRead,
//
多少字节等待读取 number of bytes to read
134
ref
int
lpNumberOfBytesRead,
//
读取多少字节 number of bytes read
135
ref
OVERLAPPED lpOverlapped
//
溢出缓冲区 overlapped buffer
136
);
137
[DllImport(
"
coredll.dll
"
)]
138
private
static
extern
bool
WriteFile(
139
int
hFile,
//
通信设备句柄 handle to file
140
byte
[] lpBuffer,
//
数据缓冲区 data buffer
141
int
nNumberOfBytesToWrite,
//
多少字节等待写入 number of bytes to write
142
ref
int
lpNumberOfBytesWritten,
//
已经写入多少字节 number of bytes written
143
ref
OVERLAPPED lpOverlapped
//
溢出缓冲区 overlapped buffer
144
);
145
[DllImport(
"
coredll.dll
"
)]
146
private
static
extern
bool
CloseHandle(
147
int
hObject
//
handle to object
148
);
149
[DllImport(
"
coredll.dll
"
)]
150
private
static
extern
uint
GetLastError();
151
152
public
void
Open()
153
{
154
155
DCB dcbCommPort
=
new
DCB();
156
COMMTIMEOUTS ctoCommPort
=
new
COMMTIMEOUTS();
157
158
//
打开串口 OPEN THE COMM PORT.
159
hComm
=
CreateFile(PortNum ,GENERIC_READ
|
GENERIC_WRITE,
0
,
0
,OPEN_EXISTING,
0
,
0
);
160
//
如果串口没有打开,就打开 IF THE PORT CANNOT BE OPENED, BAIL OUT.
161
if
(hComm
==
INVALID_HANDLE_VALUE)
162
{
163
throw
(
new
ApplicationException(
"
非法操作,不能打开串口!
"
));
164
}
165
166
//
设置通信超时时间 SET THE COMM TIMEOUTS.
167
GetCommTimeouts(hComm,
ref
ctoCommPort);
168
ctoCommPort.ReadTotalTimeoutConstant
=
ReadTimeout;
169
ctoCommPort.ReadTotalTimeoutMultiplier
=
0
;
170
ctoCommPort.WriteTotalTimeoutMultiplier
=
0
;
171
ctoCommPort.WriteTotalTimeoutConstant
=
0
;
172
SetCommTimeouts(hComm,
ref
ctoCommPort);
173
174
//
设置串口 SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.
175
GetCommState(hComm,
ref
dcbCommPort);
176
dcbCommPort.BaudRate
=
BaudRate;
177
dcbCommPort.flags
=
0
;
178
//
dcb.fBinary=1;
179
dcbCommPort.flags
|=
1
;
180
if
(Parity
>
0
)
181
{
182
//
dcb.fParity=1
183
dcbCommPort.flags
|=
2
;
184
}
185
dcbCommPort.Parity
=
Parity;
186
dcbCommPort.ByteSize
=
ByteSize;
187
dcbCommPort.StopBits
=
StopBits;
188
if
(
!
SetCommState(hComm,
ref
dcbCommPort))
189
{
190
//
uint ErrorNum=GetLastError();
191
throw
(
new
ApplicationException(
"
非法操作,不能打开串口!
"
));
192
}
193
//
unremark to see if setting took correctly
194
//
DCB dcbCommPort2 = new DCB();
195
//
GetCommState(hComm, ref dcbCommPort2);
196
Opened
=
true
;
197
}
198
199
public
void
Close()
200
{
201
if
(hComm
!=
INVALID_HANDLE_VALUE)
202
{
203
CloseHandle(hComm);
204
}
205
}
206
207
public
byte
[] Read(
int
NumBytes)
208
{
209
byte
[] BufBytes;
210
byte
[] OutBytes;
211
BufBytes
=
new
byte
[NumBytes];
212
if
(hComm
!=
INVALID_HANDLE_VALUE)
213
{
214
OVERLAPPED ovlCommPort
=
new
OVERLAPPED();
215
int
BytesRead
=
0
;
216
ReadFile(hComm,BufBytes,NumBytes,
ref
BytesRead,
ref
ovlCommPort);
217
try
218
{
219
OutBytes
=
new
byte
[BytesRead];
220
Array.Copy(BufBytes,
0
,OutBytes,
0
,BytesRead);
221
}
222
catch
223
{
224
return
BufBytes;
225
}
226
227
}
228
else
229
{
230
throw
(
new
ApplicationException(
"
串口未打开!
"
));
231
}
232
return
OutBytes;
233
//
return BufBytes;
234
}
235
236
public
void
Write(
byte
[] WriteBytes)
237
{
238
if
(hComm
!=
INVALID_HANDLE_VALUE)
239
{
240
OVERLAPPED ovlCommPort
=
new
OVERLAPPED();
241
int
BytesWritten
=
0
;
242
WriteFile(hComm,WriteBytes,WriteBytes.Length,
ref
BytesWritten,
ref
ovlCommPort);
243
}
244
else
245
{
246
throw
(
new
ApplicationException(
"
串口未打开!
"
));
247
}
248
}
249
250
public
string
GetGPS(
string
hander,
string
strGPS,
string
strFind)
251
{
252
/**/
///
从GPS中读取的数据中,找出想要的数据
253
///
GPSstring原始字符串,
254
///
strFind要查找的内容,X:经度,Y:纬度,T:时间,V:速度,N 当前可用卫星数量,H 当前海拔
255
///
返回查找到指定位置的字符串
256
if
(hander.Equals(
"
$GPRMC
"
))
257
{
258
string
handerStr
=
hander;
//
GPS串头
259
int
findHander
=
strGPS.IndexOf(handerStr);
//
看是否含有GPS串头
260
if
(findHander
<
0
)
261
{
262
return
"
-1
"
;
263
}
264
else
265
{
266
strGPS
=
strGPS.Substring(findHander, strGPS.Length
-
findHander);
267
string
[] ArryTmp
=
strGPS.Split(
"
,
"
.ToCharArray());
268
try
269
{
270
if
(ArryTmp[
2
]
==
"
V
"
)
271
{
272
return
"
GPS没有信号
"
;
//
没有信号
273
}
274
else
275
{
276
switch
(strFind)
277
{
278
case
"
X
"
:
279
return
DM2DD(ArryTmp[
5
]);
280
281
case
"
Y
"
:
282
return
DM2DD(ArryTmp[
3
]);
283
284
case
"
T
"
:
285
return
T2Time(ArryTmp[
9
], ArryTmp[
1
]);
286
287
case
"
V
"
:
288
return
Convert.ToString(Convert.ToDouble(ArryTmp[
7
])
*
1.852
);
289
290
case
"
K
"
:
291
return
ArryTmp[
7
];
292
default
:
293
return
"
V
"
;
294
295
}
296
}
297
}
298
catch
299
{
300
return
"
V
"
;
301
}
302
}
303
}
304
else
if
(hander.Equals(
"
$GPGGA
"
))
305
{
306
string
handerStr
=
hander;
//
GPS串头
307
int
findHander
=
strGPS.IndexOf(handerStr);
//
看是否含有GPS串头
308
if
(findHander
<
0
)
309
{
310
return
"
-1
"
;
311
}
312
else
313
{
314
strGPS
=
strGPS.Substring(findHander, strGPS.Length
-
findHander);
315
string
[] ArryTmp
=
strGPS.Split(
"
,
"
.ToCharArray());
316
switch
(strFind)
317
{
318
case
"
N
"
:
319
return
ArryTmp[
7
];
320
case
"
H
"
:
321
return
ArryTmp[
9
];
322
default
:
323
return
"
无法解析的命令.
"
;
324
}
325
}
326
}
327
328
return
null
;
329
330
}
331
332
public
string
T2Time(
string
strDate,
string
strTime)
333
{
334
string
dT
=
"
20
"
+
strDate.Substring(
4
,
2
)
+
"
-
"
+
strDate.Substring(
2
,
2
)
+
"
-
"
+
strDate.Substring(
0
,
2
);
335
string
TT
=
Convert.ToString(Convert.ToInt32(strTime.Substring(
0
,
2
)))
+
"
:
"
+
strTime.Substring(
2
,
2
)
+
"
:
"
+
strTime.Substring(
4
,
2
);
336
DateTime T
=
Convert.ToDateTime(dT
+
"
"
+
TT);
337
T
=
T.AddHours(
8
);
338
return
T.ToString();
339
}
340
341
public
string
DM2DD(
string
DegreeMinutes)
342
{
343
//
转换NMEA协议的“度分”格式为十进制“度度”格式
344
string
sDegree;
345
string
sMinute;
346
string
sReturn
=
""
;
347
if
(DegreeMinutes.IndexOf(
"
.
"
)
==
4
)
348
{
349
//
DegreeMinutes = Replace(DegreeMinutes, ".", "")
350
//
DM2DD = CDbl(Left(DegreeMinutes, 2)) + CDbl(Left(CStr(CDbl(Right(DegreeMinutes, Len(DegreeMinutes) - 2)) / 60), 8)) / 10000
351
DegreeMinutes
=
DegreeMinutes.Replace(
"
.
"
,
""
);
352
double
sDegree1
=
Convert.ToDouble(DegreeMinutes.Substring(
0
,
2
));
353
double
sDegree2
=
Convert.ToDouble(DegreeMinutes.Substring(
2
,DegreeMinutes.Length
-
2
));
354
string
sTmp
=
Convert.ToString(sDegree2
/
60
);
355
sDegree2
=
Convert.ToDouble(sTmp.Substring(
0
,sTmp.Length));
356
sDegree2
=
sDegree2
/
10000
;
357
sDegree
=
Convert.ToString(sDegree1
+
sDegree2);
358
if
(sDegree.Length
>
11
)
359
sDegree
=
sDegree.Substring(
0
,
11
);
360
sReturn
=
sDegree;
361
}
362
else
if
(DegreeMinutes.IndexOf(
"
.
"
)
==
5
)
363
{
364
//
DegreeMinutes = Replace(DegreeMinutes, ".", "")
365
//
DM2DD = CDbl(Left(DegreeMinutes, 2)) + CDbl(Left(CStr(CDbl(Right(DegreeMinutes, Len(DegreeMinutes) - 2)) / 60), 8)) / 10000
366
DegreeMinutes
=
DegreeMinutes.Replace(
"
.
"
,
""
);
367
double
sMinute1
=
Convert.ToDouble(DegreeMinutes.Substring(
0
,
3
));
368
double
sMinute2
=
Convert.ToDouble(DegreeMinutes.Substring(
3
,DegreeMinutes.Length
-
3
));
369
string
sTmp
=
Convert.ToString(sMinute2
/
60
);
370
sMinute2
=
Convert.ToDouble(sTmp.Substring(
0
,sTmp.Length));
371
sMinute2
=
sMinute2
/
10000
;
372
sMinute
=
Convert.ToString(sMinute1
+
sMinute2);
373
if
(sMinute.Length
>
10
)
374
sMinute
=
sMinute.Substring(
0
,
10
);
375
sReturn
=
sMinute;
376
}
377
return
sReturn;
378
}
379
380
public
bool
ScanPort()
381
{
382
383
try
384
{
385
if
(Opened)
386
{
387
Close();
388
Open();
389
}
390
else
391
{
392
Open();
//
打开串口
393
394
}
395
byte
[] bytRead
=
Read(
512
);
396
Close();
397
if
(Encoding.ASCII.GetString(bytRead,
0
,bytRead.Length).IndexOf(
"
$GP
"
)
>=
0
)
398
return
true
;
399
else
400
return
false
;
401
}
402
catch
403
{
404
return
false
;
405
}
406
407
}
408
}
409
410
class
HexCon
411
{
412
//
把十六进制字符串转换成字节型和把字节型转换成十六进制字符串 converter hex string to byte and byte to hex string
413
public
static
string
ByteToString(
byte
[] InBytes)
414
{
415
string
StringOut
=
""
;
416
foreach
(
byte
InByte
in
InBytes)
417
{
418
StringOut
=
StringOut
+
String.Format(
"
{0:X2}
"
,InByte);
419
}
420
return
StringOut;
421
}
422
public
static
byte
[] StringToByte(
string
InString)
423
{
424
string
[] ByteStrings;
425
ByteStrings
=
InString.Split(
"
"
.ToCharArray());
426
byte
[] ByteOut;
427
ByteOut
=
new
byte
[ByteStrings.Length
-
1
];
428
for
(
int
i
=
0
;i
==
ByteStrings.Length
-
1
;i
++
)
429
{
430
ByteOut[i]
=
Convert.ToByte((
"
0x
"
+
ByteStrings[i]));
431
}
432
return
ByteOut;
433
}
434
435
}
436
}
437
调用很简单:
1
GPS ss_port
=
new
GPS();
2
ss_port.PortNum
=
"
COM4:
"
;
//
串口号.后面一定要有':'
3
ss_port.BaudRate
=
4800
;
4
ss_port.ByteSize
=
8
;
5
ss_port.Parity
=
0
;
6
ss_port.StopBits
=
1
;
7
ss_port.ReadTimeout
=
1000
;
8
9
try
10
{
11
if
(ss_port.Opened)
12
{
13
ss_port.Close();
14
ss_port.Open();
15
timer1.Enabled
=
true
;
16
}
17
else
18
{
19
ss_port.Open();
//
打开串口
20
label1.Text
=
"
已打开
"
;
21
timer1.Enabled
=
true
;
22
}
23
24
}
25
catch
(Exception e1)
26
{
27
label1.Text
=
e1.Message;
28
29
}
在PDA中获取GPS信息。
近日一个项目需要用在PDA上读
取GPS卫星信号,在网上搜了一圈,整理出一个GPS的类,大家可以直接加入项目
使用。可以获得当前的经纬度、海拔、速度、连接卫星数等信息
Code
1
using
System;
2
using
System.Collections.Generic;
3
using
System.Text;
4
using
System.Runtime.InteropServices;
5
6
namespace
AnhlYiling
7
{
8
public
class
GPS
9
{
10
11
public
string
PortNum;
12
public
int
BaudRate;
13
public
byte
ByteSize;
14
public
byte
Parity;
//
0-4=no,odd,even,mark,space
15
public
byte
StopBits;
//
0,1,2 = 1, 1.5, 2
16
public
int
ReadTimeout;
17
18
//
comm port win32 file handle
19
private
int
hComm
=
-
1
;
20
21
public
bool
Opened
=
false
;
22
23
//
win32 api constants
24
private
const
uint
GENERIC_READ
=
0x80000000
;
25
private
const
uint
GENERIC_WRITE
=
0x40000000
;
26
private
const
int
OPEN_EXISTING
=
3
;
27
private
const
int
INVALID_HANDLE_VALUE
=
-
1
;
28
29
[StructLayout(LayoutKind.Sequential)]
30
public
struct
DCB
31
{
32
//
taken from c struct in platform sdk
33
public
int
DCBlength;
//
sizeof(DCB)
34
public
int
BaudRate;
//
指定当前波特率 current baud rate
35
//
these are the c struct bit fields, bit twiddle flag to set
36
public
int
fBinary;
//
指定是否允许二进制模式,在windows95中必须主TRUE binary mode, no EOF check
37
public
int
fParity;
//
指定是否允许奇偶校验 enable parity checking
38
public
int
fOutxCtsFlow;
//
指定CTS是否用于检测发送控制,当为TRUE是CTS为OFF,发送将被挂起。 CTS output flow control
39
public
int
fOutxDsrFlow;
//
指定CTS是否用于检测发送控制 DSR output flow control
40
public
int
fDtrControl;
//
DTR_CONTROL_DISABLE值将DTR置为OFF, DTR_CONTROL_ENABLE值将DTR置为ON, DTR_CONTROL_HANDSHAKE允许DTR"握手" DTR flow control type
41
public
int
fDsrSensitivity;
//
当该值为TRUE时DSR为OFF时接收的字节被忽略 DSR sensitivity
42
public
int
fTXContinueOnXoff;
//
指
定当接收缓冲区已满,并且驱动程序已经发送出XoffChar字符时发送是否停止。TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动
程序已经发送出XoffChar字符中止接收字节之后,发送继续进行。 FALSE时,在接收缓冲区接收到代表缓冲区已空的字节XonChar且驱动程序
已经发送出恢复发送的XonChar之后,发送继续进行。XOFF continues Tx
43
public
int
fOutX;
//
TRUE时,接收到XoffChar之后便停止发送接收到XonChar之后将重新开始 XON/XOFF out flow control
44
public
int
fInX;
//
TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去接收缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去 XON/XOFF in flow control
45
public
int
fErrorChar;
//
该值为TRUE且fParity为TRUE时,用ErrorChar 成员指定的字符代替奇偶校验错误的接收字符 enable error replacement
46
public
int
fNull;
//
eTRUE时,接收时去掉空(0值)字节 enable null stripping
47
public
int
fRtsControl;
//
RTS flow control
48
/**/
/*
RTS_CONTROL_DISABLE时,RTS置为OFF
49
RTS_CONTROL_ENABLE时, RTS置为ON
50
RTS_CONTROL_HANDSHAKE时,
51
当接收缓冲区小于半满时RTS为ON
52
当接收缓冲区超过四分之三满时RTS为OFF
53
RTS_CONTROL_TOGGLE时,
54
当接收缓冲区仍有剩余字节时RTS为ON ,否则缺省为OFF
*/
55
56
public
int
fAbortOnError;
//
TRUE时,有错误发生时中止读和写操作 abort on error
57
public
int
fDummy2;
//
未使用 reserved
58
59
public
uint
flags;
60
public
ushort
wReserved;
//
未使用,必须为0 not currently used
61
public
ushort
XonLim;
//
指定在XON字符发送这前接收缓冲区中可允许的最小字节数 transmit XON threshold
62
public
ushort
XoffLim;
//
指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数 transmit XOFF threshold
63
public
byte
ByteSize;
//
指定端口当前使用的数据位 number of bits/byte, 4-8
64
public
byte
Parity;
//
指定端口当前使用的奇偶校验方法,可能为:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY 0-4=no,odd,even,mark,space
65
public
byte
StopBits;
//
指定端口当前使用的停止位数,可能为:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS 0,1,2 = 1, 1.5, 2
66
public
char
XonChar;
//
指定用于发送和接收字符XON的值 Tx and Rx XON character
67
public
char
XoffChar;
//
指定用于发送和接收字符XOFF值 Tx and Rx XOFF character
68
public
char
ErrorChar;
//
本字符用来代替接收到的奇偶校验发生错误时的值 error replacement character
69
public
char
EofChar;
//
当没有使用二进制模式时,本字符可用来指示数据的结束 end of input character
70
public
char
EvtChar;
//
当接收到此字符时,会产生一个事件 received event character
71
public
ushort
wReserved1;
//
未使用 reserved; do not use
72
}
73
74
[StructLayout(LayoutKind.Sequential)]
75
private
struct
COMMTIMEOUTS
76
{
77
public
int
ReadIntervalTimeout;
78
public
int
ReadTotalTimeoutMultiplier;
79
public
int
ReadTotalTimeoutConstant;
80
public
int
WriteTotalTimeoutMultiplier;
81
public
int
WriteTotalTimeoutConstant;
82
}
83
84
[StructLayout(LayoutKind.Sequential)]
85
private
struct
OVERLAPPED
86
{
87
public
int
Internal;
88
public
int
InternalHigh;
89
public
int
Offset;
90
public
int
OffsetHigh;
91
public
int
hEvent;
92
}
93
94
[DllImport(
"
coredll.dll
"
)]
95
private
static
extern
int
CreateFile(
96
string
lpFileName,
//
要打开的串口名称
97
uint
dwDesiredAccess,
//
指定串口的访问方式,一般设置为可读可写方式
98
int
dwShareMode,
//
指定串口的共享模式,串口不能共享,所以设置为0
99
int
lpSecurityAttributes,
//
设置串口的安全属性,WIN9X下不支持,应设为NULL
100
int
dwCreationDisposition,
//
对于串口通信,创建方式只能为OPEN_EXISTING
101
int
dwFlagsAndAttributes,
//
指定串口属性与标志,设置为FILE_FLAG_OVERLAPPED(重叠I/O操作),指定串口以异步方式通信
102
int
hTemplateFile
//
对于串口通信必须设置为NULL
103
);
104
[DllImport(
"
coredll.dll
"
)]
105
private
static
extern
bool
GetCommState(
106
int
hFile,
//
通信设备句柄
107
ref
DCB lpDCB
//
设备控制块DCB
108
);
109
[DllImport(
"
coredll.dll
"
)]
110
private
static
extern
bool
BuildCommDCB(
111
string
lpDef,
//
设备控制字符串
112
ref
DCB lpDCB
//
设备控制块
113
);
114
[DllImport(
"
coredll.dll
"
)]
115
private
static
extern
bool
SetCommState(
116
int
hFile,
//
通信设备句柄
117
ref
DCB lpDCB
//
设备控制块
118
);
119
[DllImport(
"
coredll.dll
"
)]
120
private
static
extern
bool
GetCommTimeouts(
121
int
hFile,
//
通信设备句柄 handle to comm device
122
ref
COMMTIMEOUTS lpCommTimeouts
//
超时时间 time-out values
123
);
124
[DllImport(
"
coredll.dll
"
)]
125
private
static
extern
bool
SetCommTimeouts(
126
int
hFile,
//
通信设备句柄 handle to comm device
127
ref
COMMTIMEOUTS lpCommTimeouts
//
超时时间 time-out values
128
);
129
[DllImport(
"
coredll.dll
"
)]
130
private
static
extern
bool
ReadFile(
131
int
hFile,
//
通信设备句柄 handle to file
132
byte
[] lpBuffer,
//
数据缓冲区 data buffer
133
int
nNumberOfBytesToRead,
//
多少字节等待读取 number of bytes to read
134
ref
int
lpNumberOfBytesRead,
//
读取多少字节 number of bytes read
135
ref
OVERLAPPED lpOverlapped
//
溢出缓冲区 overlapped buffer
136
);
137
[DllImport(
"
coredll.dll
"
)]
138
private
static
extern
bool
WriteFile(
139
int
hFile,
//
通信设备句柄 handle to file
140
byte
[] lpBuffer,
//
数据缓冲区 data buffer
141
int
nNumberOfBytesToWrite,
//
多少字节等待写入 number of bytes to write
142
ref
int
lpNumberOfBytesWritten,
//
已经写入多少字节 number of bytes written
143
ref
OVERLAPPED lpOverlapped
//
溢出缓冲区 overlapped buffer
144
);
145
[DllImport(
"
coredll.dll
"
)]
146
private
static
extern
bool
CloseHandle(
147
int
hObject
//
handle to object
148
);
149
[DllImport(
"
coredll.dll
"
)]
150
private
static
extern
uint
GetLastError();
151
152
public
void
Open()
153
{
154
155
DCB dcbCommPort
=
new
DCB();
156
COMMTIMEOUTS ctoCommPort
=
new
COMMTIMEOUTS();
157
158
//
打开串口 OPEN THE COMM PORT.
159
hComm
=
CreateFile(PortNum ,GENERIC_READ
|
GENERIC_WRITE,
0
,
0
,OPEN_EXISTING,
0
,
0
);
160
//
如果串口没有打开,就打开 IF THE PORT CANNOT BE OPENED, BAIL OUT.
161
if
(hComm
==
INVALID_HANDLE_VALUE)
162
{
163
throw
(
new
ApplicationException(
"
非法操作,不能打开串口!
"
));
164
}
165
166
//
设置通信超时时间 SET THE COMM TIMEOUTS.
167
GetCommTimeouts(hComm,
ref
ctoCommPort);
168
ctoCommPort.ReadTotalTimeoutConstant
=
ReadTimeout;
169
ctoCommPort.ReadTotalTimeoutMultiplier
=
0
;
170
ctoCommPort.WriteTotalTimeoutMultiplier
=
0
;
171
ctoCommPort.WriteTotalTimeoutConstant
=
0
;
172
SetCommTimeouts(hComm,
ref
ctoCommPort);
173
174
//
设置串口 SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.
175
GetCommState(hComm,
ref
dcbCommPort);
176
dcbCommPort.BaudRate
=
BaudRate;
177
dcbCommPort.flags
=
0
;
178
//
dcb.fBinary=1;
179
dcbCommPort.flags
|=
1
;
180
if
(Parity
>
0
)
181
{
182
//
dcb.fParity=1
183
dcbCommPort.flags
|=
2
;
184
}
185
dcbCommPort.Parity
=
Parity;
186
dcbCommPort.ByteSize
=
ByteSize;
187
dcbCommPort.StopBits
=
StopBits;
188
if
(
!
SetCommState(hComm,
ref
dcbCommPort))
189
{
190
//
uint ErrorNum=GetLastError();
191
throw
(
new
ApplicationException(
"
非法操作,不能打开串口!
"
));
192
}
193
//
unremark to see if setting took correctly
194
//
DCB dcbCommPort2 = new DCB();
195
//
GetCommState(hComm, ref dcbCommPort2);
196
Opened
=
true
;
197
}
198
199
public
void
Close()
200
{
201
if
(hComm
!=
INVALID_HANDLE_VALUE)
202
{
203
CloseHandle(hComm);
204
}
205
}
206
207
public
byte
[] Read(
int
NumBytes)
208
{
209
byte
[] BufBytes;
210
byte
[] OutBytes;
211
BufBytes
=
new
byte
[NumBytes];
212
if
(hComm
!=
INVALID_HANDLE_VALUE)
213
{
214
OVERLAPPED ovlCommPort
=
new
OVERLAPPED();
215
int
BytesRead
=
0
;
216
ReadFile(hComm,BufBytes,NumBytes,
ref
BytesRead,
ref
ovlCommPort);
217
try
218
{
219
OutBytes
=
new
byte
[BytesRead];
220
Array.Copy(BufBytes,
0
,OutBytes,
0
,BytesRead);
221
}
222
catch
223
{
224
return
BufBytes;
225
}
226
227
}
228
else
229
{
230
throw
(
new
ApplicationException(
"
串口未打开!
"
));
231
}
232
return
OutBytes;
233
//
return BufBytes;
234
}
235
236
public
void
Write(
byte
[] WriteBytes)
237
{
238
if
(hComm
!=
INVALID_HANDLE_VALUE)
239
{
240
OVERLAPPED ovlCommPort
=
new
OVERLAPPED();
241
int
BytesWritten
=
0
;
242
WriteFile(hComm,WriteBytes,WriteBytes.Length,
ref
BytesWritten,
ref
ovlCommPort);
243
}
244
else
245
{
246
throw
(
new
ApplicationException(
"
串口未打开!
"
));
247
}
248
}
249
250
public
string
GetGPS(
string
hander,
string
strGPS,
string
strFind)
251
{
252
/**/
///
从GPS中读取的数据中,找出想要的数据
253
///
GPSstring原始字符串,
254
///
strFind要查找的内容,X:经度,Y:纬度,T:时间,V:速度,N 当前可用卫星数量,H 当前海拔
255
///
返回查找到指定位置的字符串
256
if
(hander.Equals(
"
$GPRMC
"
))
257
{
258
string
handerStr
=
hander;
//
GPS串头
259
int
findHander
=
strGPS.IndexOf(handerStr);
//
看是否含有GPS串头
260
if
(findHander
<
0
)
261
{
262
return
"
-1
"
;
263
}
264
else
265
{
266
strGPS
=
strGPS.Substring(findHander, strGPS.Length
-
findHander);
267
string
[] ArryTmp
=
strGPS.Split(
"
,
"
.ToCharArray());
268
try
269
{
270
if
(ArryTmp[
2
]
==
"
V
"
)
271
{
272
return
"
GPS没有信号
"
;
//
没有信号
273
}
274
else
275
{
276
switch
(strFind)
277
{
278
case
"
X
"
:
279
return
DM2DD(ArryTmp[
5
]);
280
281
case
"
Y
"
:
282
return
DM2DD(ArryTmp[
3
]);
283
284
case
"
T
"
:
285
return
T2Time(ArryTmp[
9
], ArryTmp[
1
]);
286
287
case
"
V
"
:
288
return
Convert.ToString(Convert.ToDouble(ArryTmp[
7
])
*
1.852
);
289
290
case
"
K
"
:
291
return
ArryTmp[
7
];
292
default
:
293
return
"
V
"
;
294
295
}
296
}
297
}
298
catch
299
{
300
return
"
V
"
;
301
}
302
}
303
}
304
else
if
(hander.Equals(
"
$GPGGA
"
))
305
{
306
string
handerStr
=
hander;
//
GPS串头
307
int
findHander
=
strGPS.IndexOf(handerStr);
//
看是否含有GPS串头
308
if
(findHander
<
0
)
309
{
310
return
"
-1
"
;
311
}
312
else
313
{
314
strGPS
=
strGPS.Substring(findHander, strGPS.Length
-
findHander);
315
string
[] ArryTmp
=
strGPS.Split(
"
,
"
.ToCharArray());
316
switch
(strFind)
317
{
318
case
"
N
"
:
319
return
ArryTmp[
7
];
320
case
"
H
"
:
321
return
ArryTmp[
9
];
322
default
:
323
return
"
无法解析的命令.
"
;
324
}
325
}
326
}
327
328
return
null
;
329
330
}
331
332
public
string
T2Time(
string
strDate,
string
strTime)
333
{
334
string
dT
=
"
20
"
+
strDate.Substring(
4
,
2
)
+
"
-
"
+
strDate.Substring(
2
,
2
)
+
"
-
"
+
strDate.Substring(
0
,
2
);
335
string
TT
=
Convert.ToString(Convert.ToInt32(strTime.Substring(
0
,
2
)))
+
"
:
"
+
strTime.Substring(
2
,
2
)
+
"
:
"
+
strTime.Substring(
4
,
2
);
336
DateTime T
=
Convert.ToDateTime(dT
+
"
"
+
TT);
337
T
=
T.AddHours(
8
);
338
return
T.ToString();
339
}
340
341
public
string
DM2DD(
string
DegreeMinutes)
342
{
343
//
转换NMEA协议的“度分”格式为十进制“度度”格式
344
string
sDegree;
345
string
sMinute;
346
string
sReturn
=
""
;
347
if
(DegreeMinutes.IndexOf(
"
.
"
)
==
4
)
348
{
349
//
DegreeMinutes = Replace(DegreeMinutes, ".", "")
350
//
DM2DD = CDbl(Left(DegreeMinutes, 2)) + CDbl(Left(CStr(CDbl(Right(DegreeMinutes, Len(DegreeMinutes) - 2)) / 60), 8)) / 10000
351
DegreeMinutes
=
DegreeMinutes.Replace(
"
.
"
,
""
);
352
double
sDegree1
=
Convert.ToDouble(DegreeMinutes.Substring(
0
,
2
));
353
double
sDegree2
=
Convert.ToDouble(DegreeMinutes.Substring(
2
,DegreeMinutes.Length
-
2
));
354
string
sTmp
=
Convert.ToString(sDegree2
/
60
);
355
sDegree2
=
Convert.ToDouble(sTmp.Substring(
0
,sTmp.Length));
356
sDegree2
=
sDegree2
/
10000
;
357
sDegree
=
Convert.ToString(sDegree1
+
sDegree2);
358
if
(sDegree.Length
>
11
)
359
sDegree
=
sDegree.Substring(
0
,
11
);
360
sReturn
=
sDegree;
361
}
362
else
if
(DegreeMinutes.IndexOf(
"
.
"
)
==
5
)
363
{
364
//
DegreeMinutes = Replace(DegreeMinutes, ".", "")
365
//
DM2DD = CDbl(Left(DegreeMinutes, 2)) + CDbl(Left(CStr(CDbl(Right(DegreeMinutes, Len(DegreeMinutes) - 2)) / 60), 8)) / 10000
366
DegreeMinutes
=
DegreeMinutes.Replace(
"
.
"
,
""
);
367
double
sMinute1
=
Convert.ToDouble(DegreeMinutes.Substring(
0
,
3
));
368
double
sMinute2
=
Convert.ToDouble(DegreeMinutes.Substring(
3
,DegreeMinutes.Length
-
3
));
369
string
sTmp
=
Convert.ToString(sMinute2
/
60
);
370
sMinute2
=
Convert.ToDouble(sTmp.Substring(
0
,sTmp.Length));
371
sMinute2
=
sMinute2
/
10000
;
372
sMinute
=
Convert.ToString(sMinute1
+
sMinute2);
373
if
(sMinute.Length
>
10
)
374
sMinute
=
sMinute.Substring(
0
,
10
);
375
sReturn
=
sMinute;
376
}
377
return
sReturn;
378
}
379
380
public
bool
ScanPort()
381
{
382
383
try
384
{
385
if
(Opened)
386
{
387
Close();
388
Open();
389
}
390
else
391
{
392
Open();
//
打开串口
393
394
}
395
byte
[] bytRead
=
Read(
512
);
396
Close();
397
if
(Encoding.ASCII.GetString(bytRead,
0
,bytRead.Length).IndexOf(
"
$GP
"
)
>=
0
)
398
return
true
;
399
else
400
return
false
;
401
}
402
catch
403
{
404
return
false
;
405
}
406
407
}
408
}
409
410
class
HexCon
411
{
412
//
把十六进制字符串转换成字节型和把字节型转换成十六进制字符串 converter hex string to byte and byte to hex string
413
public
static
string
ByteToString(
byte
[] InBytes)
414
{
415
string
StringOut
=
""
;
416
foreach
(
byte
InByte
in
InBytes)
417
{
418
StringOut
=
StringOut
+
String.Format(
"
{0:X2}
"
,InByte);
419
}
420
return
StringOut;
421
}
422
public
static
byte
[] StringToByte(
string
InString)
423
{
424
string
[] ByteStrings;
425
ByteStrings
=
InString.Split(
"
"
.ToCharArray());
426
byte
[] ByteOut;
427
ByteOut
=
new
byte
[ByteStrings.Length
-
1
];
428
for
(
int
i
=
0
;i
==
ByteStrings.Length
-
1
;i
++
)
429
{
430
ByteOut[i]
=
Convert.ToByte((
"
0x
"
+
ByteStrings[i]));
431
}
432
return
ByteOut;
433
}
434
435
}
436
}
437
调用很简单:
1
GPS ss_port
=
new
GPS();
2
ss_port.PortNum
=
"
COM4:
"
;
//
串口号.后面一定要有':'
3
ss_port.BaudRate
=
4800
;
4
ss_port.ByteSize
=
8
;
5
ss_port.Parity
=
0
;
6
ss_port.StopBits
=
1
;
7
ss_port.ReadTimeout
=
1000
;
8
9
try
10
{
11
if
(ss_port.Opened)
12
{
13
ss_port.Close();
14
ss_port.Open();
15
timer1.Enabled
=
true
;
16
}
17
else
18
{
19
ss_port.Open();
//
打开串口
20
label1.Text
=
"
已打开
"
;
21
timer1.Enabled
=
true
;
22
}
23
24
}
25
catch
(Exception e1)
26
{
27
label1.Text
=
e1.Message;
28
29
}
相关文章推荐
- 在PDA中获取GPS信息
- 在PDA中获取GPS信息。
- Android开发程序获取GPS信息步骤
- Android初级教程获取手机位置信息GPS与动态获取最佳方式
- Android 打开 GPS 导航并获取位置信息
- GPS项目\通过经纬度获取地址信息之百度地图API
- [IOS开发记录]ios10下使用Xcode8.2获取gps位置信息(swift3.0)
- Android 打开 GPS 导航并获取位置信息
- 通过 GPS 信息获取当前所在城市名的代码
- android之GPS或网络获取经纬度信息
- Android打开GPS导航并获取位置信息返回null解决方案
- 通过 GPS 信息获取当前所在城市名的代码
- Android中使用GPS和NetWork获取定位信息
- 通过 GPS 信息获取当前所在城市名的代码
- 使用GPS获取定位信息
- 通过GPS获取位置信息
- C# 如何获取照片中Exif信息里GPS信息与经纬度数
- [GoogleMap/GPS] 为啥getLastKnownLocation获取不到坐标信息?
- android GPS 获取城市信息
- Android GPS应用:动态获取位置信息