C#实现串口监听

 

Visual Stdio 2005中,对于串口操作Framework提供了一个很好的类接口-SerialPort,在这当中,串口数据的读取与写入有较大的不同。由于串口不知道数据何时到达,因此有两种方法可以实现串口数据的读取。

       1.用线程实时读串口

       2.用事件触发方式实现。

        但由于线程实时读串口的效率不是十分高效,因此比较好的方法是事件触发的方式。在SerialPort类中有DataReceived事件,当串口的读缓存有数据到达时则触发DataReceived事件,其中SerialPort.ReceivedBytesThreshold属性决定了当串口读缓存中数据多少个时才触发DataReceived事件,默认为1。

       此外,SerialPort.DataReceived事件运行比较特殊,其运行在辅线程,不能与主线程中的显示数据控件直接进行数据传输,必须用间接的方式实现。

一.创建WIndow项目,设计界面

二,编写实现代码

 

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. using System.IO.Ports;
  9. using System.Threading;
  10. using Microsoft.Win32;
  11. namespace ComMonitor
  12. {
  13.     public partial class Form1 : Form
  14.     {
  15.         public Form1()
  16.         {
  17.             InitializeComponent();
  18.         }
  19.         private SerialPort Sp = new SerialPort();
  20.         public delegate void HandleInterfaceUpdataDelegate(string text); //委托,此为重点
  21.         private HandleInterfaceUpdataDelegate interfaceUpdataHandle;
  22.         private bool qiii = false;
  23.         private void btENT_Click(object sender, EventArgs e)
  24.         {
  25.             if ((cmID.Text.Trim() != "") && (cmRate.Text != ""))
  26.             {
  27.                 interfaceUpdataHandle = new HandleInterfaceUpdataDelegate(UpdateTextBox);//实例化委托对象
  28.                 Sp.PortName = cmID.Text.Trim();
  29.                 Sp.BaudRate = Convert.ToInt32(cmRate.Text.Trim());
  30.                 Sp.Parity = Parity.None;
  31.                 Sp.StopBits = StopBits.One;
  32.                 Sp.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived);
  33.                 Sp.ReceivedBytesThreshold = 1;
  34.                 try
  35.                 {
  36.                     Sp.Open();
  37.                     ATCommand3("AT+CLIP=1/r""OK");
  38.                     btPause.Enabled = true;
  39.                     btENT.Enabled = false;
  40.                 }
  41.                 catch
  42.                 {
  43.                     MessageBox.Show("端口" + cmID.Text.Trim() + "打开失败!");
  44.                 }
  45.             }
  46.             else
  47.             {
  48.                 MessageBox.Show("请输入正确的端口号和波特率!");
  49.                 cmID.Focus();
  50.             }
  51.         }
  52.         private void btPause_Click(object sender, EventArgs e)
  53.         {
  54.             Sp.Close();
  55.             btENT.Enabled = true;
  56.             btPause.Enabled = false;
  57.         }
  58.         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  59.         {
  60.             Sp.Close();
  61.         }
  62.         private void Form1_Load(object sender, EventArgs e)
  63.         {
  64.             GetComList();
  65.             btPause.Enabled = false;
  66.         }
  67.         public void Sp_DataReceived(object sender,System.IO.Ports.SerialDataReceivedEventArgs e)
  68.         {
  69.             string strTemp = "";
  70.             double iSecond = 0.5;
  71.             DateTime dtOld = System.DateTime.Now;
  72.             DateTime dtNow = System.DateTime.Now;
  73.             TimeSpan dtInter;
  74.             dtInter = dtNow - dtOld;
  75.             int i = Sp.BytesToRead;
  76.             if (i > 0)
  77.             {
  78.                 try
  79.                 {
  80.                     strTemp = Sp.ReadExisting();
  81.                 }
  82.                 catch
  83.                 { }
  84.                 if (strTemp.ToLower().IndexOf("/r") < 0)
  85.                 {
  86.                     i = 0;
  87.                 }
  88.                 else
  89.                 {
  90.                     this.Invoke(interfaceUpdataHandle, strTemp);
  91.                 }
  92.             }
  93.             while (dtInter.TotalSeconds < iSecond && i <= 0)
  94.             {
  95.                 dtNow = System.DateTime.Now;
  96.                 dtInter = dtNow - dtOld;
  97.                 i = Sp.BytesToRead;
  98.                 if (i > 0)
  99.                 {
  100.                     try
  101.                     {
  102.                         strTemp += Sp.ReadExisting();
  103.                     }
  104.                     catch
  105.                     { }
  106.                     if (strTemp.ToLower().IndexOf("/r") < 0)
  107.                     {
  108.                         i = 0;
  109.                     }
  110.                     else
  111.                     {
  112.                         this.Invoke(interfaceUpdataHandle, strTemp);
  113.                     }
  114.                 }
  115.             }
  116.             // do null 
  117.         }
  118.         private void UpdateTextBox(string text)
  119.         {
  120.             tbData.Text = text;
  121.         }
  122.         /// <summary>
  123.         /// 执行AT指令并返回 成功失败
  124.         /// </summary>
  125.         /// <param name="ATCmd">AT指令</param>
  126.         /// <param name="StCmd">AT指令标准结束标识</param>
  127.         /// <returns></returns>
  128.         private void ATCommand3(string ATCmd, string StCmd)
  129.         {
  130.             string response = "";
  131.             response = ATCommand(ATCmd, StCmd);
  132.         }
  133.         /// <summary>
  134.         /// 执行AT指令并返回结果字符
  135.         /// </summary>
  136.         /// <param name="ATCmd">AT指令</param>
  137.         /// <param name="StCmd">AT指令标准结束标识</param>
  138.         /// <returns></returns>
  139.         private string ATCommand(string ATCmd, string StCmd)
  140.         {
  141.             string response = "";
  142.             int i;
  143.             if (!ATCmd.EndsWith("/x01a"))
  144.             {
  145.                 if (!(ATCmd.EndsWith("/r") || ATCmd.EndsWith("/r/n")))
  146.                 {
  147.                     ATCmd = ATCmd + "/r";
  148.                 }
  149.             }
  150.             Sp.WriteLine(ATCmd);
  151.             //第一次读响应数据
  152.             if (Sp.BytesToRead > 0)
  153.             {
  154.                 response = Sp.ReadExisting();
  155.                 //去除前端多可能多读取的字符
  156.                 if (response.IndexOf(ATCmd) > 0)
  157.                 {
  158.                     response = response.Substring(response.IndexOf(ATCmd));
  159.                 }
  160.                 else
  161.                 {
  162.                 }
  163.                 if (response == "" || response.IndexOf(StCmd) < 0)
  164.                 {
  165.                     if (response != "")
  166.                     {
  167.                         if (response.Trim() == "ERROR")
  168.                         {
  169.                             //throw vError = new UnknowException("Unknown exception in sending command:" + ATCmd);
  170.                         }
  171.                         if (response.IndexOf("+CMS ERROR") >= 0)
  172.                         {
  173.                             string[] cols = new string[100];
  174.                             cols = response.Split(';');
  175.                             if (cols.Length > 1)
  176.                             {
  177.                                 string errorCode = cols[1];
  178.                             }
  179.                         }
  180.                     }
  181.                 }
  182.             }
  183.             //读第一次没有读完的响应数据,直到读到特征数据或超时
  184.             for (i = 0; i < 3; i++)
  185.             {
  186.                 Thread.Sleep(1000);
  187.                 response = response + Sp.ReadExisting();
  188.                 if (response.IndexOf(StCmd) >= 0)
  189.                 {
  190.                     break;
  191.                 }
  192.             }
  193.             return response;
  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.cmID.Items.Clear();
  205.                 foreach (string sName in sSubKeys)
  206.                 {
  207.                     string sValue = (string)keyCom.GetValue(sName);
  208.                     this.cmID.Items.Add(sValue);
  209.                 }
  210.             }
  211.         }
  212.         private void cmID_DropDown(object sender, EventArgs e)
  213.         {
  214.             GetComList();
  215.         }
  216.     }
  217. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值