使用SerialPort读取GPS数据
使用C#的SerialPort在多普达P800上读取GPS数据
重新回到这个问题上,项目升级后要在.NetCF 3.5下工作,但是这个Monitor无论如何也不能工作了,无法读取,总是返回超时错误或者OutOfMenoryException,做了几个实验发现,在2.0下可以工作,不知道是不是netcf3.5的问题。顺便做了点小改动。
----
近期开发一个基于多普达P800的GPS应用,使用Microsoft的例子不能读取其中的具体数据,于是找了点资料,写了一个串口读取的类。在多普达p800,VS2005下调试“可用”,以前也没接触过,摸着石头过河吧。
已知问题:
1.波特率设置过高偶尔出现死机情况,也不一定是死机,但是失去反应了。不爱等,直接拔电池复位。
2.读取过程中经常出现OutOfMemoryException,分步调试未见异常,但速度哦过慢则读取不全。
3.除了端口不能打开,应用时不应该处理任何错误,否则容易引起程序停止响应或退出。原因不明。
GpsMonitor
1using System;
2using System.IO.Ports;
3using System.Collections;
4using System.Collections.Generic;
5using System.Windows.Forms;
6using System.Runtime.InteropServices;
7
8namespace Lordeo.AssetMan.PPC.App
9{
10 public class GpsMonitor
11 {
12 private SerialPort m_serialPort;
13
14 private System.Windows.Forms.Timer m_timer;
15 private const int defaultTimerInterval = 800; //越快越容易出错
16 //读取到事件
17 public event EventHandler OnDataRecieved;
18 //临时存储读取的信息
19 private string m_dataReaded = string.Empty;
20
21 /**//// <summary>
22 /// 构造
23 /// </summary>
24 public GpsMonitor()
25 {
26 //timer
27 m_timer = new System.Windows.Forms.Timer();
28 m_timer.Interval = defaultTimerInterval;
29 m_timer.Tick += new EventHandler(Timer_Tick);
30
31 //设置端口的默认值
32 m_serialPort = new SerialPort();
33 m_serialPort.ReadBufferSize = 2048;
34 m_serialPort.BaudRate = 4800; //P800默认的速率,过高的速率容易产生误码
35 m_serialPort.DataBits = 8;
36 m_serialPort.Parity = Parity.None;
37 m_serialPort.StopBits = StopBits.One;
38 m_serialPort.ReadTimeout = 2000;//超时
39 m_serialPort.PortName = "COM4"; //多数GPS都用COM4
40
41 m_serialPort.ErrorReceived += new SerialErrorReceivedEventHandler(SerialPort_ErrorReceived);
42 }
43
44 private void SerialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
45 {
46 this.Message = e.ToString();
47 }
48
49 timer#region timer
50 /**//// <summary>
51 /// 计时器工作
52 /// </summary>
53 /// <param name="sender"></param>
54 /// <param name="e"></param>
55 private void Timer_Tick(object sender, EventArgs e)
56 {
57 try
58 {
59 if (!string.IsNullOrEmpty(m_serialPort.ReadLine()))
60 {
61 this.Message = m_serialPort.ReadLine();
62
63
64 }
65 }
66 catch (Exception ex)
67 {
68 if (ex.GetType() == typeof(System.TimeoutException))
69 {
70 //this.StopWatch();
71 this.Message = "操作超时,请确认设备是否已经打开或尝试其他端口。";
72 }
73 }
74 }
75 #endregion
76
77 OpenSerialPort#region OpenSerialPort
78 /**//// <summary>
79 /// 打开端口
80 /// </summary>
81 private void OpenSerialPort()
82 {
83 if (!m_serialPort.IsOpen)
84 {
85 try
86 {
87 m_serialPort.Open();
88 }
89 catch (Exception x)
90 {
91 this.Message = x.Message;
92 this.StopWatch();
93 }
94 }
95 }
96 #endregion
97
98 CloseSerialPort#region CloseSerialPort
99 /**//// <summary>
100 /// 关闭端口
101 /// </summary>
102 private void CloseSerialPort()
103 {
104 m_serialPort.Close();
105 }
106 #endregion
107
108 properties#region properties
109 /**//// <summary>
110 ///设置读取的时间间隔,单位毫秒
111 /// </summary>
112 public int Interval
113 {
114 set
115 {
116 this.m_timer.Interval = value;
117 }
118 }
119
120
121 /**//// <summary>
122 /// 执行读取
123 /// </summary>
124 public void BeginWatch()
125 {
126 OpenSerialPort();
127 m_timer.Enabled = true;
128 }
129 /**//// <summary>
130 /// 停止读取
131 /// </summary>
132 public void StopWatch()
133 {
134 m_timer.Enabled = false;
135 CloseSerialPort();
136 }
137
138 /**//// <summary>
139 /// 读取到的信息
140 /// </summary>
141 public string Message
142 {
143 set
144 {
145 m_dataReaded = value;
146 OnDataRecieved(this, null);
147 }
148 get
149 {
150 return m_dataReaded;
151 }
152 }
153
154 /**//// <summary>
155 /// 设置波特率
156 /// </summary>
157 public int BaudRate
158 {
159 get { return m_serialPort.BaudRate; }
160 set { m_serialPort.BaudRate = value; }
161 }
162
163 /**//// <summary>
164 /// 数据位
165 /// </summary>
166 public int DataBits
167 {
168 get { return m_serialPort.DataBits; }
169 set { m_serialPort.DataBits = value; }
170 }
171 /**//// <summary>
172 /// 校验协议
173 /// </summary>
174 public Parity ParityType
175 {
176 get { return m_serialPort.Parity; }
177 set { m_serialPort.Parity = value; }
178 }
179 /**//// <summary>
180 /// 停止位
181 /// </summary>
182 public StopBits StopBitsType
183 {
184 get { return m_serialPort.StopBits; }
185 set { m_serialPort.StopBits = value; }
186 }
187 /**//// <summary>
188 /// 端口号
189 /// </summary>
190 public string PortName
191 {
192 get { return m_serialPort.PortName; }
193 set { m_serialPort.PortName = value; }
194 }
195 #endregion
196
197 获取可用端口#region 获取可用端口
198 /**//// <summary>
199 /// 获取本机可用端口名称
200 /// </summary>
201 /// <returns></returns>
202 public string[] GetPortNames()
203 {
204 ArrayList ports = new ArrayList();
205
206 uint hPort = INVALID_FILE_HANDLE;
207
208 string port = string.Empty;
209
210 for (int i = 0; i < 10; i++)
211 {
212 port = "COM" + i.ToString() + ":";
213
214 hPort = CreateFile(port, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, IntPtr.Zero);
215 if (hPort != INVALID_FILE_HANDLE)
216 {
217 ports.Add(port);
218 Console.WriteLine(port);
219 CloseHandle(hPort);
220 }
221 }
222
223 return (string[])ports.ToArray(typeof(string));
224 }
225
226 wince defination#region wince defination
227 private const uint GENERIC_READ = 0x80000000;
228 private const uint OPEN_EXISTING = 3;
229 private const uint INVALID_FILE_HANDLE = 0xFFFFFFFF;
230
231 [DllImport("coredll.dll")]
232 static extern uint CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, uint lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr notUsedPassZero);
233
234 [DllImport("coredll.dll")]
235 static extern int CloseHandle(uint hObject);
236 #endregion
237
238 #endregion
239 }
240}
241
1using System;
2using System.IO.Ports;
3using System.Collections;
4using System.Collections.Generic;
5using System.Windows.Forms;
6using System.Runtime.InteropServices;
7
8namespace Lordeo.AssetMan.PPC.App
9{
10 public class GpsMonitor
11 {
12 private SerialPort m_serialPort;
13
14 private System.Windows.Forms.Timer m_timer;
15 private const int defaultTimerInterval = 800; //越快越容易出错
16 //读取到事件
17 public event EventHandler OnDataRecieved;
18 //临时存储读取的信息
19 private string m_dataReaded = string.Empty;
20
21 /**//// <summary>
22 /// 构造
23 /// </summary>
24 public GpsMonitor()
25 {
26 //timer
27 m_timer = new System.Windows.Forms.Timer();
28 m_timer.Interval = defaultTimerInterval;
29 m_timer.Tick += new EventHandler(Timer_Tick);
30
31 //设置端口的默认值
32 m_serialPort = new SerialPort();
33 m_serialPort.ReadBufferSize = 2048;
34 m_serialPort.BaudRate = 4800; //P800默认的速率,过高的速率容易产生误码
35 m_serialPort.DataBits = 8;
36 m_serialPort.Parity = Parity.None;
37 m_serialPort.StopBits = StopBits.One;
38 m_serialPort.ReadTimeout = 2000;//超时
39 m_serialPort.PortName = "COM4"; //多数GPS都用COM4
40
41 m_serialPort.ErrorReceived += new SerialErrorReceivedEventHandler(SerialPort_ErrorReceived);
42 }
43
44 private void SerialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
45 {
46 this.Message = e.ToString();
47 }
48
49 timer#region timer
50 /**//// <summary>
51 /// 计时器工作
52 /// </summary>
53 /// <param name="sender"></param>
54 /// <param name="e"></param>
55 private void Timer_Tick(object sender, EventArgs e)
56 {
57 try
58 {
59 if (!string.IsNullOrEmpty(m_serialPort.ReadLine()))
60 {
61 this.Message = m_serialPort.ReadLine();
62
63
64 }
65 }
66 catch (Exception ex)
67 {
68 if (ex.GetType() == typeof(System.TimeoutException))
69 {
70 //this.StopWatch();
71 this.Message = "操作超时,请确认设备是否已经打开或尝试其他端口。";
72 }
73 }
74 }
75 #endregion
76
77 OpenSerialPort#region OpenSerialPort
78 /**//// <summary>
79 /// 打开端口
80 /// </summary>
81 private void OpenSerialPort()
82 {
83 if (!m_serialPort.IsOpen)
84 {
85 try
86 {
87 m_serialPort.Open();
88 }
89 catch (Exception x)
90 {
91 this.Message = x.Message;
92 this.StopWatch();
93 }
94 }
95 }
96 #endregion
97
98 CloseSerialPort#region CloseSerialPort
99 /**//// <summary>
100 /// 关闭端口
101 /// </summary>
102 private void CloseSerialPort()
103 {
104 m_serialPort.Close();
105 }
106 #endregion
107
108 properties#region properties
109 /**//// <summary>
110 ///设置读取的时间间隔,单位毫秒
111 /// </summary>
112 public int Interval
113 {
114 set
115 {
116 this.m_timer.Interval = value;
117 }
118 }
119
120
121 /**//// <summary>
122 /// 执行读取
123 /// </summary>
124 public void BeginWatch()
125 {
126 OpenSerialPort();
127 m_timer.Enabled = true;
128 }
129 /**//// <summary>
130 /// 停止读取
131 /// </summary>
132 public void StopWatch()
133 {
134 m_timer.Enabled = false;
135 CloseSerialPort();
136 }
137
138 /**//// <summary>
139 /// 读取到的信息
140 /// </summary>
141 public string Message
142 {
143 set
144 {
145 m_dataReaded = value;
146 OnDataRecieved(this, null);
147 }
148 get
149 {
150 return m_dataReaded;
151 }
152 }
153
154 /**//// <summary>
155 /// 设置波特率
156 /// </summary>
157 public int BaudRate
158 {
159 get { return m_serialPort.BaudRate; }
160 set { m_serialPort.BaudRate = value; }
161 }
162
163 /**//// <summary>
164 /// 数据位
165 /// </summary>
166 public int DataBits
167 {
168 get { return m_serialPort.DataBits; }
169 set { m_serialPort.DataBits = value; }
170 }
171 /**//// <summary>
172 /// 校验协议
173 /// </summary>
174 public Parity ParityType
175 {
176 get { return m_serialPort.Parity; }
177 set { m_serialPort.Parity = value; }
178 }
179 /**//// <summary>
180 /// 停止位
181 /// </summary>
182 public StopBits StopBitsType
183 {
184 get { return m_serialPort.StopBits; }
185 set { m_serialPort.StopBits = value; }
186 }
187 /**//// <summary>
188 /// 端口号
189 /// </summary>
190 public string PortName
191 {
192 get { return m_serialPort.PortName; }
193 set { m_serialPort.PortName = value; }
194 }
195 #endregion
196
197 获取可用端口#region 获取可用端口
198 /**//// <summary>
199 /// 获取本机可用端口名称
200 /// </summary>
201 /// <returns></returns>
202 public string[] GetPortNames()
203 {
204 ArrayList ports = new ArrayList();
205
206 uint hPort = INVALID_FILE_HANDLE;
207
208 string port = string.Empty;
209
210 for (int i = 0; i < 10; i++)
211 {
212 port = "COM" + i.ToString() + ":";
213
214 hPort = CreateFile(port, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, IntPtr.Zero);
215 if (hPort != INVALID_FILE_HANDLE)
216 {
217 ports.Add(port);
218 Console.WriteLine(port);
219 CloseHandle(hPort);
220 }
221 }
222
223 return (string[])ports.ToArray(typeof(string));
224 }
225
226 wince defination#region wince defination
227 private const uint GENERIC_READ = 0x80000000;
228 private const uint OPEN_EXISTING = 3;
229 private const uint INVALID_FILE_HANDLE = 0xFFFFFFFF;
230
231 [DllImport("coredll.dll")]
232 static extern uint CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, uint lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr notUsedPassZero);
233
234 [DllImport("coredll.dll")]
235 static extern int CloseHandle(uint hObject);
236 #endregion
237
238 #endregion
239 }
240}
241