关闭

C# 串口通信

845人阅读 评论(0) 收藏 举报
 串口通讯类: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
    }
}

 

 


   
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:42073次
    • 积分:761
    • 等级:
    • 排名:千里之外
    • 原创:33篇
    • 转载:16篇
    • 译文:3篇
    • 评论:16条
    最新评论