1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9 using System.IO.Ports;
10 using System.Threading;
11 using Microsoft.Win32;
12 using System.IO;
13
14 namespace 串口端口读取地磅
15 {
16 public partial class Form1 : Form
17 {
18 public Form1()
19 {
20 InitializeComponent();
21 }
22 private SerialPort SerialPort1 = new SerialPort();//串口资源对象
23 public delegate void HandleInterfaceUpdataDelegate(string text); //委托,此为重点
24 private HandleInterfaceUpdataDelegate interfaceUpdataHandle;
25 private int FanChongQuChangDu = 15;//读取缓冲区指定长度
26
27 /*
28 *特别注意:地磅电子秤如果输出接口接错,收到的则是乱码
29 */
30
31 public void Sp_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
32 {
33 try
34 {
35 if (SerialPort1.IsOpen)//端口打开中
36 {
37 string strTemp = "";
38 //程序等待0.5秒让缓冲区获取串口数据
39 double iSecond = 0.5;
40
41 DateTime dtOld = System.DateTime.Now;
42 DateTime dtNow = System.DateTime.Now;
43 TimeSpan dtInter;
44 dtInter = dtNow - dtOld;
45
46 int i = SerialPort1.BytesToRead;
47 if (i > 0)
48 {
49 try
50 {
51 strTemp = SerialPort1.ReadExisting();
52 }
53 catch
54 { }
55 if (strTemp.ToLower().IndexOf("\r") < 0)
56 {
57 i = 0;
58 }
59 else
60 {
61 this.Invoke(interfaceUpdataHandle, strTemp);
62 }
63 }
64 while (dtInter.TotalSeconds < iSecond && i <= 0)
65 {
66 dtNow = System.DateTime.Now;
67 dtInter = dtNow - dtOld;
68 i = SerialPort1.BytesToRead;
69 if (i > 0)
70 {
71 try
72 {
73 strTemp += SerialPort1.ReadExisting();
74 }
75 catch
76 { }
77 if (strTemp.ToLower().IndexOf("\r") < 0)
78 {
79 i = 0;
80 }
81 else
82 {
83 this.Invoke(interfaceUpdataHandle, strTemp);
84 }
85 }
86 }
87 }
88 }
89 catch (Exception cw)
90 {
91 MessageBox.Show(cw.ToString());
92 return ;
93 }
94
95 }
96
97 private void UpdateTextBox(string text)
98 {
99
100 txtShiShiZhongLiang.Text = text;
101
102 if (SerialPort1.IsOpen)//端口打开
103 {
104 txtState.Text = "端口连接中";
105 }
106 else
107 {
108 txtState.Text = "端口已断开";
109 }
110 }
111
112 /// <summary>
113 /// 执行AT指令并返回 成功失败
114 /// </summary>
115 /// <param name="ATCmd">AT指令</param>
116 /// <param name="StCmd">AT指令标准结束标识</param>
117 /// <returns></returns>
118 private void ATCommand3(string ATCmd, string StCmd)
119 {
120 string response = "";
121 response = ATCommand(ATCmd, StCmd);
122 }
123
124 /// <summary>
125 /// 执行AT指令并返回结果字符
126 /// </summary>
127 /// <param name="ATCmd">AT指令</param>
128 /// <param name="StCmd">AT指令标准结束标识</param>
129 /// <returns></returns>
130 private string ATCommand(string ATCmd, string StCmd)
131 {
132 string response = "";
133 int i;
134 if (!ATCmd.EndsWith("\x01a"))
135 {
136 if (!(ATCmd.EndsWith("\r") || ATCmd.EndsWith("\r\n")))
137 {
138 ATCmd = ATCmd + "\r";
139 }
140 }
141 SerialPort1.WriteLine(ATCmd);
142
143 //第一次读响应数据
144 if (SerialPort1.BytesToRead > 0)
145 {
146 response = SerialPort1.ReadExisting();
147
148 //去除前端多可能多读取的字符
149 if (response.IndexOf(ATCmd) > 0)
150 {
151 response = response.Substring(response.IndexOf(ATCmd));
152 }
153 else
154 {
155
156 }
157
158 if (response == "" || response.IndexOf(StCmd) < 0)
159 {
160 if (response != "")
161 {
162 if (response.Trim() == "ERROR")
163 {
164 //throw vError = new UnknowException("Unknown exception in sending command:" + ATCmd);
165 }
166 if (response.IndexOf("+CMS ERROR") >= 0)
167 {
168 string[] cols = new string[100];
169 cols = response.Split(';');
170 if (cols.Length > 1)
171 {
172 string errorCode = cols[1];
173 }
174 }
175 }
176 }
177 }
178
179 //读第一次没有读完的响应数据,直到读到特征数据或超时
180 for (i = 0; i < 3; i++)
181 {
182 Thread.Sleep(1000);
183 response = response + SerialPort1.ReadExisting();
184 if (response.IndexOf(StCmd) >= 0)
185 {
186 break;
187 }
188 }
189
190 return response;
191
192
193 }
194
195 /// <summary>
196 /// 从注册表获取系统串口列表
197 /// </summary>
198 private void GetComList()
199 {
200 RegistryKey keyCom = Registry.LocalMachine.OpenSubKey("Hardware\\DeviceMap\\SerialComm");
201 if (keyCom != null)
202 {
203 string[] sSubKeys = keyCom.GetValueNames();
204 this.cbxDuanKouHao.Items.Clear();
205 foreach (string sName in sSubKeys)
206 {
207 string sValue = (string)keyCom.GetValue(sName);
208 this.cbxDuanKouHao.Items.Add(sValue);
209 }
210 }
211 }
212
213 private void cmID_DropDown(object sender, EventArgs e)
214 {
215 GetComList();
216 }
217
218 private void Form1_Load(object sender, EventArgs e)
219 {
220
221 GetComList();
222 btPause.Enabled = false;
223 }
224
225 //暂停监听读取数值
226 private void btPause_Click(object sender, EventArgs e)
227 {
228 SerialPort1.Close();
229 if (SerialPort1.IsOpen)//端口打开
230 {
231 txtState.Text = "端口连接中";
232 }
233 else
234 {
235 txtState.Text = "端口已断开";
236 }
237 btENT.Enabled = true;
238 btPause.Enabled = false;
239
240 }
241 //一直监听读取数值
242 private void btENT_Click(object sender, EventArgs e)
243 {
244 if ((this.cbxDuanKouHao.Text.Trim() != "") && (this.cbxBoTeLv.Text != ""))
245 {
246 if (SerialPort1 != null )
247 {
248 interfaceUpdataHandle = new HandleInterfaceUpdataDelegate(UpdateTextBox);//实例化委托对象
249 SerialPort1.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived);
250 //串口更改
251 if (SerialPort1.PortName != this.cbxDuanKouHao.Text.Trim())
252 {
253 SerialPort1.Close();
254 SerialPort1.Dispose();
255 SerialPort1 = new SerialPort();//串口资源对象
256 interfaceUpdataHandle = new HandleInterfaceUpdataDelegate(UpdateTextBox);//实例化委托对象
257 SerialPort1.PortName = this.cbxDuanKouHao.Text.Trim();
258 SerialPort1.BaudRate = Convert.ToInt32(this.cbxBoTeLv.Text.Trim());
259 SerialPort1.Parity = JiaoYanWei(cbxJiaoYanWei.Text);
260 SerialPort1.StopBits = TingZhiWei(cbxTingZhiWei.Text);
261 SerialPort1.Encoding = Encoding.ASCII;//获取传输字符编码
262 SerialPort1.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived);
263 SerialPort1.ReceivedBytesThreshold = 1;
264 try
265 {
266 SerialPort1.Open();
267
268 ATCommand3("AT+CLIP=1\r", "OK");
269
270
271 btPause.Enabled = true;
272 btENT.Enabled = false;
273 }
274 catch (Exception)
275 {
276 MessageBox.Show("端口" + this.cbxDuanKouHao.Text.Trim() + "打开失败!");
277 }
278 }
279 else//串口未更改
280 {
281 if(SerialPort1.IsOpen)//端口已打开
282 {
283 btPause.Enabled = true;
284 btENT.Enabled = false;
285 }
286 else
287 {
288 SerialPort1.Open();
289 btPause.Enabled = true;
290 btENT.Enabled = false;
291 }
292 }
293 }
294 else
295 {
296 interfaceUpdataHandle = new HandleInterfaceUpdataDelegate(UpdateTextBox);//实例化委托对象
297 SerialPort1.PortName = this.cbxDuanKouHao.Text.Trim();
298 SerialPort1.BaudRate = Convert.ToInt32(this.cbxBoTeLv.Text.Trim());
299 SerialPort1.Parity = JiaoYanWei(cbxJiaoYanWei.Text);
300 SerialPort1.StopBits = TingZhiWei(cbxTingZhiWei.Text);
301 SerialPort1.Encoding = Encoding.ASCII;//获取传输字符编码
302 SerialPort1.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived);
303 SerialPort1.ReceivedBytesThreshold = 1;
304 try
305 {
306 SerialPort1.Open();
307
308 ATCommand3("AT+CLIP=1\r", "OK");
309
310
311 btPause.Enabled = true;
312 btENT.Enabled = false;
313 }
314 catch (Exception)
315 {
316 MessageBox.Show("端口" + this.cbxDuanKouHao.Text.Trim() + "打开失败!");
317 }
318 }
319 }
320 else
321 {
322 MessageBox.Show("请输入正确的端口号和波特率!");
323 this.cbxDuanKouHao.Focus();
324 }
325 }
326
327 /// <summary>
328 /// 读一次数:注意电子秤设置的发送信息规则:如果不是连续发送,是稳定后发送,则有时候读不到数
329 /// </summary>
330 /// <param name="sender"></param>
331 /// <param name="e"></param>
332 private void btnDuYiCi_Click(object sender, EventArgs e)
333 {
334 try
335 {
336 if ((this.cbxDuanKouHao.Text.Trim() != "") && (this.cbxBoTeLv.Text != ""))
337 {
338 if (SerialPort1 != null)
339 {
340 SerialPort1.Close();
341 SerialPort1.Dispose();
342 SerialPort1 = new SerialPort();//重新创建串口资源对象,否则导致程序卡死
343 //串口更改
344 if (SerialPort1.PortName != this.cbxDuanKouHao.Text.Trim())
345 {
346 SerialPort1.PortName = this.cbxDuanKouHao.Text.Trim();
347 SerialPort1.BaudRate = Convert.ToInt32(this.cbxBoTeLv.Text.Trim());
348 SerialPort1.Parity = JiaoYanWei(cbxJiaoYanWei.Text);
349 SerialPort1.StopBits = TingZhiWei(cbxTingZhiWei.Text);
350 SerialPort1.Encoding = Encoding.ASCII;//获取传输字符编码
351 SerialPort1.ReceivedBytesThreshold = 1;
352 try
353 {
354 SerialPort1.Open();
355
356 ATCommand3("AT+CLIP=1\r", "OK");
357 this.txtShiShiZhongLiang.Text = dushu();
358 }
359 catch (Exception)
360 {
361 MessageBox.Show("端口" + this.cbxDuanKouHao.Text.Trim() + "打开失败!");
362 }
363 }
364 else//串口未更改
365 {
366 if (SerialPort1.IsOpen)//端口已打开
367 {
368 ATCommand3("AT+CLIP=1\r", "OK");
369 this.txtShiShiZhongLiang.Text = dushu();
370 }
371 else
372 {
373 SerialPort1.Open();
374 ATCommand3("AT+CLIP=1\r", "OK");
375 this.txtShiShiZhongLiang.Text = dushu();
376 }
377 }
378 }
379 else
380 {
381
382 SerialPort1.PortName = this.cbxDuanKouHao.Text.Trim();
383 SerialPort1.BaudRate = Convert.ToInt32(this.cbxBoTeLv.Text.Trim());
384 SerialPort1.Parity = JiaoYanWei(cbxJiaoYanWei.Text);
385 SerialPort1.StopBits = TingZhiWei(cbxTingZhiWei.Text);
386
387 SerialPort1.ReceivedBytesThreshold = 1;
388 try
389 {
390 SerialPort1.Open();
391
392 ATCommand3("AT+CLIP=1\r", "OK");
393 this.txtShiShiZhongLiang.Text = dushu();
394 }
395 catch (Exception)
396 {
397 MessageBox.Show("端口" + this.cbxDuanKouHao.Text.Trim() + "打开失败!");
398 }
399 }
400 }
401 else
402 {
403 MessageBox.Show("请输入正确的端口号和波特率!");
404 this.cbxDuanKouHao.Focus();
405 }
406 if (SerialPort1.IsOpen)
407 {
408 SerialPort1.Close();
409 }
410 }
411 catch (Exception)
412 {
413
414 return;
415 }
416
417 }
418 /// <summary>
419 /// 读取缓冲区指定长度数值
420 /// </summary>
421 /// <param name="changdu"></param>
422 /// <returns></returns>
423 private string dushu()
424 {
425 string strTemp = "";
426 try
427 {
428 if (SerialPort1.IsOpen)//端口打开中
429 {
430
431 int i = SerialPort1.BytesToRead;//获取缓冲区字节数
432
433 #region 程序等待0.5秒让缓冲区获取串口数据
434 double iSecond = 0.5;
435
436 DateTime dtOld = System.DateTime.Now;
437 DateTime dtNow = System.DateTime.Now;
438 TimeSpan dtInter;
439 dtInter = dtNow - dtOld;
440
441 while (dtInter.TotalSeconds < iSecond && i <= 0)
442 {
443 dtNow = System.DateTime.Now;
444 dtInter = dtNow - dtOld;
445 i = SerialPort1.BytesToRead;
446 }
447 #endregion
448 if (i > 0)
449 {
450 try
451 {
452
453 byte[] buf = new byte[FanChongQuChangDu];// 定义接收缓冲区
454 SerialPort1.Read(buf, 0, FanChongQuChangDu);
455 for (int j = 0; j < FanChongQuChangDu; j++)
456 {
457
458 ASCIIEncoding ASCIITochar = new ASCIIEncoding();
459 char[] ascii = ASCIITochar.GetChars(buf); // 将接收字节解码为ASCII字符数组
460 strTemp += ascii[j];
461 //已读到换行符就跳出
462 if (strTemp.ToLower().IndexOf("\r") > 0)
463 {
464 break;
465 }
466 }
467 }
468 catch
469 { }
470 }
471 }
472 }
473 catch (Exception)
474 {
475
476 return strTemp;
477 }
478 return strTemp;
479 }
480
481 private void btnZhuaQu_Click(object sender, EventArgs e)
482 {
483 this.txtZhuaQuZhi.Text = this.txtShiShiZhongLiang.Text;
484 }
485 /// <summary>
486 /// 返回校验位
487 /// </summary>
488 /// <param name="zhi"></param>
489 /// <returns></returns>
490 private Parity JiaoYanWei(string zhi)
491 {
492 switch (zhi)
493 {
494 case "Even": return Parity.Even;
495 case "Mark": return Parity.Mark;
496 case "None": return Parity.None;
497 case "Odd": return Parity.Odd;
498 case "Space": return Parity.Space;
499 default: return Parity.None;
500 }
501 }
502 /// <summary>
503 /// 返回停止位
504 /// </summary>
505 /// <param name="zhi"></param>
506 /// <returns></returns>
507 private StopBits TingZhiWei(string zhi)
508 {
509 switch (zhi)
510 {
511 case "0": return StopBits.None;
512 case "1": return StopBits.One;
513 case "1.5": return StopBits.OnePointFive;
514 case "2": return StopBits.Two;
515 default: return StopBits.One;
516 }
517 }
518 /// <summary>
519 /// ASCII码转字符
520 /// </summary>
521 /// <param name="asciiCode"></param>
522 /// <returns></returns>
523 public static string asciiToString(int asciiCode)
524 {
525 if (asciiCode >= 0 && asciiCode <= 255)
526 {
527 System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
528 byte[] byteArray = new byte[] { (byte)asciiCode };
529 string strCharacter = asciiEncoding.GetString(byteArray);
530 return (strCharacter);
531 }
532 else
533 {
534 throw new Exception("ASCII Code is not valid.");
535 }
536 }
537 //用封装对象来实现
538 private void button1_Click(object sender, EventArgs e)
539 {
540 try
541 {
542 mycom mycom1 = new mycom();
543 mycom1.PortNum = cbxDuanKouHao.Text;
544 mycom1.BaudRate = Convert.ToInt32(cbxBoTeLv.Text);
545 mycom1.StopBits = 8;
546 mycom1.Parity = 0;
547 mycom1.StopBits = Convert.ToByte(cbxTingZhiWei.Text);
548 mycom1.ReadTimeout = 10;
549
550 mycom1.Open();
551 string dushu = "";
552 byte[] buf = mycom1.Read(12);
553
554 for (int j = 0; j < 12; j++)
555 {
556
557 ASCIIEncoding ASCIITochar = new ASCIIEncoding();
558 char[] ascii = ASCIITochar.GetChars(buf); // 将接收字节解码为ASCII字符数组
559 dushu += ascii[j];
560
561 }
562
563 txtShiShiZhongLiang.Text = dushu;
564
565 mycom1.Close();
566 }
567 catch (Exception cuowu)
568 {
569 MessageBox.Show(cuowu.Message);
570 return ;
571 }
572
573 }
574 }
575 }