C#中使用SerialPort类实现简单串口编程

.NET提供了SerialPort类进行串口通信,使用很简单,连我这个.NET新手也能很快上手.以下是从网上找到并自己修改后的参考代码:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Windows;
  6 using System.Windows.Controls;
  7 using System.Windows.Data;
  8 using System.Windows.Documents;
  9 using System.Windows.Input;
 10 using System.Windows.Media;
 11 using System.Windows.Media.Imaging;
 12 using System.Windows.Navigation;
 13 using System.Windows.Shapes;
 14 using System.IO.Ports;
 15 
 16 namespace CsharpComm
 17 {
 18     /// <summary>
 19     /// Window1.xaml 的交互逻辑
 20     /// </summary>
 21     public partial class Window1 : Window
 22     {
 23         public Window1()
 24         {
 25             InitializeComponent();
 26         }
 27 
 28         //定义 SerialPort对象
 29         SerialPort port1;
 30 
 31         //初始化SerialPort对象方法.PortName为COM口名称,例如"COM1","COM2"等,注意是string类型
 32         public void InitCOM(string PortName)
 33         {
 34             port1 = new SerialPort(PortName);
 35             port1.BaudRate = 9600;//波特率
 36             port1.Parity  = Parity.None;//无奇偶校验位
 37             port1.StopBits = StopBits.Two;//两个停止位
 38             port1.Handshake = Handshake.RequestToSend;//控制协议
 39             port1.ReceivedBytesThreshold = 4;//设置 DataReceived 事件发生前内部输入缓冲区中的字节数
 40             port1.DataReceived += new SerialDataReceivedEventHandler(port1_DataReceived);//DataReceived事件委托
 41         }
 42 
 43         //DataReceived事件委托方法
 44         private void port1_DataReceived(object sender, SerialDataReceivedEventArgs e)
 45         {
 46             try
 47             {
 48                 StringBuilder currentline = new StringBuilder();
 49                 //循环接收数据
 50                 while (port1.BytesToRead > 0)
 51                 {
 52                     char ch = (char)port1.ReadByte();
 53                     currentline.Append(ch);
 54                 }
 55                 //在这里对接收到的数据进行处理
 56                 //
 57                 currentline = new StringBuilder();
 58             }
 59             catch(Exception ex)
 60             {
 61                 Console.WriteLine(ex.Message.ToString());
 62             }
 63 
 64         }
 65 
 66         //打开串口的方法
 67         public void OpenPort()
 68         {
 69             try
 70             {
 71                 port1.Open();
 72             }
 73             catch { }
 74             if (port1.IsOpen)
 75             {
 76                 Console.WriteLine("the port is opened!");
 77             }
 78             else
 79             {
 80                 Console.WriteLine("failure to open the port!");
 81             }
 82         }
 83 
 84         //关闭串口的方法
 85         public void ClosePort()
 86         {
 87             port1.Close();
 88             if (!port1.IsOpen)
 89             {
 90                 Console.WriteLine("the port is already closed!");
 91             }
 92         }
 93 
 94         //向串口发送数据
 95         public void SendCommand(string CommandString)
 96         {
 97             byte[] WriteBuffer = Encoding.ASCII.GetBytes(CommandString);
 98             port1.Write(WriteBuffer, 0, WriteBuffer.Length);
 99         }
100         
101         //调用实例
102         private void btnOpen_Click(object sender, RoutedEventArgs e)
103         {
104             //我现在用的COM1端口,按需要可改成COM2,COM3
105             InitCOM("COM1");
106             OpenPort();
107         }
108     }
109 }  

值得注意的是:

1. port1.ReceivedBytesThreshold = 4;  ReceivedBytesThreshold属性设置触发一次DataReceived事件时将接收到的数据字节数.由于我的硬件是一次发上来4个字节估设置为4.如果不能正确设置这个属性的话,在SerialPort对象第一次触发DataReceived事件时还是正确的(4个字节),但是从第二次触发之后都是一个字节触发一次DataReceived事件...为什么这样搞不清楚...

2.如果在 DataReceived 委托事件中使用了不是DataReceived委托事件所在线程创建的UI控件,函数等,需要使用到Dispatcher 类来达到线程安全,不然会报错.以下是MSDN中Dispatcher类的例子(XAML),简单明了:

 1 private delegate void AddTextDelegate(Panel p, String text);
 2 
 3 private void AddText(Panel p, String text)
 4 {
 5     p.Children.Clear();
 6     p.Children.Add(new TextBlock { Text = text });
 7 }
 8 
 9 private void TestBeginInvokeWithParameters(Panel p)
10 {
11     if (p.Dispatcher.CheckAccess()) AddText(p, "Added directly.");
12     else p.Dispatcher.BeginInvoke(
13         new AddTextDelegate(AddText), p, "Added by Dispatcher.");
14 }
posted @ 2009-06-17 19:28  周晓宁  阅读(32471)  评论(7编辑  收藏