C# 串口通信

转载 2012年03月21日 17:49:48
 串口通讯类:SerialPortDao.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;

namespace LY.FuelStationPOS.Protocol
{
    /// <summary>
    /// 提供对串口的统一访问
    /// </summary>
    public sealed class SerialPortDao
    {
        #region 事件和字段定义
        public event PortDataReceivedEventHandle Received;
        public SerialPort serialPort = null;
        public bool ReceiveEventFlag = false;  //接收事件是否有效 false表示有效

        private static readonly SerialPortDao instance = new SerialPortDao();

        #endregion

        #region 属性定义
        private string protName;
        public string PortName
        {
            get { return serialPort.PortName; }
            set 
            { 
                serialPort.PortName = value;
                protName = value;
            }
        }
        #endregion

        #region 构造函数
        private SerialPortDao()
        {
            LoadSerialPort();
        }

        private void LoadSerialPort()
        {
            serialPort = new SerialPort();
            serialPort.BaudRate = 9600;
            serialPort.Parity = Parity.Even;
            serialPort.DataBits = 8;
            serialPort.StopBits = StopBits.One;
            serialPort.Handshake = Handshake.None;
            serialPort.RtsEnable = true;
            serialPort.ReadTimeout = 2000;
            serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceived);
        }

      
        #endregion      
     
        #region 串口操作集合
        /// <summary>
        /// 返回串口对象的单个实例
        /// </summary>
        /// <returns></returns>
        public static SerialPortDao GetSerialPortDao()
        {         
            return instance;
        }       

        /// <summary>
        /// 释放串口资源
        /// </summary>
        ~SerialPortDao()
        {
            Close();
        }

        /// <summary>
        /// 打开串口
        /// </summary>
        public void Open()
        {
            try
            {
                if (!serialPort.IsOpen)
                {
                    serialPort.Open();                    
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }           
        }

        /// <summary>
        /// 关闭串口
        /// </summary>
        public void Close()
        {
            if (serialPort.IsOpen)
            {
                serialPort.Close();
            }
        }

        /// <summary>
        /// 串口是否打开
        /// </summary>
        /// <returns></returns>
        public bool IsOpen()
        {
            return serialPort.IsOpen;
        }

       

        /// <summary>
        /// 数据发送
        /// </summary>
        /// <param name="data">要发送的数据字节</param>
        public void SendData(byte[] data)
        {
            try
            {
                serialPort.DiscardInBuffer();
                serialPort.Write(data, 0, data.Length);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 发送命令
        /// </summary>
        /// <param name="SendData">发送数据</param>
        /// <param name="ReceiveData">接收数据</param>
        /// <param name="Overtime">超时时间</param>
        /// <returns></returns>
        public int SendCommand(byte[] SendData, ref byte[] ReceiveData, int Overtime)
        {
            if (serialPort.IsOpen)
            {
                try
                {
                    ReceiveEventFlag = true;        //关闭接收事件
                    serialPort.DiscardInBuffer();   //清空接收缓冲区                 
                    serialPort.Write(SendData, 0, SendData.Length);
                    System.Threading.Thread.Sleep(50);
                    int num = 0, ret = 0;
                    while (num++ < Overtime)
                    {
                        if (serialPort.BytesToRead >= ReceiveData.Length)
                        {
                            break;
                        }
                        System.Threading.Thread.Sleep(50);
                    }
                    if (serialPort.BytesToRead >= ReceiveData.Length)
                    {
                        ret = serialPort.Read(ReceiveData, 0, ReceiveData.Length);
                    }
                    else
                    {
                        ret = serialPort.Read(ReceiveData, 0, serialPort.BytesToRead);
                    }
                    ReceiveEventFlag = false;       //打开事件
                    return ret;
                }
                catch (Exception ex)
                {
                    ReceiveEventFlag = false;
                    throw ex;
                }
            }
            return -1;
        }

        ///<summary>
        ///数据发送
        ///</summary>
        ///<param name="data">要发送的数据字符串</param>
        public void SendData(string data)
        {
            //禁止接收事件时直接退出
            if (ReceiveEventFlag)
            {
                return;
            }
            if (serialPort.IsOpen)
            {
                serialPort.Write(data);
            }
        }

         ///<summary>
         ///将指定数量的字节写入输出缓冲区中的指定偏移量处。
         ///</summary>
         ///<param name="data">发送的字节数据</param>
         ///<param name="offset">写入偏移量</param>
         ///<param name="count">写入的字节数</param>
        public void SendData(byte[] data, int offset, int count)
        {
            //禁止接收事件时直接退出
            if (ReceiveEventFlag)
            {
                return;
            }
            if (serialPort.IsOpen)
            {
                serialPort.Write(data, offset, count);
            }
        }
               

        /// <summary>
        /// 数据接收
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //禁止接收事件时直接退出
            if (ReceiveEventFlag)
            {
                return;
            }

            try
            {
                byte[] data = new byte[serialPort.BytesToRead];
                serialPort.Read(data, 0, data.Length);
                if (Received != null)
                {
                    Received(sender, new PortDataReciveEventArgs(data));
                }
            }
            catch (Exception ex)
            {
                //throw ex;
            }
            
        }
    }
}


 

 

 

 

串口通讯数据类:PortDataReciveEventArgs

重写PortDataReciveEventArgs参数类

 

using System;
using System.Collections.Generic;
using System.Text;

namespace LY.FuelStationPOS.Protocol
{
    public delegate void PortDataReceivedEventHandle(object sender, PortDataReciveEventArgs e);

    public class PortDataReciveEventArgs : EventArgs
    {
        private byte[] data;

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

        public PortDataReciveEventArgs()
        {
            this.data = null;
        }

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

        
    }
}

//进制转换(串口通讯中比较常用的16进制、byte、压缩BCD码、long、ASCII、Float等之间的转换方法)
//进制转换:ConvertHelper.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace LY
{
    /// <summary>
    /// 进制转换
    /// </summary>
    public static class ConvertHelper
    {
        #region 进制转换
        /// <summary>
        /// 整形转化成字节
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        public static byte IntToByte(int i)
        {
            return Convert.ToByte(i % 0x100);
        }

        /// <summary>
        /// 16进制转化成BCD
        /// </summary>
        /// <param name="b">byte</param>
        /// <returns>返回BCD码</returns>
        public static byte HexToBCD(byte b)
        {
            int r1 = b % 0x10;     // b = 0x12 -> r1 = 0x02
            int r2 = b / 0x10;     // b = 0x12 -> r2 = 0x01
            if (r1 > 9)             //r1 = 0x0A -> r1 = 0x00
                r1 = 0;
            if (r2 > 9)             //r2 = 0x0A -> r2 = 0x00
                r2 = 0;
            return Convert.ToByte(r1 + 10 * r2);    //0x12 -> 12
        }

        /// <summary>
        /// 16进制转化成BCD
        /// </summary>
        /// <param name="i">int</param>
        /// <returns>返回BCD码</returns>
        public static byte HexToBCD(int i)
        {
            return HexToBCD(IntToByte(i));
        }

        /// <summary>
        /// Double转换为压缩BCD
        /// </summary>
        /// <param name="d">0-100内的双精度浮点数字</param>
        /// <returns>返回压缩BCD码</returns>
        public static string DoubleToBCD(double d)
        {
            string[] strs = d.ToString("F2").Split('.');
            string temp1 = int.Parse(strs[0]).ToString("D2");
            string temp2 = int.Parse(strs[1]).ToString("D2");
            return string.Format("{0} {1}", temp1, temp2);
        }

        /// <summary>
        /// long转换为BCD
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static long ToBCD(long val)
        {
            long res = 0;
            int bit = 0;
            while (val >= 10)
            {
                res |= (val % 10 << bit);
                val /= 10;
                bit += 4;
            }
            res |= val << bit;
            return res;
        }

        /// <summary>
        /// BCD转换为long
        /// </summary>
        /// <param name="vals"></param>
        /// <returns></returns>
        public static long FromBCD(long vals)
        {
            long c = 1;
            long b = 0;
            while (vals > 0)
            {
                b += ((vals & 0xf) * c);
                c *= 10;
                vals >>= 4;
            }
            return b;
        }

        /// <summary>
        /// BCD转化成16进制
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public static byte BCDToHex(byte b)
        {
            int r2 = b % 100;      // b = 12 -> r2 = 12        //123 -> r2 = 23
            int r1 = r2 % 10;      //r2 = 12 -> r1 = 2     
            r2 = r2 / 10;           //r2 = 12 -> r2 =1
            return Convert.ToByte(r1 + 0x10 * r2);
        }

        /// <summary>
        /// BCD转化成16进制
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        public static byte BCDToHex(int i)
        {
            return BCDToHex(IntToByte(i));
        }

        /// <summary>
        /// btye转化成16进制字符
        /// </summary>
        /// <param name="b">byte</param>
        /// <returns></returns>
        public static string ToHexString(byte b)
        {
            return Convert.ToString(b, 16);
        }

        /// <summary>
        /// int转化成16进制字符
        /// </summary>
        /// <param name="num">int</param>
        /// <returns></returns>
        public static string ToHexString(int num)
        {
            return Convert.ToString(num, 16);
        }

        /// <summary>
        /// 16进制字符串转换成字节数组
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static byte[] HexStringToByteArray(string s)
        {
            s = s.Replace(" ", "");
            byte[] buffer = new byte[s.Length / 2];
            for (int i = 0; i < s.Length; i += 2)
            {
                buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
            }
            return buffer;
        }

        /// <summary> 
        /// 字节数组转换成16进制字符串
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string ByteArrayToHexString(byte[] data)
        {
            StringBuilder sb = new StringBuilder(data.Length * 3);
            foreach (byte b in data)
            {
                sb.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, ' '));
            }
            return sb.ToString().Trim().ToUpper();
        }

        /// <summary>
        /// ASCII转16进制
        /// </summary>
        /// <param name="ascii">ASCII</param>
        /// <returns></returns>
        public static string ASCIIToHex(string ascii)
        {
            char[] cs = ascii.ToCharArray();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < cs.Length; i++)
            {
                string hex = ((int)cs[i]).ToString("X");
                sb.AppendFormat("{0} ", hex);
            }
            return sb.ToString().TrimEnd(' ');
        }

        /// <summary>
        /// HEX to ASCII
        /// </summary>
        /// <param name="hex"></param>
        /// <returns></returns>
        public static string HexToASCII(string hex)
        {
            if (hex.Length % 2 == 0)
            {
                int iValue;
                byte[] bs;
                string sValue = string.Empty;
                string result = string.Empty;
                int length = hex.Length / 2;

                for (int i = 0; i < length; i++)
                {
                    iValue = Convert.ToInt32(hex.Substring(i * 2, 2), 16); // 16进制->10进制
                    bs = System.BitConverter.GetBytes(iValue); //int->byte[]
                    sValue = System.Text.Encoding.ASCII.GetString(bs, 0, 1);  //byte[]-> ASCII
                    result += char.Parse(sValue).ToString();
                }
                return result.PadLeft(length, '0');
            }
            return string.Empty;
        }

        /// <summary>
        /// ASCII To Float
        /// </summary>
        /// <param name="ascii"></param>
        /// <returns></returns>
        public static float ASCIIToFloat(string ascii)
        {
            if (ascii.Length == 8)
            {
                byte[] arr = new byte[4];
                for (int i = 0; i < 4; i++)
                {

                    arr[i] = Convert.ToByte(ascii.Substring((3 - i) * 2, 2), 16);
                }
                float f = BitConverter.ToSingle(arr, 0);
                return f;
            }
            return 0f;
        }

        /// <summary>
        /// Hex to Float
        /// </summary>
        /// <param name="hex"></param>
        /// <returns></returns>
        public static float HexToFloat(string hex)
        {
            string ascii = HexToASCII(hex);
            float f = ASCIIToFloat(ascii);
            return f;
        }
        #endregion
    }
}

 

 


                

C#初入串口通信(串行通信)总结

使用WinFrom来实现: 首先要知道串口通信协议以及原理 原理大概提一下:要自己翻阅看。(http://book.51cto.com/art/200911/162532.htm或者http://...
  • xujunheng
  • xujunheng
  • 2014年09月09日 19:07
  • 10726

C#.net串口通信详解!

VS.NET2005中SerialPort控件操作详解——C#语言编写(VS 2008基本一致)       (实例编写的是一个使用SerialPort类进行串口通讯,并读取和接受COM端的数据) ...
  • XueminXu
  • XueminXu
  • 2012年10月02日 13:36
  • 1769

C#串口通信程序SerialPort类

上篇文章主要是关于串口通信中单片机部分的程序编写。在实际应用中,常常还要有上位机的配合才能完成工作。写串口通信的上位机程序,常常应用的编程语言有C++,VB,C#等。VB没有学过,C++编写窗口应用程...
  • xmfthu
  • xmfthu
  • 2012年08月23日 11:57
  • 6442

在C#中实现串口通信的方法

通常,在C#中实现串口通信,我们有四种方法: 第一:通过MSCOMM控件这是最简单的,最方便的方法。可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册,不在本文讨论范围。可以访问h...
  • smartsmile2012
  • smartsmile2012
  • 2014年04月22日 17:28
  • 2762

C#做一个简单的进行串口通信的上位机

C#做一个简单的进行串口通信的上位机 乱世中的单纯 发布于 1年前,共有 10 条评论 1、上位机与下位机         上位机相当于一个软件系统,可以用于接收数据、控制数据。即可以对...
  • kasama1953
  • kasama1953
  • 2016年05月14日 08:46
  • 27490

用C#一步步写串口通信

用C#一步步写串口通信 标签: c#textboxbuttonobjectstring 2012-08-10 14:57 18916人阅读 评论(38) 收藏 举报  分类:...
  • kasama1953
  • kasama1953
  • 2016年05月17日 10:43
  • 55914

C#中串口通信编程[转载]

本文将介绍如何在.NET平台下使用C#创建串口通信程序,.NET 2.0提供了串口通信的功能,其命名 空间是System.IO.Ports。这个新的框架不但可以访问计算机上的串口,还可以和串口设...
  • fwj380891124
  • fwj380891124
  • 2012年08月11日 18:02
  • 8156

简单的C#串口通讯例子(附源文件)

由于公司需求所以就查了一些资料写了个串口和设备通讯的 话说现在用串口的应该比较少了吧。 先上一张程序UI图 简单串口通讯必备的东西都在这里了。个人建议使用的时候先短接2-3口进行...
  • koloumi
  • koloumi
  • 2017年03月07日 12:54
  • 805

C#串口通信源代码

界面 源码:下载参考了以下两篇文章: http://blog.csdn.net/geekwangminli/article/details/7851673 http://blog.csdn.ne...
  • yinnan0422
  • yinnan0422
  • 2016年05月10日 19:13
  • 2238

C#串口通讯实例

C#串口通讯实例 参考《C#网络通信程序设计》 serialport
  • song430
  • song430
  • 2016年12月19日 20:27
  • 482
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C# 串口通信
举报原因:
原因补充:

(最多只允许输入30个字)