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 }