做工业通 信有很长时间了,特别是串口(232/485),有VB/VC/C各种版本的串口操作代码,这些代码也经过了多年的现场考验,应该说是比较健壮的代码,但 是目前却没有C#相对成熟的串口操作代码,最近用Moxa的设备开发基于WinCE5.0的串口操作代码,所以就扩充完善了一下串口操作,特别是 SendCommand函数,这是我比较常用的主从通信代码,不喜欢用事件或线程接数据,在规定的超时时间内直接循环判断要接收的数据。

下面是具体的代码:

  public class PortData
    {
        public event PortDataReceivedEventHandle Received;
        public event SerialErrorReceivedEventHandler Error; 
        public SerialPort port;
        public bool ReceiveEventFlag = false;  //接收事件是否有效 false表示有效

public PortData(string sPortName, int baudrate,Parity parity,SerialInterface.SerialMode mode)
        {
            port , StopBits.One);
            port.RtsEnable = true;
            port.ReadTimeout ;
            port.DataReceived += new SerialDataReceivedEventHandler(DataReceived);
            port.ErrorReceived += new SerialErrorReceivedEventHandler(ErrorEvent);
        }

~PortData()
        {
            Close();
        }
        public void Open()
        {
            if (!port.IsOpen)
            {           
                port.Open();
            }
        }

public void Close()
        {
            if (port.IsOpen)
            {
                port.Close();
            }
        }
        //数据发送
        public void SendData(byte[] data)
        {
            if (port.IsOpen)
            {
                port.Write(data, , data.Length);
            }
        }
        public void SendData(byte[] data,int offset,int count)
        {
            if (port.IsOpen)
            {
                port.Write(data, offset, count);
            }
        }
        //发送命令
        public int SendCommand(byte[] SendData, ref  byte[] ReceiveData,int Overtime)
        {

if(port.IsOpen)
            {
                ReceiveEventFlag = true;        //关闭接收事件
                port.DiscardInBuffer();         //清空接收缓冲区                 
, SendData.Length);
                ;
                while (num++ < Overtime)
                {
                    if (port.BytesToRead >= ReceiveData.Length) break;
                    System.Threading.Thread.Sleep(); 
                }
                if (port.BytesToRead >= ReceiveData.Length) 
                    ret , ReceiveData.Length);
                ReceiveEventFlag = false;       //打开事件
                return ret;
            }
            ;
        }

public void ErrorEvent(object sender, SerialErrorReceivedEventArgs e)
        {
            if (Error != null) Error(sender, e);
        }
        //数据接收
        public void DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //禁止接收事件时直接退出
            if (ReceiveEventFlag) return;

byte[] data = new byte[port.BytesToRead];
            port.Read(data, , data.Length);
            if (Received != null) Received(sender, new PortDataReciveEventArgs(data));
        }

public bool IsOpen()
        {
            return port.IsOpen;
        }
    }
    public delegate void PortDataReceivedEventHandle(object sender, PortDataReciveEventArgs e);
    public class PortDataReciveEventArgs : EventArgs
    {
        public PortDataReciveEventArgs()
        {
            this.data = null;
        }

public PortDataReciveEventArgs(byte[] data)
        {
            this.data = data;
        }

private byte[] data;

public byte[] Data
        {
            get { return data; }
            set { data = value; }
        }
    }

【附注】1~9 串口的名称是 "COMx:",>9的以前用\\\\.\\COMx:比较好使,但是在moxa 661设备上却不行,要用如下格式"$device\\COM" + PortNo.ToString() + "\0",也许这是moxa修改了相应的串口驱动。

//注:把代码中的public PortData(string sPortName, int baudrate,Parity parity,SerialInterface.SerialMode mode) 最后一个参数去掉。
PortData comPort = new PortData("COM1:", 115200, Parity.Even);
byte[] bytSendArray = new byte[2]; //发送数据缓冲区
bytSendArray[0]=0xAC;
bytSendArray[2]=0xAA;
byte[] bytReceiveArray = new byte[5];
//该命令潜台词是你发送了两个字节的数据0xAC,0xAA 下位机应该在200毫秒超时内返回5个字节的数据
intReceiveNum = comPort.SendCommand(bytSendData, ref bytReceiveArray, 200);
//intReceiveNum为实际返回的数据个数,返回的数据放在bytReceiveArray中
comPort.Close();
该代码适合主从式通信(一应一答方式)

绿色通道:
好文要顶
关注我
收藏该文与我联系
2
0
(请您对文章做出评价)

posted on 2008-07-20 11:53 周伟 阅读(1118) 评论(0) 编辑 收藏

【C#】串口操作实用类的更多相关文章

  1. C# 串口操作系列(3) -- 协议篇,二进制协议数据解析

    原文地址:http://blog.csdn.net/wuyazhe/article/details/5627253 我们的串口程序,除了通用的,进行串口监听收发的简单工具,大多都和下位机有关,这就需要 ...

  2. C# 串口操作 ---- 系列文章

    C# 串口操作系列(5)--通讯库雏形 通讯库雏形的建立. 串口通讯介绍的高级篇,介绍更高级的抽象,为扩展为通用的客户端通讯库做铺垫,扩展性的考虑,能支持任意类型的流设备. ... 2010-08-0 ...

  3. c#实现串口操作 SerialPort

    命名空间:using System.IO.Ports;该类提供了同步 I/O 和事件驱动的 I/O.对管脚和中断状态的访问以及对串行驱动程序属性的访问. 操作类声明: SerialPort sp = ...

  4. C# 串口操作系列(5)--通讯库雏形

    C# 串口操作系列(5)--通讯库雏形 标签: 通讯c#数据分析byteclassstring 2010-08-09 00:07 21378人阅读 评论(73) 收藏 举报  分类: 通讯类库设计(4 ...

  5. C# 串口操作系列(4) -- 协议篇,文本协议数据解析

    C# 串口操作系列(4) -- 协议篇,文本协议数据解析 标签: c#uiobjectstringbyte 2010-06-09 01:50 19739人阅读 评论(26) 收藏 举报  分类: 通讯 ...

  6. 【转】C# 串口操作系列(1) -- 入门篇,一个标准的,简陋的串口例子。

    C# 串口操作系列(1) -- 入门篇,一个标准的,简陋的串口例子. 标签: c#objectnewlineexceptionbytestring 2010-05-17 01:10 117109人阅读 ...

  7. V-rep学习笔记:串口操作

    VREP Regular API提供了串口操作的相关函数,可以对串口进行打开.关闭和读写: 下面使用一款淘宝上常见的AHRS(Attitude and heading reference system ...

  8. Linux下串口操作之数据拼接

    串口操作中,特别以非阻塞的方式读取和发送数据,做好进程之间的同步很重要.有时我们会发现这样一个问题,在进行read操作时,一次read不能获得一个完整的数据帧,这就好比你买了一个电脑,送货的先把显示器 ...

  9. MATLAB串口操作和GUI编程

    程序说明 V1.0 2015/2/08 MATLAB串口操作和GUI编程   概述   本文介绍了程序AD9512_Serial_GUI的编程思路和功能.该程序设计到MATLAB的图像用户界面编程的基 ...

随机推荐

  1. css3伪放大镜(图片放大动画)效果(鼠标移入圆形区域放大图片)

    源码: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&q ...

  2. CentOS下安装Telnet服务

    环境:centos6.6   IP:172.18.0.190 1.查看是否安装Telnet: rpm -qa telnet-server rpm -qa xinetd 2.安装Telnet: yum ...

  3. Linux命令详解-man

    man 命令提供有关主题的参考信息,例如命令.子例程和文件.man 命令提供由名称指定的对命令的单行描述.man 命令也提供所有命令的信息,这些命令的描述包含用户指定的关键字集合. 1.命令格式: m ...

  4. git基本操作,一篇文章就够了!

    1. git简介 git的通用操作流程如下图(来源于网络) 主要涉及到四个关键点: 工作区:本地电脑存放项目文件的地方,比如learnGitProject文件夹: 暂存区(Index/Stage):在 ...

  5. 在jenkins和sonar中集成jacoco(三)--使用jacoco收集集成测试的覆盖率

    我们系统使用weblogic做服务器,集成测试框架使用的是junit+selenium. 首先,要把jacoco的jacocoagent.jar包放到部署应用的服务器上,接着在系统服务的JAVA_OP ...

  6. java Object对象的clone方法

    参考copy链接:http://blog.csdn.net/bigconvience/article/details/25025561 在看原型模式,发现要用到clone这个方法,以前和朋友聊过,没怎 ...

  7. 免费180天的Ashampoo Anti-Virus 2014

    官方网站:https://www.ashampoo.com/cn/rmb/pde/0449/Security_Software/Ashampoo-Anti-Virus 活动页面:http://www. ...

  8. Ubuntu 16.04系统开机紫屏的解决办法

    具体症状为卡在开机界面,按任何键都无反应. 网上查看了几篇文章 ,如下: 解决:ubuntu16.04启动时长时间停留在紫屏或跳文本的黑屏界面 Ubuntu16.04显卡驱动 电源管理 里面提到的开机 ...

  9. azure 最佳实践 -- 保持冗余

    保持冗余确保你的应用的部署体系是有冗余的,以避免单一节点失败的情况.一个弹性良好的系统可以灵活的绕过系统故障.找出应用中(请求执行)的关键路径.路径中的每个节点是否都有冗余?子系统失败时,系统能否有效 ...

  10. 转-Vue.js2.0从入门到放弃---入门实例(一)

    http://blog.csdn.net/u013182762/article/details/53021374 标签: Vue.jsVue.js 2.0Vue.js入门实例Vue.js 2.0教程 ...