叶帆工作室

嵌入式开发爱好者(十年开发经验,精通C/C++/VC/VB/C#...)

用户操作
[即时聊天] [发私信] [加为好友]
叶帆ID:yefanqiu
536323次访问,排名80好友0人,关注者224
微软MVP / CSDN 2008十大MVB/MSDN中文技术论坛版主
yefanqiu的文章
原创 218 篇
翻译 0 篇
转载 3 篇
评论 1099 篇
叶帆的公告
本博客原创文章,作者保留一切权利,需经作者同意后方可转载,转载时 请注明[叶帆工作室]及文章链接。yefan@vip.sina.com
【简介】叶帆[微软MVP]
【文章】叶帆文章列表
【软件】叶帆共享软件列表
最近评论
BinYu:我用的是vista home basic sp1,但vs2005强行装不上去,请帮忙分析一下,qq:811344767,先谢谢了
wjh6877:算法想好了吗?

没有就是空话
一生好人:其实我也想来正版,但生活逼人,没办法啊
fox23:something like java card;-)
wwqqha:不错不错
文章分类
收藏
    相册
    叶帆照片
    【叶帆软件】
    [01]VB源码之友(V2.1.548)
    [02]API浏览器.net(V5.0)
    [03]叶帆成语词典(V2.0.8)
    [04]叶帆密码库(V1.2.8)
    【叶帆资源】
    DAO 2.0引擎
    叶帆快速通道
    MSDN-MVP
    Windows Embedded 专题
    中文MSDN
    叶帆圈子--工业自动化
    叶帆工作室(博客园)
    叶帆工控--工业自动化
    叶帆群组--工业应用开发
    微软中文技术论坛
    微软硬件创新中心(HIC)
    瑞康社区论坛
    叶帆友情链接
    张欣
    枕善居
    莫依
    葛涵涛
    郑建
    陈辉
    马宁
    马骐
    魏涛序
    黎波
    存档
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 【C#】串口操作实用类收藏

    新一篇: 2007微软MVP获得连任 | 旧一篇: 初涉龙芯I/龙芯II

            做工业通信有很长时间了,特别是串口(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 
    = new SerialPort(sPortName, baudrate, parity, 8, StopBits.One);
                port.RtsEnable 
    = true;
                port.ReadTimeout 
    = 3000;
                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, 
    0, 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();         //清空接收缓冲区                 
                    port.Write(SendData, 0, SendData.Length);
                    
    int num=0,ret=0;
                    
    while (num++ < Overtime)
                    {
                        
    if (port.BytesToRead >= ReceiveData.Length) break;
                        System.Threading.Thread.Sleep(
    1); 
                    }
                    
    if (port.BytesToRead >= ReceiveData.Length) 
                        ret 
    = port.Read(ReceiveData, 0, ReceiveData.Length);
                    ReceiveEventFlag 
    = false;       //打开事件
                    return ret;
                }
                
    return -1;
            }

            
    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, 
    0, 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修改了相应的串口驱动。

     

    发表于 @ 2007年03月27日 19:32:00|评论(loading...)|编辑

    新一篇: 2007微软MVP获得连任 | 旧一篇: 初涉龙芯I/龙芯II

    评论

    #chuangen 发表于2007-04-25 13:24:25  IP: 59.52.165.*
    很实用,谢谢~~
    #chuangen 发表于2007-04-25 13:26:23  IP: 59.52.165.*
    直接从SerialPort继承似乎是个不错的选择,你觉得哪?
    #yefanqiu 发表于2007-04-26 16:05:25  IP: 222.130.248.*
    建议不错
    #yefanqiu 发表于2007-04-26 17:02:23  IP: 222.130.248.*
    建议不错
    #xiexuetao 发表于2007-05-23 10:16:44  IP: 202.106.78.*
    大哥能不能做一个调用此类的示例代码供下载学习学习啊。
    #spirit_only 发表于2007-05-28 23:52:16  IP: 124.114.165.*
    嗯,前段时间也用过这个类,效率低,而且总是有些小问题,最后还是自己调用API搞定串口操作的。
    #xiaowangsong 发表于2007-12-28 00:33:07  IP: 125.89.20.*
    请教一下,如何调用这个类?能否写一个简单的。发送命令和接收数据的示例。看了很久,还是不明白如何运用。
    #yefanqiu 发表于2007-12-30 13:05:56  IP: 221.217.140.*
    //注:把代码中的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();
    该代码适合主从式通信(一应一答方式)
    #hxqhit 发表于2008-07-30 10:58:14  IP: 221.2.164.*
    你好,我专业是电子类的,现在想学学上位机的开发软件,以前看过VC++,但是没有具体用过。目前想学习C#,能否提供一些学习思路呢?
    #yefanqiu 发表于2008-08-01 10:01:36  IP: 61.50.221.*
    有兴趣,试着做一些示例,慢慢就熟悉了。
    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © 叶帆